1. 程式人生 > >Elastic Search實戰之不停機重建索引(修改對映型別)

Elastic Search實戰之不停機重建索引(修改對映型別)

前言

我們在使用ES的時候,尤其是初學者,通常都會遇到一個問題,那就是文件欄位的對映型別建立錯誤問題,但是ES上卻不能像mysql一樣直接去修改欄位型別,這時便出現了這個棘手的問題,今天讓我們用一種索引重建的方式來修改欄位對映型別,本文使用的ES是5.6.3版本。

前提

使用索引重建並且不停機,需要有個前提,那就是你在使用索引時,都是使用索引別名而不是使用真正的索引名
,如果這點在你的程式上還沒有做的話,那麼請為其建立別名,好處很多,一旦當前索引出現了什麼問題 不能及時恢復,你可以緊急切換到備用索引上而無需再重啟服務、方便索引重建等等。

思路

說下我們索引重建的思路,假設我們現有索引名為:a_v1,代表索引a的第一個版本,其別名為索引:a,重建步驟如下:
第一步:建立索引a_v2(該索引的mapping需要與a_v1基本保持一致,除了你要修改的欄位mapping)
第二步:把a_v1的資料匯入a_v2索引中(ES中有現成的語句支援)
第三步:把a_v1別名刪除並且同時為a_v2新增別名a(此時線上程式已經切換到a_v2資料來源上了)
第四步:再次執行第二步驟,目的是增量同步a_v1中修改但沒有同步到a_v2中的資料(因為你在做第二、三步的時候很可能線上的a_v1索引資料發生修改了)

舉例說明

下面我們以商品的索引重建為例,來看下具體的語句要怎麼寫吧O(∩_∩)O~,假設現在已經有索引goods_v1別名為goods

1. 新建目標索引V2版本
curl -XPUT --header 'Accept: application/json' 'http://es.zhuma.com/goods_v2' -d '{
        "mappings": {
            "default": {
                "dynamic": "false",
                "properties": {
                    "
id": { "type": "long" }, "name": { "type": "text", "analyzer": "ik_max_word" }, "desc": { "type": "text", "
analyzer": "ik_max_word" }, "quantity": { "type": "integer" } } } }, "settings": { "index": { "number_of_shards": "5", "provided_name": "goods_v1", "max_result_window": "50000", "creation_date": "1521437794175", "analysis": { "analyzer": { "ik": { "tokenizer": "ik_max_word" } } }, "number_of_replicas": "1", "uuid": "L1FLoPmAQNiwJkpdH1KJwA", "version": { "created": "5060399" } } } }'

2. 現有索引資料匯入目標索引

curl -XPOST --header 'Accept: application/json' 'http://es.zhuma.com/_reindex' -d '{
  "conflicts": "proceed",
  "source": {
    "index": "goods_v1"
  },
  "dest": {
    "index": "goods_v2",
    "op_type": "create",
    "version_type": "external"
  }
}'

備註

  • reindex會將一個索引的資料複製到另一個已存在的索引,但是並不會複製原索引的mapping(對映)、shard(分片)、replicas(副本)等配置資訊,所以這也是為什麼我們在第一步中建立了和源索引結構基本相同的目標索引的原因。
  • 設定conflicts為proceed代表當複製資料時發生版本衝突時繼續執行(預設設定在版本衝突時會中止了reindex程序)。
  • 設定op_type為create是指在目標索引中建立丟失的文件,所有現有檔案將導致版本衝突。
  • 設定version_type為external就是指資料從源索引拷貝到目標索引的時候會同時拷貝上版本號欄位,並更新目標索引中比源索引中更舊版本的文件。
  • 這裡說下該匯入功能執行效率,線上一個索引的資料量在8w左右用時3秒多(其實跟你的索引的一個文件資料量也有關係,這裡僅僅給個參考點)。

3. 設定索引的別名

curl -XPOST --header 'Accept: application/json' 'http://es.zhuma.com/_aliases' -d '{
    "actions": [
        {"remove": {"index": "goods_v1", "alias": "goods"}},
        { "add": {"index": "goods_v2",  "alias": "goods"}}
    ]
}'

4. 再次執行匯出v1至v2匯入資料

結束語

Elastic Search在搜尋方面確實好處多多,但是其文件和國內的一些帖子並不是很多,在加上它升級時是不做相容處理的,所以網上可參考並且有意義的文件就少之又少了,所以後面我們會分享一些關於使用java api操作ES的一些使用心得和線上問題的異常處理,歡迎加關注,公眾號也會不定期推送文章哦 O(∩_∩)O~

歡迎關注我們的公眾號或加群,等你哦!