天天看點

跨叢集操作—Elastic Stack 實戰手冊

跨叢集操作—Elastic Stack 實戰手冊
https://developer.aliyun.com/topic/download?id=1295 · 更多精彩内容,請下載下傳閱讀全本《Elastic Stack實戰手冊》 https://developer.aliyun.com/topic/download?id=1295 https://developer.aliyun.com/topic/es100 · 加入創作人行列,一起交流碰撞,參與技術圈年度盛事吧 https://developer.aliyun.com/topic/es100

創作人:張劉毅

審稿人:吳斌

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"
          ]
        }
      }
    }
  }
}           
跨叢集操作—Elastic Stack 實戰手冊

在 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"
    }
  }
}           
跨叢集操作—Elastic Stack 實戰手冊

如上圖所示,通過 CCS 查詢到 3 條資料:cluster_one 的一條資料 team 10 以及 cluster_two 的兩條資料 team 1 和 team 7,和之前寫入的資料一緻。

跨叢集複制

跨叢集複制是将特定索引,從一個 Elasticsearch 叢集複制到另外的叢集。

一般用于以下場景:

  • 災備:資料中心服務中斷時,可以繼續響應使用者的搜尋請求,防止使用者大的查詢影響到寫入吞吐
  • 資料本地化:将資料複制到更靠近使用者的位置以降低搜尋延遲

跨叢集複制使用主動-被動模型,我們将索引寫入上司者索引,資料會被複制到一個或多個隻讀跟随者索引。在将跟随者索引添加到叢集之前,我們需要配置包含上司者索引的遠端叢集。

當上司者索引有寫入請求時,跟随者索引從遠端叢集上的上司者索引中拉取增量資料。我們可以手動建立跟随者索引,或配置自動跟随模式(auto-follow patterns),建立跟随者索引。

我們可以單向或雙向配置 CCR:

  • 在單向配置中,一個叢集僅包含上司者索引,而另一個叢集僅包含跟随者索引。
跨叢集操作—Elastic Stack 實戰手冊
  • 在雙向配置中,每個叢集都包含上司者索引和跟随者索引
跨叢集操作—Elastic Stack 實戰手冊

我們在伺服器上啟動兩個叢集來模拟不同地區資料中心的叢集:

  • “cluster1”:在端口 9200 上運作。我們會将文檔從 cluster1 複制到 cluster2。
  • “cluster2”:在端口 9400 上運作。cluster2 将維護一個來自 cluster1 的複制索引。
跨叢集操作—Elastic Stack 實戰手冊

配置遠端叢集

我們選擇 CCR 的單向配置,是以 CCR 是基于拉取模式,是以我們隻需要確定 cluster2 連接配接到cluster1 ,而不需要指定從 cluster2 到 cluster1 的連接配接。

下面讓我們通過 cluster2 上的 API 調用來定義 cluster1:

PUT /_cluster/settings
{
  "persistent": {
    "cluster": {
      "remote":{
        "cluster1":{
          "seeds":["192.168.2.2:9300"]
        }
      }
    }
  }
}
           
跨叢集操作—Elastic Stack 實戰手冊

Kibana 中遠端叢集管理的 UI,單擊左側導航面闆中的 “Management”(齒輪圖示),然後點選 “Stack Management” ,導航到 Elasticsearch 部分中的 “Remote Clusters”(遠端叢集)。

跨叢集操作—Elastic Stack 實戰手冊

建立要複制的索引

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 叢集複制到另一個叢集的索引。

跨叢集操作—Elastic Stack 實戰手冊

測試 CCR 複制

我們在 cluster1 上寫入資料:

POST /esfightalone/_doc
  {
    "name" :"team 1"
  }
           

然後在 cluster2 上查詢,驗證索引資料是否同步,發現此時資料已實時同步到 cluster2 中了:

GET /esfightalone-copy/_search           
跨叢集操作—Elastic Stack 實戰手冊

CCR 屬于 Elastic 官方的白金付費(Platinum License)的功能。一般企業還是會選擇自研資料同步工具,來同步叢集間的資料。

不過,需要體驗的小夥伴可以在 Elastic 官網或阿裡雲 Elasticsearch 申請 30 天免費使用或者在自己的本地安裝中啟用試用功能。

創作人簡介:

張劉毅,存儲研發工程師,曾經做過 AI 大資料平台研發,負責過 80+ES 叢集。目前專

注于生物醫藥和大資料。

部落格:

https://blog.csdn.net/dtzly

繼續閱讀