zookeeper 概覽與性能

本文根據zookeeper 概覽進行整理彙總,大量加入了我的的理解,不當之處歡迎交流.html

ZooKeeper是一個針對分佈式應用的分佈式、開源的協調服務。它公開了一組簡單的原語,分佈式應用程序能夠在這些原語的基礎上構建,以實現更高級別的服務,用於同步、配置維護、分組和命名。它被設計成易於編程,而且使用了一種相似於文件系統目錄樹結構的數據模型。它在Java中運行,而且有針對Java和C的綁定。node

協調服務是出了名的難搞。它們特別容易出現競爭條件和死鎖等錯誤。ZooKeeper背後的動機是爲了減輕分佈式應用從頭開始實現協調服務的責任。數據庫

設計目標

  • ZooKeeper is simple.apache

    • ZooKeeper容許分佈式進程(集羣中的各個服務節點)經過共享的層次結構命名空間(相似於標準文件系統)進行協調.命名空間由數據寄存器組成,用ZooKeeper的說法就是znode(它們相似於文件和目錄).與爲存儲而設計的典型文件系統不一樣,ZooKeeper的數據保存在內存中,這意味着ZooKeeper能夠實現高吞吐量和低延遲.
  • ZooKeeper is replicated編程

    • zookeeper是一個分佈式的服務,能夠將很對的zookeeper分佈式的部署在多個服務器上並組建成副本(replica)集羣,提高服務的健壯性
  • ZooKeeper is ordered緩存

    • 對於zookeeper服務來說,數據操做是有序的(數據更改操做必定從leader節點執行,可是讀取操做能夠分散到各個集羣中的各個副本上),每一個操做都有一個成前後關心的zxid,這些能夠追蹤讀寫操做的前後順序
  • ZooKeeper is fast服務器

    • zookeeper的很是適合讀多寫少的工做負載場景,在10:1的讀寫比時它的性能最好.同時zookeeper集羣的讀取壓力能夠分散到集羣中的各個節點上.zookeeper的讀性能其實很好的緣由時數據是存放在內存中的並在數據改變時會有事務提交到磁盤上,因爲多節點間要作強一致性保障因此比通常的單機事務要花更多時間,數據的改變只能從leader執行,也制約了數據改動操做沒法作到負載均衡.這是分佈式事務一致性的自己限制不是zookeeper的技術緣由

Data model and the hierarchical namespace

ZooKeeper提供的命名空間相似於標準的文件系統.名稱是用斜槓(/)分隔的路徑元素序列.ZooKeeper命名空間中的每一個節點都用路徑標識.與標準的文件系統結構不同的是zookeeper的路徑所有是絕對路徑徹底沒有相對路徑,因此任何node的path都是/開頭的數據結構

下面是node的層次繼承圖
image併發

zookeeper採用高度相似文件系統的數據結構而不是從新設計一個專屬的結構,極大的簡化的了zookeeper的學習難度,很是容易上手.負載均衡

一致性保障

zookeeper確保下面的幾個保障:

  • Sequential Consistency
  • Atomicity
  • Single System Image
  • Reliability
  • Timeliness

關於它們的詳細解讀請看: zookeeper 一致性保障

持久化

事務日誌

針對每一次客戶端的事務操做,Zookeeper都會將他們記錄到事務日誌中,固然Zookeeper也
會將數據變動應用到內存數據庫中/咱們能夠在zookeeper的主配置文件zoo.cfg中配置數據持久化目錄,也就是事務日誌的存儲路徑dataLogDir. 若是沒有配置dataLogDir(非必
填), 事務日誌將存儲到dataDir(必填項)目錄

Zookeeper進行事務日誌文件操做的時候會頻繁進行磁盤IO操做,事務日誌的不斷追加寫操做會
觸發底層磁盤IO爲文件開闢新的磁盤塊,即磁盤Seek.所以\爲了提高磁盤IO的效率,
Zookeeper在建立事務日誌文件的時候就進行文件空間的預分配,即在建立文件的時候,就向操
做系統申請一塊大一點的磁盤塊.這個預分配的磁盤大小能夠經過系統參數
zookeeper.preAllocSize進行配置。

關於zookeeper的日誌更多的信息請看:logging

快照

數據快照用於記錄Zookeeper服務器上某一時刻的全量數據,並將其寫入到指定的磁盤文件中.
能夠經過配置snapCount配置每間隔事務請求個數,生成快照,數據存儲在dataDir指定的目錄
中.

有了事務日誌,爲啥還要快照數據?
快照數據主要時爲了快速恢復,事務日誌文件是每次事務請求都會進行追加的操做,而快照是達
到某種設定條件下的內存全量數據.因此一般快照數據是反應當時內存數據的狀態.事務日誌是
更全面的數據,因此恢復數據的時候,能夠先恢復快照數據,再經過增量恢復事務日誌中的數據
便可.

zookeeper的持久化機制和Redis幾乎是徹底同樣的.同時有快照和操做日誌.

性能

理論上zookeeper的性能是很不錯的,官方給出的詳細的說明:Performance

zookeeper集羣中對於每一個服務節點來說其實有2份數據,一份是緩存在內存中,反應了當前最新的數據,例外一份就是持久化到磁盤上保證數據的可靠性.對於讀操做來說毫無疑問的是讀取內存中的數據,因爲zookeeper數據結構簡單且數據的實際大小不大,因此讀性能是十分優秀的,而且能夠分散讀請求的壓力到多個節點,在讀多寫少的場景下輕鬆的突破上萬的QPS徹底沒有壓力,可是zookeeper的目標在於分佈式一致性,那麼對於寫操做來說,分佈式一致性的協商和事務日誌的持久化就要花一些時間了,對於寫操做,單節點而言數據被更新到內存中並持久化到磁盤上,多節點間同時作了分佈式一致性協商確認後才能返回給客戶端最終的寫操做成功回執.

詳細的性能相關的文檔請看: Performance

因此我對zookeeper的性能制約因素總結以下:

  • 分佈式協商

    • follow數量: 對於一個zookeeper集羣而言,leader只會有一個可是follow有多個,follow越多協商的成本越高,因此在知足可靠性的前提下,follow合理的數量有利於zookeeper的寫性能並反應到混合讀寫性能上,讀寫比越高,follow數量的影響越小,可是follow的數量過少又會制約併發讀取性能. 如今的典型的zookeeper最好採起 1 leader + 合理數量的follow + 多個obersver 的搭配. 多個obersver基本等同於follow可是不參與選舉和一致性協商,能夠被認爲是leader的同步鏡像承擔讀操做的壓力,它能夠有效彌補follow數量多了會增長協商成本但數量不夠又影響讀操做性能的尷尬.
  • 持久化IO限制.zookeeper是強一致性高可靠設計,那麼對於每一個寫操做都會產生持久化操做,這時傳統的機械硬盤很容易由於IO性能很差而制約zookeeper的寫性能

    • 使用高IOPS的固態硬盤
    • 分離zooker的dataDirdataLogDir,數據快照和持久化操做不在一個磁盤上或者一個文件路徑下,分離這它們的位置後可能下降單個磁盤的IOPS性能要求

此外一個沒法迴避的可是影響zookeeper性能的因素是zookeeper的故障恢復會致使從新選舉的過程當中會有短暫的性能降低,可是時間通常是幾秒之內,文檔請看: Reliability

本文原創連接:zookeeper 概覽與性能

相關文章
相關標籤/搜索