1、前言html
ZooKeeper
的功能特性經過ZooKeeper
配置文件來進行控制管理( zoo.cfg
配置文件)。 ZooKeeper這樣的設計實際上是有它自身的緣由的。經過前面對ZooKeeper
的配置能夠看出,對ZooKeeper
集羣進行配置的時候,它的配置文檔是徹底相同的(對於集羣僞分佈模式來講,只有不多的部分是不一樣的)。這樣的配置方使得在部署ZooKeeper
服務的時候很是地方便。另外,若是服務器使用不一樣的配置文件,必需要確保不一樣配置文件中的服務器列表相匹配。java
在設置ZooKeeper
配置文檔的時候,某些參數是可選的,可是某些參數是必須的。這些必須的參數就構成了ZooKeeper
配置文檔的最低配置要求。算法
最近發如今用zookeeper出現常常出現鏈接超時,出現鏈接中斷,數據丟失等緣由。後面看了官網配置本身整理優化幾點:數據庫
2.1錯誤日誌: 2016-04-11 15:00:58,981 [myid:] - WARN [SyncThread:0:FileTxnLog@334] - fsync-ing the write ahead log in SyncThread:0 took 13973ms which will adversely effect operation latency. See the ZooKeeper troubleshooting guide >2.2,錯誤緣由分析 「FOLLOWER」在跟「LEADER」同步時,fsync操做時間過長,致使超時。 第一步:分析服務器問題: 我查看了服務器io和負載都不高。內存空間實際使用率不高。但是編輯文件出現了卡頓. 能夠發現: 服務器並無佔用不少內存的進程; 服務器也沒有存在不少的進程; cat /var/log/message查看系統日誌並無發現什麼異常; 另外ping服務器只有0.1ms多的延遲,所以不是網絡問題。 後面發現硬盤有故障從新更換了一塊硬盤。或者更換服務器。 >2.3,錯誤解決 增長「tickTime」或者「initLimit和syncLimit」的值,或者二者都增大。 >2.4,其餘 這個錯誤在上線「使用ZooKeeper獲取地址方案」以前也存在,只不過過沒有這麼高頻率,而上線了「ZooKeeper獲取地址方案」以後,ZooKeeper Server之間的同步數據量增大,ZooKeeper Server的負載加劇,於是最終致使高頻率出現上述錯誤。
2、配置文件:apache
下面是在最低配置要求中必須配置的參數:安全
### 最小配置 最小配置意味着全部的配置文件中必需要包含這些配置選項。 #### clientPort 服務器監聽客戶端鏈接的端口,亦即客戶端嘗試鏈接到服務器上的指定端口。 ##### dataDir ZooKeeper存儲內存數據庫快照文件的路徑,而且若是沒有指定其它路徑的話,數據庫更新的事務日誌也將存儲到該路徑下。 注意:事務日誌會影響ZooKeeper服務器的總體性能,因此建議將事務日誌放置到由dataLogDir參數指定的路徑下。 ##### tickTime 單個tick的時間長度,它是ZooKeeper中使用的基本時間單元,以毫秒爲單位。它用來調節心跳和超時時間。例如,最小會話超時時間是2個tick。
生產環境例子:服務器
tickTime:CS通訊心跳數 Zookeeper 服務器之間或客戶端與服務器之間維持心跳的時間間隔,也就是每一個 tickTime 時間就會發送一個心跳。tickTime以毫秒爲單位。 tickTime=2000 initLimit:LF初始通訊時限 集羣中的follower服務器(F)與leader服務器(L)之間初始鏈接時能容忍的最多心跳數(tickTime的數量)。 initLimit=5 syncLimit:LF同步通訊時限 集羣中的follower服務器與leader服務器之間請求和應答之間能容忍的最多心跳數(tickTime的數量)。 syncLimit=2 dataDir:數據文件目錄 Zookeeper保存數據的目錄,默認狀況下,Zookeeper將寫數據的日誌文件也保存在這個目錄裏。 dataDir=/home/michael/opt/zookeeper/data dataLogDir:日誌文件目錄 Zookeeper保存日誌文件的目錄。 dataLogDir=/home/michael/opt/zookeeper/log clientPort:客戶端鏈接端口 客戶端鏈接 Zookeeper 服務器的端口,Zookeeper 會監聽這個端口,接受客戶端的訪問請求。 clientPort=2333 服務器名稱與地址:集羣信息(服務器編號,服務器地址,LF通訊端口,選舉端口) 這個配置項的書寫格式比較特殊,規則以下: server.N=YYY:A:B 其中N表示服務器編號,YYY表示服務器的IP地址,A爲LF通訊端口,表示該服務器與集羣中的Leader交換的信息的端口。B爲選舉端口,表示選舉新Leader時服務器間相互通訊的端口(當Leader掛掉時,其他服務器會相互通訊,選擇出新的Leader)。通常來講,集羣中每一個服務器的A端口都是同樣,每一個服務器的B端口也是同樣。可是當所採用的爲僞集羣時,IP地址都同樣,只能時A端口和B端口不同。 #下面是一個非僞集羣的例子: server.0=233.34.9.144:2008:6008 server.1=233.34.9.145:2008:6008 server.2=233.34.9.146:2008:6008 server.3=233.34.9.147:2008:6008 #下面是一個僞集羣的例子: server.0=127.0.0.1:2008:6008 server.1=127.0.0.1:2007:6007 server.2=127.0.0.1:2006:6006 server.3=127.0.0.1:2005:6005
3、高級配置項說明網絡
本節的配置選項是可選的。你可使用它們進一步的優化ZooKeeper服務器的行爲。有些可使用Java系統屬性來設置,通常的格式是「zookeeper.keyword」。若是有具體的系統屬性,會在配置選項下面標註出來。併發
說明:設置Java系統屬性能夠在啓動時後面加「-D」參數,好比:-Dzookeeper.keyword=xxx。而這些配置項默承認以經過$ZOOKEEPER_HOME/conf/zoo.cfg進行配置。app
dataLogDir
沒有對應的Java系統屬性。
該參數用於配置ZooKeeper服務器存儲事務日誌文件的路徑,ZooKeeper默認將事務日誌文件和數據快照存儲在同一個目錄下,應儘可能將它們分開存儲。
注意:將事務日誌文件存儲到一個專門的日誌設備上對於服務器的吞吐量和穩定的延遲有很大的影響。事務日誌對磁盤性能要求比較高,爲了保證數據一致性,ZooKeeper 在響應客戶端事務請求以前,須要將請求的事務日誌寫到磁盤上,因此事務日誌的寫入性能直接影響ZooKeeper服務器處理請求的吞吐。因此建議給事務日誌的輸出配置一個單獨的磁盤或者掛載點。
globalOutstandingLimit
對應的Java系統屬性:zookeeper.globalOutstandingLimit。
客戶端提交請求的速度可能比ZooKeeper處理的速度快得多,特別是當客戶端的數量很是多的時候。爲了防止ZooKeeper由於排隊的請求而耗盡內存,ZooKeeper將會對客戶端進行限流,即限制系統中未處理的請求數量不超過globalOutstandingLimit設置的值。默認的限制是 1000。
preAllocSize
對應的Java系統屬性:zookeeper.preAllocSize。
用於配置ZooKeeper事務日誌文件預分配的磁盤空間大小。默認的塊大小是64M。改變塊大小的其中一個緣由是當數據快照文件生成比較頻繁時能夠適當減小塊大小。好比 1000次事務會新產生一個快照(參數爲snapCount),新產生快照後會用新的事務日誌文件,假設一個事務信息大小100b,那麼事務日誌預分配的磁盤空間大小爲100kb會比較好。
snapCount
對應的Java系統屬性:zookeeper.snapCount。
ZooKeeper 將事務記錄到事務日誌中。當 snapCount 個事務被寫到一個日誌文件後,啓動一個快照並建立一個新的事務日誌文件。snapCount 的默認值是 100,000。
traceFile
對應的Java系統屬性:requestTraceFile。
若是定義了該選項,那麼請求將會記錄到一個名爲traceFile.year.month.day的跟蹤文件中。使用該選項能夠提供頗有用的調試信息,可是會影響性能。
注意:requestTraceFile這個系統屬性沒有zookeeper前綴,而且配置的變量名稱和系統屬性不同。
maxClientCnxns
沒有對應的Java系統屬性
在socket級別限制單個客戶端到ZooKeeper集羣中單臺服務器的併發鏈接數量,能夠經過IP地址來區分不一樣的客戶端。它用來阻止某種類型的DoS攻擊,包括文件描述符資源耗盡。默認值是60。將值設置爲0將徹底移除併發鏈接的限制。
clientPortAddress
服務器監聽客戶端鏈接的地址(ipv4,ipv6或主機名),亦即客戶端嘗試鏈接到服務器上的地址。該參數是可選的,默認咱們以這樣一種方式綁定,即對於服務器上任意 address/interface/nic,任何鏈接到clientPort的請求將會被接受。
minSessionTimeout
沒有對應的Java系統屬性
服務器容許客戶端會話的最小超時時間,以毫秒爲單位。默認值是2倍的tickTime。
maxSessionTimeout
沒有對應的Java系統屬性
服務器容許客戶端會話的最大超時時間,以毫秒爲單位。默認值是20倍的tickTime。
fsync.warningthresholdms
對應的Java系統屬性:fsync.warningthresholdms。
用於配置ZooKeeper進行事務日誌(WAL)fsync操做消耗時間的報警閾值,一旦超過這個閾值將會打印輸出報警日誌。該參數的默認值是1000,以毫秒爲單位。參數值只能做爲系統屬性來設置。
autopurge.snapRetainCount
沒有對應的Java系統屬性。
當啓用自動清理功能後,ZooKeeper將只保留autopurge.snapRetainCount個最近的數據快照(dataDir)和對應的事務日誌文件(dataLogDir),其他的將會刪除掉。默認值是3。最小值也是3。
autopurge.purgeInterval
沒有對應的Java系統屬性。
用於配置觸發清理任務的時間間隔,以小時爲單位。要啓用自動清理,能夠將其值設置爲一個正整數(大於 1)。默認值是0。
syncEnabled
對應的Java系統屬性:zookeeper.observer.syncEnabled。
和參與者同樣,觀察者如今默認將事務日誌以及數據快照寫到磁盤上,這將減小觀察者在服務器重啓時的恢復時間。將其值設置爲「false」能夠禁用該特性。默認值是 「true」。
4、集羣配置選項說明
本節中的選項主要用於ZooKeeper集羣。
electionAlg
沒有對應的Java系統屬性。
用於選擇使用的Leader選舉算法。」0」對應於原始的基於UDP的版本,「1」對應於快速Leader選舉基於UDP的無身份驗證的版本,「2」對應於快速Leader選舉有基於UDP的身份驗證的版本,而「3」對應於快速Leader選舉基於TCP的版本。目前默認值是算法3。
注意:Leader選舉0,1,2這三種實現已經廢棄,在接下來的版本中將會移除它們,這樣就只剩下FastLeaderElection算法。
initLimit
沒有對應的Java系統屬性。
默認值是10,即tickTime屬性值的10倍。它用於配置容許Followers鏈接並同步到Leader的最大時間。若是ZooKeeper管理的數據量很大的話能夠增長這個值。
leaderServes
對應的Java系統屬性:zookeeper.leaderServes。
用於配置Leader是否接受客戶端鏈接,默認值是「yes」,即Leader將會接受客戶端鏈接。在ZooKeeper中,Leader服務器主要協調事務更新請求。對於事務更新請求吞吐很高而讀取請求吞吐很低的狀況能夠配置Leader不接受客戶端鏈接,這樣就能夠專一於協調工做。
注意:當ZooKeeper集羣中服務器的數量超過3個時,建議開啓Leader選舉。
server.x=[hostname]:nnnnn:nnnnn
沒有對應的Java系統屬性。
組成ZooKeeper集羣的服務器。當服務器啓動時,能夠經過查找數據目錄中的myid文件來決定它是哪一臺服務器。myid文件包含服務器編號,而且它要匹配「server.x」中的x。
客戶端用來組成ZooKeeper集羣的服務器列表必須和每一個ZooKeeper服務器中配置的ZooKeeper服務器列表相匹配。
有兩個端口號nnnnn,第一個是Followers用來鏈接到Leader,第二個是用於Leader選舉。若是想在單臺機器上測試多個服務,則能夠爲每一個服務配置不一樣的端口。
syncLimit
沒有對應的Java系統屬性。
默認值是5,即tickTime屬性值的5倍。它用於配置Leader和Followers間進行心跳檢測的最大延遲時間。若是在設置的時間內Followers沒法與Leader進行通訊,那麼Followers將會被丟棄。
group.x=nnnnn[:nnnnn]
沒有對應的Java系統屬性。
Enables a hierarchical quorum construction.」x」 是一個組的標識,等號右邊的數字對應於服務器的標識。賦值操做右邊是冒號分隔的服務器標識。注意:組必須是不相交的,而且全部組聯合後必須是 ZooKeeper 集羣。
weight.x=nnnnn
沒有對應的Java系統屬性。
和「group」一塊兒使用,當造成集羣時它給每一個服務器賦權重值。這個值對應於投票時服務器的權重。ZooKeeper中只有少數部分須要投票,好比Leader選舉以及原子的廣播協議。服務器權重的默認值是1。若是配置文件中定義了組,可是沒有權重,那麼全部服務器的權重將會賦值爲1。
cnxTimeout
對應的Java系統屬性:zookeeper.cnxTimeout。
用於配置Leader選舉過程當中,打開一次鏈接(選舉的Server互相通訊創建鏈接)的超時時間。默認值是5s。
5、身份認證和受權選項說明
本節的選項容許經過身份認證和受權來控制服務執行。
zookeeper.DigestAuthenticationProvider.superDigest
對應的Java系統屬性:zookeeper.DigestAuthenticationProvider.superDigest。
該功能默認是禁用的。
可以使ZooKeeper集羣管理員能夠做爲一個「super」用戶來訪問ZNode層級結構。特別是對於一個已經認證爲超級管理員的用戶不須要ACL檢查。
org.apache.zookeeper.server.auth.DigestAuthenticationProvider能夠用來生成superDigest,調用它帶有「super:「參數的方法。當啓動集羣中的每臺服務器時,將生成的「super:「做爲系統屬性提供。
當ZooKeeper客戶端向ZooKeeper服務器進行身份認證時,會傳遞一個「digest」和「super:「的認證數據。注意摘要式身份驗證將認證數據以普通文本的形式傳遞給服務器,在網絡中須要謹慎使用該認證方法,要麼只在本機上或經過一個加密的鏈接。
6、實驗性選項/特性說明
本節列舉了一些目前還處於實驗階段的新特性。
服務器只讀模式
對應的Java系統屬性:readonlymode.enabled。
將其設置爲true將會啓用服務器只讀模式支持,默認是禁用的。ROM容許請求了ROM支持的客戶端會話鏈接到服務器,即便當服務器可能已經從集羣中分隔出去。在該模式中,ROM客戶端仍然能夠從ZK服務中讀取值,可是不能進行寫操做以及看見其它客戶端所作的一些變動。更多詳細信息能夠參見ZOOKEEPER-784獲取更多詳細信息。
不安全的選項
下面的選項會頗有用,可是使用的時候須要特別當心。
forceSync
對應的Java系統屬性:zookeeper.forceSync。
用於配置是否須要在事務日誌提交的時候調用FileChannel.force來保證數據徹底同步到磁盤。默認值是「yes」。若是該選項設置爲「no」,ZooKeeper將不會強制同步事務更新日誌到磁盤。
jute.maxbuffer
對應的Java系統屬性:jute.maxbuffer。沒有zookeeper前綴。
用於指定一個ZNode中能夠存儲數據量的最大值,默認值是0xfffff,或1M內。若是這個選項改變了,那麼該系統屬性必須在全部的服務端和客戶端進行設置,不然會出現問題。ZooKeeper旨在存儲大小爲千字節數量的數據。
skipACL
對應的Java系統屬性:zookeeper.skipACL。
用於配置ZooKeeper服務器跳過ACL權限檢查。這將必定程度的提升服務器吞吐量,可是也向全部客戶端徹底開放數據訪問。
quorumListenOnAllIPs
當設置爲true時,ZooKeeper服務器將會在全部可用的IP地址上監聽來自其對等點的鏈接請求,而不只是配置文件的服務器列表中配置的地址。它會影響處理ZAB協議和Fast Leader Election協議的鏈接。默認值是false。
7、ZooKeeper優化建議
一、將ZooKeeper與其餘應用分開部署,避免相互影響;
對於ZooKeeper來講,若是在運行過程當中,須要和其它應用程序來競爭磁盤、CPU、網絡、內存資源,那麼總體性能將會大打折扣。咱們在使用ZooKeeper初期嘗試將ZooKeeper與其餘應用公用機器,在系統流量上漲後,因爲IO及CPU被其餘應用使用很大,形成ZooKeeper的Session常常超時甚至應用與ZooKeeper的鏈接斷開。所以,建議ZooKeeper與其餘應用分開部署;
二、將數據文件和事務日誌分開存放,提升ZooKeeper性能;
咱們先分析一下磁盤對ZooKeeper性能的影響。客戶端對ZK的更新操做都是永久的,不可回退的。爲作到這點,ZK會將每次更新操做以事務日誌的形式寫入磁盤,寫入成功後纔會給予客戶端響應。明白這點以後,你就會明白磁盤的吞吐性能對於ZK的影響了,磁盤寫入速度制約着ZK每一個更新操做的響應。所以,咱們在選擇機型時儘可能選擇多塊硬盤的機器,ZK的事務日誌輸出是一個順序寫文件的過程,自己性能是很高的,因此儘可能保證不要和其它隨機寫的應用程序共享一塊磁盤,儘可能避免對磁盤的競爭。
三、儘可能避免內存與磁盤空間的交換,確保設置一個合理的JVM堆大小;
若是設置太大,會讓內存與磁盤進行交換,這將使ZK的性能大打折扣。例如一個4G內存的機器的,若是你把JVM的堆大小設置爲4G或更大,那麼會使頻繁發生內存與磁盤空間的交換,一般設置成3G就能夠了。
8、啓動內存設置實例
新建zookeeper/conf/java.env文件。
java.env文件內容以下:
#!/bin/sh export JAVA_HOME=/usr/java/jdk # heap size MUST be modified according to cluster environment export JVMFLAGS=」-Xms512m -Xmx1024m $JVMFLAGS」
對於內存的分配,仍是根據項目和機器狀況而定。若是內存夠用,適當的大點能夠提高ZK性能。
ZooKeeper配置文件修改以下:
maxClientCnxns=1000 minSessionTimeout=30000 maxSessionTimeout=60000
9、日誌優化實例
log4j配置,因爲ZK是經過nohup啓動的,會有一個zookeeper.out日誌文件,該文件中記錄的是輸出到console的日誌。log4j中只要配置輸出到console便可,zookeeper.out日積月累會不斷變大,要放在容量大的磁盤上。
修改配置文件(zoo.cfg)以下:
zookeeper.root.logger=INFO, CONSOLE zookeeper.console.threshold=INFO log4j.rootLogger=${zookeeper.root.logger} log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.Threshold=${zookeeper.console.threshold} log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n
zoo.cfg文件中,dataDir是存放快照數據的,dataLogDir是存放寫前日誌的。這兩個目錄不要配置成一個路徑,要配置到不一樣的磁盤上。若是磁盤是使用了RAID,系統就一塊磁盤,那配置到一塊磁盤上也能夠。寫前日誌的部分對寫請求的性能影響很大,保證dataLogDir所在磁盤性能良好。
10、其它優化配置實例
一、zoo.cfg文件中skipACL=yes,忽略ACL驗證,能夠減小權限驗證的相關操做,提高一點性能。
二、zoo.cfg文件中forceSync=no,這個對寫請求的性能提高頗有幫助,是指每次寫請求的數據都要從pagecache中固化到磁盤上,纔算是寫成功返回。當寫請求數量到達必定程度的時候,後續寫請求會等待前面寫請求的forceSync操做,形成必定延時。若是追求低延時的寫請求,配置forceSync=no,數據寫到pagecache後就返回。可是機器斷電的時候,pagecache中的數據有可能丟失。
三、zk的dataDir和dataLogDir路徑下,若是沒有配置ZK自動清理,會不斷的新增數據文件。可配置成ZK系統自動清理數據文件,可是最求系統最高性能的話,建議人工手動清理文件:
zkCleanup.sh -n 3
這樣保留三份文件。
四、配置fsync.warningthresholdms=20,單位是毫秒,在forceSync=yes的時候,若是數據固化到磁盤的操做fsync超過20ms的時候,將會在zookeeper.out中輸出一條warn日誌。這個目前zk的3.4.5和3.5版本有bug,在zoo.cfg中配置不生效。個人作法是在conf/java.env中添加java系統屬性:
export JVMFLAGS="-Dfsync.warningthresholdms=20 $JVMFLAGS"
參考:
http://www.chinacloud.cn/upload/2014-04/14042009468555.pdf
http://blog.csdn.net/u013673976/article/details/50153631
http://zlfwmm.blog.51cto.com/5892198/1710111
http://www.52yunwei.net/767.html(以上部份內容轉自此篇文章)
http://www.cnblogs.com/fanweiwei/p/4517012.html(以上內容部分轉自此篇博客)