Elasticsearch系列---生產(chǎn)集群的索引管理

概要

索引是我們使用Elasticsearch里最頻繁的部分日常的操作都與索引有關(guān),本篇從運(yùn)維人員的視角,來玩一玩Elasticsearch的索引操作。

基本操作

在運(yùn)維童鞋的視角里,索引的日常操作除了CRUD,還是打開關(guān)閉、壓縮、alias重置,我們來了解一下。

創(chuàng)建索引

[esuser@elasticsearch02 ~]$curl -XPUT 'http://elasticsearch02:9200/music?pretty' -H 'Content-Type: application/json' -d '
{
    "settings" : {
        "index" : {
            "number_of_shards" : 3, 
            "number_of_replicas" : 2 
        }
    },
    "mappings" : {
        "type1" : {
            "properties" : {
                "name" : { "type" : "text" }
            }
        }
    }
}'

{
    "acknowledged": true,
    "shards_acknowledged": true
}

默認(rèn)情況下,索引創(chuàng)建命令會(huì)在每個(gè)primary shard的replica shard 開始進(jìn)行復(fù)制后,或者是請(qǐng)求超時(shí)之后,返回響應(yīng)消息,如上。

acknowledged表示這個(gè)索引是否創(chuàng)建成功,shards_acknowledged表明了每個(gè)primary shard有沒有足夠數(shù)量的replica開始進(jìn)行復(fù)制。

可能這兩個(gè)參數(shù)會(huì)為false,但是索引依然可以創(chuàng)建成功。因?yàn)檫@些參數(shù)僅僅是表明在請(qǐng)求超時(shí)之前,這兩個(gè)操作有沒有成功,也有可能請(qǐng)求超時(shí)了,在超時(shí)前都沒成功,但是實(shí)際上Elasticsearch Server端接收到了消息,并且都執(zhí)行了,只是響應(yīng)前還沒來得及執(zhí)行,所以響應(yīng)的是false。

刪除索引

curl -XDELETE 'http://elasticsearch02:9200/music?pretty'

查詢索引設(shè)置信息

curl -XGET 'http://elasticsearch02:9200/music?pretty'

打開/關(guān)閉索引

curl -XPOST 'http://elasticsearch02:9200/music/_close?pretty'
curl -XPOST 'http://elasticsearch02:9200/music/_open?pretty'

如果一個(gè)索引關(guān)閉了,那么這個(gè)索引就沒有任何的性能開銷了,只要保留這個(gè)索引的元數(shù)據(jù)即可,然后對(duì)這個(gè)索引的讀寫操作都不會(huì)成功。一個(gè)關(guān)閉的索引可以接著再打開,打開以后會(huì)進(jìn)行shard recovery過程。

如果集群數(shù)據(jù)定時(shí)有備份,在執(zhí)行恢復(fù)的操作之前,必須將待恢復(fù)的索引關(guān)閉,否則恢復(fù)會(huì)報(bào)失敗。

壓縮索引

我們知道索引的primary shard數(shù)量在創(chuàng)建時(shí)一旦指定,后期就不能修改了,但是有一個(gè)這樣的情況:預(yù)估的shard數(shù)量在實(shí)際生產(chǎn)之后,發(fā)現(xiàn)估算得有點(diǎn)高,比如原來設(shè)置number_of_shards為8,結(jié)果生產(chǎn)上線后發(fā)現(xiàn)數(shù)據(jù)量沒那么大,我想把這個(gè)索引的primary shard壓縮一下,該如何操作呢?

shrink命令的作用就是對(duì)索引進(jìn)行壓縮的,不過有個(gè)限制:壓縮后的shard數(shù)量必須可以被原來的shard數(shù)量整除。如我們的8個(gè)primary shard的index可以只能被壓縮成4個(gè),2個(gè),或者1個(gè)primary shard的index。

shrink命令的工作流程:
  1. 創(chuàng)建一個(gè)跟source index的定義一樣的target index,但是唯一的變化就是primary shard變成了指定的數(shù)量。
  2. 將source index的segment file直接用hard-link的方式連接到target index的segment file,如果操作系統(tǒng)不支持hard-link,那么就會(huì)將source index的segment file都拷貝到target index的data dir中,會(huì)很耗時(shí)。如果用hard-link會(huì)很快。
  3. target index進(jìn)行shard recovery恢復(fù)。
案例演示
  1. 我們創(chuàng)建一個(gè)number_of_shards為8的索引,名稱為music8
