前言
前面幾篇以spring作為主題也是有些時日了,高併發分散式這個主題也挺大能說挺多東西的,也是再開了個坑,然後分P來慢慢跟進吧。 我和大部分人一樣是一名學習者,不是佈道者,更多的是自己的學習總結而不具有權威,進行總結,儘量讓人看的簡單是我的本意,然後有錯則改,無則加勉是最好的,在此也希望大家共同進步。
高併發分散式開發技術體系已然非常的龐大,從國內網際網路企業使用情況,可發現RPC、Dubbo、ZK是最基礎的技能要求。 關於Zookeeper你是不是還停留在Dubbo註冊中心的印象中呢?還有它的工作原理呢?經典應用場景呢?對前面三個問題,如若回答時沒有自己的思路或者說並未瞭解,那麼我覺得我可以幫助到你去入門,並深化這些知識,讓你在面試中更好地去回答。
話不多說進入正題
1. 併發環境下面臨的挑戰
回憶我們學多執行緒的時候,網上有個圖也是十分的有意思
其實我們把執行緒換成程式,相當於每臺服務上跑了一個程式,相同的應用程式執行於多個伺服器叢集上,是為了解決單臺服務面對高併發處理不來的情況。而嘗試去處理這些情況,我們就會面臨很多諸如此類的問題
比如說我們現在是3臺伺服器的一個叢集, 怎麼保證所有機器共享的配置資訊保持一致?
有一臺機器掛掉了,其他機器如何感知到這一變化並接管任務?
使用者量突然的爆增,需要增加機器來緩解壓力,如何做到不重啟叢集而完成機器的新增?
分散式系統,怎麼高效協同多臺服務對同一網路檔案進行寫操作(網路並不是即時的,它並不可靠,存在延時)?
此時我們就需要一個類似於執行緒協同機制的能讓程式進行協同的工具
2. Zookeeper的介紹
① Zookeeper的名字由來
在apache上的許多開源專案都是以動物形象作為icon,比如tomcat就是一隻貓,hive是隻黃蜂等,zookeeper的工作就是把這些動物的行動進行協調
② Zookeeper的簡介
zookeeper就是一種用於分散式應用程式的高效能協調服務,它的特點就是資料是存於記憶體中的,持久化實現在日誌中。它的記憶體類似於樹形結構,且高吞吐低延遲,可以幫助我們實現分散式統一配置中心,服務註冊,分散式鎖等 組成ZooKeeper服務的伺服器必須彼此瞭解。它們維護記憶體中的狀態影像,以及永續性儲存中的事務日誌和快照。只要大多數伺服器可用,ZooKeeper服務就可用。客戶端連線到單個ZooKeeper伺服器。客戶端維護TCP連線,通過該連線傳送請求,獲取響應,獲取監視事件以及傳送tick。如果與伺服器的TCP連線中斷,則客戶端將連線到其他伺服器。
③ Zookeeper的安裝(linux下)
1.JDK版本需要在1.6以上
2.下載: https://archive.apache.org/dist/zookeeper/zookeeper-3.5.2/zookeeper-3.5.2.tar.gz
3.解壓後的conf目錄,增加配置檔案zoo.cfg
4.啟動服務端 bin/zkServer.sh start
5.測試,客戶端連線: bin/zkCli.sh -server 127.0.0.1:2181
zoo.cfg的關鍵配置有3個:
tickTime=2000:一次心跳的基本時間,
dataDir:資料與日誌的存放處
clientPort:埠號
複製程式碼
④ Zookeeper的特點
1.資料結構簡單
類似於Unix檔案系統樹形結構,每個目錄成為Znode節點,但它不同於檔案系統,它既可以視為資料夾,也可以視為檔案來存放資料,但是我們平時還是得叫它節點,別叫資料夾這麼掉價。
需要注意:同一個節點下的子節點名稱不能相同,且命名是有規範的,它的路徑是沒有相對路徑的概念的,都是絕對路徑,任何開始都以"/"開始,最後就是,它存放資料的大小是有限制的
2.資料模型特點
層次名稱空間:就是上面已經提到的,類似於unix的檔案系統,以"/"為根,節點可以包含關聯資料和子節點,絕對路徑 Znode:名稱唯一,命名有規範,型別分4種:持久,順序,臨時,臨時順序,節點的資料構成之後再提
3.命名規範
節點名稱除下列限制外,可以使用任何unicode字元:
1. null字元(\u0000)不能作為路徑名的一部分;
2. 以下字元不能使用,因為它們不能很好地顯示,或者以令人困惑的方式呈現:\u0001 - \u0019和\u007F - \u009F。
3. 不允許使用以下字元:\ud800 - uf8fff, \uFFF0 - uFFFF。
4. “.”字元可以用作另一個名稱的一部分,但是“.”和“..”不能單獨用於指示路徑上的節點,因為ZooKeeper不使用相對路徑。
下列內容無效:“/a/b/. / c”或“c / a / b / . . /”。
5. “zookeeper”是保留節點名。
複製程式碼
4.一些命令
因為我的電腦是window系統的,所以我找了一個window版本的zookeeper來進行演示
先大致解釋一下各個目錄的內容
bin ---> 包括了linux和window的執行程式的執行目錄
conf ---> zookeeper的配置zoo.cfg
contrib ---> 其他一些元件和發行版本
dist-maven ---> maven釋出下的一些jar包
docs ---> 文件
lib ---> 庫
recipe ---> 一些應用例項
src ---> zookeeper的原始碼,因為zookeeper是java寫出來的
複製程式碼
啟動bin目錄下的zkServer.cmd,再啟動zkClient.cmd即可,在我根本不知道該如何進行學習的時候,一般來說輸入help,-help,-h這些指令就可以獲取到幫助,下圖我就是在客戶端輸入了-help指令
因為命令都相對簡單所以也不進行演示了,唯一需要注意的是要注意路徑"/"的問題,比如 ls / 就是根目錄,create /zk 123,還有各個命令的依託條件,比如create必須要提供父節點,delete節點時次節點不能有子節點等···
5.Zookeeper的重要特點---有序
提供多種方式跟蹤時間,ZooKeeper給每個更新貼上一個數字,這個數字反映了所有ZooKeeper事務的順序,嚴格的順序意味著可以在客戶機上實現複雜的同步原語 解釋czxid、version、zoo.cfg中ticks配置
- Zxid :Zookeeper中每次寫請求都對應一個唯一的事務id,稱為 Zxid,它是全域性的且有序的,如果 Zxid1 小於 Zxid2,那 Zxid1 就一定是發生在 Zxid2 前
- version numbers : 版本號,對節點的寫請求都會導致該節點的3種版本號增加(其實套路和樂觀鎖差不多),dataVersion(對znode資料的更改次數),cversion(對znode子節點的更改次數),aclVersion(對znode ACL的更改次數
- ticks : 當使用多伺服器Zookeeper時,伺服器使用一個“滴答”來定義事件的時間,如狀態上傳,會話超時等,它通過最小會話超時(預設是滴答時間x2)間接公開,如果客戶端請求超過這個時間,那客戶端就不再能連線上伺服器端
- real time:Zookeeper並不使用真實時間
你可以使用stat path或者ls2來檢視這些資訊
cZxid:建立該節點的zxid
ctime:該節點的建立時間
mZxid:該節點的最後修改zxid
mtime:該節點的最後修改時間
pZxid:該節點的最後子節點修改zxid
cversion:該節點的子節點變更次數
dataVersion:該節點資料被修改的次數
aclVersion:該節點的ACL變更次數
aphemeraOwner:臨時節點所有者會話id,非臨時的為0
dataLength:該節點資料長度
numChildren:子節點數
複製程式碼
這些資料都在從側面告訴我們,zookeeper是一個協調者
6.zookeeper的第二個特點---可複製
資料可複製,可備份。zookeeper可以快速地搭建一個叢集,內部自帶了這樣的一些工具與機制,我們只需要設定一些配置即可,保證服務可靠,不會成為單點故障
7.zookeeper的第三個特點---迅速
zookeeper的一些特點可以應用於大型分散式系統
3.zookeeper的理論
① zookeeper的會話機制
Session會話
1.一個客戶端連線一個會話,由zookeeper分配唯一會話id
2.客戶端以特定的時間間隔傳送心跳以保持會話有效,
3.超過會話超時時間未收到客戶端的心跳,則判斷客戶端無效(預設2倍tickTime)
4.會話中額請求是FIFO(先進先出原則)的順序執行
複製程式碼
② znode的資料構成
節點資料:儲存的基本資訊(狀態,配置,位置等)
節點後設資料:stat命令下的一些資料
資料大小:限制1M
複製程式碼
③ znode的節點型別
1.持久節點:直接通過create path value所建立
2.臨時節點:create -e path value
3.順序節點:create -s path value
注意
1.session會話失效時,臨時節點就會被刪除
2.順序節點的建立,後為10位十進位制序號,每個父節點擁有一個計數器,這個計數器也是有限制的,到2147483647之後將溢位
3.順序節點在會話結束仍然存在
複製程式碼
④ Watch監聽機制
客戶端能在znodes上設定watch,監聽znode的變化,包括增刪改查,通過stat path ,ls2 path get path皆可檢視
觸發watch事件的條件有4種,create,delete,change,child(子節點事件)
watch的重要特性
1.僅一次性:watch觸發後會立即刪除,要持續監聽變化的話就要持續提供設定watch,這也是watch的注意事項
2.有序性:客戶端先得到watch通知才可檢視變化結果
複製程式碼
watch的注意事項
1.剛剛提及到的它的僅一次性
2.獲取事件和傳送watch,獲取watch,這些請求有可能存在延時,所以不能絕對可靠得到每個節點發生的每個更改
3.一個watch物件只會被通知一次,如果一個watch同時註冊了多個介面(exists,getData),如果此時刪除節點,雖然這個事件對exists和getData都有效,但是watch只會被呼叫一次
複製程式碼
阻塞執行緒喚醒機制—客戶端可以被動接受其他客戶端程式狀態通知
⑤ zookeeper的特性
1.順序一致性(Sequential Consistency),保證客戶端操作是按順序生效的;
2.原子性(Atomicity),更新成功或失敗。沒有部分結果。
3.單個系統映像,無論連線到哪個伺服器,客戶端都將看到相同的內容
4.可靠性,資料的變更不會丟失,除非被客戶端覆蓋修改。
5.及時性,保證系統的客戶端當時讀取到的資料是最新的。
複製程式碼
finally
通過上面的闡述應該我們對於zookeeper有了一個初步的認識,之後會陸續說說分散式鎖,叢集還有一些場景的應用
下一篇:從零開始的高併發(2)---Zookeeper實現分散式鎖