Observer:在不傷害寫性能的情況下擴展ZooKeeper。
雖然通過Client直接連接到ZooKeeper集群的性能已經很好了,可是這樣的架構假設要承受超大規模的Client,就必須添加ZooKeeper集群的Server數量,隨着Server的添加,ZooKeeper集群的寫性能必定下降。我們知道ZooKeeper的ZNode變更是要過半數投票通過,隨着機器的添加,因為網絡消耗等原因必定導致投票成本添加,從而導致寫性能的下降。
Observer是一種新型的ZooKeeper節點。能夠幫助解決上述問題,提供ZooKeeper的可擴展性。Observer不參與投票,僅僅是簡單的接收投票結果。因此我們添加再多的Observer,也不會影響集群的寫性能。除了這個區別,其它的和Follower基本上全然一樣。比如:Client都能夠連接到他們,而且都能夠發送讀寫請求給他們,收到寫請求都會上報到Leader。
Observer有另外一個優勢,由於它不參與投票,所以他們不屬於ZooKeeper集群的關鍵部位,即使他們Failed,或者從集群中斷開,也不會影響集群的可用性。
Observer和Follower在一些方面是一樣的。詳細點來講,他們都向Leader提交proposal(投票)。但與Follower不同,Observer不參與投票的過程。它簡單的通過接收Leader發過來的INFORM(通知)消息來learn已經Commit的proposal。因為Leader都會給Follower和Observer發送INFORM消息,所以它們都被稱為Learner。
INFORM消息背后的原理
因為Observer不會接收proposal並參與投票,Leader不會發送proposal給Observer。Leader發送給Follower的Commit消息只包含zxid,並沒有proposal本身。所以,只發送Commit消息給Observer則不會讓Observer得知已提交的proposal。這就是使用INFORM消息的原因,此消息本質上是一個包含了已被Commit的proposal的Commit消息。
簡而言之,Follower會得到兩個消息,而Observer只會得到一個。Follower通過廣播得到proposal的內容,接下來獲得一個簡單Commit消息,此消息只包含了zxid。相反,Observer得到一個包含了已被Commit的proposal的INFORM消息。
參與了決定是否Commit一個proposal的投票的server就稱為PARTICIPANT Server,Leader和Follower都屬於這種Server。Observer則稱為OBSERVER Server。
使用Observer模式的一個主要的理由就是對讀請求進行擴展。通過增加更多的Observer,可以接收更多的請求的流量,卻不會犧牲寫操作的吞吐量。注意到寫操作的吞吐量取決於quorum的Size。如果增加更多的Server進行投票,quorum會變大,這會降低寫操作的吞吐量。然而增加Observer並不會完全沒有損耗,每一個新的Observer在每提交一個事務后收到一條額外的消息,這就是前面提到的INFORM消息。這個損耗比起加入Follower來投票來說損耗更少。
使用Observer的另一個原因是跨數據中心部署。把participant分散到多個數據中心可能會極大拖慢系統,因為數據中心之間的網絡的延遲。使用Observer的話,更新操作都在一個單獨的數據中心來處理,並發送到其他數據中心,讓其他數據中心的client消費數據。阿里開源的跨機房同步系統Otter就使用了Observer模式,可以參考。
注意Observer的使用並無法完全消除數據中心之間的網絡延遲,因為Observer不得不把更新請求轉發到另一個數據中心的Leader,並處理INFORM消息,網絡速度極慢的話也會有影響,它的優勢是為本地讀請求提供快速響應。
場景應用:
依據Observer的特點。我們能夠使用Observer做跨數據中心部署。假設把Leader和Follower分散到多個數據中心的話,由於數據中心之間的網絡的延遲。勢必會導致集群性能的大幅度下降。使用Observer的話,將Observer跨機房部署。而Leader和Follower部署在單獨的數據中心,這樣更新操作會在同一個數據中心來處理,並將數據發送的其它數據中心(包括Observer的),然后Client就能夠在其它數據中心查詢數據了。可是使用了Observer並不是就能全然消除數據中心之間的延遲,由於Observer還得接收Leader的同步結果合Observer有更新請求也必須轉發到Leader,所以在網絡延遲非常大的情況下還是會有影響的,它的優勢就為了本地讀請求的高速響應。
大致的架構例如以下圖:
配置
為了使用Observer模式,在任何想變成Observer模式的配置文件($ZOOKEEPER_HOME/conf/zoo.cfg)中加入如下配置:
peerType=observer
並在所有Server的配置文件($ZOOKEEPER_HOME/conf/zoo.cfg)中,配置成Observer模式的server的那行配置追加:observer,例如:
server.1:localhost:2181:3181:observer
然后客戶端的操作和Leader和Follow模式完全不變。
zookeeper寫請求流程圖:
observer服務器在這個流程中只參與了1,4兩個步驟,不參與投票。