
創作人:張劉毅
審稿人:吳斌
Elasticsearch 叢集天然支援橫向水準擴充,是以當業務規模擴大、對叢集産生讀寫壓力時,增加節點總是運維人員的“懶人選擇”。但随着節點數增多,叢集主節點要維護的 meta 資訊也随之增多,這會導緻叢集更新壓力增大,甚至無法提供正常服務。 另外每個企業的資料中心都需要有災備方案,在叢集間同步資料,因為單點叢集會存在隐患。
鑒于此,Elastic官方提供了跨叢集操作。主要包括:
(1)跨叢集搜尋(CCS):允許配置多個遠端叢集并且在所有已配置的叢集中實作聯合搜尋。
(2)跨叢集複制(CCR):允許跨多個叢集複制索引,适合于做災備方案和資料本地化場景。
跨叢集配置
跨叢集操作有兩種配置模式連接配接遠端的叢集:嗅探模式(Sniff mode)或者代理模式(Proxy mode)。
- 在嗅探模式下,我們使用叢集名稱和種子節點清單注冊遠端叢集。注冊後,叢集狀态将被種子節點擷取,該模式要求本地群集可以通路網關節點的釋出位址。
- 在代理模式下,使用叢集名稱和單個代理位址注冊遠端叢集。代理模式不需要遠端叢集節點具有可通路的釋出位址。
我們可以在 Kibana 上動态配置遠端叢集,也可以在各個節點的 elasticsearch.yml 檔案的上配置。
動态配置遠端叢集
我們在 Kibana 上使用 cluster update settings API 為每個節點動态配置遠端叢集。
例如:
PUT _cluster/settings
{
"persistent": {
"cluster": {
"remote": {
"cluster_one": {
"seeds": [
"127.0.0.1:9300"
],
"transport.ping_schedule": "30s"
},
"cluster_two": {
"mode": "sniff",
"seeds": [
"127.0.0.1:9301"
],
"transport.compress": true,
"skip_unavailable": true
},
"cluster_three": {
"mode": "proxy",
"proxy_address": "127.0.0.1:9302"
}
}
}
}
}
上面的配置中,目前叢集是 cluster_one,一起聯合遠端通路的叢集 cluster_two、cluster_three。其中 cluster_two 的連接配接方式是嗅探模式,cluster_three 的連接配接方式是代理模式,代理位址是 "127.0.0.1:9302"。
其中:
- transport.compress:網絡傳輸的壓縮參數
- transport.ping_schedule :叢集内部通信(tcp)的通路頻率
- skip_unavailable:預設情況下如果請求中的任何叢集都不可用則會傳回錯誤。如果跳過不可用的叢集,可以将 skip_unavailable 設定為 true。
以上這些參數是可以動态調整的,但必須要包括 seed 清單或者代理位址。
我們如果想關閉壓縮、将 ping_schedule 由 30s 改成 60s可以通過如下示例方式
PUT _cluster/settings
{
"persistent": {
"cluster": {
"remote": {
"cluster_one": {
"seeds": [
"127.0.0.1:9300"
],
"transport.ping_schedule": "60s"
},
"cluster_two": {
"mode": "sniff",
"seeds": [
"127.0.0.1:9301"
],
"transport.compress": false
},
"cluster_three": {
"mode": "proxy",
"proxy_address": "127.0.0.1:9302",
"transport.compress": true
}
}
}
}
}
靜态配置遠端叢集
在節點的 elasticsearch.yml 中配置遠端連接配接,隻有在 YAML 檔案中設定的節點,才能連接配接到遠端叢集,并處理遠端叢集請求。
舉例
cluster:
remote:
cluster_one:
seeds: 127.0.0.1:9300
transport.ping_schedule: 30s
cluster_two:
mode: sniff
seeds: 127.0.0.1:9301
transport.compress: true
skip_unavailable: true
cluster_three:
mode: proxy
proxy_address: 127.0.0.1:9302
其中,cluster_one,cluster_two 和 cluster_three 是表示與每個叢集的連接配接的叢集名稱,用于區分本地索引和遠端索引。
跨叢集搜尋
跨叢集搜尋可以針對一個或多個遠端叢集,運作單個搜尋請求。例如,我們可以使用跨叢集搜尋,來過濾和分析存儲,在不同資料中心的叢集中的日志資料。
在5.3.0之前的版本,Elastic 官方提供了 Tribe Node 實作多叢集通路的解決方案。
Tribe Node 是以 Client Node 的角色添加到叢集中。但是由于不保留叢集的 meta 資訊,每次重新開機需要重新加載初始化。是以,在5.3版本中 Elastic 官方提供了 CCS 的功能,允許叢集中的任何節點可以聯合查詢。
快速入門
下面以兩個叢集的跨叢集搜尋為例。我們預先啟動了兩個叢集:cluster1、cluster2,目前叢集是 cluster1。現在的任務是聯合遠端通路的叢集 cluter2 進行跨叢集搜尋。
我們分别在兩個叢集上動态配置 remote cluster。
注意:在 seeds 清單中填寫的是叢集節點間通信的 TCP 端口而不是 HTTP 端口。
PUT _cluster/settings
{
"persistent": {
"cluster": {
"remote": {
"cluster_one": {
"seeds": [
"192.168.2.2:9300"
]
},
"cluster_two": {
"seeds": [
"192.168.2.2:9500"
]
}
}
}
}
}
在 cluster1 中插入資料
PUT esfighttogether/_doc/1
{
"teamname":"team 10"
}
在 cluster2 中插入資料
PUT esfighttogether/_doc/1
{
"teamname":"team 1"
}
PUT esfighttogether/_doc/2
{
"teamname":"team 7"
}
在兩個叢集上分别驗證資料。因為寫入時 Elasticsearch 自帶的預設分詞器會對資料進行分詞,我們通過 team 就可以查詢到所有資料。
查詢語句如下:
GET esfighttogether/_search
{
"query": {
"match": {
"teamname": "team"
}
}
}
執行跨叢集搜尋
GET cluster_one:esfighttogether,cluster_two:esfighttogether/_search?timeout=5m
{
"query": {
"match": {
"teamname": "team"
}
}
}
如上圖所示,通過 CCS 查詢到 3 條資料:cluster_one 的一條資料 team 10 以及 cluster_two 的兩條資料 team 1 和 team 7,和之前寫入的資料一緻。
跨叢集複制
跨叢集複制是将特定索引,從一個 Elasticsearch 叢集複制到另外的叢集。
一般用于以下場景:
- 災備:資料中心服務中斷時,可以繼續響應使用者的搜尋請求,防止使用者大的查詢影響到寫入吞吐
- 資料本地化:将資料複制到更靠近使用者的位置以降低搜尋延遲
跨叢集複制使用主動-被動模型,我們将索引寫入上司者索引,資料會被複制到一個或多個隻讀跟随者索引。在将跟随者索引添加到叢集之前,我們需要配置包含上司者索引的遠端叢集。
當上司者索引有寫入請求時,跟随者索引從遠端叢集上的上司者索引中拉取增量資料。我們可以手動建立跟随者索引,或配置自動跟随模式(auto-follow patterns),建立跟随者索引。
我們可以單向或雙向配置 CCR:
- 在單向配置中,一個叢集僅包含上司者索引,而另一個叢集僅包含跟随者索引。
- 在雙向配置中,每個叢集都包含上司者索引和跟随者索引
我們在伺服器上啟動兩個叢集來模拟不同地區資料中心的叢集:
- “cluster1”:在端口 9200 上運作。我們會将文檔從 cluster1 複制到 cluster2。
- “cluster2”:在端口 9400 上運作。cluster2 将維護一個來自 cluster1 的複制索引。
配置遠端叢集
我們選擇 CCR 的單向配置,是以 CCR 是基于拉取模式,是以我們隻需要確定 cluster2 連接配接到cluster1 ,而不需要指定從 cluster2 到 cluster1 的連接配接。
下面讓我們通過 cluster2 上的 API 調用來定義 cluster1:
PUT /_cluster/settings
{
"persistent": {
"cluster": {
"remote":{
"cluster1":{
"seeds":["192.168.2.2:9300"]
}
}
}
}
}
Kibana 中遠端叢集管理的 UI,單擊左側導航面闆中的 “Management”(齒輪圖示),然後點選 “Stack Management” ,導航到 Elasticsearch 部分中的 “Remote Clusters”(遠端叢集)。
建立要複制的索引
PUT esfightalone
{
"settings": {
"index": {
"number_of_shards": 1,
"number_of_replicas": 0,
"soft_deletes": {
"enabled": true
}
}
},
"mappings": {
"properties": {
"name": {
"type": "keyword"
}
}
}
}
CCR 的 Leader 索引需要使用軟删除(soft_deletes),無論何時删除或更新現有文檔,都可以将操作曆史記錄保留在上司者分片上,等重新操作曆史記錄時,供追随者分片任務使用。
當追随者分片從上司者複制資料時,會在上司者分片上留下标記,這樣上司者就知道追随者在曆史記錄中的所在位置。基于這些标記,上司者分片将會保留這些操作,直到分片曆史記錄保留到設定時間結束(預設為 12 個小時)。
我們已經為遠端叢集建立了一個别名,并建立了一個我們要複制的索引,接下來我們啟動複制。在 cluster2 上,執行:
PUT /esfightalone-copy/_ccr/follow
{
"remote_cluster" : "cluster1",
"leader_index" : "esfightalone"
}
注意,複制索引是隻讀的,不能接受寫操作。至此,我們已配置了要從一個 Elasticsearch 叢集複制到另一個叢集的索引。
測試 CCR 複制
我們在 cluster1 上寫入資料:
POST /esfightalone/_doc
{
"name" :"team 1"
}
然後在 cluster2 上查詢,驗證索引資料是否同步,發現此時資料已實時同步到 cluster2 中了:
GET /esfightalone-copy/_search
CCR 屬于 Elastic 官方的白金付費(Platinum License)的功能。一般企業還是會選擇自研資料同步工具,來同步叢集間的資料。
不過,需要體驗的小夥伴可以在 Elastic 官網或阿裡雲 Elasticsearch 申請 30 天免費使用或者在自己的本地安裝中啟用試用功能。
創作人簡介:
張劉毅,存儲研發工程師,曾經做過 AI 大資料平台研發,負責過 80+ES 叢集。目前專
注于生物醫藥和大資料。
部落格:
https://blog.csdn.net/dtzly