elasticsearch跨叢集資料遷移

一寸HUI發表於2020-09-13

寫這篇文章,主要是目前公司要把ES從2.4.1升級到最新版本7.8,不過現在是7.9了,官方的文件:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

由於從2.4.1跨很大基本的升級,所以不能平滑的升級了,只能重新搭建叢集進行資料遷移,所以遷移資料是第一步,但是呢,2.4.1是可以支援多個type的,現在的新版已經不能支援多個type了,所以在遷移的過程中要將每一個type建立相應的索引,目前只是根據原先的type之間建立新的索引,還沒考慮到業務的需求,這個可能需要重新設計索引。

本文主要針對在實際過程中遇到的幾個問題進行闡述,第一步遷移的方案選擇,第二怎麼去遷移,第三對遇到的問題進行解決

一、遷移方案的選擇

主要參考下這篇文章:https://www.jianshu.com/p/50ef4c9090f0

我個人覺得比較熟悉的方法選擇三種:

一個是備份和還原,也就是說使用snapshot,官方的網址:https://www.elastic.co/guide/en/elasticsearch/reference/current/snapshot-restore.html

 

然後發現只能跨一個版本升級,並不不符合我目前的需求,所以排除這個方案。

第二個是使用elk的方式,使用logstash,我有另外一篇文章介紹這個的玩法:從0到1學會logstash的玩法(ELK)

logstash的官方文件:https://www.elastic.co/guide/en/logstash/current/index.html

這個方法確實可以實現遷移,但是對於不熟悉這個elk的童鞋來說有點難,因為剛開始接觸,也不是那麼的友好,所以我在這裡並沒有優先選擇。

第三種方案就是採用elasticsearch的一個介面_reindex,這個方法很簡單,官方文件也很詳細,上手也比較快,所以選擇了該方案,以前也沒接觸過,所以也要研究下吧,所以就有官方的文件:https://www.elastic.co/guide/en/elasticsearch/reference/7.9/docs-reindex.html,對英文不是很熟的童鞋完全可以搜尋其他部落格,很多部落格都有詳細的介紹,我也是看別人的部落格,但是忘記網址了,然後再來看官網補充下,畢竟官網的是比較可信點。

 

二、遷移的語法

我們的需求是跨叢集進行資料遷移,所以這裡不說同叢集的遷移,因為對於跨叢集來說,同一個叢集更簡單。

第一步:配置新版es的引數,就是配置白名單,允許哪個叢集可以reindex資料進來,在官網copy了一段,根據自己的實際情況進行修改就好,需要重啟

reindex.remote.whitelist: "otherhost:9200, another:9200, 127.0.10.*:9200, localhost:*"

第二步:就是在新版的es上建立索引,設定好分片,副本(剛開始為0吧)等,因為自動建立的分片和副本都是1,所以自己先建立好索引比較好

第三步:直接配置啦,這裡我就直接貼程式碼了,具體的介紹可以去看官網啦

curl -u user:password   -XPOST "http://ip_new:port/_reindex" -H 'Content-Type:application/json'  -d '  #這裡的user,port,ip,password都是新叢集的
{
  "conflicts": "proceed",
  "source": {
    "remote": { #這是2.4.1的配置
      "host": "http://ip:port/",  
      "username": "user",
      "password": "password"
    },
    "index": "index_name_source", #2.4.1的要遷移的索引
    "query": {
       "term": {
        "_type":"type_name"  #查詢單個type的資料
}
    },
    "size": 6000  #這個引數可以根據實際情況調整
  },
  "dest": {
    "index": "index_name_dest",  #這裡是新es的索引名字
  }
}'

好,很好,好了,那就跑起來,剛開始第一個小的索引跑起來沒任何問題,剛開始以為就這麼簡單,後來索引大了,不合理的設計,就出現下面的問題了

三、遇到的問題和解決方案

我。。。這是神馬設計,一個文件的id這麼長id is too long, must be no longer than 512 bytes but was: 574;

 

 因為在elasticsearch7.8中的id最長為512啦,可以看看這個:https://github.com/elastic/elasticsearch/pull/16036/commits/99052c3fef16d6192af0839558ce3dbf23aa148d

 

沒啥不服氣的吧,那怎麼解決這個問題呢,id好像不好改吧,網上都說要自己寫程式碼去重新縮短這個id的長度。好吧,感覺有點複雜了,我又去看reindex這個文件的,官方文件啦,原來還支援指令碼呢,但是這裡這個支援的指令碼有點強大,比那個update_by_query的指令碼強大,可以改id哦,

 

 看到沒,這些都可以修改,看到了希望有沒有?接下我就修改遷移的程式碼啦:

curl -u user:password   -XPOST "http://ip_new:port/_reindex" -H 'Content-Type:application/json'  -d '  #這裡的user,port,ip,password都是新叢集的
{
  "conflicts": "proceed",
  "source": {
    "remote": { #這是2.4.1的配置
      "host": "http://ip:port/",  
      "username": "user",
      "password": "password"
    },
    "index": "index_name_source",
    "query": {
       "term": {
        "_type":"type_name"  #查詢單個type的資料
  }
    },
    "size": 6000  #這個引數可以根據實際情況調整
  },
  "dest": {
    "index": "index_name_dest",  #這裡是新es的索引名字
  },
  "script": {
    "source": "if (ctx._id.length()>512) {ctx._id = ctx._id.substring(0,511)}",  #這裡我簡單粗暴,截斷了,各位可以根據需求去改,這裡和java的語法相似的
    "lang": "painless"
  }
}'

果然解決了問題,遷移資料沒問題了,很好,非常好,但是總是不那麼如意,當一個索引很大,3+個T的資料(吐槽下,什麼鬼,原來的索引還只有6個分片,這個設計。。。)就會curl出問題了,出問題了,中途中斷了,說是無法接收到網路資料:

curl: (56) Failure when receiving data from the peer  #這個問題網上很多人都問,但是都沒解決方案,有人說這是bug

就這麼認命了嗎,每次跑了一半多,白乾活了,這個錯誤也是真的沒啥詳細說明呀,有點慘,我想升級這個curl的版本,但是升級失敗了

 

 算了,沒勁,那就換一個centos7.x的機器看看curl的版本吧,果然比這個高一些,那就換機器繼續試試啦。果然沒讓我失望,沒在出現這個問題了。好吧順利的去遷移資料去了,不過那個size引數是可以調整的,太大了會報錯的,要根據文件的大小*size,這個值在5-15M之間速度會比較快一些,我這也還沒對比測試。

這裡感謝各個寫部落格的博主,看了很多的部落格,解決問題思路,但是沒有記錄下,現在也就記得這麼多了,好久沒寫部落格了,最近看了很多基礎的書,果然出來混遲早是要還的,以前落下的基礎知識,總要花費一個代價補回去的,也希望自己能夠與各位童鞋一起學習進步,一直相信最好的學就是教會別人

相關文章