日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

ZooKeeper: 简介, 配置及运维指南

發(fā)布時(shí)間:2025/3/15 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ZooKeeper: 简介, 配置及运维指南 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. 概覽

ZooKeeper是一個(gè)供其它分布式應(yīng)用程序使用的軟件, 它為其它分布式應(yīng)用程序提供所謂的協(xié)調(diào)服務(wù). 所謂的協(xié)調(diào)服務(wù), 是指ZooKeeper的如下能力

  • naming 命名
  • configuration management 配置管理
  • synchronization 同步
  • group service 分組服務(wù)
  • 上面四個(gè)功能可能現(xiàn)在不太好說(shuō)清, 但大致上目前你需要明白ZooKeeper就是為其它分布式應(yīng)用程序提供一些基礎(chǔ)功能的程序就好了. 我們以其中的配置管理為例. 假設(shè)你在寫一個(gè)可橫向擴(kuò)容的集群應(yīng)用程序, 在你的預(yù)想里, 你的應(yīng)用程序最終將部署到成千上萬(wàn)臺(tái)機(jī)器上去, 那么, 這成千上萬(wàn)臺(tái)機(jī)器上的成千上萬(wàn)個(gè)實(shí)例如何保持配置文件的一致性呢? 簡(jiǎn)單: 你的分布式應(yīng)用程序不要自己處理配置管理的問(wèn)題, 而是把配置管理交給ZooKeeper去做, 如果某個(gè)實(shí)例需要取配置文件, 去訪問(wèn)ZooKeeper就好了, ZooKeeper向你保證一致性.

    并且用上面說(shuō)到的四種功能, 還能組合實(shí)現(xiàn)出其它高級(jí)玩法, 比如:

  • implement consensus. 在需要一致性的時(shí)候, 由ZooKeeper實(shí)現(xiàn)一致性
  • group management. 分組管理
  • leader election. 集群選爹或組內(nèi)選爹
  • presence protocols. 探測(cè)集群中各個(gè)實(shí)例的死活
  • 下面各個(gè)章節(jié)將詳細(xì)敘述相關(guān)內(nèi)容.

    需要說(shuō)明的是, ZooKeeper本身的官方文檔雖然質(zhì)量上乘(Apache產(chǎn)品的一貫風(fēng)格), 但內(nèi)容上并不完整, 我的這篇譯文也有兩個(gè)缺陷: 一是可能錯(cuò)譯, 由于我本身對(duì)ZooKeeper的理解出現(xiàn)了偏差導(dǎo)致的. 二是可能有廢話, 我并不是照章一字一句翻譯的. 總之請(qǐng)作為參考來(lái)閱讀, 不要作為標(biāo)準(zhǔn)來(lái)閱讀.

    1.1 簡(jiǎn)介

    1.1.1 一個(gè)為分布式應(yīng)用程序提供服務(wù)的 分布式協(xié)調(diào)服務(wù)

    ZooKeeper是:

  • 開(kāi)源的
  • 為其它分布式應(yīng)用程序提供服務(wù)的
  • 它本身也是分布式的
  • 向其它創(chuàng)面式應(yīng)用程序提供協(xié)調(diào)功能
  • ZooKeeper對(duì)外提供了一系列的原語(yǔ)(primitives), 其它分布式應(yīng)用程序利用這些原語(yǔ), 可以很方便的實(shí)現(xiàn)一些高級(jí)抽象功能, 比如: 同步, 配置管理維護(hù), 分組, 命名等. ZooKeeper的設(shè)計(jì)宗旨就有兩條:

  • 簡(jiǎn)單易用, 使用時(shí)的編碼難度低.
  • 使用樹(shù)型邏輯結(jié)構(gòu)組織數(shù)據(jù).
  • ZooKeeper是用Java寫的, 其對(duì)外的API有Java版本的, 也有C的binding版.

    1.1.2 ZooKeeper的設(shè)計(jì)原則

    ZooKeeper是簡(jiǎn)單易用的

    如果將使用ZooKeeper的分布式應(yīng)用程序看做是千千萬(wàn)萬(wàn)個(gè)獨(dú)立的進(jìn)程實(shí)例, ZooKeeper則是構(gòu)建了一個(gè)共享的, 層級(jí)式的名稱空間(shared hierarchal namespace)以供這千千萬(wàn)萬(wàn)個(gè)進(jìn)程實(shí)例去訪問(wèn). 這個(gè)所謂的層級(jí)式的名稱空間邏輯上和*nix中的文件系統(tǒng)很像. 名稱空間由數(shù)據(jù)寄存器(data register)構(gòu)成, 數(shù)據(jù)寄存器也被稱謂節(jié)點(diǎn)(node), 類比于文件系統(tǒng)的話, 節(jié)點(diǎn)相當(dāng)于文件系統(tǒng)中的文件, 或目錄. 不過(guò)與文件系統(tǒng)不同的是: 文件系統(tǒng)是在持久化存儲(chǔ)設(shè)備上抽象數(shù)據(jù)存儲(chǔ)的一層, 但ZooKeeper是把所有數(shù)據(jù)都放在內(nèi)存中的.

    ZooKeeper是既快又穩(wěn)的

    數(shù)據(jù)全扔在內(nèi)存里, 保證的ZooKeeper很快, 性能很好. ZooKeeper的設(shè)計(jì)實(shí)現(xiàn)中, 除了簡(jiǎn)單易用, 還把以下三點(diǎn)列進(jìn)了宗旨里:

  • 性能要高. 要快, 所以數(shù)據(jù)扔內(nèi)存里.
  • 要高可用. 要穩(wěn), 所以ZooKeeper本身是分布式的, 并且掛掉一小半實(shí)例都不影響服務(wù).
  • 嚴(yán)格有序的訪問(wèn). 保證客戶端使用原語(yǔ)可以實(shí)現(xiàn)可靠的同步服務(wù).
  • ZooKeeper本身是分布式的

    ZooKeeper本身是分布式的. 我們把ZooKeeper寄生的多臺(tái)機(jī)器集合稱為一個(gè)ensemble, 這個(gè)詞不是很好翻譯, 干脆不翻譯了, 這個(gè)單詞的意思和集群差不多.

    在下圖中, 每個(gè)Server是一個(gè)ZooKeeper實(shí)例進(jìn)程, 每個(gè)Client是一個(gè)使用ZooKeeper服務(wù)的客戶端, 這個(gè)客戶端一般是另外一個(gè)分布式程序的一個(gè)實(shí)例. 一個(gè)有效的ZooKeeper服務(wù)是由多個(gè)Server構(gòu)成的(實(shí)際上并沒(méi)有限定每個(gè)Server獨(dú)占一臺(tái)機(jī)器). 每個(gè)ZooKeeper服務(wù)中的Server都必須知道其它所有Server的位置. 每個(gè)Server都在內(nèi)存中保存了一些數(shù)據(jù)(in-memory image of state), 并且在磁盤上保存著事務(wù)日志(transaction logs)與快照(snapshot). 只要整個(gè)ZooKeeper服務(wù)中的大多數(shù)Server正常工作著, 那么整個(gè)Server就能正常的向外提供服務(wù).

    而對(duì)于ZooKeeper的使用者, 也就是圖中的Client來(lái)說(shuō), 也就是另外一個(gè)分布式應(yīng)用程序(中的一個(gè)實(shí)例), 要使用ZooKeeper的服務(wù), 只需要通過(guò)TCP連接到ZooKeeper服務(wù)中的一個(gè)Server上即可, 將這個(gè)連接置為長(zhǎng)連接, 由Client負(fù)責(zé)TCP連接的維護(hù), 并通過(guò)這個(gè)TCP連接向Server發(fā)送請(qǐng)求, 接收回應(yīng), 發(fā)送心跳, 獲取監(jiān)控事件等. 當(dāng)Server不幸掛掉的時(shí)候, Client需要自己來(lái)將連接切換到另外一個(gè)Server上去.

    ZooKeeper是嚴(yán)格有序的

    ZooKeeper對(duì)每次內(nèi)部變更都有一個(gè)版本戳一樣的機(jī)制, 這也就是簡(jiǎn)單的事務(wù)機(jī)制. 它保證了ZooKeeper整個(gè)服務(wù)對(duì)外提供的原語(yǔ)是原子性的, 并且是嚴(yán)格有序的.

    ZooKeeper很快

    當(dāng)讀寫比例超過(guò)10:1的時(shí)候, ZooKeeper的性能表現(xiàn)很好. 低于這個(gè)比例的話, 可能就不是很適合使用ZooKeeper了.

    1.1.3 ZooKeeper中的數(shù)據(jù)模型與層級(jí)式名稱空間

    ZooKeeper中的層級(jí)式名稱空間和文件系統(tǒng)很類似, 每個(gè)節(jié)點(diǎn)都有獨(dú)一無(wú)二的一個(gè)路徑, 和文件系統(tǒng)一樣, 如下圖所示:

    長(zhǎng)期節(jié)點(diǎn)與短期節(jié)點(diǎn)

    和文件系統(tǒng)不同, 每個(gè)ZooKeeper節(jié)點(diǎn)都有自己的數(shù)據(jù), 而文件系統(tǒng)中, 目錄是不存儲(chǔ)數(shù)據(jù)的. ZooKeeper中的節(jié)點(diǎn)也被簡(jiǎn)稱為znode.

    znode本身除了數(shù)據(jù)之外, 還存儲(chǔ)著:

  • 數(shù)據(jù)變更的版本號(hào)
  • ACL變更的版本號(hào)
  • 時(shí)間戳
  • 每次znode中的數(shù)據(jù)有變更, 版本號(hào)都會(huì)遞增, 并且, Client向znode獲取數(shù)據(jù)時(shí), 實(shí)際上不光獲取了數(shù)據(jù)本身, 還獲取了數(shù)據(jù)的版本號(hào).

    znode中數(shù)據(jù)的讀寫是原子性的, 讀, 會(huì)讀到整個(gè)znode中的所有數(shù)據(jù), 寫, 會(huì)替換掉znode中的所有數(shù)據(jù). 每個(gè)znode還額外有一個(gè)ACL(訪問(wèn)控制表. Access Control List)來(lái)限定讀寫的.

    普通的znode是持久性的, 這意味著只要ZooKeeper服務(wù)健在, 那么這個(gè)znode就存在著. 但有一種znode不是這樣的: 它隨著某個(gè)創(chuàng)建znode的會(huì)話的開(kāi)始, 被創(chuàng)建, 而一旦這個(gè)會(huì)話被撤除掉, 這個(gè)znode就會(huì)自動(dòng)被ZooKeeper刪除. 這個(gè)特性在某些場(chǎng)合特別有用.

    監(jiān)控

    ZooKeeper支持一個(gè)叫監(jiān)控(watches)的概念: Client可以對(duì)某個(gè)znode設(shè)置監(jiān)控, 當(dāng)這個(gè)znode有變更的時(shí)候, 就會(huì)產(chǎn)生監(jiān)控事件, 這個(gè)事件會(huì)由ZooKeeper通知至Client, 即是Client會(huì)收到來(lái)自Server的通知.

    另外如果在監(jiān)控過(guò)程中, Client和Server之間的連接掛掉了, 那么Client會(huì)收到一個(gè)連接掛掉的通知.

    1.1.4 ZooKeeper對(duì)使用者的承諾

  • Sequential Consistency 順序一致性. 同一個(gè)Client發(fā)送的多個(gè)請(qǐng)求, 會(huì)按請(qǐng)求發(fā)送的順序被應(yīng)用到Server上
  • Atomicity 原子性. 請(qǐng)求要么成功, 要么失敗, 沒(méi)有中間狀態(tài)
  • Single System Image 單系統(tǒng)鏡像. 無(wú)論Client接的是哪個(gè)Server, ZooKeeper保證Client獲得的服務(wù)是完全相同的.
  • Reliability 可靠性. 一旦一個(gè)更新操作被ZooKeeper接受且應(yīng)用實(shí)施, 那么直至某個(gè)Client再次更新之前, ZooKeeper會(huì)保持住這個(gè)狀態(tài).
  • Timeliness 及時(shí)性. ZooKeeper保證Client看到的都是及時(shí)更新的數(shù)據(jù).
  • 1.1.5 ZooKeeper的API

    API名稱語(yǔ)義
    create在名稱空間樹(shù)中的指定位置創(chuàng)建一個(gè)節(jié)點(diǎn)
    delete刪除一個(gè)指定節(jié)點(diǎn)
    exists查詢指定節(jié)點(diǎn)是否存在
    get data獲取指定節(jié)點(diǎn)上的數(shù)據(jù)
    set data向指定節(jié)點(diǎn)寫數(shù)據(jù)
    get children獲取一個(gè)指定節(jié)點(diǎn)的所有子節(jié)點(diǎn)
    sync等待數(shù)據(jù)傳播完成

    1.1.5 ZooKeeper的實(shí)現(xiàn)

    下圖是ZooKeeper的組件圖: ZooKeeper是由下面圖中的幾個(gè)組件(component)構(gòu)成的, 除了圖中的request processor(請(qǐng)求接收器)組件之外, ZooKeeper的每個(gè)Server都有著其它組件的單獨(dú)實(shí)例.

    replicated database(數(shù)據(jù)庫(kù)), 這里的replicated是指, 這個(gè)數(shù)據(jù)庫(kù)在每個(gè)Server中都有一個(gè)獨(dú)立的實(shí)例. 并且每個(gè)Server中的數(shù)據(jù)庫(kù)都存儲(chǔ)著整個(gè)名稱空間樹(shù), 另外注意這個(gè)數(shù)據(jù)庫(kù)是內(nèi)存數(shù)據(jù)庫(kù). 每當(dāng)數(shù)據(jù)樹(shù)要更新的時(shí)候, 都會(huì)向磁盤寫入日志(為了故障恢復(fù)使用), 并且對(duì)數(shù)據(jù)樹(shù)的寫操作, 是先將數(shù)據(jù)序列化后寫入磁盤, 再寫入數(shù)據(jù)庫(kù)的.

    每個(gè)ZooKeeper Server都對(duì)外向多個(gè)Client提供服務(wù), 而Client只能接一個(gè)Server來(lái)收發(fā)請(qǐng)求回應(yīng). 當(dāng)Client發(fā)出讀請(qǐng)求的時(shí)候, 數(shù)據(jù)是直接從本地?cái)?shù)據(jù)庫(kù)返回的, 而如果Client發(fā)送的是一個(gè)寫請(qǐng)求, 那就有點(diǎn)麻煩了, 這個(gè)寫請(qǐng)求的處理要經(jīng)過(guò)一個(gè)協(xié)商協(xié)議(agreement protocol)的處理. 這個(gè)邏輯很自然, 因?yàn)閷懖僮魇且S持多個(gè)Server之間數(shù)據(jù)的一致性的.

    那么核心問(wèn)題就是, 這個(gè)所謂的agreement protocol是如何保證寫操作全局一致的呢? 它有兩個(gè)策略:

  • ZooKeeper中的所有Server, 有一個(gè)是爹(leader), 其它都是兒子(follower)
  • 爹向兒子傳達(dá)什么信息, 兒子毫不遲疑的執(zhí)行.
  • ZooKeeper內(nèi)部有一個(gè)選爹機(jī)制, 保證在爹出現(xiàn)意外(進(jìn)程掛死, 機(jī)器斷網(wǎng))的情況下, 選出一個(gè)新爹
  • 兒子接收到寫請(qǐng)求時(shí), 先將寫請(qǐng)求交給爹. 之后爹再將寫請(qǐng)求廣播給所有兒子.
  • ZooKeeper在消息通信上使用了一個(gè)自定義的原子消息協(xié)議, 消息協(xié)議的原子性保證了ZooKeeper中每個(gè)Server, 無(wú)論是爹還是兒子, 數(shù)據(jù)庫(kù)中存儲(chǔ)的數(shù)據(jù)都是實(shí)時(shí)的. 當(dāng)?shù)盏接蓛鹤舆f交的一個(gè)寫請(qǐng)求后, 會(huì)做如下事情:

  • 對(duì)比數(shù)據(jù)庫(kù)中的當(dāng)前狀態(tài), 預(yù)計(jì)寫操作執(zhí)行后的預(yù)期狀態(tài), 把兩個(gè)狀態(tài)之間的差額做成一個(gè)事務(wù)請(qǐng)求
  • 將這個(gè)事務(wù)請(qǐng)求分發(fā)給所有兒子
  • 1.1.6 ZooKeeper的用法

    ZooKeeper的編程接口十分簡(jiǎn)單, 這部分內(nèi)容會(huì)在后續(xù)章節(jié)涉及到. 簡(jiǎn)單意味著API數(shù)量少, 容易被理解, 但也有一點(diǎn)壞處, 就是接口能實(shí)現(xiàn)的功能十分基本基礎(chǔ), 要實(shí)現(xiàn)高級(jí)一點(diǎn)的功能, 你需要自己寫邏輯, 當(dāng)然這也不會(huì)十分困難.

    1.1.7 ZooKeeper的性能

    前面吹了那么多ZooKeeper的好處, 是時(shí)候用一些證據(jù)來(lái)支撐前面吹的逼了. ZooKeeper的實(shí)際性能到底有多少? 我相信很多傳統(tǒng)的C/C++后臺(tái)開(kāi)發(fā)人員在看到ZooKeeper是跑在JVM上的Java程序的時(shí)候都在內(nèi)心默默的鄙視了一下ZooKeeper.

    但反直覺(jué)的是, 根據(jù)雅虎的ZooKeeper研發(fā)團(tuán)隊(duì)報(bào)告, ZooKeeper的性能確實(shí)十分強(qiáng)勁, 但性能強(qiáng)勁是有前提條件的: 那就是對(duì)數(shù)據(jù)的讀取操作量遠(yuǎn)大于數(shù)據(jù)寫入操作量. 當(dāng)然作為一個(gè)供其它應(yīng)用程序使用的協(xié)調(diào)服務(wù), 讀量大于寫量應(yīng)該是一個(gè)典型現(xiàn)象.

    下圖是ZooKeeper的性能圖表, 其中橫軸是指請(qǐng)求量中讀操作的占比, 縱軸是每秒能處理的請(qǐng)求量. 顏色不同的線代表ZooKeeper的實(shí)例個(gè)數(shù)(顯然每個(gè)實(shí)例獨(dú)占一臺(tái)機(jī)器). 可以直觀的看到, 在讀操作占比超過(guò)80%后, ZooKeeper的吞吐量就起飛了. 并且5個(gè)實(shí)例構(gòu)成的ensemble在性能的提升上對(duì)比3個(gè)實(shí)例構(gòu)成的ensemble有顯著提升, 但超過(guò)5之后, 增加實(shí)例個(gè)數(shù)對(duì)ZooKeeper的整體性能提升就不是很明顯了. 當(dāng)然這只是一個(gè)參考圖表, 應(yīng)用實(shí)施的時(shí)候, 各家都有各家的特殊國(guó)情, 還需要自行探究.

    上面這邊圖的測(cè)試現(xiàn)場(chǎng)大致是這樣的:

  • 用的ZooKeeper版本為3.2
  • 每個(gè)ZooKeeper實(shí)例獨(dú)占一臺(tái)機(jī)器, 每臺(tái)機(jī)器雙核心2GHz Xeon處理器, 磁盤兩塊, 磁盤的性能規(guī)格是 SATA 盤. 15K RPM. 其中一塊硬盤專用于存放ZooKeeper的日志, 另一塊磁盤專用于存儲(chǔ)快照.
  • 讀寫的數(shù)據(jù)量均是1k字節(jié). 模塊client的機(jī)器大約有30臺(tái).
  • ensemble被設(shè)置為爹不允許直連client.
  • 這大致能解釋為什么ensemble中實(shí)例的數(shù)量從3到5的時(shí)候, 性能有一個(gè)飛躍: 因?yàn)?個(gè)實(shí)例組成的ensemble中, 干活的只有兩個(gè), 另外一個(gè)是爹. 變成5個(gè)實(shí)例組成的ensemble后, 干活的就有四個(gè)了, 提升了一倍.

    1.1.8 ZooKeeper的可靠性

    除開(kāi)吞吐量外, 使用者另外關(guān)心的一個(gè)指標(biāo)就是可靠性, 下面這張圖依然出自雅虎團(tuán)隊(duì), 搭建了一個(gè)7個(gè)實(shí)例組成的ensemble, 然后用910個(gè)client去瘋狂懟這個(gè)ZooKeeper集群, 懟ZooKeeper時(shí)其它參數(shù)和上面的性能測(cè)試一致, 不同的是寫操作的比例為30%, 讀操作為70%. 在懟的過(guò)程中, 依次手動(dòng)模塊了如下情況:

  • 一個(gè)兒子掛了, 被恢復(fù)
  • 另外一個(gè)兒子掛了, 被恢復(fù)
  • 爹掛了, 被恢復(fù)
  • 兩個(gè)兒子掛了, 被恢復(fù)
  • 另外一個(gè)爹掛了, 被恢復(fù)
  • 圖中橫軸是時(shí)間, 單位是秒, 縱軸是吞吐量. 圖中帶圓圈的數(shù)字分別代表了有上面對(duì)應(yīng)的錯(cuò)誤發(fā)生.

    client共有910個(gè), 所以比起上一張圖來(lái)說(shuō), 吞吐圖下降了不少. 從圖中可以看出:

  • 單個(gè)兒子實(shí)例有異常波動(dòng)基本不影響ZooKeeper的性能, 對(duì)使用者來(lái)講, 基本感覺(jué)不到.
  • 爹掛的時(shí)候會(huì)影響ZooKeeper的性能, 但很快就能恢復(fù). ZooKeeper在爹掛了之后重新選舉一個(gè)爹的時(shí)間大致在200ms左右.
  • 1.1.9 ZooKeeper的應(yīng)用前景

    ZooKeeper的版本號(hào), 直至我翻譯這個(gè)文檔的時(shí)候, 穩(wěn)定版已經(jīng)到3.4.12了, beta版已經(jīng)到3.5.4了. 能迭代到這個(gè)程序說(shuō)明Apache對(duì)這個(gè)項(xiàng)目的態(tài)度已經(jīng)顯然不止于玩票了. 實(shí)際上ZooKeeper已經(jīng)成功的應(yīng)用在許多業(yè)界的產(chǎn)品上了. 雅虎用ZooKeeper做Message Broker的協(xié)調(diào)和錯(cuò)誤恢復(fù)服務(wù), 這應(yīng)當(dāng)是ZooKeeper能傍上的最粗的大腿了.雅虎的這個(gè)消息隊(duì)列是一個(gè)很基礎(chǔ)的發(fā)布-訂閱消息系統(tǒng), 規(guī)模很大. 受這個(gè)成功案例的影響, 雅虎里的一標(biāo)廣告系統(tǒng)在在用ZooKeeper做可靠性服務(wù).

    1.2 快速上手指南

    這一小節(jié)主要是面向開(kāi)發(fā)者的, 大致閱讀本小節(jié)的內(nèi)容, 能讓你快速上手, 在你的代碼中使用上ZooKeeper的功能, 并且為了配合自測(cè), 這一小節(jié)大致會(huì)簡(jiǎn)單的講一下如何搭建一個(gè)由單個(gè)實(shí)例組成的ZooKeeper ensemble(僅供開(kāi)發(fā)調(diào)試使用的部署模式), 并且講幾個(gè)小命令用以檢測(cè)你的ZooKeeper是否搭建成功, 再附上一些代碼片斷幫助你直觀的理解ZooKeeper接口的用法.

    這一節(jié)不會(huì)涉及生產(chǎn)環(huán)境中多Server模式的部署方法, 也不會(huì)涉及部署中的詳細(xì)配置參數(shù)等. 這一節(jié)只是一個(gè)快速上手指南: 并且是面向開(kāi)發(fā)人員的快速上手指南.

    1.2.1 系統(tǒng)要求

    請(qǐng)參考第四章

    1.2.2 下載ZooKeeper

    從這里下載ZooKeeper的最新的穩(wěn)定版.

    1.2.3 單實(shí)例模式

    搭一個(gè)單實(shí)例模式的ZooKeeper很簡(jiǎn)單,

  • 下載ZooKeeper的安裝包, 解壓
  • 寫一個(gè)配置文件, 建議把這個(gè)配置文件放在zookeeper/conf/zoo.cfg這個(gè)位置, 配置文件是一個(gè)文本文件, 鑒于現(xiàn)在搭的是一個(gè)開(kāi)發(fā)環(huán)境, 所以配置文件里簡(jiǎn)單的寫下面這三行就可以了
  • tickTime=2000 dataDir=/var/lib/zookeeper clientPort=2181
  • 來(lái)稍微解釋一下這個(gè)配置文件中的配置項(xiàng), 總共有三個(gè)
  • tickTime: 這是一個(gè)基本的時(shí)間單位, 后面的值的單位是毫秒, 比如上面我們?cè)O(shè)置為2000, 意思是一個(gè)tickTime代表了2000毫秒. tickTime主要用于發(fā)送心跳, 以及默認(rèn)的最小會(huì)話超時(shí)時(shí)間是兩個(gè)tickTime
  • dataDir: 這個(gè)目錄是用于存儲(chǔ)內(nèi)存數(shù)據(jù)庫(kù)的快照的, 并且默認(rèn)情況下除非特別指定, 事務(wù)日志也會(huì)存在這里
  • clientPort: 這是開(kāi)發(fā)給client用于連接的端口號(hào)
  • 在寫完配置文件, 并且把配置文件放在zookeeper/conf/zoo.cfg后, 運(yùn)行zookeeper/bin/zkServer.sh這個(gè)腳本就會(huì)啟動(dòng)一個(gè)單實(shí)例ZooKeeper服務(wù).
  • 另外需要注意的還有以下幾點(diǎn):

  • ZooKeeper用log4j接口來(lái)輸出運(yùn)行日志. 注意這里說(shuō)的是運(yùn)行日志, 而不是前面提到的事務(wù)日志. 更多的細(xì)節(jié)在第二章會(huì)涉及. 默認(rèn)情況下日志會(huì)輸出至控制臺(tái), 如果你希望把日志寫進(jìn)一個(gè)文件里, 需要自行配置log4j
  • 注意按上面步驟搭的是一個(gè)單實(shí)例ZooKeeper服務(wù), 沒(méi)有什么可靠性可言, 生產(chǎn)環(huán)境中千萬(wàn)不要這么干, 這只是給使用ZooKeeper接口寫程序的開(kāi)發(fā)人員用的一個(gè)本地測(cè)試環(huán)境, 而且由于是單實(shí)例, 一旦這個(gè)唯一的ZooKeeper server進(jìn)程掛了, 整個(gè)ZooKeeper服務(wù)就不可用了.
  • 1.2.4 管理ZooKeeper的存儲(chǔ)

    ZooKeeper有兩個(gè)地方使用到了本地磁盤存儲(chǔ), 如果你仔細(xì)閱讀了之前的章節(jié)的話, 會(huì)知道這兩個(gè)點(diǎn)分別是:

  • 事務(wù)日志
  • 內(nèi)存數(shù)據(jù)庫(kù)快照
  • 生產(chǎn)環(huán)境建議這兩個(gè)東西分開(kāi)存儲(chǔ), 并且最好是物理上分開(kāi)存儲(chǔ): 分別使用一塊獨(dú)立的硬盤. 但具體細(xì)節(jié)這一章節(jié)就不說(shuō)了, 后續(xù)在運(yùn)維相關(guān)的章節(jié)會(huì)講到.

    1.2.5 連接至ZooKeeper服務(wù)

    執(zhí)行安裝包里的這個(gè)腳本可以連接至上面搭建好的ZooKeeper本地單實(shí)例服務(wù)上去:

    $ zookeeper/bin/zkCli.sh -server 127.0.0.1:2181

    這打開(kāi)了一個(gè)交互式命令行程序, 連接成功后, 大致會(huì)有類似于以下的輸出:

    Connecting to localhost:2181 log4j:WARN No appenders could be found for logger (org.apache.zookeeper.ZooKeeper). log4j:WARN Please initialize the log4j system properly. Welcome to ZooKeeper! JLine support is enabled [zkshell: 0]

    在這個(gè)命令行程序內(nèi)部, 鍵入help獲取一些基本命令的用法, 比如這樣:

    [zkshell: 0] help ZooKeeper host:port cmd argsget path [watch]ls path [watch]set path data [version]delquota [-n|-b] pathquitprintwatches on|offcreatepath data aclstat path [watch]listquota pathhistorysetAcl path aclgetAcl pathsync pathredo cmdnoaddauth scheme authdelete path [version]setquota -n|-b val path

    類似于mysql的命令行工具, 你可以在這個(gè)命令行工具里向ZooKeeper服務(wù)發(fā)出一些指令, 比如你想查看目前ZooKeeper的層級(jí)名稱空間里都存儲(chǔ)了些啥玩意, 你可以使用ls命令

    [zkshell: 8] ls / [zookeeper]

    初始狀態(tài)下, 層級(jí)名稱空間里啥都沒(méi)有, 根/下只有一個(gè)名為zookeeper的節(jié)點(diǎn), 也就是znode. 你可以使用命令create來(lái)創(chuàng)建一個(gè)節(jié)點(diǎn), 也就是znode, 像下面這樣

    [zkshell: 9] create /zk_test my_data Created /zk_test

    上面這個(gè)命令創(chuàng)建了一個(gè)znode, 這個(gè)znode的路徑是/zk_text, 并且把一個(gè)字符串"my_data"存在了這個(gè)znode中. 現(xiàn)在再用ls查看節(jié)點(diǎn), 輸出會(huì)類似如下:

    [zkshell: 11] ls / [zookeeper, zk_test]

    現(xiàn)在根名稱空間/下有兩個(gè)節(jié)點(diǎn), 一個(gè)是默認(rèn)存在的zookeeper, 一個(gè)是我們剛才創(chuàng)建好的zk_text節(jié)點(diǎn).

    如果你想取出znode中的數(shù)據(jù), 可以使用get命令來(lái)獲取, 如下:

    [zkshell: 12] get /zk_test my_data cZxid = 5 ctime = Fri Jun 05 13:57:06 PDT 2009 mZxid = 5 mtime = Fri Jun 05 13:57:06 PDT 2009 pZxid = 5 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0 dataLength = 7 numChildren = 0

    輸出了不少東西, 正如我們?cè)诤?jiǎn)介里提到的那樣, 當(dāng)你向znode寫入數(shù)據(jù)時(shí), znode不光會(huì)保存數(shù)據(jù)本身, 還會(huì)保存一些其它玩意, 比如數(shù)據(jù)的創(chuàng)建時(shí)間, 數(shù)據(jù)的版本號(hào)之類的, 上面的輸出很豐富, 第一行當(dāng)然是我們?cè)趧?chuàng)建/zk_text節(jié)點(diǎn)時(shí)寫入的字符串"my_data", 余下的行則是與這個(gè)數(shù)據(jù)有關(guān)的其它信息. 詳細(xì)細(xì)節(jié)這里先略過(guò).

    當(dāng)你想修改一個(gè)znode下的數(shù)據(jù)的時(shí)候, 你可以使用set命令, 就像下面這樣, 我們把上面/zk_text節(jié)點(diǎn)里的數(shù)據(jù), 從原先的"my_data"字符串, 修改為新字符串"junk":

    [zkshell: 14] set /zk_test junk cZxid = 5 ctime = Fri Jun 05 13:57:06 PDT 2009 mZxid = 6 mtime = Fri Jun 05 14:01:52 PDT 2009 pZxid = 5 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0 dataLength = 4 numChildren = 0

    修改數(shù)據(jù)也會(huì)輸出節(jié)點(diǎn)的額外信息, 接下來(lái)再用get命令查看一下剛才的修改效果:

    [zkshell: 15] get /zk_test junk cZxid = 5 ctime = Fri Jun 05 13:57:06 PDT 2009 mZxid = 6 mtime = Fri Jun 05 14:01:52 PDT 2009 pZxid = 5 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0 dataLength = 4 numChildren = 0

    可以看到, 數(shù)據(jù)已經(jīng)被修改了.

    當(dāng)你想刪除一個(gè)znode的時(shí)候, 你可以使用delete命令, 就像下面這樣, 我們刪除上面我們創(chuàng)建的/zk_text節(jié)點(diǎn), 在刪除后再用ls命令查看一下刪除效果

    [zkshell: 16] delete /zk_test [zkshell: 17] ls / [zookeeper] [zkshell: 18]

    你看, 這樣是不是就很直觀, 簡(jiǎn)介里說(shuō)了一大堆, 比不上你自己動(dòng)手感受一下. 在這個(gè)交互式命令行程序里的各個(gè)命令, 其它都對(duì)應(yīng)著ZooKeeper API里的各個(gè)接口, 有了上面的直觀認(rèn)識(shí), 再參照著編程手冊(cè)使用ZooKeeper就很容易理解了.

    1.2.6 在代碼中使用ZooKeeper

    ZooKeeper對(duì)外提供的API有Java版和C語(yǔ)言兩個(gè)版本, 功能上是完全一樣的. C語(yǔ)言的API還有兩個(gè)子版本: 一個(gè)用于在單線程環(huán)境中使用, 一個(gè)用于在多線程環(huán)境中使用. 更多的具體信息請(qǐng)參考后續(xù)章節(jié).

    1.2.7 搭建多實(shí)例的ZooKeeper ensemble

    生產(chǎn)環(huán)境中顯然不能使用單實(shí)例的ZooKeeper, 這里簡(jiǎn)單提一下如何搭建多實(shí)例構(gòu)成的ZooKeeper ensemble. 多個(gè)實(shí)例構(gòu)成的ensemble中, 每個(gè)ZooKeeper server進(jìn)程都有自己的內(nèi)存數(shù)據(jù)庫(kù), 但所有實(shí)例的內(nèi)存數(shù)據(jù)庫(kù)里的內(nèi)容是一毛一樣的, 這也是為什么官方文檔里把多實(shí)例模式的ZooKeeper ensemble稱為Replicated ZooKeeper的原因. 有一點(diǎn)小蛋疼的地方是, 每個(gè)ZooKeeper server進(jìn)程在啟動(dòng)時(shí)都需要一個(gè)配置文件, 在多實(shí)例ZooKeeper ensemble中, 這多個(gè)實(shí)例使用的配置文件必須一毛一樣, 多個(gè)實(shí)例正常情況下應(yīng)當(dāng)分布在多個(gè)不同的機(jī)器上, 所以這個(gè)配置文件的一致性嘛, 就需要運(yùn)維部署人員手工維護(hù)了.

    在這篇翻譯的文檔里, 我始終堅(jiān)持把這種多個(gè)ZooKeeper server進(jìn)程構(gòu)成的ZooKeeper服務(wù)稱為多實(shí)例模式ZooKeeper, 而不叫集群, 原因是: ZooKeeper并沒(méi)有嚴(yán)格限制你, 必須每個(gè)ZooKeeper server獨(dú)占一臺(tái)機(jī)器. 雖然從邏輯上講, 多實(shí)例模式下應(yīng)當(dāng)為每個(gè)ZooKeeper server分配一臺(tái)獨(dú)立的機(jī)器, 但你非要在一臺(tái)機(jī)器上啟動(dòng)100個(gè)ZooKeeper server, 這是完全行得通的.

    在多實(shí)例模式下, 實(shí)例的數(shù)量是有最低要求的: 最少要有3個(gè)實(shí)例. 并且強(qiáng)烈建議你, 實(shí)例的數(shù)目設(shè)定為奇數(shù): 我們?cè)诤?jiǎn)介中提到過(guò), ZooKeeper服務(wù)運(yùn)行時(shí), 如果有少量實(shí)例掛掉了, 整個(gè)ZooKeeper服務(wù)還會(huì)正常運(yùn)轉(zhuǎn). 這里對(duì)于少量的定義, 其實(shí)就是看掛掉的實(shí)例數(shù)量有沒(méi)有達(dá)到二分之一. 奇數(shù)數(shù)目的實(shí)例, 比較容易判定二分之一.

    多實(shí)例模式下的配置文件, 依然建議放在zookeeper/conf/zoo.cfg中, 內(nèi)容與單實(shí)例模式稍有不同

    tickTime=2000 dataDir=/var/lib/zookeeper clientPort=2181 initLimit=5 syncLimit=2 server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888

    其中tickTime, dataDir, clientPort三個(gè)配置項(xiàng)的含義這里不再重復(fù), 新增的字段的含義如下:

  • initLimit: 這是一個(gè)超時(shí)時(shí)間, 它的單位是tickTime, 它限制了ZooKeeper中兒子與爹建立連接的超時(shí)時(shí)間. 比如上面設(shè)置為5, 且tickTime的值設(shè)置為2000毫秒, 意思是: 兒子與爹建立連接必須在10秒內(nèi)完成, 超過(guò)10秒, 就會(huì)認(rèn)為這個(gè)兒子廢掉了.
  • syncLimit: 這也是一個(gè)超時(shí)時(shí)間, 單位依然是tickTime. 上面設(shè)置為2, 意思是指, 當(dāng)兒子執(zhí)行數(shù)據(jù)同步的時(shí)候, 在4秒內(nèi)必須完成, 超過(guò)4秒, 就會(huì)認(rèn)為這個(gè)兒子廢掉了.
  • server.X: 配置文件里共有三行這種配置, 每一行描述了當(dāng)前多實(shí)例ZooKeeper服務(wù)內(nèi)的一個(gè)實(shí)例. 當(dāng)每個(gè)ZooKeeper server實(shí)例進(jìn)程啟動(dòng)的時(shí)候, 它先去 dataDir 目錄下找一個(gè)名為myid的文本文件, 這個(gè)文件里寫著一個(gè)數(shù)字, 這個(gè)數(shù)字為1, 就代表當(dāng)前啟動(dòng)的server 進(jìn)程是配置文件里的server.1. 然后進(jìn)程就會(huì)讀取配置文件里server.1的值, 這里值為zoo1:2888:3888, 2888是用于兒子和爹建立連接使用的端口, 3888是用于選舉爹的時(shí)候使用的端口號(hào). 注意, 如果你在一臺(tái)機(jī)器上啟動(dòng)多個(gè)ZooKeeper server實(shí)例, 那么注意多個(gè)實(shí)例間不能使用相同的端口號(hào).
  • 1.2.8 簡(jiǎn)單的優(yōu)化建議

    為了獲取更好的性能, 建議在配置文件中額外配置一個(gè)配置項(xiàng), 名為dataLogDir, 值為一個(gè)目錄地址. 配置該配置項(xiàng)之后, 會(huì)導(dǎo)致當(dāng)前實(shí)例會(huì)將事務(wù)日志寫向?qū)?yīng)地址. 否則會(huì)直接寫向dataDir中去.

    更多的優(yōu)化建議, 與更細(xì)節(jié)的多實(shí)例ZooKeeper部署指導(dǎo)會(huì)在后續(xù)運(yùn)維章節(jié)仔細(xì)說(shuō)明.

    2. 面向開(kāi)發(fā)者的文檔

    // TODO

    3. BookKeeper

    // TODO

    4. 面向系統(tǒng)管理員與運(yùn)維人員的文檔

    4.1 系統(tǒng)管理員指南

    4.1.1 部署

    4.1.1.1 系統(tǒng)要求

    支持的操作系統(tǒng)平臺(tái)

    ZooKeeper下有多個(gè)組件. 有些組件在各大平臺(tái)上都能跑, 有些則只能跑在指定的一部分平臺(tái)上. 這些組件包括:

  • Client. 指的是ZooKeeper的客戶端庫(kù), 用于其它應(yīng)用程序與ZooKeeper ensemble建立連接并使用ZooKeeper的功能
  • Server. 指的是ZooKeeper server. 跑在ZooKeeper ensemble中各個(gè)機(jī)器上的應(yīng)用程序, 也就是ZooKeeper server進(jìn)程.
  • Native Client. 一個(gè)用C語(yǔ)言實(shí)現(xiàn)的庫(kù), 功能和Client一樣, 只不過(guò)面向的是C系開(kāi)發(fā)者.
  • Contrib. 其它可選的組件.
  • 下表展示了各個(gè)組件在各個(gè)操作系統(tǒng)平臺(tái)上的受支持程度:

    操作系統(tǒng)Client組件Server組件Native Client組件Contrib其它組件
    GNU/Linux可用于開(kāi)發(fā)及生產(chǎn)可用于開(kāi)發(fā)及生產(chǎn)可用于開(kāi)發(fā)及生產(chǎn)可用于開(kāi)發(fā)及生產(chǎn)
    Solaris可用于開(kāi)發(fā)及生產(chǎn)可用于開(kāi)發(fā)及生產(chǎn)不支持不支持
    FreeBSD可用于開(kāi)發(fā)及生產(chǎn)可用于開(kāi)發(fā)及生產(chǎn)不支持不支持
    Windows可用于開(kāi)發(fā)及生產(chǎn)可用于開(kāi)發(fā)及生產(chǎn)不支持不支持
    Max OS X僅可用于開(kāi)發(fā)僅可用于開(kāi)發(fā)不支持不支持

    其它沒(méi)提到的操作系統(tǒng)平臺(tái)就自求多福吧.

    需要的軟件

    ZooKeeper是用Java寫的, 所以需要一個(gè)版本在1.6或更高的JDK. 對(duì)于多實(shí)例模式的部署建議使用多臺(tái)機(jī)器.

    4.1.1.2 多實(shí)例模式

    我們?cè)诘谝徽碌目焖偕鲜种改现刑岬竭^(guò), 生產(chǎn)環(huán)境建議使用多實(shí)例模式部署ZooKeeper, 并且建議單個(gè)實(shí)例獨(dú)占一臺(tái)機(jī)器, 且建議實(shí)例的個(gè)數(shù)為奇數(shù). 個(gè)中緣由這里不再重復(fù).

    下面是如何部署多實(shí)例模式中的一個(gè)實(shí)例的步驟. 在多臺(tái)機(jī)器上重復(fù)以上步驟, 就能搭起一個(gè)多實(shí)例模式的ZooKeeper服務(wù).

  • 安裝JDK
  • 設(shè)置Java運(yùn)行時(shí)的"heap size"(堆容量). 額外設(shè)置這個(gè)是由于當(dāng)內(nèi)存不足時(shí), swapping操作會(huì)嚴(yán)重拖慢zookeeper的性能(wtf? 2018年了好吧!). 一般情況下, 如果機(jī)器是zookeeper獨(dú)占的, 那么內(nèi)存多大就設(shè)置多大就可以了.
  • 下載ZooKeeper, 點(diǎn)這里
  • 解壓下載好的壓縮包
  • 寫一個(gè)配置文件, 配置文件的路徑和文件名隨便啥都行. 內(nèi)容如下. 配置文件中各個(gè)配置項(xiàng)的具體含義在 4.1.2.10 配置參數(shù)中有詳細(xì)說(shuō)明. 如下的配置文件對(duì)應(yīng)的使用要求是:
  • 三臺(tái)機(jī)器, 每個(gè)實(shí)例獨(dú)占一臺(tái)機(jī)器. 實(shí)例的編號(hào)分別為1, 2, 3
  • 機(jī)器的2888端口用于兒子和爹通信, 3888端口用于爹的選舉
  • 對(duì)外提供服務(wù)的端口號(hào)為2181
  • tickTime=2000 dataDir=/var/lib/zookeeper/ clientPort=2181 initLimit=5 syncLimit=2 server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
  • 在配置文件指定的dataDir路徑下創(chuàng)建一個(gè)名為myid的文件, 這是一個(gè)文本文件, 文件內(nèi)容只有一個(gè)數(shù)字: 實(shí)例的編號(hào)
  • 使用類似于下面的命令行啟動(dòng)實(shí)例:
  • java -cp zookeeper.jar:lib/log4j-1.2.15.jar:conf org.apache.zookeeper.server.quorum.QuorumPeerMain zoo.cfg 0. ZooKeeper server是Java程序, 所以用`java`命令啟動(dòng) 0. -cp 參數(shù)指示JVM虛擬機(jī)去哪里找需要的class文件. 這里指定了兩個(gè)jar包文件, 和一個(gè)目錄地址. 用分號(hào)`:`隔開(kāi)0. zookeeper.jar. 這個(gè)jar包里存著ZooKeeper server的主要class文件0. lib/log4j-1.2.15.jar. 這個(gè)jar包里存著ZooKeeper輸出運(yùn)行日志所需要的`log4j`的class文件0. conf. 這個(gè)目錄里的jar包存著其它啟動(dòng)ZooKeeper所需要的class文件 0. `org.apache.zookeeper.server.quorum.QuorumPeerMain`是main函數(shù)所在的類路徑 0. `zoo.cfg`是配置文件路徑 0. 簡(jiǎn)單點(diǎn), 你可以把配置文件放在`zookeeper/conf/zoo.cfg`中, 然后直接運(yùn)行`zookeeper/bin/zkServer.sh`腳本來(lái)啟動(dòng). 這個(gè)腳本中的內(nèi)容更豐富. 但核心命令和上面那行基本一樣. 這樣的好處是很無(wú)腦, 很方便.
  • 要測(cè)試當(dāng)前ZooKeeper Server實(shí)例進(jìn)程是否正確運(yùn)行, 可以使用下面的腳本進(jìn)行測(cè)試:
  • $ bin/zkCli.sh -server 127.0.0.1:2181

    4.1.1.3 單實(shí)例模式

    單實(shí)例模式一般僅用于開(kāi)發(fā)自測(cè)使用, 具體的部署步驟在1.2.3 單實(shí)例模式章節(jié)有描述, 請(qǐng)翻回去看.

    4.1.2 系統(tǒng)管理

    4.1.2.1 部署設(shè)計(jì)

    ZooKeeper的可靠性依賴于兩個(gè)假設(shè)

  • 假設(shè)你的ZooKeeper以多實(shí)例模式部署, 且每個(gè)實(shí)例占用一臺(tái)機(jī)器. 這些機(jī)器在運(yùn)行過(guò)程中, 不可能出現(xiàn)在同一時(shí)間有超過(guò)二分之一的機(jī)器宕機(jī)的可能.
  • 每臺(tái)機(jī)器有網(wǎng)絡(luò)狀況與磁盤狀況良好, 多實(shí)例進(jìn)程啟動(dòng)時(shí)運(yùn)行的jar包代碼是一致的.
  • 要使第一個(gè)假設(shè)盡可能的成立, 你可以做如下的事情:

  • 預(yù)估你的機(jī)器宕機(jī)的頻率與持續(xù)時(shí)間, 恢復(fù)時(shí)間, 算出基本不可能同時(shí)宕機(jī)的機(jī)器臺(tái)數(shù). 比如你根據(jù)去年的運(yùn)維記錄, 查一下去年的宕機(jī)概率, 然后根據(jù)這個(gè)概率估算出整個(gè)機(jī)房同時(shí)有指定的1臺(tái)機(jī)器宕機(jī)的概率, 同時(shí)有指定的兩臺(tái)機(jī)器宕機(jī)的概率. 把這個(gè)概率降低到你能接受的程度, 比如你估算出你的機(jī)房中, 同時(shí)有指定的5臺(tái)機(jī)器同時(shí)宕機(jī)的概率不足千萬(wàn)分之一, 這個(gè)你可以接受, 那么將ZooKeeper多實(shí)例的規(guī)則設(shè)置為 2*5 + 1 == 11個(gè), 即在11臺(tái)機(jī)器上部署ZooKeeper, 這樣保證在估算正確的情況下, 即便有千萬(wàn)分之一的概率發(fā)生了同時(shí)有五臺(tái)機(jī)器宕機(jī), ZooKeeper服務(wù)依然能正常工作.
  • 盡可能的保證uklfZooKeeper的機(jī)器之間的宕機(jī)沒(méi)有關(guān)聯(lián)性. 比如如果你使用云主機(jī), 盡量保證所有vm都分屬不同的host, 使用實(shí)體機(jī), 盡可能的將機(jī)器分散至多個(gè)IDC之類的.
  • 要使第二個(gè)假設(shè)盡可能的成立, 你可以做如下的事情:

  • 如果有條件, 盡可能的使部署的機(jī)器上只有一個(gè)ZooKeeper server進(jìn)程.
  • 如果沒(méi)有條件做到上面一條, 那么盡量避免ZooKeeper server進(jìn)程與其它進(jìn)程爭(zhēng)用網(wǎng)絡(luò)資源或存儲(chǔ)資源. 即預(yù)留給ZooKeeper server進(jìn)程足夠的帶寬或獨(dú)占網(wǎng)卡, 為ZooKeeper預(yù)留足夠的IO資源以及內(nèi)存空間
  • ZooKeeper里很拖性能的兩個(gè)點(diǎn)就是寫事務(wù)日志與內(nèi)在數(shù)據(jù)庫(kù)快照, 盡量將這兩部分日志寫向不同的物理磁盤. 即是在啟動(dòng)配置中, 獨(dú)立配置dataDir與dataLogDir, 并將兩個(gè)配置的路徑指向不同的物理磁盤.
  • 運(yùn)行時(shí)為JVM分配合理的heap size, 以防止發(fā)生swapping拖慢進(jìn)程.
  • 4.1.2.2 Provisioning

    // TODO, 官方文檔這里留空了

    4.1.2.3 Things to Consider: ZooKeeper Strengths and Limitations

    // TODO, 官方文檔這里留空了

    4.1.2.4 Administering

    // TODO, 官方文檔這里留空了

    4.1.2.5 運(yùn)維

    對(duì)于長(zhǎng)期運(yùn)行的ZooKeeper ensemble來(lái)說(shuō), 運(yùn)維工作是必須做的, 運(yùn)維人員需要注意以下幾點(diǎn):

    清理磁盤文件

    ZooKeeper中有兩處使用到了磁盤: 事務(wù)日志與內(nèi)存數(shù)據(jù)庫(kù)快照. ZooKeeper名稱空間里的節(jié)點(diǎn)發(fā)生變更的時(shí)候, 就會(huì)有內(nèi)容寫入事務(wù)日志. 通常情況下, 當(dāng)單個(gè)事務(wù)日志文件變的越來(lái)越大的時(shí)候, 事務(wù)日志就需要?jiǎng)?chuàng)建一個(gè)新的文件. 但在創(chuàng)建新的事務(wù)日志文件之前, ZooKeeper會(huì)先把當(dāng)前的內(nèi)存數(shù)據(jù)庫(kù)的狀態(tài)寫入磁盤先做快照, 然后再生成一個(gè)新的事務(wù)日志文件. 這樣就保證了快照文件和事務(wù)日志文件是一一對(duì)應(yīng)的. 但快照落地需要時(shí)間, 在快照落地期間如果還有事務(wù)來(lái)臨, 那么這部分事務(wù)的日志依然會(huì)寫向舊的事務(wù)日志文件里. 這就導(dǎo)致, 快照文件對(duì)應(yīng)的那個(gè)事務(wù)日志文件里, 存儲(chǔ)的事務(wù)日志可能要比當(dāng)前快照文件要.

    ZooKeeper server進(jìn)程在默認(rèn)啟動(dòng)的情況下, 是不會(huì)自動(dòng)刪除事務(wù)日志文件和快照文件的. 當(dāng)然這是可配置的, 配置項(xiàng)分別是autopurge.snapRetainCount和autopurge.purgeInterval. 這兩個(gè)配置項(xiàng)的具體含義在4.1.2.10章節(jié)有詳細(xì)描述. 但需要注意: 如果你要這樣做, 那么最好為每臺(tái)部署的機(jī)器提供不同的配置值, 除非這些機(jī)器的規(guī)格是完全一毛一樣的!

    除過(guò)在配置文件中設(shè)定, 還有一種方法就是調(diào)用一個(gè)ZooKeeper提供的小工具, 大致如下:

    java -cp zookeeper.jar:lib/log4j-1.2.15.jar:conf org.apache.zookeeper.server.PurgeTxnLog <dataDir> <snapDir> -n <count>

    其中<dataDir>是事務(wù)日志的保存目錄, <snapDir>是快照文件的保存目錄, <count>是要保留的個(gè)數(shù). 建議大于3. 運(yùn)行該命令后, 除過(guò)最近的<count>對(duì)事務(wù)日志文件與快照文件, 其它文件都將被刪除. 這是一個(gè)一次性命令. 如果你想定期清理, 那么只能自己寫個(gè)腳本咯.

    注意兩點(diǎn):

  • 永遠(yuǎn)不建議手動(dòng)刪除事務(wù)日志文件與快照文件
  • 通過(guò)配置項(xiàng)使ZooKeeper server自動(dòng)刪除, 只有在ZooKeeper版本大于3.4后才可用
  • PrugeTxnLog工具是一個(gè)一次性工具, 如果需要定期清理, 你需要自己寫一個(gè)腳本.
  • 當(dāng)機(jī)器規(guī)格不同的時(shí)候, 建議按照不同規(guī)格定制不同的清楚閾值
  • 清理運(yùn)行日志

    ZooKeeper用log4j來(lái)輸出運(yùn)行日志. 如果要更改運(yùn)行日志的相關(guān)配置, 你需要獨(dú)立為log4j提供配置文件. 建議使用log4j提供的滾動(dòng)日志特性, 這樣就免去了清理運(yùn)行日志的問(wèn)題. 更多詳細(xì)信息請(qǐng)參閱4.1.2.8 運(yùn)行日志

    4.1.2.6 監(jiān)控ZooKeeper server進(jìn)程的死活

    ZooKeeper的server進(jìn)程在錯(cuò)誤發(fā)生的時(shí)候會(huì)立即自殺, ZooKeeper的設(shè)計(jì)哲學(xué)是這樣的:

  • 單個(gè)實(shí)例掛掉, 或少量實(shí)例掛掉不影響整體服務(wù)
  • 當(dāng)單個(gè)實(shí)例遇到錯(cuò)誤的時(shí)候, 實(shí)例會(huì)立即掛掉
  • 實(shí)例被重啟后會(huì)自動(dòng)加入ensemble
  • 但實(shí)例不會(huì)自動(dòng)重啟
  • 所以搞一個(gè)監(jiān)控進(jìn)程, 在實(shí)例進(jìn)程掛掉之后將其立即拉起是一個(gè)很好的做法. 比如daemontools或SMF. 還比如我們親愛(ài)的織云.

    4.1.2.7 監(jiān)控ZooKeeper server服務(wù)的狀態(tài)

    要監(jiān)控ZooKeeper服務(wù)的狀態(tài), 有兩個(gè)選擇

  • 用4字命令去檢查. 這個(gè)在4.1.2.11 ZooKeeper4字命令中有詳情
  • JMX. 這個(gè)在4.3 JMX中有詳情
  • 4.1.2.8 運(yùn)行日志

    ZooKeeper使用log4j 1.2來(lái)輸出運(yùn)行日志. 默認(rèn)的配置文件在zookeeper/conf/log4j.properties中. log4j的配置文件要求要么放在工作目錄里, 要么放在類路徑里.

    詳情請(qǐng)查看log4j的官方手冊(cè)

    4.1.2.9 問(wèn)題定位

    由于文件損壞導(dǎo)致實(shí)例不能啟動(dòng)

    ZooKeeper的server進(jìn)程在事務(wù)日志文件被損壞的情況下是起不來(lái)的. 這時(shí)運(yùn)行日志會(huì)說(shuō)在載入ZooKeeper database時(shí)出現(xiàn)IOException. 這種情況下, 你需要做的是:

  • 通過(guò)四字命令stat檢查ensemble中的其它實(shí)例是否正常工作
  • 如果其它實(shí)例正常, 那么把當(dāng)前實(shí)例dataDir目錄下的version-2子目錄中的所有文件刪除, 再把dataLogDir下的version-2子目錄下的所有文件刪除, 然后重啟就可以了.
  • 這種情況是當(dāng)前實(shí)例的事務(wù)文件損壞, 不能重建內(nèi)存數(shù)據(jù)庫(kù), 刪除掉事務(wù)日志和數(shù)據(jù)庫(kù)快照后, 當(dāng)前的實(shí)例在重啟后會(huì)通過(guò)其它實(shí)例拉取內(nèi)在數(shù)據(jù)庫(kù), 重建事務(wù)日志和快照文件.

    4.1.2.10 配置參數(shù)

    ZooKeeper的行為受配置文件影響. 所有同一個(gè)ensemble中的實(shí)例建議使用完全相同的配置文件. 但使用完全相同的配置文件有一個(gè)前提條件: 就是所有實(shí)例所屬的機(jī)器上的磁盤布局是相同的. 磁盤布局不同意味著不同的機(jī)器下的實(shí)例在配置dataDir和dataLogDir的時(shí)候配置值可能有差異, 但除此之外, 一個(gè)ensemble中的所有實(shí)例的配置文件必須保證server.x=xxxx這些配置值是完全一致的.

    最小配置

    下面列出來(lái)的是要讓ensemble正常工作, 每個(gè)實(shí)例都需要配置的配置項(xiàng)

    配置項(xiàng)含義
    clientPort當(dāng)前實(shí)例對(duì)外提供服務(wù)的端口號(hào). 即是client通過(guò)該端口號(hào)連接到該實(shí)例上. 建議所有實(shí)例都配置為相同的值.
    dataDir內(nèi)在數(shù)據(jù)庫(kù)快照的存儲(chǔ)地址. 如果沒(méi)有配置dataLogDir的話, 該目錄還會(huì)存儲(chǔ)事務(wù)日志
    tickTimeZooKeeper中計(jì)量時(shí)間的最基本單位. 配置值的單位是毫秒
    高級(jí)可選配置

    下面列出來(lái)的是一此可選配置, 屬于高級(jí)選項(xiàng). 你可以用這些配置項(xiàng)進(jìn)一步個(gè)性化ZooKeeper server的行為. 其中一些配置項(xiàng)的值可以通過(guò)在啟動(dòng)server進(jìn)程的時(shí)候?qū)懭隞ava 系統(tǒng)屬性來(lái)設(shè)置.

    配置項(xiàng)對(duì)應(yīng)的Java系統(tǒng)屬性名含義
    dataLogDir無(wú)事務(wù)日志的寫入地址
    globalOutstandingLimitzookeeper.globalOutstandingLimitclient向ZooKeeper server遞交請(qǐng)求的速度可以比ZooKeeper server處理請(qǐng)求的速度快, 特別是有多個(gè)client訪問(wèn)同一個(gè)ZooKeeper server的時(shí)候. 通常情況下對(duì)于不能及時(shí)處理的請(qǐng)求, server都會(huì)將其緩存到隊(duì)列中. 但這個(gè)隊(duì)列也不是無(wú)限長(zhǎng)的, 這個(gè)配置項(xiàng)就是在設(shè)置這個(gè)隊(duì)列的長(zhǎng)度, 默認(rèn)值是1000, 超過(guò)隊(duì)列長(zhǎng)度后, 再發(fā)請(qǐng)求請(qǐng)求就會(huì)被丟棄
    preAllocSizezookeeper.preAllocSize為了避免頻繁的seek操作, ZooKeeper的事務(wù)日志文件默認(rèn)是以64M為基本單位的. 設(shè)置這個(gè)值就可以改寫這個(gè)默認(rèn)的塊大小, 這個(gè)配置項(xiàng)的單位是kb
    snapCountzookeeper.snapCount默認(rèn)值是100000, 這是指每向事務(wù)日志里記錄十萬(wàn)個(gè)事務(wù), 內(nèi)存數(shù)據(jù)庫(kù)就會(huì)被快照一次, 同時(shí)事務(wù)日志會(huì)開(kāi)新文件. 但為了避免所有的ZooKeeper server在同一時(shí)刻落地快照更換事務(wù)日志文件, 為了把這個(gè)操作錯(cuò)開(kāi), 所以真實(shí)的值是 位于區(qū)間 [50001, 100000] 區(qū)間的一個(gè)隨機(jī)數(shù). 即是 [snapCount/2 + 1, snapCount]區(qū)間
    maxClientCnxns無(wú)同一個(gè)個(gè)client是可以和同一個(gè)ZooKeeper ensemble之間建立多個(gè)連接的, 這個(gè)配置項(xiàng)就是在限制同一個(gè)client與ZooKeeper ensemble之間建立的連接數(shù). 這可以有效預(yù)防DoS攻擊, 還可以預(yù)防ZooKeeper server所在的機(jī)器文件描述符耗盡. 這個(gè)值默認(rèn)是60, 當(dāng)這個(gè)值被設(shè)置為0時(shí), 是取消掉這個(gè)限制的意思
    clientPortAddress無(wú)這是一個(gè)3.3版本后的新配置項(xiàng), 這是一個(gè)IP地址, 當(dāng)配置了之后, ZooKeeper server在監(jiān)聽(tīng)端口的時(shí)候, 就會(huì)綁定到這個(gè)地址上. 而默認(rèn)情況下, 在監(jiān)聽(tīng)clientPort端口的時(shí)候, 綁定的是ANYADDR
    minSessionTimeout無(wú)這也是一個(gè)3.3版本后的新配置項(xiàng), 這個(gè)配置項(xiàng)的單位是毫秒, 而不是tickTime. 指的是會(huì)話超時(shí)r的最小時(shí)間, 默認(rèn)的會(huì)話超時(shí)時(shí)間是2個(gè)tickTime. 這個(gè)值可以和client協(xié)商.
    maxSessionTimeout無(wú)這依然是一個(gè)3.3版本后的新配置項(xiàng). 和minSessionTimeout類似, 但這是會(huì)話超時(shí)的最大時(shí)間. 默認(rèn)是20個(gè)tickTime
    fsync.warningthresholdmszookeeper.fsync.warningthresholdms3.3.4版本后的一個(gè)新配置項(xiàng). 這是一個(gè)時(shí)間量, 單位是毫秒, 默認(rèn)是1000, 也就是一秒. 這指的是當(dāng)fsync 事務(wù)日志的耗時(shí)大于1秒時(shí), 就會(huì)向運(yùn)行日志里輸出一條warning日志. 注意這個(gè)配置項(xiàng)只能通過(guò)Java系統(tǒng)屬性設(shè)置
    autopurge.snapRetainCount無(wú)3.4版本后的一個(gè)新配置項(xiàng), 當(dāng)設(shè)置了該配置項(xiàng)后, ZooKeeper將會(huì)自動(dòng)清理快照文件和對(duì)應(yīng)的事務(wù)日志文件. 僅保留最近的autopurge.snapRetainCount個(gè). 默認(rèn)值是3, 最小值是3, 不能設(shè)置比3更小的值
    autopurge.purgeInterval無(wú)這是一個(gè)開(kāi)關(guān)配置項(xiàng), 也是一個(gè)時(shí)間配置項(xiàng). 當(dāng)設(shè)置為0的時(shí)候, 是關(guān)閉自動(dòng)清理快照和事務(wù)日志文件的功能的意思. 當(dāng)設(shè)置為1或更高的值時(shí), 是指每隔autopurge.purgeInterval個(gè)小時(shí), 就執(zhí)行一次自動(dòng)清理任務(wù)
    syncEnabledzookeeper.observer.syncEnabled3.4.6有這個(gè)配置項(xiàng), 3.5.0和更高的版本有. observer在默認(rèn)情況下會(huì)和participants一樣記錄事務(wù)日志, 落地快照. 將這個(gè)值設(shè)置為false就是關(guān)掉了observer記錄事務(wù)日志落地快照的行為, 默認(rèn)是true. observer和participants的概念會(huì)在4.4章節(jié)介紹
    多實(shí)例模式下的配置項(xiàng)

    下面列出來(lái)的配置項(xiàng)是多實(shí)例模式下的一些配置項(xiàng). 有一些配置項(xiàng)可以通過(guò)在啟動(dòng)server進(jìn)程的時(shí)候?qū)懭隞ava系統(tǒng)屬性來(lái)設(shè)置.

    配置項(xiàng)對(duì)應(yīng)的Java系統(tǒng)屬性名含義
    electionAlg無(wú)選爹算法. 0 - 原始的基于UDP的選爹算法. 1 - 不帶身份認(rèn)證的, 基于UDP的快速選爹算法. 2 - 帶身份認(rèn)證的, 基于UDP的快速選爹算法. 3 - 基于TCP的快速選爹算法. 默認(rèn)值是3. 其中, 0, 1, 2被官方文檔標(biāo)記為了deprecated, 也就是說(shuō), 除非有特殊需求, 不要?jiǎng)邮峙渲眠@個(gè)配置項(xiàng)
    initLimit無(wú)時(shí)間值, 單位是tickTime, 指的是兒子與爹建立連接并同步數(shù)據(jù)的超時(shí)時(shí)限. 當(dāng)ZooKeeper管理的數(shù)據(jù)特別多特別大的話, 建議適當(dāng)增加這個(gè)配置值. 這個(gè)配置項(xiàng)沒(méi)有默認(rèn)值, 所以配置文件里必寫
    leaderServeszookeeper.leaderServes控制爹是否也向client提供服務(wù), 默認(rèn)是允許的. 如果client的業(yè)務(wù)比較復(fù)雜的話, 建議關(guān)閉這個(gè)功能, 讓爹專心管兒子
    server.x=[hostname]:nnnn[:nnnn]無(wú)ensemble中的每一個(gè)實(shí)例都要這樣登記在配置文件里. x是dataLog目錄下的myid文件里的數(shù)字, 即是實(shí)例的編號(hào). hostname是對(duì)應(yīng)的實(shí)例所在的機(jī)器名, 或者直接寫成IP地址, 前一個(gè)nnnn是用于爹和兒子通信用的. 第二個(gè)nnnn 是用于選舉爹用的.
    syncLimit無(wú)時(shí)間值, 單位是tickTime, 兒子向爹報(bào)平安的時(shí)限, 如果兒子在超過(guò)這個(gè)時(shí)間值后沒(méi)有給爹報(bào)平安, 爹就認(rèn)為兒子死了. 關(guān)于initLimit和syncLimit這兩個(gè)配置項(xiàng)之間的不同, 請(qǐng)參考這個(gè)郵件列表里的解釋. 官方文檔里寫的簡(jiǎn)直讓人懷疑是不是復(fù)制粘貼過(guò)來(lái)的.
    group.x=nnnn[:nnnn]無(wú)給server實(shí)例分組. x是組編號(hào). nnnn則是實(shí)例編號(hào). 注意如果你給ensemble中的實(shí)例分組的話, 各個(gè)組之間不能有交集, 并且要保證所有組的并集就是整個(gè)ZooKeeper ensemble. (換句話說(shuō)你不能單獨(dú)為其中某一些實(shí)例分組, 所有的實(shí)例都必須從屬于一個(gè)組), 這里有一個(gè)例子
    weight.x=nnnn無(wú)為一個(gè)組設(shè)置權(quán)重. ZooKeeper只有在少量的一些場(chǎng)合才需要考慮權(quán)重, 已知的兩個(gè)場(chǎng)合, 一個(gè)是選爹的時(shí)候, 權(quán)重影響實(shí)例投票的影響力, 另外一個(gè)是atomic broadcast protocol. 默認(rèn)情況下權(quán)重值是1
    cnxTimeoutzookeeper.cnxTimeout時(shí)間值, 單位是秒. 爹選出來(lái)后, 所有人都需要知道爹是誰(shuí), 這個(gè)時(shí)間就是選爹時(shí)每個(gè)機(jī)器都會(huì)把選爹端口打開(kāi)的時(shí)間, 在這個(gè)時(shí)間內(nèi)應(yīng)當(dāng)有一個(gè)結(jié)果, 并且結(jié)果將通知到每個(gè)實(shí)例的選爹端口上. 這個(gè)配置項(xiàng)僅在electionAlg的值為3時(shí)才有用. 默認(rèn)值是5秒
    4lw.commands.whitelistzookeeper.4lw.commands.whitelist四字命令白名單, 未出現(xiàn)在名單上的四字命令, ZooKeeper將不處理. 默認(rèn)值包括除過(guò)wchp和wchc兩個(gè)之外的所有四字命令. 如果要設(shè)置這個(gè)配置項(xiàng)的值, 注意各個(gè)四字命令之間要以逗號(hào)區(qū)分, 比如: r4lw.commands.whitelist=stat, ruok, conf, isro, 如果你需要開(kāi)啟所有四字命令, 可以簡(jiǎn)單的使用通配符4lw.commands.whitelist=*
    ipReachableTimeoutzookeeper.ipReachableTimeout3.4.11版本后的新配置項(xiàng), 時(shí)間值, 單位是毫秒. 當(dāng)一個(gè)server的hostname不是IP地址時(shí), 并且恰巧DNS服務(wù)或者h(yuǎn)osts表里這個(gè)名字后面掛著多個(gè)ip地址時(shí), 這個(gè)值就有用了. 默認(rèn)情況下, ZooKeeper會(huì)默認(rèn)使用名字解析出來(lái)的第一個(gè)IP地址, 而不檢查這個(gè)IP是否可達(dá), 而如果這個(gè)值設(shè)置成了一個(gè)大于0的值, 那么ZooKeeper就會(huì)使用InetAddress.isReachable(ipReachableTimeout)來(lái)判斷這個(gè)IP是否可達(dá), 如果不可達(dá), 就換下一個(gè), 如果全都不可達(dá), 那么就會(huì)絕望的使用第一個(gè)IP地址
    tcpKeepAlivezookeeper.tcpKeepAlive3.4.11版本后的新配置項(xiàng). 如果這個(gè)配置項(xiàng)被設(shè)置為true, 那么server之間用來(lái)選舉的TCP連接就會(huì)被置為長(zhǎng)連接, 默認(rèn)情況下這個(gè)值是false
    身份認(rèn)證與授權(quán)相關(guān)的配置項(xiàng)

    下面這些配置項(xiàng)與身份認(rèn)證授權(quán)相關(guān).

    為了避免看不懂下面的配置項(xiàng)都在干嘛, 先大致說(shuō)一下Zookeeper里的認(rèn)證與授權(quán)

    在ZooKeeper server端, 每個(gè)znode存儲(chǔ)兩部分內(nèi)容: 數(shù)據(jù)和狀態(tài). 狀態(tài)中包含ACL信息. 創(chuàng)建一個(gè)znode會(huì)產(chǎn)生一個(gè)ACL表, 每個(gè)ACL記錄有以下內(nèi)容:

  • 驗(yàn)證模式(scheme)
  • 具體內(nèi)容(id). 比如當(dāng)scheme=="digest"的時(shí)候, id為是用戶名和密碼, 比如"root:J0sTy9BCUKubtK1y8pkbL7qoxSw="
  • 這個(gè)ACL擁有的權(quán)限
  • ZooKeeper提供了如下幾種驗(yàn)證模式(scheme)

  • digest. 就是用戶名+密碼.
  • auth. 不使用任何id, 表示任何已確認(rèn)用戶
  • ip. 用client連接至server時(shí)使用的IP地址進(jìn)行驗(yàn)證
  • world. 固定ID為"anyone", 為所有client端開(kāi)放權(quán)限
  • super. 在這種scheme下, 對(duì)應(yīng)的id擁有超級(jí)權(quán)限.
  • 注意的是, exists操作的getAcl操作不受ACL控制, 任何client都可以執(zhí)行這兩個(gè)操作.

    znode的權(quán)限主要有以下幾種:

  • create
  • read
  • write
  • delete
  • admin. 允許對(duì)本節(jié)點(diǎn)執(zhí)行setAcl操作
  • 配置項(xiàng)對(duì)應(yīng)的Java系統(tǒng)屬性名含義
    zookeeper.DigestAuthenticationProvider.superDigest僅能通過(guò)Java系統(tǒng)屬性設(shè)置3.2版本中的新配置項(xiàng). 允許管理員以超級(jí)用戶的身份來(lái)訪問(wèn)ZooKeeper中的層級(jí)名稱空間. 當(dāng)以超級(jí)用戶訪問(wèn)時(shí), znode的ACL完全放行. 以參數(shù)"super:<password>"來(lái)調(diào)用org.apache.zookeeper.server.auth.DigestAuthenticationProvider可以生成一個(gè)超級(jí)用戶. 然后用前面命令生成的"super:<data>"作為Java系統(tǒng)屬性, 在啟動(dòng)各個(gè)server的時(shí)候傳遞給進(jìn)程, 就開(kāi)啟了這個(gè)功能. 注意當(dāng)一個(gè)client通過(guò)scheme=digest的方式來(lái)認(rèn)證, 并且提供的認(rèn)證數(shù)據(jù)是超級(jí)用戶的認(rèn)證數(shù)據(jù), 也就是前面提到的"super:"`的時(shí)候, 就可以對(duì)server為所欲為了. 注意啊, 認(rèn)證信息從client傳遞給server的過(guò)程中, 是明文傳輸?shù)? 所以沒(méi)事不要作死.
    實(shí)驗(yàn)性的配置項(xiàng)
    配置項(xiàng)對(duì)應(yīng)的Java系統(tǒng)屬性名含義
    Read Only Mode Serverreadonlymode.enabled顯然這個(gè)值只能有過(guò)Java系統(tǒng)屬性來(lái)設(shè)置. 將其設(shè)置為true, 配置ZooKeeper為只讀模式. 具體細(xì)節(jié)參見(jiàn)ZOOKEEPER-784
    不安全的配置項(xiàng)
    配置項(xiàng)對(duì)應(yīng)的Java系統(tǒng)屬性名含義
    forceSynczookeeper.forceSync默認(rèn)情況下, ZooKeeper強(qiáng)制要求在有數(shù)據(jù)變更請(qǐng)求時(shí), 先寫事務(wù)日志, 再執(zhí)行變更. 如果將這個(gè)配置設(shè)置為no, ZooKeeper在執(zhí)行數(shù)據(jù)變更時(shí)就不會(huì)等事務(wù)日志寫完再執(zhí)行了.
    jute.maxbufferjute.maxbuffer這個(gè)配置項(xiàng)僅能通過(guò) Java系統(tǒng)屬性設(shè)置. 這設(shè)置的是一個(gè)znode中能存儲(chǔ)的數(shù)據(jù)的容量. 默認(rèn)值是0xfffff, 也就是1M. 注意如果要更改這個(gè)值, 所有server都要同步更改. 注意如果你要改這個(gè)值, 請(qǐng)先反思一下你使用ZooKeeper的姿勢(shì)是不是有點(diǎn)不正確
    skipACLzookeeper.skipACL跳過(guò)ACL檢查, 這能帶來(lái)極大的性能提升, 但很不安全
    quorumListenOnAllIPs無(wú)如果設(shè)置為true, server在監(jiān)聽(tīng)端口的時(shí)候, 將嘗試監(jiān)聽(tīng)所有本地可用的IP+端口的組合. 默認(rèn)情況下這個(gè)配置是false, 這個(gè)行為是關(guān)閉的
    使用Netty框架進(jìn)行通信

    這是3.4版本后的一個(gè)特性. Netty是一個(gè)基于NIO的客戶端-服務(wù)器通信框架, 這個(gè)框架簡(jiǎn)化了Java在網(wǎng)絡(luò)通信層上的很多繁操作, 并且內(nèi)置支持SSL和認(rèn)證授權(quán), 當(dāng)然SSL和認(rèn)證授權(quán)是額外的可選功能.

    3.4之前, ZooKeeper是直接用NIO的, 在3.4之后, NIO只是一個(gè)可選項(xiàng), 但依然是默認(rèn)選項(xiàng), 如果要使用Netty的話, 需要把zookeeper.serverCnxnFactory替換為org.apache.zookeeper.server.NettyServerCnxnFactory. 你可以只在client上使用Netty, 也可以在server上使用Netty, 但通常情況下, 建議要改一起改.

    蛋疼的是相關(guān)的文檔官方還沒(méi)有寫.

    4.1.2.11 四字命令

    ZooKeeper支持一系列的四字命令, 你可以在client上通過(guò)telnte或nc直接向server發(fā)送這些四字命令.

    使用一個(gè)四字命令如下所示, 下面使用echo和nc將四字命令ruok發(fā)送給本機(jī)的server

    $ echo ruok | nc 127.0.0.1 5111

    下表是所有支持的四字命令, 注意有些命令僅在特定版本之后才受支持:

    命令語(yǔ)義
    conf3.3版本后支持. 打印出server的配置信息
    cons3.3版本后支持. 打印出server上的所有連接/會(huì)話
    crst3.3版本后支持. 重置有關(guān)連接/會(huì)話的統(tǒng)計(jì)數(shù)據(jù)
    dump這個(gè)命令只有發(fā)給ensemble中的爹有才效. 列出所有重要的會(huì)話和生命周期隨會(huì)話的znode
    envi打印出server運(yùn)行環(huán)境
    ruokare you ok, 如果回復(fù) imok, 則說(shuō)明這個(gè)server很健康. 如果server有問(wèn)題, 則不會(huì)收到回復(fù). 需要注意的是, 一個(gè)server回復(fù)了ruok不代表這個(gè)server在ensemble中的狀態(tài)是正常的, 這僅代表server進(jìn)程正常啟動(dòng)了. 要查看ensemble的概況需要用stat命令
    srst重置server上的所有統(tǒng)計(jì)數(shù)據(jù)
    srvr3.3后的新命令. 列出server的全部信息
    stat列出server的細(xì)節(jié)信息和與之相連的clients
    wchs3.3后的新命令, 列出對(duì)該server的所有監(jiān)控(watch)
    wchc3.3后的新命令, 列出監(jiān)控這個(gè)server的所有會(huì)話, 并列出每個(gè)會(huì)話監(jiān)控的名稱空間路徑. 注意, 在會(huì)話較多的server上, 這個(gè)命令可能會(huì)相當(dāng)耗時(shí)
    wchp3.3后的新命令, 列出被監(jiān)控的所有層級(jí)名稱空間路徑, 以及相關(guān)的會(huì)話. 注意同上, 這個(gè)命令也可能會(huì)相當(dāng)耗時(shí)
    mntr3.4后的新命令. 列出有關(guān)ensemble的一系列狀態(tài)值. 通過(guò)這些狀態(tài)值可以查看整個(gè)ensemble是不是正常
    isro3.4后的新命令. 檢查server是否運(yùn)行在只讀狀態(tài), 回復(fù)ro代表server在只讀狀態(tài), 回復(fù)rw代表server在可讀可寫狀態(tài)
    gtmk獲取當(dāng)前的trace mask值, 以10進(jìn)制64位有符號(hào)數(shù)值形式返回, 具體trace mask的含義下面會(huì)講
    stmk設(shè)置trace mask

    這里需要注意的有:

  • mntr命令的輸出大致長(zhǎng)下面這樣. 輸出格式符合java屬性格式, 如果你要寫個(gè)腳本定時(shí)發(fā)送這個(gè)命令以監(jiān)控ensemble的運(yùn)行狀態(tài), 注意輸出的字段的數(shù)量可能會(huì)有變化, 寫腳本的時(shí)候注意這一點(diǎn). 另外有一些字段是與操作系統(tǒng)平臺(tái)相關(guān)的, 有些字段則只有爹才會(huì)回復(fù). 輸出每一行的格式是key \t value, 下面是一個(gè)示例
  • $ echo mntr | nc localhost 2185zk_version 3.4.0 zk_avg_latency 0 zk_max_latency 0 zk_min_latency 0 zk_packets_received 70 zk_packets_sent 69 zk_outstanding_requests 0 zk_server_state leader zk_znode_count 4 zk_watch_count 0 zk_ephemerals_count 0 zk_approximate_data_size 27 zk_followers 4 - only exposed by the Leader zk_synced_followers 4 - only exposed by the Leader zk_pending_syncs 0 - only exposed by the Leader zk_open_file_descriptor_count 23 - only available on Unix platforms zk_max_file_descriptor_count 1024 - only available on Unix platforms
  • trace mask是一個(gè)64位的數(shù)值, 按位設(shè)flag表示一些運(yùn)行日志開(kāi)關(guān). 另外log4j必須設(shè)置運(yùn)行日志級(jí)別為TRACE才能看到trace日志信息. trace mask中各位的含義如下:
  • trace mask bit含義
    0b0000000001保留位
    0b0000000010記錄client的請(qǐng)求, 不包括ping
    0b0000000100保留位
    0b0000001000記錄client的ping請(qǐng)求
    0b0000010000記錄來(lái)自爹的信息, 不包括ping
    0b0000100000記錄會(huì)話的創(chuàng)建, 銷毀和核實(shí)
    0b0001000000記錄監(jiān)控事件發(fā)生時(shí)向client報(bào)告的日志
    0b0010000000記錄來(lái)自爹的ping
    0b0100000000保留位
    0b1000000000保留位

    默認(rèn)的trace mask是0b0100110010. 另外stmk的用法也稍微復(fù)雜一點(diǎn), 還要注意將trace mask的值通過(guò)stmk命令傳遞給server的時(shí)候, 要使用大端字節(jié)序, 也就是網(wǎng)絡(luò)序. 下面是一個(gè)使用perl調(diào)用stmk命令的例子:

    $ perl -e "print 'stmk', pack('q>', 0b0011111010)" | nc localhost 2181 250

    調(diào)用stmk命令時(shí), server會(huì)將設(shè)置后的trace mask以十進(jìn)制數(shù)值的形式返回回來(lái).

    4.1.2.12 數(shù)據(jù)文件管理

    將事務(wù)日志文件和快照文件存儲(chǔ)在不同的物理磁盤上, 可以提升系統(tǒng)性能.

    快照存儲(chǔ)目錄

    配置項(xiàng)dataDir指向的目錄路徑中主要存儲(chǔ)兩種文件:

  • myid: 這個(gè)文件里寫著當(dāng)前server實(shí)例的編號(hào)
  • snapshot.<zxid>: 這里存儲(chǔ)著內(nèi)存數(shù)據(jù)庫(kù)的快照
  • server實(shí)例的編號(hào)用在兩個(gè)場(chǎng)合: myid文件里, 以及配置文件里的server.X配置項(xiàng)中. 當(dāng)前server實(shí)例在啟動(dòng)的時(shí)候, 先去配置文件里看dataDir的值, 然后去找dataDir/myid這個(gè)文件, 查看文件內(nèi)容, 得知自己的編號(hào), 然后在配置文件里再找對(duì)應(yīng)的server.x查看要開(kāi)的端口號(hào).

    快照文件的后綴, <zxid>, 是一個(gè)事務(wù)ID. 這是在落地內(nèi)存數(shù)據(jù)庫(kù)這個(gè)過(guò)程開(kāi)始時(shí), 成功執(zhí)行的最后一個(gè)事務(wù)的ID號(hào), 但蛋疼的是, 在落地快照的過(guò)程中, server還在接受請(qǐng)求, 執(zhí)行事務(wù), 也就是在落地的過(guò)程中, 內(nèi)存數(shù)據(jù)庫(kù)中的數(shù)據(jù)還處于一個(gè)變動(dòng)的過(guò)程中, 這就導(dǎo)致落地后的快照文件像是一個(gè)扭曲的文件. 像是你在用手機(jī)拍攝全景照片的過(guò)程中, 有一只貓隨著你的鏡頭走, 然后最終拍攝出來(lái)的照片里有一只長(zhǎng)度為17米的貓. 最終落地生成的快照文件里的數(shù)據(jù)狀態(tài)可能和任何一個(gè)時(shí)刻內(nèi)存數(shù)據(jù)庫(kù)的狀態(tài)都對(duì)不上, 就是因?yàn)檫@個(gè)原因. 但ZooKeeper依然可以用這種扭曲的快照文件重建內(nèi)存數(shù)據(jù)庫(kù), 這是因?yàn)閆ooKeeper中的update操作是冪等的, 這就保證了在扭曲的快照文件之上重放事務(wù)日志里的日志, 就可以將進(jìn)程的內(nèi)存狀態(tài)恢復(fù)到日志結(jié)束時(shí)的那個(gè)時(shí)刻.

    事務(wù)日志目錄

    在有update請(qǐng)求的時(shí)候, server的默認(rèn)行為是先寫事務(wù)日志, 再執(zhí)行update操作. 單個(gè)事務(wù)日志里存儲(chǔ)的事務(wù)個(gè)數(shù)超過(guò)一個(gè)閾值的時(shí)候, 就會(huì)導(dǎo)致事務(wù)日志新開(kāi)一個(gè)文件, 同時(shí)會(huì)導(dǎo)致內(nèi)在數(shù)據(jù)庫(kù)落地快照, 這個(gè)閾值在上面的配置項(xiàng)中有提. 日志文件的后綴是日志文件里第一個(gè)日志的ID

    文件管理

    快照文件的格式和事務(wù)日志文件的格式是死的, 這就允許你從現(xiàn)網(wǎng)的server機(jī)器上將事務(wù)日志和內(nèi)存快照拷貝至你的開(kāi)發(fā)機(jī), 在你的開(kāi)發(fā)環(huán)境重現(xiàn)現(xiàn)網(wǎng)的情景, 從而進(jìn)行一些調(diào)試或問(wèn)題定位操作.

    使用舊的事務(wù)日志文件和快照文件還能重建過(guò)去某個(gè)指定時(shí)刻server的狀態(tài), LogFormatter類可以用來(lái)訪問(wèn)事務(wù)日志文件, 以獲取可讀的信息. 當(dāng)然使用的時(shí)候需要有管理員權(quán)限, 因?yàn)閿?shù)據(jù)是加密的.

    server進(jìn)程本來(lái)是沒(méi)有刪除事務(wù)日志和快照文件的能力的, 但這在3.4版本中也隨著新的配置項(xiàng)autopurge.snapRetainCount和autopurge.purgeInterval添加上了.

    4.1.2.13 要避免的事情

    下面是幾個(gè)你應(yīng)當(dāng)在部署運(yùn)維的時(shí)候極力避免的事情:

  • ensemble中各個(gè)server使用的配置文件中, server.X配置表不一致. 所有的配置文件中, 都要以server.X配置項(xiàng)的形式列出當(dāng)前ensemble中的所有server, 包括自己. 如果這個(gè)東西不一致, 會(huì)炸.
  • 事務(wù)日志目錄設(shè)置不合理. 將事務(wù)日志目錄指向一個(gè)IO繁忙的磁盤, 會(huì)導(dǎo)致server始終處于一個(gè)半死不活的狀態(tài).
  • 不正確的java heap size. 頻繁的swap操作會(huì)嚴(yán)重拖慢性能. 保守起見(jiàn), 如果你的機(jī)器有4G內(nèi)存, 把java heap size設(shè)置為3G就好了.
  • 部署的時(shí)候不考慮安全性. 建議在生產(chǎn)環(huán)境中合理配置防火墻.
  • 轉(zhuǎn)載于:https://www.cnblogs.com/neooelric/p/9230967.html

    總結(jié)

    以上是生活随笔為你收集整理的ZooKeeper: 简介, 配置及运维指南的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    久久精品一二三区白丝高潮 | 又黄又爽又色无遮挡免费 | 正在播放 久久 | 在线免费试看 | 亚洲精品久久久久久久不卡四虎 | 国产精品美女久久久久久久久久久 | 欧美激情视频在线观看免费 | 美女视频黄免费 | 亚洲精品午夜久久久久久久久久久 | 黄色大全视频 | 九九免费视频 | 国产字幕在线观看 | 超碰电影在线观看 | 丁香六月激情 | 丝袜网站在线观看 | 成人影视免费看 | 日韩欧美专区 | 亚洲经典视频 | 国产精品久久久久久久免费大片 | 人人射人人射 | 欧美午夜一区二区福利视频 | 中文字幕av在线电影 | 国产黄色网| 黄色av三级在线 | 国产成人免费观看久久久 | 欧美精品在线视频 | 免费观看丰满少妇做爰 | 久久在线免费观看 | 国产视频日本 | 综合色久 | 国产精品毛片一区二区在线看 | 久久国产电影 | 国产精品美女免费视频 | 99精品在线直播 | 国产精品一区二区三区四区在线观看 | 在线免费视频a | 麻豆一区二区三区视频 | 欧美色噜噜噜 | 九草视频在线观看 | 中文字幕一区二区在线播放 | 日p视频在线观看 | 五月综合久久 | 久久国产精品99精国产 | 黄网av在线 | 看片黄网站 | 女人18精品一区二区三区 | 黄色大片免费网站 | 成年人在线播放视频 | 久久电影中文字幕视频 | 国产视频精品久久 | 久久久免费播放 | 五月天中文字幕mv在线 | 免费a一级 | 久草免费在线观看 | 国产亚洲综合性久久久影院 | 国产精品视频永久免费播放 | 日韩在线不卡视频 | 日韩精品视频第一页 | 综合伊人av | 亚洲天天做 | 99在线观看免费视频精品观看 | 99久久久精品 | 91麻豆精品国产91久久久久 | 黄色一级大片在线免费看国产一 | 免费在线观看成人 | 夜夜操天天操 | 96香蕉视频 | 成人黄在线观看 | 超碰在线天天 | 在线视频观看你懂的 | 国产视频一区精品 | 国产精品精品国产色婷婷 | 久久国产精品99国产精 | 久久精品小视频 | 国产精品福利视频 | 狠狠色伊人亚洲综合网站色 | 色av男人的天堂免费在线 | 日本69hd| 黄色毛片视频免费 | 在线91观看 | 日韩资源视频 | 亚洲精品色视频 | 看国产黄色大片 | 婷婷色六月天 | 亚洲成人av免费 | 久久综合精品一区 | www.日本色| 久久情爱| 久久久污| 亚洲成人软件 | 欧美不卡视频在线 | 久久草在线视频国产 | 欧美小视频在线 | 国产成人在线综合 | 99热精品在线观看 | 日本精品一区二区 | 婷婷色中文网 | 日韩一区二区三区观看 | 免费看污黄网站 | 九九激情视频 | 亚洲免费不卡 | 日批网站免费观看 | 国产一区二区在线观看视频 | 激情欧美一区二区三区 | 人人射av| 久久久精品国产一区二区三区 | 成人a视频在线观看 | 丁香婷婷激情啪啪 | 不卡的av在线 | 91成人免费视频 | 午夜精品福利一区二区 | 免费亚洲片 | 久久成熟 | 免费中文字幕在线观看 | 麻豆国产在线播放 | 久草五月 | 99免费精品| 欧美日韩精品免费观看 | 国产高清在线免费 | 91九色视频| 五月婷婷六月丁香激情 | 成人国产精品一区二区 | 免费看的黄色 | 亚洲夜夜网 | 伊人宗合网 | 51久久夜色精品国产麻豆 | 国产视频手机在线 | 午夜久久久久久久久久久 | 黄色小网站在线观看 | 国产精品久久久久久久久久免费 | 久久6精品 | 91黄色在线视频 | 免费视频一二三 | 99精品视频在线观看视频 | av短片在线观看 | 欧美日韩国产三级 | 97视频在线观看网址 | 精品一区二区三区电影 | 亚洲一区二区三区四区精品 | 91免费版在线 | 操操操天天操 | 欧美色888 | 黄色免费在线看 | 久久久人 | 国内精品久久久久影院优 | 中文字幕一区二区在线播放 | 国产特级毛片aaaaaaa高清 | 国产亚洲综合精品 | 日韩av一区二区在线影视 | 午夜视频免费 | 久久精品99久久 | 手机av片| www.在线观看视频 | 国产一级免费片 | 免费在线电影网址大全 | 日韩最新av在线 | 91av久久| 久久久国产精品人人片99精片欧美一 | 久草在线网址 | 日本中文字幕在线免费观看 | 五月婷婷在线视频观看 | 欧美日韩三区二区 | 色狠狠久久av五月综合 | 国产福利在线免费观看 | 99久久99久国产黄毛片 | 亚洲在线日韩 | 久久综合色天天久久综合图片 | 一区二区三区精品久久久 | 精品国产一区二区三区久久影院 | 亚洲天堂网视频 | 久一久久| 999亚洲国产996395 | 99色视频在线 | 一区二区三区三区在线 | 日本视频精品 | 午夜视频在线网站 | 色播六月天 | 天天天天天天干 | 在线观看一区视频 | 99精品国产aⅴ | 激情综合站 | 青草视频在线看 | 久久综合视频网 | 久久艹人人 | 日本夜夜草视频网站 | 久久精品这里都是精品 | 97夜夜澡人人爽人人免费 | 俺要去色综合狠狠 | 国产又粗又猛又爽又黄的视频免费 | 中文字幕乱码在线播放 | 一区二区三区中文字幕在线观看 | 国产无遮挡又黄又爽在线观看 | 伊人狠狠| 色噜噜狠狠狠狠色综合久不 | 婷婷色网| 波多野结衣视频一区二区三区 | 99久久久久| 国产精品久久久久久久久久不蜜月 | 激情av一区二区 | 国产成人一区二区在线观看 | 三上悠亚一区二区在线观看 | 国产69精品久久久久久久久久 | 一区三区视频 | 日韩一级片大全 | 四虎成人网 | 啪啪免费观看网站 | 热久久免费视频 | 一区二区亚洲精品 | av在线收看 | 久久综合影院 | av电影免费看| 四虎影视8848dvd | 97超级碰碰 | 日本中文在线观看 | 色综合久久综合网 | 字幕网在线观看 | 在线观看国产亚洲 | 亚洲韩国一区二区三区 | sesese图片 | 免费观看第二部31集 | 天天干天天干天天操 | 国产九九热视频 | 毛片一级免费一级 | 久久av电影 | 国产精品电影一区二区 | 久操伊人 | 麻豆系列在线观看 | 成人国产精品 | 亚洲午夜精品在线观看 | 最近中文字幕视频网 | av在线影视 | 97在线观看免费视频 | 在线看黄色的网站 | 97视频亚洲 | 久久久性 | 久久久在线免费观看 | 永久免费观看视频 | 天天天天天操 | 99se视频在线观看 | 国产精品久久久久久久久久了 | 中文字幕高清在线播放 | 亚洲精品国产综合99久久夜夜嗨 | 国内精品久久久久久久久久久久 | 日韩综合在线观看 | 欧美日韩亚洲精品在线 | 精品久久久久国产免费第一页 | 国产乱对白刺激视频在线观看女王 | 狠狠久久 | 精品欧美一区二区精品久久 | 日韩在线播放av | 粉嫩av一区二区三区免费 | 精品国产黄色片 | 久久视频在线观看免费 | 国产成人在线精品 | 天天舔夜夜操 | 欧美成人久久 | 视频国产在线观看18 | 91久久偷偷做嫩草影院 | 成人欧美一区二区三区在线观看 | 久久久精品免费观看 | 久久夜色精品亚洲噜噜国4 午夜视频在线观看欧美 | 国产精品久久久久久久久久久免费看 | 在线中文字幕一区二区 | 日批视频在线播放 | 91av中文| 免费视频 三区 | 狠狠gao| 成人av电影免费观看 | 国产精品a久久 | 欧洲精品码一区二区三区免费看 | 最新中文字幕在线播放 | 免费日韩 精品中文字幕视频在线 | 欧美少妇xxx| 国产一级片一区二区三区 | av片在线看| 狠狠干2018 | 一区二区三区日韩视频在线观看 | 成人一级片在线观看 | 国产黄a三级三级三级三级三级 | 成人综合日日夜夜 | 久久久91精品国产一区二区三区 | www.国产精品 | 九九九九热精品免费视频点播观看 | 国产a国产a国产a | 久久精品欧美一区 | 韩国av永久免费 | 国内三级在线 | 亚洲作爱 | 欧美激情第一区 | 一级免费看| 探花国产在线 | 午夜精品av在线 | 国产精品久久久久av | 五月婷婷av在线 | 婷婷福利影院 | 欧美巨大荫蒂茸毛毛人妖 | 国产69久久久欧美一级 | 国产欧美最新羞羞视频在线观看 | 日韩精品视频在线观看网址 | 在线精品视频在线观看高清 | 奇米网8888| 九九视频在线观看视频6 | 亚洲视频久久 | wwwwwww黄 | 91麻豆精品国产午夜天堂 | 久久久视频在线 | 国产久草在线 | 国产精品入口66mio女同 | 免费在线观看一级片 | 一区在线播放 | 亚洲免费在线 | 亚洲欧美精品在线 | 日韩精品久久一区二区三区 | 国产对白av| 成人av久久 | 免费特级黄毛片 | 国产精品九九九九九 | 97成人在线 | 欧美在线一级片 | 天天干,天天射,天天操,天天摸 | 亚洲精品国产精品国自产在线 | 欧美激情综合五月色丁香 | 一区二区中文字幕在线播放 | 成人性生交大片免费观看网站 | 亚洲高清视频在线播放 | 九九免费在线视频 | 国产精品24小时在线观看 | 日韩精品最新在线观看 | 中文av字幕在线观看 | 97超碰资源总站 | 一级片免费观看视频 | 欧美日韩电影在线播放 | 国产视频一区在线免费观看 | 国产黑丝一区二区三区 | 91久久精品日日躁夜夜躁国产 | 国产视频在线看 | 中文字幕一二三区 | 黄色小视频在线观看免费 | 日韩中文字幕第一页 | 久久精品99国产精品日本 | 免费激情网 | 国产精品成人aaaaa网站 | 久久精品国产精品亚洲 | 国产亚洲精品久久19p | 深爱激情亚洲 | 超碰97在线人人 | 国产精品久久久久久久久免费 | 人人网人人爽 | 在线观看中文字幕亚洲 | 国产亚洲视频在线观看 | 亚洲色图 校园春色 | 国产日本亚洲高清 | 成人av手机在线 | 一区二区久久久久 | 91精品国产99久久久久久红楼 | 91在线精品一区二区 | 狠狠色丁香婷婷综合视频 | a在线v| 91在线色| 九九免费在线观看视频 | 欧美日韩久久不卡 | 国产精品九九热 | 亚洲一区日韩 | 亚洲午夜精品久久久 | av福利在线播放 | 亚洲精品视频在线观看网站 | 成人午夜在线观看 | 香蕉久久国产 | 麻豆小视频在线观看 | 国产成人av一区二区三区在线观看 | 99色免费| 在线看日韩av | 国产小视频福利在线 | av一级一片 | 日韩高清在线不卡 | 日韩欧美精品免费 | 亚洲人毛片 | 欧美日韩免费观看一区二区三区 | 国产精品成久久久久 | 国产一区 在线播放 | 欧美一区中文字幕 | 在线国产激情视频 | 天天色天天上天天操 | 久草在线播放视频 | 高清av在线免费观看 | 日韩黄在线观看 | 国产精品久久久一区二区三区网站 | 国产中文字幕大全 | 91成人在线网站 | 国产一级三级 | 精品免费久久 | 久久99精品国产91久久来源 | 夜夜骑首页 | 91看片淫黄大片一级在线观看 | 日本aa在线| 久久精品中文字幕一区二区三区 | 亚洲男男gaygay无套 | 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 99视频播放 | 国产一级淫片免费看 | 久草在线免费看视频 | 揉bbb玩bbb少妇bbb | 国产精品永久免费在线 | 亚洲在线免费视频 | 国产激情小视频在线观看 | 欧美日韩一区二区在线观看 | 开心激情久久 | 亚洲激情网站免费观看 | 99精品美女 | 中文字幕色在线视频 | 深爱婷婷| 国产黄色片在线 | 久久无码精品一区二区三区 | 成人小视频在线观看免费 | 91网站免费观看 | 午夜狠狠操 | 国产高清精品在线 | 免费高清无人区完整版 | 欧美五月婷婷 | 欧美二区在线播放 | 久久99亚洲精品久久 | 午夜视频一区二区 | 国产99久久99热这里精品5 | jizzjizzjizz亚洲 | 在线观看视频你懂得 | 天天色 天天 | 国产精品美乳一区二区免费 | 人人干人人艹 | 香蕉日日 | 欧美乱大交 | 丁香六月天| 久久a久久 | 日韩欧美电影在线 | www.888av | 看毛片的网址 | 最新真实国产在线视频 | 亚洲爱av| 久久免费a| 国产1区2 | www国产亚洲| 精品国产一区二区三区久久久蜜月 | 精品久久久久一区二区国产 | 国产精品第十页 | 香蕉日日| 成人9ⅰ免费影视网站 | 国产精品青草综合久久久久99 | 国产麻豆果冻传媒在线观看 | 欧美电影在线观看 | 中文字幕人成一区 | 日韩理论 | 国产精品igao视频网网址 | 国产精品18久久久久白浆 | 国产这里只有精品 | 高清av网站 | 毛片黄色一级 | 国产精品igao视频网入口 | 91网在线看 | 五月开心综合 | 视频福利在线观看 | 九九99 | 久久久精品免费观看 | ww亚洲ww亚在线观看 | 91色亚洲 | 精品福利视频在线 | 91九色蝌蚪在线 | 亚洲精品女 | 久久只精品99品免费久23小说 | 中文乱幕日产无线码1区 | 国产剧情在线一区 | 91高清一区 | 亚洲a网| 婷婷六月天在线 | 在线草 | 狠狠色丁香婷婷综合基地 | 免费看色视频 | 国产一区免费 | 成人丁香花 | 九九热在线精品 | 婷婷网站天天婷婷网站 | 亚洲欧洲精品一区二区 | 国产精品久久久久四虎 | 伊人久久精品久久亚洲一区 | 国产精品成人一区二区 | 91麻豆精品久久久久久 | 国产99中文字幕 | www色网站| 天天干天天拍 | 午夜av在线播放 | 久久精品国产免费观看 | 国产精品成人自产拍在线观看 | 91精品免费在线视频 | 久久国产精品系列 | 五月天激情开心 | 97久久久免费福利网址 | 亚洲国产中文在线 | av电影中文字幕 | 国产91影院 | 欧美精品色 | 国产色网站 | 国产免费二区 | 一区国产精品 | 久操中文字幕在线观看 | 色婷婷狠狠操 | 久久久久久久久久久久亚洲 | 欧美在线视频一区二区三区 | 免费久久99精品国产婷婷六月 | 中文字幕亚洲国产 | 97香蕉久久国产在线观看 | 精品久久美女 | 婷婷在线五月 | 免费日韩在线 | av一区二区在线观看中文字幕 | 国产又粗又猛又黄视频 | 日韩精品久久中文字幕 | 日本精品一 | 69国产盗摄一区二区三区五区 | 日韩视频一区二区三区在线播放免费观看 | 日韩久久精品一区二区 | 8090yy亚洲精品久久 | 91在线免费视频观看 | 91成人免费在线视频 | 精品视频123区在线观看 | 91激情视频在线 | 91成年视频 | 狠狠婷婷| 久久久精品国产一区二区三区 | 国产h片在线观看 | 国产在线中文字幕 | 日韩二区三区在线观看 | 国产亚洲婷婷免费 | 欧美亚洲xxx | 在线观看视频三级 | 99爱国产精品 | 九九视频免费观看视频精品 | 欧美精品一区二区在线观看 | 国产成人精品一区在线 | 97人人精品 | 国产成年免费视频 | 国产精品高清在线 | 91精品国产成人www | 天天综合精品 | 国产午夜精品理论片在线 | 国产一级久久久 | 久久小视频 | av片中文| 日本最新中文字幕 | 婷婷激情小说网 | 成人av免费在线看 | 麻豆精品91| 精品在线小视频 | 国产精品第一页在线 | 色香网 | 在线观看视频99 | 亚洲日本一区二区在线 | 欧美韩国在线 | 深夜免费小视频 | 午夜影院一级 | 日韩电影中文字幕 | 91丝袜美腿 | 日本中文在线 | 深夜国产福利 | 五月天高清欧美mv | 国产精品一区二区三区免费视频 | 日韩欧美视频在线免费观看 | 精品国产中文字幕 | 久久a v视频 | 97av视频| 亚洲精品视频在线 | 激情大尺度视频 | 亚洲年轻女教师毛茸茸 | 欧美精品免费在线观看 | 中文字幕影片免费在线观看 | 99精品黄色| 精选久久 | 欧美九九视频 | 国产中文字幕国产 | 国产二区电影 | 日韩中文字幕在线观看 | 国产精品入口麻豆www | 免费视频你懂的 | 在线成人av | 亚洲最新在线 | 久久一二三四 | 2019中文在线观看 | 一级一片免费看 | 色综合久久久久久久久五月 | 97在线观看免费观看 | 中文字幕在线观看视频一区 | 色噜噜日韩精品欧美一区二区 | 免费视频区| 久久夜色精品亚洲噜噜国4 午夜视频在线观看欧美 | 在线av资源 | 99精品一区 | 一级精品视频在线观看宜春院 | 久久久久网址 | 国产一区视频免费在线观看 | 999久久久久久久久 69av视频在线观看 | 国产专区日韩专区 | 欧洲亚洲女同hd | 在线观看亚洲电影 | 国产一级黄色电影 | av免费看在线 | 九9热这里真品2 | 99在线视频播放 | 狠狠做六月爱婷婷综合aⅴ 日本高清免费中文字幕 | 久草久草在线观看 | 欧美 日韩 视频 | 久久免费精品 | 99超碰在线播放 | 91av小视频 | 亚洲午夜久久久久久久久久久 | 伊人婷婷网| 国产伦精品一区二区三区照片91 | 久久综合五月天婷婷伊人 | 日本久久免费视频 | 国内成人精品视频 | 久草在线资源免费 | 偷拍视频一区 | 久久午夜免费视频 | 色天天综合网 | 国产久视频| 亚洲天天综合 | 久草综合在线观看 | 免费中午字幕无吗 | 国产成人精品一区二区三区福利 | 日韩黄色一级电影 | 男女免费av| 天天爽夜夜爽人人爽一区二区 | 久久精品国产精品亚洲 | 五月在线视频 | 国产精品一区一区三区 | 91亚洲精品久久久蜜桃借种 | 久久99精品国产一区二区三区 | 精品国产123 | 欧美日本一区 | 五月婷婷国产 | 色国产视频 | 免费97视频 | 久久精品香蕉 | 成人免费观看av | a成人在线| 伊人五月在线 | 久久精品国产亚洲aⅴ | 狠狠天天| 91麻豆免费视频 | 久久精品日产第一区二区三区乱码 | 国产精品91一区 | 欧美精品成人在线 | 五月天国产精品 | 精品人妖videos欧美人妖 | 久久涩涩网站 | 欧美精品在线观看一区 | 精品国产自 | 91精品久久久久久粉嫩 | 亚洲精品乱码久久久久久写真 | 97视频免费观看2区 亚洲视屏 | 国内精自线一二区永久 | 黄a在线观看 | 国产精品一区二区在线观看 | 在线黄色国产电影 | 久久夜色精品国产欧美乱 | 国产精久久久久久久 | 狠狠色丁香九九婷婷综合五月 | 婷婷看片| 国产一区在线免费观看 | 精品亚洲网 | 成人免费在线播放视频 | 国内精品久久久久久中文字幕 | 午夜精品视频免费在线观看 | 久久综合狠狠综合久久激情 | 午夜精品三区 | 国产资源精品在线观看 | 免费精品视频在线 | 少妇超碰在线 | 久久久久久久精 | 久久不见久久见免费影院 | 成年人网站免费在线观看 | 99久久婷婷国产一区二区三区 | 日本久久久久久久久久久 | 日韩欧美在线播放 | 丁香五月亚洲综合在线 | 久久99精品久久久久久 | 亚洲精品高清在线观看 | 91天天操 | 久久久精品国产一区二区 | 国内精品久久久久久久 | 日韩另类在线 | 亚洲国产精品激情在线观看 | 可以免费看av | 国产成人三级在线 | 国产一二三四在线视频 | 久久精品免费播放 | 午夜视频在线观看一区二区三区 | 九九涩涩av台湾日本热热 | 国产午夜精品福利视频 | 欧美极品少妇xxxx | 91视频在线观看下载 | av在线小说 | 天天天干夜夜夜操 | 亚洲成人黄色在线 | 四虎在线免费观看视频 | 欧美精品少妇xxxxx喷水 | 久久夜色精品国产欧美乱极品 | 天堂av在线网 | 91理论片午午伦夜理片久久 | 日韩av在线小说 | 国产成人久久 | 日韩久久影院 | 久久亚洲影院 | 成人黄色免费在线观看 | 久要激情网 | 欧美久久久一区二区三区 | 中文字幕一区在线 | 奇米网777 | 国产成人专区 | 国内三级在线观看 | 在线影视 一区 二区 三区 | 久久精美视频 | 美女免费视频黄 | 视色网站| 五月天激情视频在线观看 | 日韩一区二区三区观看 | 四虎国产免费 | 中文字幕第一页在线 | 日本精品视频在线观看 | 在线v| av不卡中文| 国产成人精品一区二区三区网站观看 | 91成品视频 | 天天操福利视频 | 成人毛片一区 | 操操操人人 | 五月天久久婷 | 81精品国产乱码久久久久久 | 激情视频一区二区 | 久草网在线观看 | 久久久久久久久久久综合 | 久久九九久久九九 | 久久人视频| 在线视频免费观看 | 人人爽人人爽人人片av免 | 高清不卡毛片 | 亚洲一级影院 | 玖玖爱免费视频 | 国产午夜精品一区二区三区 | 青青草在久久免费久久免费 | 丝袜一区在线 | www.夜夜操.com | 久久综合偷偷噜噜噜色 | 麻花传媒mv免费观看 | 亚洲国产精品一区二区久久,亚洲午夜 | 久久综合免费视频影院 | 国产欧美精品一区二区三区四区 | 中文字幕亚洲在线观看 | 精品美女国产在线 | 天天激情| 精品国产精品久久一区免费式 | 精品一区二区影视 | 久草视频免费 | 久久免费国产电影 | 日韩视频三区 | 亚洲天堂网站视频 | 成年人毛片在线观看 | 五月婷婷六月丁香 | 91看片淫黄大片一级在线观看 | 精品国产一区二区三区av性色 | 国产资源av | 亚洲精品国产精品国 | 久久精品亚洲精品国产欧美 | 91精品免费在线视频 | 日本精品视频在线观看 | aav在线| 欧美一级日韩免费不卡 | 99久久婷婷国产综合亚洲 | 久久 国产一区 | 国产亚洲欧洲 | 99久久久国产精品美女 | 99国产精品免费网站 | 97视频入口免费观看 | 中文字幕在线观看免费 | 日韩中文字幕亚洲一区二区va在线 | 中文字幕在线观看播放 | 久久精品一区八戒影视 | 国产黄色片一级三级 | 93久久精品日日躁夜夜躁欧美 | 久久精品一 | 超碰大片 | 国产二级视频 | zzijzzij亚洲日本少妇熟睡 | 欧美日韩精品电影 | 三级av在线 | 观看免费av | 免费高清国产 | 中文资源在线官网 | 中文字幕免费在线 | 99久久久成人国产精品 | 日韩欧美在线一区 | 久久久五月天 | 一区二区三区免费在线观看 | 久久久久五月天 | 在线观看亚洲免费视频 | 中文在线免费观看 | 国产精品成久久久久 | 91成人在线视频 | 国产精品大片免费观看 | 欧美性生交大片免网 | 一级片免费视频 | av在线一二三区 | 亚洲精品一区二区三区新线路 | 久久精品美女 | 国产亚洲在线 | 亚洲综合在线一区二区三区 | 高清视频一区 | 国产午夜精品一区二区三区 | www.色国产 | 精品在线一区二区三区 | 一级免费av | 国产最新在线 | 中文字幕 91 | 中文在线字幕免费观看 | 超碰在线免费97 | 狠狠色丁香久久婷婷综 | 日韩久久网站 | 亚洲理论电影网 | 91精品夜夜| 麻豆精品视频 | 欧美 日韩 国产 成人 在线 | 91免费高清在线观看 | 久久人人97超碰com | 日韩伦理片hd | 中文一区二区三区在线观看 | 久草视频中文在线 | 99久久久国产精品免费观看 | 国产精品久久99 | 99热在线国产精品 | 日韩一区二区三区高清在线观看 | 国产成人一区二区三区在线观看 | 亚洲综合视频在线观看 | 片网站 | 久久午夜羞羞影院 | 免费黄色看片 | 亚洲成av人片一区二区梦乃 | 特级西西www44高清大胆图片 | 91入口在线观看 | 500部大龄熟乱视频使用方法 | 99免费在线播放99久久免费 | 亚洲精品美女久久 | 91精品国产92久久久久 | 亚洲区色 | 日本中文在线 | 国产在线精品福利 | 最近中文字幕免费大全 | 国产一区二区不卡视频 | 99久久综合国产精品二区 | 色综合久久中文字幕综合网 | 91丨九色丨蝌蚪丰满 | 国产精品v欧美精品 | 亚洲乱码在线 | 久久久久久久久久影视 | 在线一区观看 | 高清不卡一区二区在线 | 五月天堂网 | 久久精品视频在线看 | 欧洲一区二区三区精品 | 日韩1级片 | 免费看的黄色 | 国产麻豆精品久久一二三 | 日本一区二区高清不卡 | 日韩av高清 | 国产直播av| 天天射天天拍 | 美女视频免费精品 | 国产精品麻 | 黄色字幕网 | 国产九九九九九 | 日日夜夜网 | 国产一区二区三区黄 | 亚洲精品456在线播放第一页 | 又湿又紧又大又爽a视频国产 | 午夜精品久久久久99热app | 国产在线国偷精品产拍 | 2019中文| 精品久久美女 | 免费观看的av网站 | 久久精品日本啪啪涩涩 | 亚洲一区免费在线 | 最新av网址大全 | 欧美日韩国产二区三区 | 日本精品一区二区在线观看 | 日日摸日日添夜夜爽97 | 国产精品黑丝在线观看 | 97人人添人澡人人爽超碰动图 | avav片| 美女性爽视频国产免费app | www.久久免费视频 | 国产免费精彩视频 | 日日干天夜夜 | 午夜黄色大片 | 九九久久久久99精品 | 免费观看视频的网站 | 欧美日韩中文国产一区发布 | 午夜av在线播放 | 久久99精品久久久久婷婷 | 亚洲另类在线视频 | 成人小视频在线观看免费 | 婷婷播播网 | 69精品在线 | 日本电影黄色 | 久久精品久久久久 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 久久精品国产亚洲aⅴ | 啪啪动态视频 | 亚洲精品网站在线 | 中文在线免费一区三区 | 欧美精品视 | 国产高清视频网 | 国内精品国产三级国产aⅴ久 | 99久免费精品视频在线观看 | 天堂av免费看 | 国内三级在线观看 | 日日夜夜操操操操 | 日韩三区在线观看 | 91精品国产综合久久福利不卡 | 日本天天操 | 伊人色综合久久天天 | 欧美韩国日本在线 | 网站免费黄 | 国产精品永久久久久久久www | 成人av电影网址 | 在线视频黄 | 国产精品美女免费 | 九九在线精品视频 | 97夜夜澡人人爽人人免费 | 欧美激情精品 | 黄色成人av | 91桃色免费观看 | 久久精品国产一区二区电影 | 天天色综合天天 | 99re中文字幕 | 97超碰人人澡 | 中文字幕在线看 | 日韩欧美视频在线观看免费 | 麻豆视频免费入口 | 精品伦理一区二区三区 | 一级欧美日韩 | 婷婷深爱 | 国产黄色电影 | 欧美日本国产在线观看 | 久草影视在线观看 | 在线影院av| 午夜精品久久久久久久99水蜜桃 | 精品视频资源站 | 日本久久中文 | 免费在线黄| 18网站在线观看 | 国产免费av一区二区三区 | 国产视频 亚洲视频 | 精品免费视频 | 国产色婷婷精品综合在线手机播放 | 三级小视频在线观看 | 国产精品久久久久久欧美 | 国产精品网站一区二区三区 | 久久99精品国产99久久6尤 | 超碰97网站 | 亚洲永久字幕 | 涩涩爱夜夜爱 | 最近中文字幕免费大全 | 国产麻豆剧果冻传媒视频播放量 | 亚洲激情在线观看 | 国产一区二区三区黄 | 欧美一二三区在线观看 | 日本精品一区二区在线观看 | 在线播放 日韩专区 | 欧美日韩一区二区在线 | av黄色在线播放 | 中文字幕乱偷在线 | 欧美精品亚州精品 | 国产精品免费在线 | 国产精品久久久久久久久久久久久 | 激情网五月天 | 国产精品久久久久久久久久久杏吧 | 天天干,天天射,天天操,天天摸 | 日韩欧美精品免费 | 粉嫩一区二区三区粉嫩91 | av高清一区二区三区 | 亚洲国产网站 | 免费国产在线视频 | 九九av| 成人wwwxxx视频 | 欧美成人h版在线观看 | 丁香综合五月 | 欧美电影黄色 | 国产精品视频地址 | 狠狠狠色丁香婷婷综合久久五月 | 91豆麻精品91久久久久久 | 欧美做受高潮1 | 黄色毛片大全 | 欧美视频在线二区 |