一、解壓 tar -zxvf zookeeper-3.4.5.tar.gz ; 打包 tar -czvf *.tar.gz dirnamejava
二、修改conf中zoo_sample.cfg名字爲zoo.cfgnode
三、啓動zookeeper服務端zkServer.shgit
1)服務端經常使用命令github
2) ./zkServer.sh start出現錯誤:算法
oms@10-10-248-10:/data/zookeeper-3.3.6/bin$ ./zkServer.sh start
JMX enabled by default
Using config: /data/zookeeper-3.3.6/bin/../conf/zoo.cfg
Starting zookeeper ... ./zkServer.sh: 103: ./zkServer.sh: cannot create /tmp/zookeeper/zookeeper_server.pid: Directory nonexistent
FAILED TO WRITE PID數據庫
解決方法:以上的啓動過程發生了一個錯誤,說是沒法建立/tmp/zookeeper/zookeeper_server.pid,zookeeper啓動後,該文件中保存進程id,咱們能夠手動建立該目錄。apache
在zookeeper目錄下輸入命令 mkdir -p tmp/zookeeper api
若是要建立目錄A並建立目錄A的子目錄B,沒有用-p的狀況下是mkdir 2次 若是用-p 能夠直接建立2個目錄 mkdir -p 目錄A/子目錄B就能夠
四、啓動zookeeper服務端zkServer.sh服務器
1)客戶端經常使用命令網絡
2)建立節點操做而後刪除
ls /查看當前zk中的內容
create /workers "" 空字符串不但願在這個節點保存數據
delete /workders
ls /
quit
五、會話的狀態及狀態的轉換
六、zookeeper單機集羣配置
解壓Zookeeper的安裝包到/opt目錄下,這裏用三個目錄來表明三個Zookeeper實例,分別是/opt/zookeeper1,/opt/zookeeper2和/opt/zookeeper3.
1). 首先編輯每一個Zookeeper目錄下的conf/zoo.cfg文件。三個配置配置文件的內容分別以下
其中有幾點須要注意
* dataDir: 三個Zookeeper實例的dataDir目錄要區別開,這裏分別指定到各個Zookeeper實例目錄下的data目錄。
* clientPort: 定義Zookeeper客戶端鏈接Zookeeper服務端時使用的端口,這裏由於是在一臺機器上作的集羣,因此三個實例的端口要區分開。服務的監聽端口。
* server.: 定義Zookeeper集羣的各個實例的的ip和端口,這裏由於是在一臺機器上作的集羣,因此IP都定義的是127.0.0.1,可是後面的端口要區分開。
initLimit:多少個心跳時間內,容許其餘server鏈接並初始化數據,若是ZooKeeper管理的數據較大,則應相應增大這個值
dataDir:用於存放內存數據庫快照的文件夾,同時用於集羣的myid文件也存在這個文件夾裏(注意:一個配置文件只能包含一個dataDir字樣,即便它被註釋掉了。)
dataLogDir:用於單獨設置transaction log的目錄,transaction log分離能夠避免和普通log還有快照的競爭
syncLimit:多少個tickTime內,容許follower同步,若是follower落後太多,則會被丟棄。
2).建立data目錄和實例id文件
這裏要注意須要在每一個Zookeeper的dataDir目錄下建立myid文件,內容是記錄各個Zookeeper的實例ID。
3) 啓動Zookeeper服務
分別進入各個Zookeeper的bin目錄,而後運行「./zkServer.sh start」來啓動一個Zookeeper服務。
4) 客戶端鏈接
隨便進入一個Zookeeper的bin目錄,而後運行下面的命令來分別鏈接Zookeeper服務。
在其中的一個client上建立一個znode節點
而後在別的client上查看新建立zonde節點
5)查看Zookeeper狀態
啓動Zookeeper以後,因爲Zookeeper本身會有一套leader的選舉算法,因此此時若是想知道那個Zookeeper是leader能夠在各個Zookeeper的bin目錄運行「./zkServer.sh status」命令來查看。
若是是Leader
若是不是Leader
此時能夠把leader的那個節點停了,而後再看查看其它兩個Zookeeper實例,此時剩下的兩個Zookeeper實例就會再選舉出一個leader。
6)主從模式例子實現
1)create -e /master "master1.example.com.2223" -e標識臨時節點
2)stat命令能夠獲得一個zode節點的屬性,並容許咱們在已經存在的zode節點上設置監視點,經過在路徑後面設置參數true來添加監視點;state /master true
當節點崩潰時顯示:WatchedEvent state:SyncConnected type:NodeDeleted path /master
3)從節點,任務,分配
主節點會監視/works,/task節點的數據變化 :ls /works true; ls /task true經過true參數,能夠設置對應zode的子節點變化的監視點
從節點要通知主節點,告知從節點能夠執行任務,能夠在從節點經過建立/works的子節點進行通知
從節點建立一個 /assign/work1.example.com來接受任務分配,並經過參數true的ls命令來監視這個節點的變化
4)客戶端:向系統提交任務
create -s /task/task - "cmd"
Create /tasks/task-00000000000
因爲主節點監聽了/task,會檢查這個新的任務,獲取可用的從節點,將任務分配給從節點
create /assign/worker1.example.com/task-0000000000
從節點會收到通知,確認該任務是不是分配給本身的,一旦從節點完成任務的執行,它就會在/tasks中添加一個狀態zode
create /tasks/task-00000000/status "done"
客戶端接到一個通知 get /tasks/task-0000000000 status
./zkCli.sh -timeout(心跳時間毫秒) 0 -r(只讀) -server ip(服務ip):port(端口)
如: ./zkCli.sh -timeout 5000 -server 127.0.0.1:2181
1)create /mykey dsfsdf
2)get /mykey
zookeeper對節點數據的修改都認爲是一次事務,每次事務都需分配個事務id,
cZxid:該節點建立時的事務id
ctime:該節點建立的時間
mZxid:該節點最後一次更新的事務id
mtime:該節點修改時間
pZxid:該節點的子節點列表修改的事務id(添加子節點,刪除子節點,不包括修改子節點的內容)
cversion:子節點的版本號
dataVersion:數據版本號
aclVersion:權限版本號
ephemeralOwner :建立該臨時節點的事務id,若是爲持久節點,則默認爲0x0
dataLength:節點存放數據的長度
numChildren:子節點的個數
3)ls2 /mykey
4)stat /mykey 查看節點的狀態信息
5)create [-s](順序節點) [-e] (臨時節點)path data acl
順序節點如截圖,能夠用於分佈式的主鍵生成器
6)quit退出客戶端
7)set path value 修改節點的數值,版本號dataversion增長
8)delete刪除指定節點(只能刪除沒有字節點的節點) rmr命令遞歸刪除
9 )setquota -n|-b val path 設置節點的配額(子節點的數量或者數據的長度)
超出配額只會在日誌裏有警告信息,不會拋出異常
10)列出節點的配額 listquota path
-1表示沒有限制
11)刪除節點的配額 delquota [-n|-b] path
12)history 顯示對應的編號和命令
redo cmdno 從新執行命令編碼
13)acl權限控制
ACL aclIp = new ACL(Perms.READ,new Id("ip","192.168.1.105")); ACL aclDigest = new ACL(Perms.READ|Perms.WRITE,new Id("digest",DigestAuthenticationProvider.generateDigest("jike:123456"))); ArrayList<ACL> acls = new ArrayList<ACL>(); acls.add(aclDigest); acls.add(aclIp); //zookeeper.addAuthInfo("digest", "jike:123456".getBytes()); String path = zookeeper.create("/node_4", "123".getBytes(), acls, CreateMode.PERSISTENT); System.out.println("return path:"+path);
若是不是192.168.1.105鏈接服務,獲取節點信息失敗,由於沒有權限
因此要註冊權限信息 addauth digest jeke:123456
建立一個有權限的節點
(源碼下載: https://github.com/apache/zookeeper)
(idea導入zookeeper:http://www.tuicool.com/articles/vE7bIf)
應用命名服務
顧名思義,就是提供名稱的服務,例如數據庫表格ID,通常用得比較多的有兩種ID,一種是自動增加的ID,一種是UUID(9291d71a-0354-4d8e-acd8-64f7393c64ae),兩種ID各自都有缺陷,自動增加的ID侷限在單庫單表中使用,不能在分佈式中使用,UUID能夠在分佈式中使用可是因爲ID沒有規律難於理解,咱們能夠借用ZK來生成一個順序增加的,能夠在集羣環境下使用的,命名易於理解的ID
一、zookeeper的api圍繞zookeeper句柄而構建,這個句柄表明與zookeeper之間的一個會話。若是與一個服務器的會話斷開,這個會話就會遷移到另外一臺zookeeper服務器上。
二、建立句柄的構造函數
Zookeeper( String connectString, int sessionTimeout, Watcher watcher)
connectString:主機名字和端口
sessionTimeout:通常設置超時時間爲5到10秒,即:5000到10000
Watcher:客戶端使用Watcher接口來監控與zookeeper之間的會話的健康情況
三、程序結束後,默認是到了超時時間,服務器纔會結束會話。須要調用Zookeeper.close()方法會銷燬Zookeeper對象實例所表示的會話。這是使會話當即消失的方式
注意:請不要試着本身去管理客戶端的鏈接,客戶端會監控與服務之間的鏈接,不只會告訴咱們鏈接發生的問題,還會主動嘗試從新創建鏈接。
四、獲取管理權(因爲沒太讀懂,略):在羣獸選舉的算法中,全部潛在的主節點進程嘗試建立/master節點,但只有一個成功,這個成功的進程成爲主節點
咱們將會在程序中添加
String serverId=Integer.toHexString(random.nexInt());
void runForMaster(){
zk.create("/master",serverId.getBytes(),OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
}
建立會產生兩種異常,KeeperException(ConnectionLossException)和InterruptedException,當處理ConnectionLossException異常時,咱們須要找出那個進程建立的/master節點,若是進程是本身的,就開始成爲羣首角色。咱們經過getData方法來處理
byte[] getData(String path,bool watch,Stat stat)
五、異步獲取管理權
create方法的異步調用,調用返回前不會等待create命令完成,因此無需關心異常
void create(String path,List<ACL> acl,CreateMode createMode,AsyncCallback.StringCallback cb,Object ctx)
比同步的方法多了2個參數:提供回調方法的對象,用戶指定上下文信息
回調函數實現只有一個方法的StirngCallback接口:
void processResult(int rc,String path,Object ctx,String name)
rc:返回調用的結構,返回ok或者異常對應的編碼
path:路徑
ctx:上下文
name:節點名稱
六、註冊從節點
master節點對應的服務器宕機,或者zk與服務器之間的網絡不穩定,都會致使主節點被刪除,從而發生master選舉,優化的策略是判斷最近一次的master是本身嗎,優先讓最近一次的master爭選爲master,防止資源的遷移致使系統的開銷
第六章、運行zookeeper
一、基本配置參數
clientPort:客戶端所鏈接的服務器所監聽的TCP端口
tickTime:心跳時間,單位爲毫秒
leaderServer:配置yes或者no,指示羣首服務器是否爲客戶端提供服務
二、日誌
1)事務日誌
事務日誌指zookeeper系統在正常運行過程當中,針對全部的更新操做,在返回客戶端「更新成功」的響應前,zookeeper會保證已經將本次更新操做的事務日誌已經寫到磁盤上,只有這樣,整個更新操做纔會生效。在datalog/目錄下存在一個文件夾version-2,該文件夾中保存着事物日誌文件,日誌文件的命名規則爲log.**,文件大小爲64MB,**表示寫入該日誌的第一個事務的ID,十六進制表示。
2)快照日誌
zookeeper的數據在內存中是以樹形結構進行存儲的,而快照就是每隔一段時間就會把整個DataTree的數據序列化後存儲在磁盤中,這就是zookeeper的快照文件。zookeeper快照日誌的存儲路徑一樣能夠在zoo.cfg中查看,如上文截圖所示。訪問dataDir路徑能夠看到version-2文件夾,zookeeper快照文件的命名規則爲snapshot.**,其中**表示zookeeper觸發快照的那個瞬間,提交的最後一個事務的ID。
3)log4j日誌
zk採用slf4j庫(java簡易日誌門面)做爲日誌的抽象層,默認使用log4j進行實際的日誌記錄功能,conf目錄下的log4j.properties,bin目錄下的zookeeper.out輸出
三、