基於ES 7.7, 官方文檔 https://www.elastic.co/guide/en/elasticsearch/reference/7.x/indices.html#indices
上半篇: https://my.oschina.net/abensky/blog/5280911
0x06 Shrink index
收縮索引, 減少主分片的數量.
POST /<index>/_shrink/<target_index>
在執行shrink之前要求:
- 索引必須是只讀的(read-only)
- 索引的所有主分片必須在一個節點上(All primary shards for the index must reside on the same node.)
- 索引的健康狀態必須是 green.
- 目標索引不存在
爲了更容易的進行分片的分配操作, 建議移除該索引的副本分片, 然後再重新添加副本分片.
可以用下面的更新索引設置api來移除副本分片, 把餘下的分片重新定位到同一個節點, 並設置爲只讀:
# 移除副本分片, 並把餘下的分片重新定位到同一個節點
PUT /<source_index_name>/_settings
{
"settings":{
"index.number_of_replicas":0,
"index.routing.allocation.require._name":"shrink_node_name",
"index.blocks.write":true
}
}
- index.number_of_replicas = 0: 移除副本分片
- index.routing.allocation.require._name = shrink_node_name : 重新定位索引的分片到
shrink_node_name
節點 - 阻止對該索引的寫操作. 但是元數據(metadata)的修改操作, 比如刪除索引 ,仍然是允許的.
目標主分片數量必須是原數量的因子. 比如, 原來是8個那麼可以收縮成4/2/1個, 原來是15個key收縮成5/3/1個, 如果原來的個數是一個質數則只能收縮成1個.
如果目標索引主分片數量是1, 則要求源索引的文檔數量不能超過單個分片的最大文檔數量限制 2,147,483,519。
收縮操作的過程:
-
- 按照源索引的定義創建一個新的索引, 但是主分片數量更少
-
- 將segments從源索引硬連接(hard link)到新的索引.(如果文件系統不支持hard link就會執行復制操作, 更消耗時間; 而且 hard link不支持跨硬盤操作, 分佈在多個路徑下的分片也會執行復制操作)
-
- 恢復新的索引, 就好像是一個closed的索引被重新打開了.
感覺這個操作與MySQL中的"optimize table xxx"類似, 會重建整個表, 以shrink表空間.
收縮操作:
# 收縮操作: shrink(默認主副分片數都是1), 並清除來自源索引的設置
POST /<source_index_name>/_shrink/<target_index_name>
{
"settings": {
"index.routing.allocation.require._name": null,
"index.blocks.write": null
}
}
當前默認的主分片和副本分片數量都是1 index.routing.allocation.require._name = null 表示清除來自源索引的定位的要求 index.blocks.write = null 表示清除來自源索引的禁止寫設置 不需要特別指定mappings,會從源索引複製??
可以像create操作一樣設置別名.
請求提交後, 一旦目標索引添加到集羣的狀態中就會立即返回結果, 它不會等待shrink操作真正開始, 所以, 我們需要監視shrink的進度.
更多請參考官方文檔
一個完整的操作代碼如下:
# Shrink an index
DELETE /test4,test4_new
## 創建源索引
PUT /test4
{
"settings": {
"index.number_of_shards": 8,
"index.number_of_replicas": 1
}
,"mappings": {
"properties": {
"name": {
"type": "text"
}
}
}
}
GET /test4
## 準備
PUT /test4/_settings
{
"settings": {
"index.number_of_replicas": 0,
"index.routing.allocation.require._name": "shrink_node_name",
"index.blocks.write": true
}
}
## Shrink執行
# > 默認的主分片和副本分片的數量都是1
# > 可以像create操作一樣指定別名
POST /test4/_shrink/test4_new
{
"settings": {
"index.routing.allocation.require._name": null,
"index.blocks.write": null,
"index.number_of_replicas": 1,
"index.number_of_shards": 1,
"index.codec": "best_compression"
},
"aliases": {
"test4_new_alias": {}
}
}
那麼新的索引的名稱怎麼更名呢? 有個操作
_reindex
可以複製索引, 但是數據量大時會非常的耗費時間和資源, 所以建議使用別名!!! 而且親測win10下的 _reindex 操作無法複製!
POST /_reindex
{
"source": {"index": "test4_new"},
"dest": {"index": "test4_new2"}
}
# 這個複製操作後, test4_new2 找不到. 而且也不建議使用 _reindex
0x07 Split index
索引(的分片的)分隔, 把一個索引分割到一個新的有更多主分片的索引上.
POST /<source_index_name>/_split/<target_index_name>
{
"settings":{
"index.number_of_shards":2
}
}
要求:
- 源索引必須是只讀(read-only)狀態
- 集羣健康狀態必須是green
- 目標索引不存在
設置源索引爲不可寫狀態:
# 設置索引爲不可寫狀態
PUT /<source_index_name>/_settings
{
"settings":{
"index.blocks.write": true
}
}
阻止對該索引的寫操作. 但是元數據(metadata)的修改操作, 比如刪除索引 ,仍然是允許的.
描述
Split索引的過程, 其實就是把原來的主分片都分割成2個以上的主分片.
GET /test4_new?include_defaults=true 可以看到 index.number_of_routing_shards
未完待續。。。