分布式環境的特點
- 分布性
-
并發性
程式運作過程中,并發性操作室很常見的。比如同一個分布式系統中的多個節點,同時通路一個共享資源。資料庫、分布式存儲
-
無序性
程序之間的消息通信,會出現順序不一緻問題
#分布式環境下面臨的問題
-
網絡通信
網絡本身的不可靠性,是以會涉及到一些網絡通信的問題
-
網絡分區(腦裂)
當網絡發生異常倒是分布式系統中部分節點之間的網絡延時不斷增大,最終導緻組成分布式架構的所有節點,隻有部分節點能正常通信
-
三态
在分布式架構裡面,有三種狀态,成功、失敗、逾時
-
分布式事務
ACID(原子性、一緻性、隔離性、持久性)
#中心化和去中心化
-
冷備或者熱備
分布式架構裡,很多的架構思想采用的是:當叢集發生故障的時候,叢集中的人群會自動“選舉”出一個新的上司。
最典型的是:zookeeper/etcd
#經典的CAP/BASE理論
##CAP
C(一緻性Consistency):所有節點上的資料,時刻保持一緻
A(可用性Availability):每個請求都能夠收到一個響應,無論響應成功或者失敗
P(分區容錯Partition-tolerance):表示系統出現腦裂以後,可能導緻某些server與叢集中的其他機器失去聯系
CP/AP
CAP理論僅适用于原子讀寫的Nosql場景,不适用于資料庫系統
##BASE
- 基于CAP理論,CAP理論并不适用于資料庫事務(因為更新一些錯誤的資料而導緻資料出現紊亂,無論什麼樣的資料庫高可用方案都是徒勞),雖然XA事務可以保證資料庫在分布式系統下的ACID特性,但是會帶來性能方面的影響;
- eBay嘗試了一種完全不同的套路,放寬了對事務ACID的要求。提出了BASE理論
- Basically available:資料庫采用分片模式,把100W的使用者資料分布在5個執行個體上。如果破壞了其中一個執行個體,仍然可以保證80%的使用者可用
- soft-state:在基于client-server模式的系統中,server端是否有狀态,決定了系統是否具備良好的水準擴充、負載均衡、故障恢複等特性。Server端承諾會維護client端狀态資料,這個狀态僅僅維護一小段時間,這段時間以後,server端就會丢棄這個狀态,恢複正常狀态
- Eventually consistent :資料的最終一緻性
初步認識zookeeper
- zookeeper是一個開源的分布式協調服務,是由雅虎建立的,基于google chubby
-
zookeeper是什麼
分布式資料一緻性的解決方案
-
zookeeper能做什麼
資料的釋出/訂閱(配置中心:disconf)、負載均衡(dubbo利用了zookeeper機制實作負載均衡)、命名服務、master選舉(kafka、hadoop、hbase)、分布式隊列、分布式鎖
- zookeeper的特性
-
順序一緻性
從同一個用戶端發起的事務請求,最終會嚴格按照順序被應用到zookeeper中
-
原子性
所有的事務請求的處理結果在整個叢集中的所有機器上的應用情況是一緻的,也就是說,要麼整個叢集中的所有機器都成功的應用了某一事務,要麼全都不應用
-
可靠性
一旦伺服器成功應用了某一個事務資料,并且對用戶端做了相應,那麼這個資料在整個叢集中一定是同步并且保留下來的
-
實時性
一旦一個事務被成功應用,用戶端就能夠立即從伺服器端讀取到事務變更後的最新資料狀态;(zookeeper僅僅保證在一定時間内,近實時)
-
zookeeper安裝
- 單機環境安裝
-
下載下傳zookeeper的安裝包
http://apache.fayea.com/zookeeper/stable/zookeeper-3.4.10.tar.gz
-
解壓zookeeper
tar -zxvf zookeeper-3.4.10.tar.gz
-
cd 到 ZK_HOME/conf , copy一份zoo.cfg
cp zoo_sample.cfg zoo.cfg
-
sh zkServer.sh
{start|start-foreground|stop|restart|status|upgrade|print-cmd}
- sh zkCli.sh -server ip:port
-
叢集環境
zookeeper叢集, 包含三種角色: leader / follower /observer
observer
observer是一種特殊的zookeeper節點。可以幫助zookeeper的擴充性(如果大量用戶端通路我們zookeeper叢集需要增加zookeeper叢集機器數量。進而增加zookeeper叢集的性能,導緻zookeeper寫性能下降,zookeeper的資料變更需要半數以上伺服器投票通過,造成網絡消耗增加投票成本)
- observer不參與投票,隻接受投票結果
- 不屬于zookeeper的關鍵部位
-
在zoo.cfg裡面增加
peerType=observer
server.1=192.168.11.129:2181:3181:observer
server.2=192.168.11.131:2181:3181
server.3=192.168.11.135:2181:3181
第一步: 修改配置檔案
server.id=host:port:port
id的取值範圍: 1~255; 用id來辨別該機器在叢集中的機器序号
2181是zookeeper的端口; //3306
3181表示leader選舉的端口
server.1=192.168.11.129:2181:3181
server.2=192.168.11.131:2181:3181
server.3=192.168.11.135:2181:3181
第二步:建立myid
在每一個伺服器的dataDir目錄下建立一個myid的檔案,檔案就一行資料,資料内容是每台機器對應的server ID的數字
第三步:啟動zookeeper
192.168.11.129
192.168.11.131
192.168.11.135
zoo.cfg配置檔案分析
-
tickTime=2000
zookeeper中最小的時間機關長度(ms)
-
initLimit=10
follower節點啟動後與leader節點完成資料同步的時間
-
syncLimit=5
leader節點與follower節點進行心跳監測的最大延時時間
-
dataDir=/tmp/zookeeper
表示zookeeper伺服器存儲快照檔案的目錄
- dataLogDir 表示配置zookeeper事務日志的存儲路徑,預設指定在dataDir目錄下
- clientPort 表示用戶端和服務端建立連接配接的端口号: 2181
zookeeper中的一些概念
資料模型
zookeeper的資料模型和檔案系統類似,每一個節點稱為:znode 是zookeeper中的最小資料單元,每一個znode上都可以儲存資料和挂載子節點,進而構成一個階層化的屬性結構
節點特性
- 持久化節點:節點建立後會一直存在zookeeper伺服器上,直到主動删除
- 持久化有序節點:每個節點都會為它的一級子節點維護一個順序
- 臨時節點:臨時節點的生命周期和用戶端的回話保持一緻。當用戶端回話失效,該節點自動清理
- 臨時有序節點:在臨時節點上多了一個順序性特性
會話
- watcher
- zookeeper提供了分布式資料釋出/訂閱,zookeeper允許用戶端向伺服器注冊一個watcher監聽,當伺服器的節點觸發指定事件的時候會觸發watcher伺服器會向用戶端發送一個事件通知,watcher的通知是一次性,一旦觸發一次通知後,該watcher就失效
- ACL
-
zookeeper提供控制及诶單通路權限的功能,用于有效的保證zookeeper中資料的安全性,避免誤操作而導緻系統出現重大事故
CREATE /READ/WRITE/DELETE/ADMIN
-
zookeeper的指令操作
-
create [-s] [-e] path data acl
-s 表示節點是否有序
-e 表示是否為臨時節點
預設情況下,是持久化節點
-
get path [watch]
獲得指定 path的資訊
-
set path data [version]
修改節點 path對應的data
樂觀鎖的概念
資料庫裡面有一個 version 字段去控制資料行的版本号
-
delete path [version]
删除節點
stat資訊
cversion = 0 子節點的版本号
aclVersion = 0 表示acl的版本号,修改節點權限
dataVersion = 1 表示的是目前節點資料的版本号
czxid 節點被建立時的事務ID
mzxid 節點最後一次被更新的事務ID
pzxid 目前節點下的子節點最後一次被修改時的事務ID
ctime = Sat Aug 05 20:48:26 CST 2017
mtime = Sat Aug 05 20:48:50 CST 2017
cZxid = 0x500000015
ctime = Sat Aug 05 20:48:26 CST 2017
mZxid = 0x500000016
mtime = Sat Aug 05 20:48:50 CST 2017
pZxid = 0x500000015
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0 建立臨時節點的時候,會有一個sessionId 。 該值存儲的就是這個sessionid
dataLength = 3 資料值長度
numChildren = 0 子節點數
java api的使用
- 權限控制模式
- schema:授權對象
- ip : 192.168.1.1
- Digest : username:password
- world : 開放式的權限控制模式,資料節點的通路權限對所有使用者開放。 world:anyone
- super :超級使用者,可以對zookeeper上的資料節點進行操作
- 連接配接狀态
- KeeperStat.Expired 在一定時間内用戶端沒有收到伺服器的通知, 則認為目前的會話已經過期了。
- KeeperStat.Disconnected 斷開連接配接的狀态
- KeeperStat.SyncConnected 用戶端和伺服器端在某一個節點上建立連接配接,并且完成一次version、zxid同步
- KeeperStat.authFailed 授權失敗
- 事件類型
- NodeCreated 當節點被建立的時候,觸發
- NodeChildrenChanged 表示子節點被建立、被删除、子節點資料發生變化
- NodeDataChanged 節點資料發生變化
- NodeDeleted 節點被删除
- None 用戶端和伺服器端連接配接狀态發生變化的時候,事件類型就是None
zkclient
curator
Curator本身是Netflix公司開源的zookeeper用戶端;
- curator提供了各種應用場景的實作封裝
- curator-framework 提供了fluent風格api
- curator-replice 提供了實作封裝
curator連接配接的重試政策
- ExponentialBackoffRetry() 衰減重試
- RetryNTimes 指定最大重試次數
- RetryOneTime 僅重試一次
- RetryUnitilElapsed 一直重試知道規定的時間
zookeeper的實際應用場景
zookeeper能夠實作哪些場景
訂閱釋出
watcher機制
統一配置管理(disconf)
分布式鎖
redis
zookeeper
資料庫
負載均衡
ID生成器
分布式隊列
統一命名服務
master選舉
分布式鎖
master選舉
資料釋出訂閱/ 配置中心
實作配置資訊的集中式管理和資料的動态更新
實作配置中心有兩種模式:push 、pull。
長輪訓
zookeeper采用的是推拉相結合的方式。 用戶端向伺服器端注冊自己需要關注的節點。一旦節點資料發生變化,那麼伺服器端就會向用戶端
發送watcher事件通知。用戶端收到通知後,主動到伺服器端擷取更新後的資料
- 資料量比較小
- 資料内容在運作時會發生動态變更
- 叢集中的各個機器共享配置
負載均衡
請求/資料分攤多個計算機單元上
分布式鎖
通常實作分布式鎖有幾種方式
- redis。 setNX 存在則會傳回0, 不存在
-
資料方式去實作
建立一個表, 通過索引唯一的方式
create table (id , methodname …) methodname增加唯一索引
insert 一條資料XXXdelete 語句删除這條記錄
mysql for update
- zookeeper實作
- 排他鎖
- 共享鎖(讀鎖)
實作共享鎖,使用java api的方式
命名服務
master選舉
7*24小時可用, 99.999%可用
master-slave模式
使用zookeeper解決
curator 提供應用場景的封裝
- curator-reciples
- master/leader選舉
- 分布式鎖(讀鎖、寫鎖)
-
分布式隊列
…
LeaderLatch
寫一個master
LeaderSelector
每一個應用都寫一個臨時有序節點,根據最小的節點來獲得優先權
zookeeper叢集角色
leader
leader是zookeeper叢集的核心
- 事務請求的唯一排程者和處理者,保證叢集事務處理的順序性
- 叢集内部各個伺服器的排程者
follower
- 處理用戶端非事務請求,以及轉發事務請求給leader伺服器
- 參與事務請求提議(proposal)的投票(用戶端的一個事務請求,需要半數伺服器投票通過以後才能通知leader commit;leader會發起一個提案,要求follower投票)
- 參與leader選舉的投票
observer
- 觀察zookeeper叢集中最新狀态的變化并将這些狀态同步到observer伺服器上
- 增加observer不影響叢集中事務處理能力,同時還能提升叢集的非事務處理能力
zookeeper的叢集組成
zookeeper一般是由2n+1台伺服器 組成