ES異地雙活方案


對於單機房而言,只要參考Elastic Search 官方文檔,搭建一個集群即可,示意圖如下:

原理類似分布式選舉那一套,當一個master節點宕機時,剩下2個投票選出1個新老大,整個集群可以繼續服務。對於核心系統,只部署單機房總歸有點不保險,萬一單機房故障就廢了(比如:斷電斷網、或光纜被挖斷)。那有同學肯定會想,多弄幾個機房,把集群中的節點分散到多個機房不就好了么?

理論上講,上面這種結構是可行的,但實際應用中,要考慮的因素會更多:

1、1個機房變3個機房,這成本就得翻好幾倍了,回想一下mysql之類的解決方案,master-slave架構頂多放2個機房就可以了。

2、如果3個機房分屬異地,比如:上海、廣州、北京,三個城市間數據傳輸必然增加延時,要降低延時一般是拉專線,這樣一方面成本還會繼續增加,而且這么長距離傳輸,網絡抖動是難免的,抖動期間,會增加選舉"誤切換"的概率。

3、3個節點之間不斷的數據同步,會使三地機房間的網絡流量增加,特別是某個節點掛了,重新恢復后,會在短時間內從master上同步數據,有流量風暴的隱患。

 

當然,官方有一個Cross  Cluster Replication(CCR)的方案,架構示意圖如下:

 原理上講,這其實也是把一個集群的節點分散部署在2個idc機房,另外,該方案並非免費午餐,官方的描述中,這是企業級的商業收費服務:

 

那么,普通屌絲公司有沒有經濟點的做法,即相對省錢,又能達到高可用呢?

圈內有一句名言:“沒有什么是不能通過增加一個抽象層解決的,如果沒有,就再加一層”。

我們把這個問題分解一下,無非就是“讀”高可用,以及“寫”高可用,先來看“讀”:

假設有2個機房A、B,每個機房各部署1個ES集群,然后有一個java服務,按現在流行的做法,不管是spring cloud也好,還是dubbo也罷,一般也是多機房部署,同樣部署在A、B二個機房。可以在service內部引入一個檢測機制,用2個線程,分別定時檢測A、B二個機房的ES集群健康情況(類似心跳檢測),然后把檢測結果,寫入java service實例的內部全局變量中,假設ES集群狀態正常為up,如果掛了為down。這樣每個機房的java service就能知道2個ES集群是否可用,然后結合自身所在的機房,優先就近訪問(這1點不難做到,服務注冊時,可以在meta data元數據里主動標識自身所屬的ip,根據ip地址段,就能區分出所在機房)。即:如果A,B二個機房的ES集群都是up健康狀態,A機房的java service訪問同機房的ES實例,避免了跨機房調用。

 

當發生故障時,這里有2種情況,一種是某個機房的ES集群down了,但是該機房的java service還是正常的,類似下面:

B機房的ES集群故障,這時候檢查結果會標識B:down,B機房的java service此時知道本機房的ES集群有問題,退而求其次,訪問另一側機房的ES.

 

如果某一側機房徹底掛了,比如:斷電、斷網。這時候,剩下一側機房的java service仍然是優先訪問同機房的ES,整個系統仍然可用。

 

解決了雙機房ES"讀"的問題,再來看“寫”的問題,可能有同學說了,這還不簡單,直接雙寫就行了吧,一份數據,向A、B機房的ES集群各寫一份。聽想來貌似可行,但是有一些細節問題 :
1、雙寫並非原子操作,如果A機房的ES集群寫成功了,B機房的ES集群沒寫成功,該怎么辦?
2、當B機房的ES掛了,雙寫不進去時,過一段時間又恢復后,故障期間的數據,B機房的ES集群怎么補進去?如果手動事后補數據,雖然可行,但是畢竟麻煩。

這里,可以引入一層MQ,類似下圖這樣:

 

向ES寫入的數據,先發到MQ,然后java service再消費這個Topic,要點在於,分成2個Consumer Group來消費,2個group分別對應於2側的ES,即A-Group消費的Message,寫入A機房的ES集群,B-Group消費的Message,寫入B機房的ES集群。寫入ES成功后,才Ack確認消費成功。由於2個group的消費是各自獨立的(各自有各自的offset)。

當1側ES down時,寫入不成功,該Group的Message就不會Ack成功,一直壓積着(而另1側的group則不受影響),等ES恢復時,會繼續消費,把故障期間的數據,自動補進去。這樣就免去了事后手動補數據的麻煩。

當然,這個方案的提前是MQ本身是高可用的,不過這個不難做到,已經有一些rocket mq雙機房多活的案例,不在本文討論范圍,大家可以自行搜索。 

 

參考文檔:

https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-discovery.html

https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html

https://www.elastic.co/cn/blog/bi-directional-replication-with-elasticsearch-cross-cluster-replication-ccr

https://zhuanlan.zhihu.com/p/82702078


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM