少年阿賓

          那些青春的歲月

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks

          #

          import MySQLdb
          import time
          try:
              conn=MySQLdb.connect(host='localhost',user='root',passwd='',db='abin',port=3306)
              cur=conn.cursor()
              result=cur.execute('select * from tabin')
              print result
              print '-------'
              info=cur.fetchmany(result)
              for ii in info:
                  currentTime = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
                  values=[ii[1],currentTime]
                  cur.execute('insert into sabin (name,create_time) values (%s,%s)',values)
                  print '===='
              cur.close()
              conn.commit()
              conn.close()
          except MySQLdb.Error,e:
              print "Mysql Error %d: %s % ()e.args[0],e.args[1]"



          import urllib
          params = urllib.urlencode({'type':'mobile','parameter':'13521502037','pageNum':1,'pageSize':10})
          conn = urllib.urlopen("http://test.qunar.com:7400/complaints/find.action",params);
          result = conn.read()
          print result
          posted @ 2015-01-28 11:57 abin 閱讀(424) | 評論 (0)編輯 收藏

          一 前言
              tomcat的運行模式有3種.修改他們的運行模式.3種模式的運行是否成功,可以看他的啟動控制臺,或者啟動日志.或者登錄他們的默認頁面http://localhost:8080/查看其中的服務器狀態。

          二 bio
          默認的模式 blocking IO,性能非常低下,沒有經過任何優化處理和支持.

          三 nio
          利用java的異步io護理技術,no blocking IO技術.
          想運行在該模式下,直接修改server.xml里的Connector節點,修改protocol為
          <Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol"
          connectionTimeout="20000"
          URIEncoding="UTF-8"
          useBodyEncodingForURI="true"
          enableLookups="false"
          redirectPort="8443" />
          啟動后,就可以生效。性能得到初步優化但與apr相比,還是有一些差距。

          四 apr
          安裝起來最困難,但是從操作系統級別來解決異步的IO問題,大幅度的提高性能.
          必須要安裝apr和native,直接啟動就支持apr。
          下面的修改純屬多余,僅供大家擴充知識,但仍然需要安裝apr和native
          如nio修改模式,修改protocol為org.apache.coyote.http11.Http11AprProtocol

          五 補充
          1)安裝APR的方法,請看我另一篇博客http://phl.iteye.com/blog/910984;
          2)關于性能數據請讀者們自行研究,筆者不是在寫教科書在此只是給出思路,性能研究是個很深的領域,請各位按需自行搭建環境測試;
          3)總的來說,bio是不推薦使用的,apr的模式推薦;

          item protocol Requests per second
          BIO org.apache.coyote.http11.Http11Protocol 916.06 [#/sec] (mean)
          NIO org.apache.coyote.http11.Http11NioProtocol 2102.26 [#/sec] (mean)
          APR org.apache.coyote.http11.Http11AprProtocol 1997.24 [#/sec] (mean)




          http://phl.iteye.com/blog/910996
          posted @ 2015-01-23 12:09 abin 閱讀(435) | 評論 (0)編輯 收藏


          先來個例子理解一下概念,以銀行取款為例:

          • 同步 : 自己親自出馬持銀行卡到銀行取錢(使用同步IO時,Java自己處理IO讀寫)。

          • 異步 : 委托一小弟拿銀行卡到銀行取錢,然后給你(使用異步IO時,Java將IO讀寫委托給OS處理,需要將數據緩沖區地址和大小傳給OS(銀行卡和密碼),OS需要支持異步IO操作API)。

          • 阻塞 : ATM排隊取款,你只能等待(使用阻塞IO時,Java調用會一直阻塞到讀寫完成才返回)。

          • 非阻塞 : 柜臺取款,取個號,然后坐在椅子上做其它事,等號廣播會通知你辦理,沒到號你就不能去,你可以不斷問大堂經理排到了沒有,大堂經理如果說還沒到你就不能去(使用非阻塞IO時,如果不能讀寫Java調用會馬上返回,當IO事件分發器會通知可讀寫時再繼續進行讀寫,不斷循環直到讀寫完成)。


          Java對BIO、NIO、AIO的支持

          • Java BIO : 同步并阻塞,服務器實現模式為一個連接一個線程,即客戶端有連接請求時服務器端就需要啟動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷,當然可以通過線程池機制改善。

          • Java NIO : 同步非阻塞,服務器實現模式為一個請求一個線程,即客戶端發送的連接請求都會注冊到多路復用器上,多路復用器輪詢到連接有I/O請求時才啟動一個線程進行處理。

          • Java AIO(NIO.2) : 異步非阻塞,服務器實現模式為一個有效請求一個線程,客戶端的I/O請求都是由OS先完成了再通知服務器應用去啟動線程進行處理,


          BIO、NIO、AIO適用場景分析:

          • BIO方式適用于連接數目比較小且固定的架構,這種方式對服務器資源要求比較高,并發局限于應用中,JDK1.4以前的唯一選擇,但程序直觀簡單易理解。

          • NIO方式適用于連接數目多且連接比較短(輕操作)的架構,比如聊天服務器,并發局限于應用中,編程比較復雜,JDK1.4開始支持。

          • AIO方式使用于連接數目多且連接比較長(重操作)的架構,比如相冊服務器,充分調用OS參與并發操作,編程比較復雜,JDK7開始支持。


          另外,I/O屬于底層操作,需要操作系統支持,并發也需要操作系統的支持,所以性能方面不同操作系統差異會比較明顯。


          本文出自 “力量來源于赤誠的愛!” 博客,請務必保留此出處http://stevex.blog.51cto.com/4300375/1284437

          posted @ 2015-01-23 12:08 abin 閱讀(574) | 評論 (0)編輯 收藏

          一、線程池的創建

          我們可以通過ThreadPoolExecutor來創建一個線程池。

          new  ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, milliseconds,runnableTaskQueue, handler);

          創建一個線程池需要輸入幾個參數:

          • corePoolSize(線程池的基本大小):當提交一個任務到線程池時,線程池會創建一個線程來執行任務,即使其他空閑的基本線程能夠執行新任務也會創建線程,等到需要執行的任務數大于線程池基本大小時就不再創建。如果調用了線程池的prestartAllCoreThreads方法,線程池會提前創建并啟動所有基本線程。
          • runnableTaskQueue(任務隊列):用于保存等待執行的任務的阻塞隊列。 可以選擇以下幾個阻塞隊列。
            • ArrayBlockingQueue:是一個基于數組結構的有界阻塞隊列,此隊列按 FIFO(先進先出)原則對元素進行排序。
            • LinkedBlockingQueue:一個基于鏈表結構的阻塞隊列,此隊列按FIFO (先進先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。靜態工廠方法Executors.newFixedThreadPool()使用了這個隊列。
            • SynchronousQueue:一個不存儲元素的阻塞隊列。每個插入操作必須等到另一個線程調用移除操作,否則插入操作一直處于阻塞狀態,吞吐量通常要高于LinkedBlockingQueue,靜態工廠方法Executors.newCachedThreadPool使用了這個隊列。
            • PriorityBlockingQueue:一個具有優先級的無限阻塞隊列。
          • maximumPoolSize(線程池最大大小):線程池允許創建的最大線程數。如果隊列滿了,并且已創建的線程數小于最大線程數,則線程池會再創建新的線程執行任務。值得注意的是如果使用了無界的任務隊列這個參數就沒什么效果。
          • ThreadFactory:用于設置創建線程的工廠,可以通過線程工廠給每個創建出來的線程設置更有意義的名字。
          • RejectedExecutionHandler(飽和策略):當隊列和線程池都滿了,說明線程池處于飽和狀態,那么必須采取一種策略處理提交的新任務。這個策略默認情況下是AbortPolicy,表示無法處理新任務時拋出異常。以下是JDK1.5提供的四種策略。
            • AbortPolicy:直接拋出異常。
            • CallerRunsPolicy:只用調用者所在線程來運行任務。
            • DiscardOldestPolicy:丟棄隊列里最近的一個任務,并執行當前任務。
            • DiscardPolicy:不處理,丟棄掉。
            • 當然也可以根據應用場景需要來實現RejectedExecutionHandler接口自定義策略。如記錄日志或持久化不能處理的任務。
          • keepAliveTime(線程活動保持時間):線程池的工作線程空閑后,保持存活的時間。所以如果任務很多,并且每個任務執行的時間比較短,可以調大這個時間,提高線程的利用率。
          • TimeUnit(線程活動保持時間的單位):可選的單位有天(DAYS),小時(HOURS),分鐘(MINUTES),毫秒(MILLISECONDS),微秒(MICROSECONDS, 千分之一毫秒)和毫微秒(NANOSECONDS, 千分之一微秒)。

           

          二、Executors提供了一些方便創建ThreadPoolExecutor的常用方法,主要有以下幾個:

          1、 Executors.newFixedThreadPool(int nThreads);創建固定大小(nThreads,大小不能超過int的最大值)的線程池

          //線程數量

           int nThreads = 20;

          //創建executor 服務 

           ExecutorService executor = Executors.newFixedThreadPool(nThreads) ;

          重載后的版本,需要多傳入實現了ThreadFactory接口的對象。

           ExecutorService executor = Executors. newFixedThreadPool(nThreads,threadFactory);

          說明:創建固定大小(nThreads,大小不能超過int的最大值)的線程池,緩沖任務的隊列為LinkedBlockingQueue,大小為整型的最大數,當使用此線程池時,在同執行的任務數量超過傳入的線程池大小值后,將會放入LinkedBlockingQueue,在LinkedBlockingQueue中的任務需要等待線程空閑后再執行,如果放入LinkedBlockingQueue中的任務超過整型的最大數時,拋出RejectedExecutionException。

          2、Executors.newSingleThreadExecutor():創建大小為1的固定線程池。

           ExecutorService executor = Executors.newSingleThreadExecutor();

          重載后的版本,需要多傳入實現了ThreadFactory接口的對象。

           ExecutorService executor = Executors. newSingleThreadScheduledExecutor(ThreadFactory threadFactory) 

          說明:創建大小為1的固定線程池,同時執行任務(task)的只有一個,其它的(任務)task都放在LinkedBlockingQueue中排隊等待執行。

          3、Executors.newCachedThreadPool();創建corePoolSize為0,最大線程數為整型的最大數,線程keepAliveTime為1分鐘,緩存任務的隊列為SynchronousQueue的線程池。

           ExecutorService executor = Executors.newCachedThreadPool();

          當然也可以以下面的方式創建,重載后的版本,需要多傳入實現了ThreadFactory接口的對象。

           ExecutorService executor = Executors.newCachedThreadPool(ThreadFactory threadFactory) ;

          說明:使用時,放入線程池的task任務會復用線程或啟動新線程來執行,注意事項:啟動的線程數如果超過整型最大值后會拋出RejectedExecutionException異常,啟動后的線程存活時間為一分鐘。

          4、Executors.newScheduledThreadPool(int corePoolSize):創建corePoolSize大小的線程池。

          //線程數量

           int corePoolSize= 20;

          //創建executor 服務 

           ExecutorService executor = Executors.newScheduledThreadPool(corePoolSize) ;

          重載后的版本,需要多傳入實現了ThreadFactory接口的對象。

           ExecutorService executor = Executors.newScheduledThreadPool(corePoolSize, threadFactory) ;

          說明:線程keepAliveTime為0,緩存任務的隊列為DelayedWorkQueue,注意不要超過整型的最大值。







          posted @ 2015-01-21 22:18 abin 閱讀(537) | 評論 (0)編輯 收藏

          1、volatile

          volatile字段的寫入操作happens-before于每一個后續的同一個字段的讀操作。

          因為實際上putremove等操作也會更新count的值,所以當競爭發生的時候,volatile的語義可以保證寫操作在讀操作之前,也就保證了寫操作對后續的讀操作都是可見的,這樣后面get的后續操作就可以拿到完整的元素內容。

          使用建議:在兩個或者更多的線程訪問的成員變量上使用volatile。當要訪問的變量已在synchronized代碼塊中,或者為常量時,不必使用。


          volatile實際上只有在多cpu或者多核下才有用。當讀取數據時,他不會cache緩存中讀取,而是強制從內從中讀取,這樣讀到的就是最新值。當寫入數據的時候,會直接將數據寫入內存中,并刷新所有其他核中的緩存,這樣其他核看到的就是最新寫入的值,也就是說,其他線程就看到了最新寫入的值。

          一般說來,volatile用在如下的幾個地方:

          1、中斷服務程序中修改的供其它程序檢測的變量需要加volatile;

          2、多任務環境下各任務間共享的標志應該加volatile;

          3、存儲器映射的硬件寄存器通常也要加volatile說明,因為每次對它的讀寫都可能由不同意義;


          聲明方式為  volatile declaration


          備注
          系統總是在 volatile 對象被請求的那一刻讀取其當前值,即使上一條指令從同一對象請求值。而且,該對象的值在賦值時立即寫入。

          volatile 修飾符通常用于由多個線程訪問而不使用 lock 語句來序列化訪問的字段。使用 volatile 修飾符能夠確保一個線程檢索由另一線程寫入的最新值。


          posted @ 2015-01-18 21:08 abin 閱讀(390) | 評論 (0)編輯 收藏

          讀文件的方法:

          第一步: 將文件的內容通過管道(|)或重定向(<)的方式傳給while

          第二步: while中調用read將文件內容一行一行的讀出來,并付值給read后跟隨的變量。變量中就保存了當前行中的內容。

          例如讀取文件/sites/linuxpig.com.txt

          1)管道的方式:
           
               cat /sites/linuxpig.com.txt |while read LINE
               do
                   echo $LINE
               done

              當然也可以將cat /sites/linuxpig.com.txt 寫成一些復雜一些的,比如:
              
              示例1:
              find -type f -name "*.txt" -exec cat |while read LINE
               do
                   echo $LINE
               done
              可以將當前目錄所有以 .txt 結尾的文件讀出
              
              示例2:
              grep -r "linuxpig.com" ./ | awk -F":" '{print $1}' | cat |while read LINE
               do
                   echo $LINE
               done

              可以將含有 "linuxpig.com" 字符串的所有文件打開并讀取。。

              示例沒有實際測試,如果使用請先測試。。。。。:-)
              

          2)重定向的方式:

            2.1 利用重定向符<

               while read LINE
               do
                   echo $LINE
               done < /sites/linuxpig.com.txt

            2.2 利用文件描述符(0~9)和重定向符 <

               exec 3<&0
               exec 0</sites/linuxpig.com.txt
               while read LINE
               do
                   echo $LINE
               done
               exec 0<&3

          posted @ 2015-01-13 12:59 abin 閱讀(505) | 評論 (1)編輯 收藏

          ZooKeeper是一個高可用的分布式數據管理與系統協調框架。基于對Paxos算法的實現,使該框架保證了分布式環境中數據的強一致性,也正是基于這樣的特性,使得ZooKeeper解決很多分布式問題。網上對ZK的應用場景也有不少介紹,本文將結合作者身邊的項目例子,系統地對ZK的應用場景進行一個分門歸類的介紹。

          值得注意的是,ZK并非天生就是為這些應用場景設計的,都是后來眾多開發者根據其框架的特性,利用其提供的一系列API接口(或者稱為原語集),摸索出來的典型使用方法。因此,也非常歡迎讀者分享你在ZK使用上的奇技淫巧。

           ZooKeeper典型應用場景一覽

          數據發布與訂閱(配置中心)
          發布與訂閱模型,即所謂的配置中心,顧名思義就是發布者將數據發布到ZK節點上,供訂閱者動態獲取數據,實現配置信息的集中式管理和動態更新。例如全局的配置信息,服務式服務框架的服務地址列表等就非常適合使用。
              1. 應用中用到的一些配置信息放到ZK上進行集中管理。這類場景通常是這樣:應用在啟動的時候會主動來獲取一次配置,同時,在節點上注冊一個Watcher,這樣一來,以后每次配置有更新的時候,都會實時通知到訂閱的客戶端,從來達到獲取最新配置信息的目的。
              2. 分布式搜索服務中,索引的元信息和服務器集群機器的節點狀態存放在ZK的一些指定節點,供各個客戶端訂閱使用。
              3. 分布式日志收集系統。這個系統的核心工作是收集分布在不同機器的日志。收集器通常是按照應用來分配收集任務單元,因此需要在ZK上創建一個以應用名作為path的節點P,并將這個應用的所有機器ip,以子節點的形式注冊到節點P上,這樣一來就能夠實現機器變動的時候,能夠實時通知到收集器調整任務分配。
              4. 系統中有些信息需要動態獲取,并且還會存在人工手動去修改這個信息的發問。通常是暴露出接口,例如JMX接口,來獲取一些運行時的信息。引入ZK之后,就不用自己實現一套方案了,只要將這些信息存放到指定的ZK節點上即可。
          注意:在上面提到的應用場景中,有個默認前提是:數據量很小,但是數據更新可能會比較快的場景。
          負載均衡
          這里說的負載均衡是指軟負載均衡。在分布式環境中,為了保證高可用性,通常同一個應用或同一個服務的提供方都會部署多份,達到對等服務。而消費者就須要在這些對等的服務器中選擇一個來執行相關的業務邏輯,其中比較典型的是消息中間件中的生產者,消費者負載均衡。

          消息中間件中發布者和訂閱者的負載均衡,linkedin開源的KafkaMQ和阿里開源的metaq都是通過zookeeper來做到生產者、消費者的負載均衡。這里以metaq為例如講下:

          生產者負載均衡:metaq發送消息的時候,生產者在發送消息的時候必須選擇一臺broker上的一個分區來發送消息,因此metaq在運行過程中,會把所有broker和對應的分區信息全部注冊到ZK指定節點上,默認的策略是一個依次輪詢的過程,生產者在通過ZK獲取分區列表之后,會按照brokerId和partition的順序排列組織成一個有序的分區列表,發送的時候按照從頭到尾循環往復的方式選擇一個分區來發送消息。

          消費負載均衡: 在消費過程中,一個消費者會消費一個或多個分區中的消息,但是一個分區只會由一個消費者來消費。MetaQ的消費策略是:

              1. 每個分區針對同一個group只掛載一個消費者。
              2. 如果同一個group的消費者數目大于分區數目,則多出來的消費者將不參與消費。
              3. 如果同一個group的消費者數目小于分區數目,則有部分消費者需要額外承擔消費任務。
                在某個消費者故障或者重啟等情況下,其他消費者會感知到這一變化(通過 zookeeper watch消費者列表),然后重新進行負載均衡,保證所有的分區都有消費者進行消費。
          命名服務(Naming Service)
          命名服務也是分布式系統中比較常見的一類場景。在分布式系統中,通過使用命名服務,客戶端應用能夠根據指定名字來獲取資源或服務的地址,提供者等信息。被命名的實體通常可以是集群中的機器,提供的服務地址,遠程對象等等——這些我們都可以統稱他們為名字(Name)。其中較為常見的就是一些分布式服務框架中的服務地址列表。通過調用ZK提供的創建節點的API,能夠很容易創建一個全局唯一的path,這個path就可以作為一個名稱。

          阿里巴巴集團開源的分布式服務框架Dubbo中使用ZooKeeper來作為其命名服務,維護全局的服務地址列表,點擊這里查看Dubbo開源項目。在Dubbo實現中:

          服務提供者在啟動的時候,向ZK上的指定節點/dubbo/${serviceName}/providers目錄下寫入自己的URL地址,這個操作就完成了服務的發布。

          服務消費者啟動的時候,訂閱/dubbo/${serviceName}/providers目錄下的提供者URL地址, 并向/dubbo/${serviceName} /consumers目錄下寫入自己的URL地址。

          注意,所有向ZK上注冊的地址都是臨時節點,這樣就能夠保證服務提供者和消費者能夠自動感應資源的變化。 另外,Dubbo還有針對服務粒度的監控,方法是訂閱/dubbo/${serviceName}目錄下所有提供者和消費者的信息。

          分布式通知/協調
          ZooKeeper中特有watcher注冊與異步通知機制,能夠很好的實現分布式環境下不同系統之間的通知與協調,實現對數據變更的實時處理。使用方法通常是不同系統都對ZK上同一個znode進行注冊,監聽znode的變化(包括znode本身內容及子節點的),其中一個系統update了znode,那么另一個系統能夠收到通知,并作出相應處理
              1. 另一種心跳檢測機制:檢測系統和被檢測系統之間并不直接關聯起來,而是通過zk上某個節點關聯,大大減少系統耦合。
              2. 另一種系統調度模式:某系統有控制臺和推送系統兩部分組成,控制臺的職責是控制推送系統進行相應的推送工作。管理人員在控制臺作的一些操作,實際上是修改了ZK上某些節點的狀態,而ZK就把這些變化通知給他們注冊Watcher的客戶端,即推送系統,于是,作出相應的推送任務。
              3. 另一種工作匯報模式:一些類似于任務分發系統,子任務啟動后,到zk來注冊一個臨時節點,并且定時將自己的進度進行匯報(將進度寫回這個臨時節點),這樣任務管理者就能夠實時知道任務進度。
          總之,使用zookeeper來進行分布式通知和協調能夠大大降低系統之間的耦合
          集群管理與Master選舉
              1. 集群機器監控:這通常用于那種對集群中機器狀態,機器在線率有較高要求的場景,能夠快速對集群中機器變化作出響應。這樣的場景中,往往有一個監控系統,實時檢測集群機器是否存活。過去的做法通常是:監控系統通過某種手段(比如ping)定時檢測每個機器,或者每個機器自己定時向監控系統匯報“我還活著”。 這種做法可行,但是存在兩個比較明顯的問題:
                  1. 集群中機器有變動的時候,牽連修改的東西比較多。
                  2. 有一定的延時。

                  利用ZooKeeper有兩個特性,就可以實現另一種集群機器存活性監控系統:

                  1. 客戶端在節點 x 上注冊一個Watcher,那么如果 x?的子節點變化了,會通知該客戶端。
                  2. 創建EPHEMERAL類型的節點,一旦客戶端和服務器的會話結束或過期,那么該節點就會消失。

                 例如,監控系統在 /clusterServers 節點上注冊一個Watcher,以后每動態加機器,那么就往 /clusterServers 下創建一個 EPHEMERAL類型的節點:/clusterServers/{hostname}. 這樣,監控系統就能夠實時知道機器的增減情況,至于后續處理就是監控系統的業務了。

              2. Master選舉則是zookeeper中最為經典的應用場景了。

          在分布式環境中,相同的業務應用分布在不同的機器上,有些業務邏輯(例如一些耗時的計算,網絡I/O處理),往往只需要讓整個集群中的某一臺機器進行執行,其余機器可以共享這個結果,這樣可以大大減少重復勞動,提高性能,于是這個master選舉便是這種場景下的碰到的主要問題。

          利用ZooKeeper的強一致性,能夠保證在分布式高并發情況下節點創建的全局唯一性,即:同時有多個客戶端請求創建 /currentMaster 節點,最終一定只有一個客戶端請求能夠創建成功。利用這個特性,就能很輕易的在分布式環境中進行集群選取了。

          另外,這種場景演化一下,就是動態Master選舉。這就要用到EPHEMERAL_SEQUENTIAL類型節點的特性了。

          上文中提到,所有客戶端創建請求,最終只有一個能夠創建成功。在這里稍微變化下,就是允許所有請求都能夠創建成功,但是得有個創建順序,于是所有的請求最終在ZK上創建結果的一種可能情況是這樣: /currentMaster/{sessionId}-1 ,/currentMaster/{sessionId}-2,/currentMaster/{sessionId}-3 ….. 每次選取序列號最小的那個機器作為Master,如果這個機器掛了,由于他創建的節點會馬上小時,那么之后最小的那個機器就是Master了。

              1. 在搜索系統中,如果集群中每個機器都生成一份全量索引,不僅耗時,而且不能保證彼此之間索引數據一致。因此讓集群中的Master來進行全量索引的生成,然后同步到集群中其它機器。另外,Master選舉的容災措施是,可以隨時進行手動指定master,就是說應用在zk在無法獲取master信息時,可以通過比如http方式,向一個地方獲取master。
              2. 在Hbase中,也是使用ZooKeeper來實現動態HMaster的選舉。在Hbase實現中,會在ZK上存儲一些ROOT表的地址和HMaster的地址,HRegionServer也會把自己以臨時節點(Ephemeral)的方式注冊到Zookeeper中,使得HMaster可以隨時感知到各個HRegionServer的存活狀態,同時,一旦HMaster出現問題,會重新選舉出一個HMaster來運行,從而避免了HMaster的單點問題
          分布式鎖

          分布式鎖,這個主要得益于ZooKeeper為我們保證了數據的強一致性。鎖服務可以分為兩類,一個是保持獨占,另一個是控制時序

              1. 所謂保持獨占,就是所有試圖來獲取這個鎖的客戶端,最終只有一個可以成功獲得這把鎖。通常的做法是把zk上的一個znode看作是一把鎖,通過create znode的方式來實現。所有客戶端都去創建 /distribute_lock 節點,最終成功創建的那個客戶端也即擁有了這把鎖。
              2. 控制時序,就是所有視圖來獲取這個鎖的客戶端,最終都是會被安排執行,只是有個全局時序了。做法和上面基本類似,只是這里 /distribute_lock 已經預先存在,客戶端在它下面創建臨時有序節點(這個可以通過節點的屬性控制:CreateMode.EPHEMERAL_SEQUENTIAL來指定)。Zk的父節點(/distribute_lock)維持一份sequence,保證子節點創建的時序性,從而也形成了每個客戶端的全局時序。

          分布式隊列
          隊列方面,簡單地講有兩種,一種是常規的先進先出隊列,另一種是要等到隊列成員聚齊之后的才統一按序執行。對于第一種先進先出隊列,和分布式鎖服務中的控制時序場景基本原理一致,這里不再贅述。 第二種隊列其實是在FIFO隊列的基礎上作了一個增強。通常可以在 /queue 這個znode下預先建立一個/queue/num 節點,并且賦值為n(或者直接給/queue賦值n),表示隊列大小,之后每次有隊列成員加入后,就判斷下是否已經到達隊列大小,決定是否可以開始執行了。這種用法的典型場景是,分布式環境中,一個大任務Task A,需要在很多子任務完成(或條件就緒)情況下才能進行。這個時候,凡是其中一個子任務完成(就緒),那么就去 /taskList 下建立自己的臨時時序節點(CreateMode.EPHEMERAL_SEQUENTIAL),當 /taskList 發現自己下面的子節點滿足指定個數,就可以進行下一步按序進行處理了。

           

          本文出自 “專欄:Paxos與ZooKeeper” 博客,請務必保留此出處http://nileader.blog.51cto.com/1381108/1040007

          posted @ 2015-01-11 02:57 abin 閱讀(537) | 評論 (0)編輯 收藏

          1、free -m
          2、uptime
          3、vmstat 1 5
          4、iostat -x -h -t
          5、mpstat -P ALL
          6、netstat -natp | grep 8080
          7、netstat -natp | find "80"(windows)
          8、ps -aux | grep java
          9、ps -ef | grep java
          10、top -H -p 9768
          posted @ 2015-01-11 02:42 abin 閱讀(448) | 評論 (0)編輯 收藏

          1、把命令結果賦值給變量
          #!/bash/bin
          echo "1 2 3 4"|awk '{print $1}'
          temp=`echo "1 2 3 4"|awk '{print $1}'`;
          echo $temp;
          2、




















          posted @ 2015-01-11 01:23 abin 閱讀(462) | 評論 (0)編輯 收藏


             for in 格式
          for 無$變量 in 字符串
          do
            $變量
          done
          一簡單的字符串 枚舉遍歷法,利用for in格式對字符串按空格切份的功能

          SERVICES="80   22   25   110   8000   23   20   21   3306   "

          for   x   in   $SERVICES    
            do     
            iptables   -A   INPUT   -p   tcp   --dport   $x   -m   state   --state   NEW   -j   ACCEPT     
            done 

            
              for variable in values   --------字符串數組依次賦值
          #!/bin/sh
          for i in a b c           字符串列表A B C 
                   字符串用空格分隔,沒有括號,沒有逗號, 然后循環將其依次賦給變量i
                   變量沒有$
          do
          echo "i is $i"
          done  
          [macg@machome ~]$ sh test.sh
          i is a
          i is b
          i is c


              for in 里,變量和*不等價
          #!/bin/bash

          for i in *.h ;
          do
          cat ${i}.h
          done  
          [macg@vm test]$ ./tip.sh
          cat: *.h.h: No such file or directory 
          $i代表的是整個路徑,而不是*.h里的.h前面的部分
          改正
          #!/bin/bash

          for i in *.h
          do
          cat $i
          done  
          [macg@vm test]$ echo hahaha >>1.h
          [macg@vm test]$ echo ha >>2.h

          [macg@vm test]$ ./tip.sh
          hahaha
          ha    
          例2:
          for i in /etc/profile.d/*.sh 
           do
            $i
          done  
           $i代表的是/etc/profile.d/color.sh,
          /etc/profile.d/alias.sh, /etc/profile.d/default.sh

                    
              for in 對(命令行,函數)參數遍歷
          test()
          {
                  local i

                  for i in $* ; do
                       echo "i is $i"
                  done
            
          $*是字符串:以"參數1 參數2 ... " 形式保存所有參數 
          $i是變量i的應用表示
          [macg@machome ~]$ sh test.sh p1 p2 p3 p4

          i is p1
          i is p2
          i is p3
          i is p4 


              for in語句與通配符*合用,批量處理文件
              批量改文件名
          [root@vm testtip]# ls
          aaa.txt  ccc.txt  eee.txt  ggg.txt  hhh.txt  jjj.txt  lll.txt  nnn.txt
          bbb.txt  ddd.txt  fff.txt  go.sh    iii.txt  kkk.txt  mmm.txt  ooo.txt
          [root@vm testtip]# cat go.sh
          for i in *.txt                 *.txt相當于一個字符串數組,依次循環賦值給i
          do
          mv "$i" "$i.bak"       
          done
          [root@vm testtip]# sh go.sh

          [root@vm testtip]# ls
          aaa.txt.bak  ccc.txt.bak  eee.txt.bak  ggg.txt.bak  hhh.txt.bak  jjj.txt.bak  lll.txt.bak  nnn.txt.bak bbb.txt.bak  ddd.txt.bak  fff.txt.bak  go.sh        iii.txt.bak  kkk.txt.bak  mmm.txt.bak  ooo.txt.bak

              for in語句與` `和$( )合用,利用` `或$( )的將多行合為一行的缺陷,實際是合為一個字符串數組
          for i in $(ls *.txt)        
          do
          echo $i
          done
          [macg@machome ~]$ sh test
          111-tmp.txt
          111.txt
          22.txt
          33.txt
          或者說,利用for in克服` `和$( ) 的多行合為一行的缺陷


             利用for in 自動對字符串按空格遍歷的特性,對多個目錄遍歷
          LIST="rootfs usr data data2"
             
          for d in $LIST; do         
            mount /backup/$d
            rsync -ax --exclude fstab --delete /$d/ /backup/$d/
            umount /backup/$d
          done    

          posted @ 2015-01-10 22:06 abin 閱讀(4156) | 評論 (0)編輯 收藏

          僅列出標題
          共50頁: First 上一頁 5 6 7 8 9 10 11 12 13 下一頁 Last 
          主站蜘蛛池模板: 留坝县| 屏山县| 杭州市| 万山特区| 永川市| 南陵县| 长沙市| 定南县| 平凉市| 乌拉特中旗| 黄浦区| 遂溪县| 赤壁市| 南雄市| 双流县| 溆浦县| 信丰县| 齐齐哈尔市| 淮北市| 图木舒克市| 钦州市| 宜兴市| 罗城| 沐川县| 兴化市| 贞丰县| 云南省| 乌拉特前旗| 高清| 彭州市| 探索| 石狮市| 平果县| 洱源县| 高碑店市| 兖州市| 霍城县| 昌图县| 松原市| 山东省| 威海市|