curl -XPUT 'http://elasticsearch02:9200/music8?pretty' -H 'Content-Type: application/json' -d '
{
    "settings" : {
        "index" : {
            "number_of_shards" : 8, 
            "number_of_replicas" : 2 
        }
    },
    "mappings" : {
        "children" : {
            "properties" : {
                "name" : { "type" : "text" }
            }
        }
    }
}'
  1. 在索引內(nèi)灌點(diǎn)數(shù)據(jù)進(jìn)去
  2. 將索引的shard都移到一個(gè)node上去,如node1
curl -XPUT 'http://elasticsearch02:9200/music8/_settings?pretty' -H 'Content-Type: application/json' -d '
{
  "settings": {
    "index.routing.allocation.require._name": "node-1", 
    "index.blocks.write": true 
  }
}'

這個(gè)過程叫shard copy relocate,使用

`curl -XGET 'http://elasticsearch02:9200/_cat/recovery?v'

可以查看該過程的進(jìn)度。

  1. 執(zhí)行shrink命令,新的索引名稱為music9
curl -XPOST 'http://elasticsearch02:9200/music8/_shrink/music9?pretty' -H 'Content-Type: application/json' -d '
{
  "settings": {
    "index.number_of_shards": 2, 
    "index.number_of_replicas": 1,
    "index.codec": "best_compression" 
  }
}'

執(zhí)行完成后,可以看到music9的shard數(shù)據(jù)變化了,并且擁有music8所有的數(shù)據(jù)。

  1. 將別名指向新的music9索引,客戶端訪問無感知。

rollover索引

我們最常見的日志索引,需要每天創(chuàng)建一個(gè)新的帶日期的索引,但客戶端又使用同一個(gè)alias進(jìn)行寫入,此時(shí)可以用rollover命令將alias重置到這個(gè)新的索引上。

假設(shè)log_write別名已經(jīng)存在,示例命令:

curl -XPOST 'http://elasticsearch02:9200/log_write/_rollover/log-20120122
-H 'Content-Type: application/json' -d '
{
  "conditions": {
    "max_age":   "1d"
  }
}'

用crontab定時(shí)每天執(zhí)行一次,并且將日期部分用shell腳本進(jìn)行參數(shù)化,這樣每天都創(chuàng)建一個(gè)帶日期的索引名字,而客戶端那邊一直使用log_write別名作寫入操作,對(duì)日志系統(tǒng)非常實(shí)用。

索引mapping管理

索引的mapping管理是非?;A(chǔ)的操作,我們可以在創(chuàng)建索引時(shí)定義mapping信息,也可以在索引創(chuàng)建成功后執(zhí)行增加字段操作。

列舉以下幾個(gè)常用示例:

查看索引的mapping信息

curl -XGET 'http://elasticsearch02:9200/music/_mapping/children?pretty'

查看索引指定field的mapping信息

curl -XGET 'http://elasticsearch02:9200/music/_mapping/children/field/content?pretty'

創(chuàng)建索引時(shí)帶上mapping信息

# 節(jié)省篇幅,省略大部分字段
curl -XPUT 'http://elasticsearch02:9200/music?pretty' -H 'Content-Type: application/json' -d ' 
{
  "mappings": {
    "children": {
      "properties": {
        "content": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        }
      }
    }
  }
}'

為索引增加一個(gè)字段name,類型為text

curl -XPUT 'http://elasticsearch02:9200/music/_mapping/children?pretty' -H 'Content-Type: application/json' -d ' 
{
  "properties": {
    "name": {
      "type": "text"
    }
  }
}'

索引別名

客戶端訪問Elasticsearch的索引時(shí),規(guī)范化操作都不會(huì)直接使用索引名稱,而是使用索引別名,索引別名能夠起到封裝Elasticsearch真實(shí)索引的作用,像上面的rollover操作,索引重建操作,別名起到了非常關(guān)鍵的作用。

我們來簡(jiǎn)單看一下索引的基本操作:

# 創(chuàng)建索引別名
curl -XPOST 'http://elasticsearch02:9200/_aliases?pretty' -H 'Content-Type: application/json' -d '
{
    "actions" : [
        { "add" : { "index" : "music", "alias" : "music_prd" } }
    ]
}'
# 刪除索引別名
curl -XPOST 'http://elasticsearch02:9200/_aliases?pretty' -H 'Content-Type: application/json' -d '
{
    "actions" : [
        { "remove" : { "index" : "music", "alias" : "music_prd" } }
    ]
}'
# 重命名別名:先刪掉后添加
curl -XPOST 'http://elasticsearch02:9200/_aliases?pretty' -H 'Content-Type: application/json' -d '
{
    "actions" : [
        { "remove" : { "index" : "music", "alias" : "music_prd" } },
        { "add" : { "index" : "music2", "alias" : "music_prd" } }
    ]
}'
# 多個(gè)索引綁定一個(gè)別名
curl -XPOST 'http://elasticsearch02:9200/_aliases?pretty' -H 'Content-Type: application/json' -d '
{
    "actions" : [
        { "add" : { "indices" : ["music1", "music2"], "alias" : "music_prd" } }
    ]
}'

索引setting修改

查看索引setting信息:

curl -XGET 'http://elasticsearch02:9200/music/_settings?pretty'

修改setting信息:

curl -XPUT 'http://elasticsearch02:9200/music/_settings?pretty' -H 'Content-Type: application/json' -d '
{
    "index" : {
        "number_of_replicas" : 1
    }
}'

setting最常見的修改項(xiàng)就是replicas的數(shù)量,其他的參數(shù)修改的場(chǎng)景不是特別多。

索引template

假設(shè)我們正在設(shè)計(jì)日志系統(tǒng)的索引結(jié)構(gòu),日志數(shù)據(jù)量較大,可能每天創(chuàng)建一個(gè)新的索引,索引名稱按日期標(biāo)記,但別名是同一個(gè),這種場(chǎng)景就比較適合使用index template。

我們舉個(gè)示例,先創(chuàng)建一個(gè)索引模板:

curl -XPUT 'http://elasticsearch02:9200/_template/template_access_log?pretty' -H 'Content-Type: application/json' -d '
{
  "template": "access-log-*",
  "settings": {
    "number_of_shards": 2
  },
  "mappings": {
    "log": {
      "_source": {
        "enabled": false
      },
      "properties": {
        "host_name": {
          "type": "keyword"
        },
        "thread_name": {
          "type": "keyword"
        },
        "created_at": {
          "type": "date",
          "format": "YYYY-MM-dd HH:mm:ss"
        }
      }
    }
  },
  "aliases" : {
      "access-log" : {}
  }
}'

索引名稱符合"access-log-*"將使用該模板,我們創(chuàng)建一個(gè)索引:

curl -XPUT 'http://elasticsearch02:9200/access-log-01?pretty'

查看該索引:

curl -XGET 'http://elasticsearch02:9200/access-log-01?pretty'

可以看到如下結(jié)構(gòu):

[esuser@elasticsearch02 bin]$ curl -XGET 'http://elasticsearch02:9200/access-log-01?pretty'
{
  "access-log-01" : {
    "aliases" : {
      "access-log" : { }
    },
    "mappings" : {
      "log" : {
        "_source" : {
          "enabled" : false
        },
        "properties" : {
          "created_at" : {
            "type" : "date",
            "format" : "YYYY-MM-dd HH:mm:ss"
          },
          "host_name" : {
            "type" : "keyword"
          },
          "thread_name" : {
            "type" : "keyword"
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "creation_date" : "1581373546223",
        "number_of_shards" : "2",
        "number_of_replicas" : "1",
        "uuid" : "N8AHh3wITg-Zh4T6umCS2Q",
        "version" : {
          "created" : "6030199"
        },
        "provided_name" : "access-log-01"
      }
    }
  }
}

說明使用了模板的內(nèi)容。

當(dāng)然也有命令可以查看和刪除template:

curl -XGET 'http://elasticsearch02:9200/_template/template_access_log?pretty'

curl -XDELETE 'http://elasticsearch02:9200/_template/template_access_log?pretty'

索引常用查詢

索引操作統(tǒng)計(jì)查詢

發(fā)生在索引上的所有CRUD操作,Elasticsearch都是會(huì)做統(tǒng)計(jì)的,而且統(tǒng)計(jì)的內(nèi)容非常翔實(shí),我們可以使用這條命令:

curl -XGET 'http://elasticsearch02:9200/music/_stats?pretty'

內(nèi)容非常詳細(xì),有好幾百行,從doc的數(shù)據(jù)和占用的磁盤字節(jié)數(shù),到get、search、merge、translog等底層數(shù)據(jù)應(yīng)有盡有。

segment信息查詢

索引下的segment信息,可以使用這條命令進(jìn)行查詢:

curl -XGET 'http://elasticsearch02:9200/music/_segments?pretty'

內(nèi)容也同樣挺多,我們摘抄出關(guān)鍵的部分做個(gè)示例:

"segments" : {
  "_1" : {
    "generation" : 1,
    "num_docs" : 1,
    "deleted_docs" : 0,
    "size_in_bytes" : 7013,
    "memory_in_bytes" : 3823,
    "committed" : true,
    "search" : true,
    "version" : "7.3.1",
    "compound" : true,
    "attributes" : {
      "Lucene50StoredFieldsFormat.mode" : "BEST_SPEED"
    }
  }
}

這個(gè)片段表示名稱為_1的segment的信息。詳細(xì)如下:

  • _1:segment的名稱
  • generation:segment的自增長(zhǎng)ID
  • num_docs:segment中沒有被刪除的document的數(shù)量
  • deleted_docs:segment中被刪除的document數(shù)量
  • size_in_bytes:segment占用的磁盤空間
  • memory_in_bytes:segment會(huì)將一些數(shù)據(jù)緩存在內(nèi)存中,這個(gè)數(shù)值就是segment占用的內(nèi)存的空間大小
  • committed:segment是否被sync到磁盤上去了
  • search:segment是否可被搜索,如果這個(gè)segment已經(jīng)被sync到磁盤上,但是還沒有進(jìn)行refresh,值為false
  • version:lucene的版本號(hào)
  • compound:true表示lucene已將這個(gè)segment所有的文件都merge成了一個(gè)文件
shard存儲(chǔ)信息

查看索引下shard的存儲(chǔ)情況,分布在哪個(gè)node上,這條命令還是挺有用處的:

curl -XGET 'http://elasticsearch02:9200/music/_shard_stores?status=green&pretty'

摘抄了一個(gè)片段,3表示shard的id:

"3" : {
  "stores" : [
    {
      "A1s1uus7TpuDSiT4xFLOoQ" : {
        "name" : "node-2",
        "ephemeral_id" : "Q3uoxLeJRnWQrw3E2nOq-Q",
        "transport_address" : "192.168.17.137:9300",
        "attributes" : {
          "ml.machine_memory" : "3954196480",
          "rack" : "r1",
          "xpack.installed" : "true",
          "ml.max_open_jobs" : "20",
          "ml.enabled" : "true"
        }
      },
      "allocation_id" : "o-t-AwGZRrWTflYLP030jA",
      "allocation" : "primary"
    },
    {
      "RGw1IXzZR4CeZh9FUrGHDw" : {
        "name" : "node-1",
        "ephemeral_id" : "B1pv6c4TRuu1vQNvL40iPg",
        "transport_address" : "192.168.17.138:9300",
        "attributes" : {
          "ml.machine_memory" : "3954184192",
          "rack" : "r1",
          "ml.max_open_jobs" : "20",
          "xpack.installed" : "true",
          "ml.enabled" : "true"
        }
      },
      "allocation_id" : "SaXqL8igRUmLAoBBQyQNqw",
      "allocation" : "replica"
    }
  ]
},
補(bǔ)充幾個(gè)操作
  1. 清空索引緩存

curl -XPOST 'http://elasticsearch02:9200/music/_cache/clear?pretty'

  1. 強(qiáng)制flush

強(qiáng)行將os cache里的數(shù)據(jù)強(qiáng)制fsync到磁盤上去,同時(shí)還會(huì)清理掉translog中的日志

curl -XPOST 'http://elasticsearch02:9200/music/_flush?pretty'

  1. refresh操作

顯式地刷新索引,讓在自動(dòng)refresh前的所有操作變成可見

curl -XPOST 'http://elasticsearch02:9200/music/_flush?pretty'

  1. force merge

強(qiáng)制合并segment file,可以減小segment的數(shù)量
curl -XPOST 'http://elasticsearch02:9200/music/_forcemerge?pretty'

以上4個(gè)操作,一般是由Elasticsearch自動(dòng)去執(zhí)行,非特殊情況下不需要人工干預(yù)。

小結(jié)

本篇從運(yùn)維角度簡(jiǎn)單介紹了一下索引的一些日常操作與管理,能夠熟練應(yīng)用的話,可以提升操縱索引的效率。

專注Java高并發(fā)、分布式架構(gòu),更多技術(shù)干貨分享與心得,請(qǐng)關(guān)注公眾號(hào):Java架構(gòu)社區(qū)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容