zookeeper設置客戶端連接超時被expired


在網絡環境非常差的情況下,使用zookeeper集群往往會遇到連接expired了:

客戶端提示連接從ZOO_CONNECTION_STATE變為ZOO_EXPIRED_SEESION_STATE,然后應用失去與zookeeper集群的連接。

在使用過程中,我們一般會加大客戶端的rec_timeout值,例如設置為30s,但對是否發生expired沒有太大影響,仔細查看文檔發現要在服務器端設置minSessionTimeout。

 

那么什么情況下連接會過期?

當客戶端創建連接時,會隨機和一個zookeeper節點創建連接,並互發heartbeat;session的信息會同步到其他zookeeper節點上,比如session的id、watcher、臨時目錄等等信息。

當網絡抖動或者與他創建連接的zk節點掉線了,這個時候client與zk的的session將斷開,此時,client無需處理,zk的重試機制會自動跟其他存活的zk節點創建session:

1)如果連接在minSessionTimeout之內連接成功,那么新的連接將同步之前斷開連接的臨時數據和watcher,並同步狀態。

2)如果這個重連接過程超過了minSessionTimeout,那么該session就會被zk集群提出去即expired掉,會清除該session所有資源和數據,主要包括臨時數據和watcher。當使用zookeeper_init指定session的id去重新連接,也會報錯,返回一個空的句柄回來。

 

下面我們來仔細看看:

1)一般我們會設置連接超時時間,在客戶端設置,其API為:

ZOOAPI zhandle_t *zookeeper_init(const char *host, 
				 watcher_fn fn,
                                 int recv_timeout,
                                 const clientid_t * clientid,
                                 void *context, int flags);
功能: 創建一個句柄(handle)和一個響應(response)這個句柄的會話(session)。 

參數:
host:zookeeper主機列表,用逗號間隔。 
fn:用於監視的回調函數。 
clientid:客戶端嘗試重連的先前會話的ID,如果不需要重連先前的會話,則設置為 0。客戶端可以通過調用 zoo_client_id來訪問一個已經連接上的並且有效的會話ID,如果clientid對應的會話超時,或者由於某種原因 clientid變為無效了,那么zookeeper_init 將返回一個非法的 zhandle_t,通過 zhandle_t 的狀態可以獲知 zookeeper_init 調用失敗的原因。 (通常為 ZOO_EXPIRED_SESSION_STATE). 意思是如果該ID的連接是被expired了的話,重新連接也會失敗,服務器已經清理了相關的資源和信息。
context:暫時用不到,忽略。(TODO)
flags:設置為0,zookeeper開發團隊保留以后使用。

 

大量,包括代碼里面的注釋上都沒有說recv_timeout的意思,按字面意思,肯定不是session_timeout,而是多長時間zk創建連接不成功的時間?

 


2)在服務器端zoo.conf中有相關設置:minSessionTimeout,最小的客戶端超時時間,默認值為2個ticktime,單位是毫秒:

minSessionTimeout
  最小的客戶端session超時時間,默認值為2個tickTime,單位是毫秒
maxSessionTimeout
  最大的客戶端session超時時間,默認值為20個tickTime,單位是毫秒

 

3)於是我們最終修改的zoo.conf文件為:

tickTime=1000
dataDir=/opt/zookeeper/zkdata
dataLogDir=/opt/zookeeper/zklogs
clientPort=2181
initLimit=5
syncLimit=2
minSessionTimeout=16000
maxSessionTimeout=30000
server.1=xxxx:2888:3888
server.2=xxxx:2888:3888
server.3=xxxx:2888:3888

 

注意,在僅配置了minSessionTimeout參數時,zk會啟動失敗,提示該參數超過了maxSessionTimeout值,這個時候需要在配置文件把最大值也配上。

 

4)服務端配置詳解:

(1)dataDir
  用於存放內存數據庫快照的文件夾,同時用於集群的myid文件也存在這個文件夾里。
(2)dataLogDir
  用於單獨設置transaction log的目錄,transaction log分離可以避免和普通log還有快照的競爭。
(3)tickTime
  心跳時間,為了確保client-server連接存在的,以毫秒為單位,最小超時時間為兩個心跳時間。
(4)clientPort
  客戶端監聽端口。
(5)globalOutstandingLimit
  client請求隊列的最大長度,防止內存溢出,默認值為1000。
(6)preAllocSize
  預分配的Transaction log空間block為proAllocSize KB,默認block為64M,一般不需要更改,除非snapshot過於頻繁。
(7)snapCount
  在snapCount個snapshot后寫一次transaction log,默認值是100,000。
(8)traceFile
  用於記錄請求的log,打開會影響性能,用於debug,最好不要定義。
(9)maxClientCnxns
  最大並發客戶端數,用於防止DOS的,默認值是10,設置為0是不加限制。
(11)clientPortBindAddress
  可以設置指定的client ip以及端口,不設置的話等於ANY:clientPort
(12)minSessionTimeout
  最小的客戶端session超時時間,默認值為2個tickTime,單位是毫秒
(13)maxSessionTimeout
  最大的客戶端session超時時間,默認值為20個tickTime,單位是毫秒
(14)electionAlg
  用於選舉的實現的參數:
  ①0:為以原始的基於UDP的方式協作
  ②1:為不進行用戶驗證的基於UDP的快速選舉
  ③2:為進行用戶驗證的基於UDP的快速選舉
  ④3:為基於TCP的快速選舉,默認值為3
(15)initLimit
  多少個tickTime內,允許其他server連接並初始化數據,如果zooKeeper管理的數據較大,則應相應增大這個值。
(16)syncLimit
  多少個tickTime內,允許follower同步,如果follower落后太多,則會被丟棄。
(17)leaderServes
  leader是否接受客戶端連接。默認值為yes。leader負責協調更新。當更新吞吐量遠高於讀取吞吐量時,可以設置為不接受客戶端連接,以便leader可以專注於同步協調工作。
(18)server.x=[hostname]:nnnnn[:nnnnn]
  配置集群里面的主機信息,其中:
  ①server.x:server.x的x要寫在myid文件中,決定當前機器的id,
  ②第一個port用於連接leader,
  ③第二個用於leader選舉。
  ④如果electionAlg為0,則不需要第二個port。
  ⑤hostname也可以填ip。
(19)group.x=nnnnn[:nnnnn]
        分組信息,表明哪個組有哪些節點,例如group.1=1:2:3 group.2=4:5:6 group.3=7:8:9。
(20)weight.x=nnnnn
   權重信息,表明哪個結點的權重是多少,例如weight.1=1 weight.2=1 weight.3=1。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM