日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

zookeeper简介以及C客户端用法

發布時間:2024/2/28 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 zookeeper简介以及C客户端用法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

zookeeper簡介以及C客戶端用法

    • 前言
    • 簡介
    • zookeeper保證
      • 理解zookeeper的順序一致性
    • zookeeper 接口
    • 安裝
    • zoo.cfg參數詳解
    • 常用命令
    • C API
    • zookeeper C API
      • 如何在代碼中使用zk C API
      • zookeeper引用計數
    • zookeeper節點類型
    • zookeeper集群
    • ZooKeeper典型使用場景
    • zk c client 連接流程
      • zk 狀態轉換
      • 連接中的異常
        • 應對
    • 記一次線上事故
    • 參考鏈接

前言

zookeeper用法有很多,但是針對C++的工具集和文檔卻很少,本文主要介紹zk的使用方法,特別是在C++上的一些用法。

簡介

Zookeepe維護一個類似文件系統的數據結構:每個子目錄項如 NameService 都被稱作為 znode(目錄節點),和文件系統一樣,我們能夠自由的增加、刪除znode,在一個znode下增加、刪除子znode,唯一的不同在于znode是可以存儲數據的。
有四種類型的znode:

  • PERSISTENT-持久化目錄節點
    • 客戶端與zookeeper斷開連接后,該節點依舊存在
  • PERSISTENT_SEQUENTIAL-持久化順序編號目錄節點
    • 客戶端與zookeeper斷開連接后,該節點依舊存在,只是Zookeeper給該節點名稱進行順序編號
  • EPHEMERAL-臨時目錄節點
    • 客戶端與zookeeper斷開連接后,該節點被刪除
  • EPHEMERAL_SEQUENTIAL-臨時順序編號目錄節點
    • 客戶端與zookeeper斷開連接后,該節點被刪除,只是Zookeeper給該節點名稱進行順序編號
  • zookeeper保證

    根據zookeeper官方文檔,zookeeper提供了如下保證:

    • Sequential Consistency - Updates from a client will be applied in the order that they were sent.
    • Atomicity - Updates either succeed or fail. No partial results.
    • Single System Image - A client will see the same view of the service regardless of the server that it connects to. i.e., a client will never see an older view of the system even if the client fails over to a different server with the same session. 如果client首先看到了新數據,再嘗試重連到存有舊數據的follower,該follower會拒絕該連接(client的zxid高于follower)
    • Reliability - Once an update has been applied, it will persist from that time forward until a client overwrites the update.
    • Timeliness - The clients view of the system is guaranteed to be up-to-date within a certain time bound.

    由此可見,zookeeper只提供順序一致性和分區容錯性

    理解zookeeper的順序一致性

    ZooKeeper Programmer’s Guide提到:

    Sometimes developers mistakenly assume one other guarantee that ZooKeeper does not in fact make. This is:
    Simultaneously Conistent Cross-Client Views
    ZooKeeper does not guarantee that at every instance in time, two different clients will have identical views of ZooKeeper data. Due to factors like network delays, one client may perform an update before another client gets notified of the change. Consider the scenario of two clients, A and B. If client A sets the value of a znode /a from 0 to 1, then tells client B to read /a, client B may read the old value of 0, depending on which server it is connected to. If it is important that Client A and Client B read the same value, Client B should should call the sync() method from the ZooKeeper API method before it performs its read.
    So, ZooKeeper by itself doesn’t guarantee that changes occur synchronously across all servers, but ZooKeeper primitives can be used to construct higher level functions that provide useful client synchronization.

    就是說zookeeper并不保證每次從其一個server讀到的值是最新的,它只保證這個server中的值是順序更新的,如果想要讀取最新的值,必須在get之前調用sync()

    zookeeper 接口

    zookeeper的接口十分簡單,只支持以下操作:

    • create : creates a node at a location in the tree
    • delete : deletes a node
    • exists : tests if a node exists at a location
    • get data : reads the data from a node
    • set data : writes data to a node
    • get children : retrieves a list of children of a node
    • sync : waits for data to be propagated 對某個節點sync,保證拿到這個節點為最新的。(不確定是否是同步操作)

    安裝

    入門安裝指南

    Step1:配置JAVA環境,檢驗環境:java -version, 一般就用1.8

    Step2:下載并解壓zookeeper

    注:如果當前的java版本和zk要求的不同,可以簡單的export臨時變量

    JAVA_HOME=/home/test/jdk1.8.0_161/ export JAVA_HOME CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar export CLASSPATH PATH=$JAVA_HOME/bin:$PATH export PATH cd /usr/local wget http://mirror.bit.edu.cn/apache/zookeeper/stable/zookeeper-3.4.12.tar.gz tar -zxvf zookeeper-3.4.12.tar.gz cd zookeeper-3.4.12

    Step3:重命名配置文件zoo_sample.cfg

    cp conf/zoo_sample.cfg conf/zoo.cfg

    Step4:啟動zookeeper

    bin/zkServer.sh start

    Step5:檢測是否成功啟動,用zookeeper客戶端連接下服務端

    bin/zkCli.sh -timeout 5000 -r -server ip:port

    zoo.cfg參數詳解

    名稱說明
    tickTimezk中的時間單元,zk中所有時間都是以這個時間為基礎,進行整數倍配置的,如session的最小超時時間是2*tickTime, 每隔tickTime發送一個心跳
    clientPort客戶端連接zookeeper服務器的端口號,默認2181
    dataLogDir事務日志輸出目錄,盡量給事務日志的輸出配置單獨的磁盤或掛載點,這將極大的提升zk性能,用于單獨設置transaction log的目錄,transaction log分離可以避免和普通log還有快照的競爭。
    dataDir存儲快照(snapshot)文件目錄,默認事務日志也存儲在此路徑下,建議同時配置dataLogDir,會影響zk性能,zk會通過org.apache.zookeeper.server.ZKDatabase開加載
    globalOutstandingLimit系統屬性:zookeeper.globalOutstandingLimit 默認1000,如果有大量的client,會造成zk server對請求的處理速度小于client的提交請求的速度,會造成server端大量請求queue滯留而導致OOM,此參數可以控制server最大持有為處理的請求個數
    preAllocSize系統屬性:zookeeper.preAllocSize ,為了避免大量磁盤檢索,zk對txn log文件進行空間的預分配,默認為64M,當剩余空間小于4k時,會再次“預分配”。你可以嘗試減小此值,比如當快照較為頻繁時,可以適當減小
    traceFile系統屬性:requestTraceFile 請求跟蹤文件,如果設置了此參數,所有請求將會被記錄在traceFile.year.month.day,類似與nginx的request log,不過此參數會帶來性能問題
    maxClientCnxns默認:60, 一個client與server最大的socket連接數,根據IP區分,設置為0,取消此限制。可以避免DOS攻擊
    clientPortAddressip或者hostName,指定監聽clientPort的address,此參數可選,默認是clientPort會綁定到所有ip上,在物理server具有多個網絡接口時,可以設置特定的IP
    minSessionTimeout默認 2*tickTime,也是server允許的最小值,如果設置的值過小,將會采用默認值
    maxSessionTimeout默認20*tickTime,允許的最大值, 可以一句話概括,客戶端上報的期望timeout(zookeeper_init()函數的第三個參數)一定要在服務端設置的上下界之間,如果越過邊界,則以邊界為準。
    autopurge.snapRetainCountzk server啟動時會開啟一個org.apache.zookeeper.server.DatadirCleanupManager的線程,用于清理"過期"的snapshot文件和其相應的txn log file,此參數用于設定需要被retain保留的文件個數(從QuorumPeerMain跟蹤代碼)
    autopurge.purgeInterval和上述參數配合使用,清理任務的時間間隔,單位為hours, 可以查看org.apache.zookeeper.server.DatadirCleanupManager的105行
    snapCount系統屬性:zookeeper.snapCount 默認為:100000,在新增Log條數達到snapCount/2 +Random.nextInt(snapCount/2)時,將會對zkDatabase內存數據庫進行snapshot,將內存中的DataTree反序列化到snapshot文件數據,同時log計數重置為0,以此循環, snapshot過程中,同時也伴隨txn log的新文件創建,snapshot時使用隨機數的原因:讓每個server snapshot的時機具有隨機且可控,避免所有的server同時snapshot可見:org.apache.zookeeper.server.SyncRequestProcessor.run()方法實現
    electionAlg選舉算法,默認為3,可以選擇(0,1,2,3), 0表示使用原生的UDP(LeaderElection), 1表示使用費授權的UDP2表示使用授權的UDP(AuthFastLeaderElection) 3基于TCP的快速選舉(FastLeaderElection)具體可見:org.apache.zookeeper.server.quorum.QuorumPeer 159行createElectionAlgorithm(electionType);org.apache.zookeeper.server.quorum.LeaderElection (已被廢棄)org.apache.zookeeper.server.quorum.AuthFastLeaderElection(已被廢棄)org.apache.zookeeper.server.quorum.FastLeaderElection
    initLimitLeader與learner建立連接中 socket通訊read所阻塞的時間(initLimit * tickTime) 如果是Leaner數量較多或者leader的數量很大, 可以增加此值 ,代碼參考:org.apache.zookeeper.server.quorum.LearnerHandler第297行run()方法
    SyncLimitlearner與leader建立連接中,socket通訊read阻塞的時間.其中包括數據同步/數據提交等, 參考代碼:org.apache.zookeeper.server.quorum.Learner222行connectToLeader()316行syncWithLeader()
    peerTypezkserver 類型 observer 觀察者, participant參與者 ,默認為參與者
    leaderServes系統屬性 zookeeper.leaderServes leader是否接受client請求,默認為yes即leader可以接受client的連接,在zk cluster 環境中,當節點數為>3時,建議關閉
    cnxTimeout系統屬性:zookeeper.cnxTimeout leader選舉時socket連接打開的時長,只有在electionAlg=3有效
    skipACL系統屬性:zookeeper.skipACL 默認為no,是否跳過ACL檢查
    forceSync系統屬性:zookeeper.forceSync 默認yes 在update執行之前,是否強制對操作立即持久寫入txn log文件.關閉此選項,會造成服務器失效后,尚未持久化的數據丟失

    常用命令

    bin/zkCli.sh ## 后面進入命令行 ls / # 使用 ls 命令來查看當前 ZooKeeper 中所包含的內容 create /zkPro myData # 創建一個新的 znode get /zkPro # 查 set /zkPro myData123 # 改 delete /zkPro # 刪

    C API

    • ZooKeeper Programmer’s Guide(官方C++例程)

    zookeeper C API

    zookeeper只有C API,沒有C++ API
    CAPI的代碼已經五六年沒更改過了,整體代碼并不難,這里只記一些碰到過的坑
    https://github.com/apache/zookeeper.git

    int zookeeper_init(); // 這個函數會開啟兩個線程,一個下發IO:do_io, 一個做completion回調(watcher) do_completion 當連接expire之后,do_io里面會檢查is_unrecoverable,然后直接退出do_io線程,這時候do_completion線程仍然需要在外面顯式調用zookeeper_close去關閉。int zookeeper_close(zhandle_t *zh); // 關閉之前打開的zhandle,如果引用計數不為0,則會跳過一些步驟,如果引用計數為0,則會銷毀init中打開的鎖,free空間。不用擔心外部顯式調用的close因為引用計數的關系沒有完全關閉,zk內部的引用計數減一函數api_epilog會檢查,如果引用計數降到0會再次調用zookeeper_close

    如何在代碼中使用zk C API

  • 在cmake文件里加上編譯好的lib文件路徑,
  • 如果你需要編譯多線程版本客戶端程序,
    • 請添加編譯選項 -dthreaded,
    • 同時鏈接時應鏈接 zookeeper_mt 庫;
  • 如果你需要編譯單線程客戶端程序,
    • 請不要添加編譯選項 -dthreaded,
    • 同時鏈接時應鏈接 zookeeper_st 庫。
  • zookeeper引用計數

    • 用zookeeper_init建立的zhandle包含成員ref_count,如果引用計數不為0,則無法關閉zookeeper(zookeeper_close)
    • ref_count可以用api_prolog加1,常見的應用場合:
      • 發送隊列里有東西的時候
      • 正在初始化thread的時候
      • do_io和do_completion都會讓引用計數+1

    zookeeper節點類型

  • 是否持久

    • persistent :持久節點。需要主動刪除
    • ephemeral : 瞬時節點。與客戶端session結束,自動刪除; 不能有子節點
  • 是否有序

    • persistent_sequential : 持久有序節點。
    eg: create -s /zk/n6_ n6 Created /zk/n6_0000000006
    • ephemeral_sequential : 瞬時有序節點。
  • eg:create -e -s /zk/temp/t4 t4 Created /zk/temp/t40000000003

    zookeeper集群

    ZooKeeper典型使用場景

    • ZooKeeper典型使用場景一覽 - 阿里
    • ZooKeeper的強一致性,能夠保證在分布式高并發情況下節點創建的全局唯一性,即:同時有多個客戶端請求創建 /currentMaster 節點,最終一定只有一個客戶端請求能夠創建成功。

    zk c client 連接流程

  • 客戶端連接zookeeper服務時,zookeeper服務創建session,每個session會有一個64位數字作為其ID;
  • 除了為session分配單獨ID,zookeeper還會為每個session ID創建密碼,用以會話的認證。
  • 客戶端與zookeeper服務會話建立之后,session ID和密碼會發送到客戶端。
  • 當由于某種原因,比如當前連接節點的zookeeper服務因OOM被kill掉了,客戶端從列表中找到下一個zookeeper節點嘗試建立連接;
  • session ID和密碼會發送到新的zookeeper節點,認證通過后,客戶端到zookeeper新節點的會話恢復成功,否則會話因認證失敗無法建立
  • zk 狀態轉換

    有一點很關鍵,zk的狀態,有一些是由zkserver轉換,有一些是由zkclient轉換的。

    C++客戶端中的connecting,這是客戶端的狀態(也就是curator中的SUSPENDED),如果客戶端準備連接到server但是還沒連接成功,或者連接上之后發給zkserver的心跳沒有回應(網絡異常),導致client斷開當前session連接,并且換一個server地址重連。client就會把自己設為connecting狀態。

  • 初始化鏈接的時候,如果連接上了,server會向client發connected事件
  • 連接已經建立,但是在2/3的session timeout時間內server沒有收到client的心跳,server會發送KeeperState.Disconnected并斷開當前的session連接。
    • 同理,client如果在沒有收到server的心跳回包,也會斷開當前鏈接,并且用zoo_cycle_next_server(C++客戶端)找下一個可用的zkserver嘗試重連。
  • session timeout超時后,server會向client發expired事件,當然這個事件只有等重連成功之后,client才收得到
  • 連接中的異常

  • 如果,zkserver重啟之后所有的的數據都丟失了,client仍然會無限的嘗試重連zkserver,導致所有之前建立的session,以及在他之上的zk client不可用。
  • 該情況很容易復現:(在測試集群中)停掉所有節點上zookeeper服務 → 刪除所有節點上snapshot以及transaction日志 → 啟動所有節點上zookeeper服務;經過數據的清理過程,重啟之后的zookeeper服務會丟失所有會話信息,但之前已經建立session的客戶端因保存有session ID以及session密碼,會不斷嘗試向不同的zookeeper節點恢復會話;
  • 除非重啟客戶端,令客戶端重新建立會話,否則客戶端會進入“鍥而不舍”的會話恢復悲劇之中。
  • 應對

  • Zookeeper的zxid會由于狀態的變更主鍵遞增1,為了保證事務的順序一致性,zookeeper采用了遞增的事務id號(zxid)來標識事務。這在選舉的時候啟動至關重要。
  • 但是如果把snapshot和transitionlog刪除掉之后重啟zookeeper, zk server的zxid編號會從0開始遞增。
  • 但是客戶端仍然使用自己申請到的zxid重連,服務端發現客戶端的id比服務端大,所以拒絕服務。
  • 網上的說法都是遇到這種情況需要重啟zk客戶端。如果不想重啟,就需要改zk庫的邏輯,在重連到達一定次數之后重新建立連接
  • 記一次線上事故

    • 我司使用zk做選主+服務發現,在某天夜里,突然zk因為壓力太大,被打爆了,從而引發了多個問題
    • zk腦裂:
    • 我們多個服務向zk同一個節點注冊,注冊的升級為master節點,其他的為follower
    • 但是事故發生時,zk服務不可用,master節點沒有感知到expired事件,因此認為自己仍是master
    • 有一個follower服務感知到了master節點被刪除的事件,把自己提升為master,從此,集群有了兩個master,因此導致了整個集群的癱瘓。
    • zk hang
    • zk客戶端和服務端網絡不通暢的時候,服務端發出的expire事件并不能及時通知到客戶端,客戶端如果不能及時對connecting狀態做出反應,仍然向server拉節點,如果用同步API,就會造成hang,如果用異步API,operation_timeout的通知也會過很久(C客戶端上拉取節點超時的時間是三分之二的zktimeout時間)才返回。
    • zk雪崩
    • zk客戶端的邏輯是:重連之后會對所有節點重新watch, 如果zk不可用導致所有的zk連接expire,那么會導致所有的節點去server watch節點,驚群效應會導致zk壓力過大–>服務處理延遲過大–>導致client認為客戶端連接失敗–>zk客戶端重連–>連接失敗–>然后就會一直重連。無限循環
    • Zookeeper中Session Timeout的那些事
    # 服務端日志 2020-04-07 17:34:28,388 [myid:0] - WARN [NIOWorkerThread-43:ZooKeeperServer@1013] - Connection request from old client /192.168.152.105:55508; will be dropped if server is in r-o mode 2020-04-07 17:34:28,388 [myid:0] - INFO [NIOWorkerThread-43:ZooKeeperServer@1032] - Refusing session request for client /192.168.152.105:55508 as it has seen zxid 0x300000001 our last zxid is 0x0 client must try another server 2020-04-07 17:34:33,397 [myid:0] - WARN [NIOWorkerThread-44:ZooKeeperServer@1013] - Connection request from old client /192.168.152.105:55514; will be dropped if server is in r-o mode 2020-04-07 17:34:33,397 [myid:0] - INFO [NIOWorkerThread-44:ZooKeeperServer@1032] - Refusing session request for client /192.168.152.105:55514 as it has seen zxid 0x300000001 our last zxid is 0x0 client must try another server # 客戶端日志 2020-04-07 17:37:18,668:13583(0x7f881b3e8700):ZOO_INFO@check_events@1728: initiated connection to server [192.168.152.105:2182] 2020-04-07 17:37:18,669:13583(0x7f881b3e8700):ZOO_ERROR@handle_socket_error_msg@1746: Socket [192.168.152.105:2182] zk retcode=-4, errno=112(Host is down): failed while receiving a server response 2020-04-07 17:37:18,670:13583(0x7f881b3e8700):ZOO_INFO@check_events@1728: initiated connection to server [192.168.152.105:2183] 2020-04-07 17:37:18,671:13583(0x7f881b3e8700):ZOO_ERROR@handle_socket_error_msg@1746: Socket [192.168.152.105:2183] zk retcode=-4, errno=112(Host is down): failed while receiving a server response

    參考鏈接

  • zookeeper系列(基礎+實戰)
  • ZooKeeper如何模擬會話失效(Session Expired)
  • Zookeeper C Client分析 推薦
  • zookeeper FAQ 非常好
  • ZooKeeper 筆記
  • ZooKeeper Programmer’s Guide 國內的簡介包括保序性之類的,都是翻自這個官方文檔
  • ZooKeeper Recipes and Solutions 官方文檔,介紹了客戶端使用方法,包括主選舉,隊列,鎖等等
  • Zookeeper的關鍵機制的實現原理 包括會話機制,仲裁機制
  • ZooKeeper session管理 zk負載均衡,講zk各項和session state相關的改動。
  • zookeeper c 客戶端源碼分析以及使用注意點
  • zookeeper C API 的安裝和使用指南 編譯指南,make install 的時候可以通過增加--prefix選項指定安裝的目錄(CMAKE有對應的語句CMAKE_INSTALL_PREFIX)
  • ServiceLatencyOverview 這篇文章是zookeeper的commiter寫的,文章寫了做項目的latency測試的方法,掌握其中的思想很重要
  • zookeeper 集群搭建
  • Zookeeper運維小結–CancelledKeyException
  • Zookeeper和跨數據中心分布式協調
  • 理解zookeeper選舉機制
  • Zookeeper集群節點數量為什么要是奇數個?
  • zookeeper實現主從選舉
  • expired ephemeral node reappears after ZK leader change
  • 深入淺析zookeeper的一致性模型及其實現講解了為什么zookeeper的一致性和其他一致性協議有區別
  • How ZooKeeper guarantees “Single System Image”?
  • ZooKeeper: Wait-free coordination for Internet-scale systems yahoo的論文
  • ZooKeeper FAQ 官方文檔告訴你應該如何處理CONNECTION_LOSS,SESSION_EXPIRED等等,真的對zk有所了解的人都會問的問題。。。
  • Tech Note 10JVM pause也有可能導致腦裂
  • KIP-537: Increase default zookeeper session timeout
  • SpringBoot集成Zookeeper另外還簡單的講了一些zookeeper的理論基礎如ZAB
  • Spring Cloud Zookeeperspring cloud如何集成zookeeper的官方教程。Spring Cloud Zookeeper uses Apache Curator behind the scenes.
  • 可能是全網把 ZooKeeper 概念講的最清楚的一篇文章
  • 超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

    總結

    以上是生活随笔為你收集整理的zookeeper简介以及C客户端用法的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。