说明
对一些常用的或在官网文档中不易找到的 ES 命令,做个简单整理,方便查找,想起时再做更新和维护。
Ps:大多命令为基于 5.4.2 版本 ES 集群。
Commands
索引缩容(减少主分片数)
es-5.4 官方文档 : https://www.elastic.co/guide/en/elasticsearch/reference/5.4/indices-shrink-index.html
首先,修改原索引 test 设置 : 索引设为只读状态;
PUT /test/_settings
{
"settings": {
"index.blocks.write": true
}
}
然后,创建目标索引 shrink_test , 并设置目标索引 shrink_test 的分片数和副本数;
目标索引 shrink_test 的分片数必须比原索引 test 的分片数小,且收缩后的分片数必须是原始分片数的一个因数:
如 原8个分片可收缩为 4、2、1,原分片数为素数(如7,11)则只能收缩为 1 个分片。
POST test/_shrink/shrink_test
{
"settings": {
"index.number_of_replicas": 1,
"index.number_of_shards": 1,
"index.codec": "best_compression"
},
"aliases": {
"test_alias": {}
}
}
执行命令后,可通过查看集群状态,判断索引是否已缩容结束,若成功缩容结束,原索引 test 仍存在且处于只读状态,可删除原索引。
索引扩容(增加主分片数)
注:
ES 5.x 版本索引不支持增加主分片数,除非通过 Reindex API 的方式重建索引;
ES 6.x 版本起,索引可支持增加主分片数,但有限制:不支持增量重新分片,本例子以 ES 6.7.2 版本为例。
Indices APIs » Split Index
es-6.7 官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/6.7/indices-split-index.html
说明
1、动态扩容分片,在索引创建时必须指定 index.number_of_routing_shards 参数,已创建好的索引,更新 settings 增加 routing_shards 参数或更新 routing_shards 参数,均无法动态扩容分片(即 es 不支持增量重新分片);
2、动态扩容分片时,必须将源索引阻塞写操作,扩容结束才能写
目的:防止 split 过程中出现问题,导致数据丢失
3、可以拆分索引的次数(以及每个原始分片可以拆分成的分片数)由 index.number_of_routing_shards 设置决定 。routing_shards 的数量指定内部使用的散列空间,以便在具有一致散列的分片中分发文档。例如, number_of_routing_shards 设置为 30(5 x 2 x 3)的5个分片索引 可以用因子2或3拆分。换句话说,它可以拆分如下:
-
5 → 10 → 30 (split by 2, then by 3)
-
5 → 15 → 30 (split by 3, then by 2)
-
5 → 30 (split by 6)
原理
拆分的工作原理如下(摘自官网):
-
首先,它创建一个新的目标索引,其定义与源索引相同,但主分片数量较多;
-
然后,它将源索引中的段硬链接到目标索引(如果文件系统不支持硬链接,则会将所有段复制到新索引中,这是一个更耗时的过程);
-
创建低级文件后,所有文档将hashed,已删除属于不同分片的文档。
-
最后,恢复目标索引,好像它是一个刚重新打开的封闭索引。
使用
创建源索引 & 阻塞写操作
PUT my_source_index
{
"settings": {
"index.number_of_shards": 2,
"index.number_of_routing_shards": 30,
"index.blocks.write": true
}
}
动态扩容分片 & 设置别名
目标索引的分片数必须是 routing_shards 的一个公约数,且大于源索引的分片数。
POST my_source_index/_split/my_target_index?copy_settings=true
{
"settings":{
"index.number_of_shards": 10,
"index.number_of_routing_shards": 30,
},
"aliases":{
"split_index":{}
}
}
拆分索引前置条件
-
目标索引不得存在
-
索引必须具有比目标索引更少的主分片
-
目标索引中的主分片数必须是源索引中 routing_shards 的一个因子
-
处理拆分进程的节点必须具有足够的可用磁盘空间,以容纳现有索引的第二个副本
数据迁移(Reindex)
索引数据迁移的要求
1、索引在数据迁移期间,不可有数据变动(新增、删除、更新),否则变动的数据无法迁移到新索引中;
数据迁移开始时,es会在此时此刻生成一个快照,之后的数据变动,无法体现在快照中,也就无法迁移到新索引中
2、索引在数据迁移期间,有数据变动,但业务可通过重跑任务对迁移期间的数据变动在新索引进行重放,也可以进行迁移;
3、索引在数据迁移期间,有数据变动,且业务无法满足第2点要求,那么如果索引只有数据新增,且索引中有字段,可根据此字段进行范围迁移(如时间字段,则可只迁移2020年这一年的数据到新索引),那么可先将大部分数据迁至新索引,最后业务停写任务,将剩余的少部分数据迁移新索引后,直接写新索引;
4、以上要求均无法满足,则不能进行数据迁移。
使用
# 多并发迁移数据
# slices 设置可根据索引的主分片数来设置,如索引主分片数为5,则 slices=4 表示有5个并发同时进行数据迁移
POST _reindex?slices=2
{
"source":{
"index":"index_one", // 源索引名称
"size":5000, // 这里的 size ,表示只迁移 5k 条数据,一般不进行此设置;批量删除时同样支持指定size(即删除指定条数的文档)
# 迁移条件,无则默认迁移所有数据
"query":{
"range":{
"time":{
"gte":"xxxx",
"lte":"xxxx"
}
}
}
},
"dest":{
"index":"index_two" // 目标索引名称
}
}
# 查看当前所有的迁移任务(detailed=true 表示返回任务详细信息)
GET _tasks?detailed=true&actions=*reindex
# 取消某个迁移任务
POST _tasks/node_id:task_id/_cancel
# 取消全部的迁移任务
POST _tasks/_cancel?actions=*reindex
# 取消全部的删除数据任务
POST _tasks/_cancel?actions=*delete/byquery
调整 ES 集群索引分片分配权重
index 权重高,表示优先将索引分片分配到不同的节点上;
shard 权重高,表示优先将索引分片分配到节点分片数较少的节点上;
两者相加必须等于 1;
es 默认,index 0.55,shard 0.45
PUT _cluster/settings
{
"transient": {
"cluster": {
"routing": {
"allocation.balance.index":0.9,
"allocation.balance.shard":0.1
}
}
}
}
same_shard.host
PUT _cluster/settings
{
"persistent": {
"cluster": {
"routing": {
"allocation.same_shard.host": true
}
}
}
}
这个命令用于单机多实例,作用:保证主分片和副本不会同时分配在一个节点上;
这样单机多实例的节点,也可以直接停机下线。
索引分片延迟分配
PUT _all/_settings
{
"index.unassigned.node_left.delayed_timeout":"30m"
}
这个命令用于延时恢复未分配的分片,默认一分钟;
在进行集群节点滚动重启时可适当延长此时间以防止分片拷贝动作的发生,减少集群资源浪费。
元数据变化耗时记录
PUT _cluster/settings
{
"persistent": {
"cluster": {
"service":{
"slow_task_logging_threshold":"10ms"
}
}
}
}
设置 master 参数,可以查看日志中元数据耗时时长,重新选举master后,下发元数据的时间,与日志中此项打印的耗时差不多。
查询索引特定分片
查询索引特定某个分片的数据:https://www.elastic.co/guide/en/elasticsearch/reference/5.4/search-request-preference.html
GET index/_search?preference=_prefer_nodes:node1
_primary : 只在主分片执行
_primary_first : 在主分片执行,如主分片不可用,在其他分片执行
_replica : 只在副本上执行
_replica_first : 在副本上执行,如果不可用,在其他分片执行
_local : 优先在本地分配的分片上执行
_prefer_nodes : 如适用,优先在提供的节点name上执行
_shards : 将操作限制为指定的分片;可与其他选项结合使用,但必须首先显示,eg:_shards:2,3|_primary
_only_nodes : 将操作限制为指定的节点,后跟节点name
GET _nodes : 返回节点ID,等其余节点信息
查询 fielddate
GET _cat/nodes?v&h=name,sm,fm&s=sm:desc
sm:段数目 fm:fielddate
GET _cat/fielddata?v&h=id,node,field,size&s=size:desc
GET /_stats/fielddata?fields=* //各个分片、索引的fielddata在内存中的占用情况
GET /_nodes/stats/indices/fielddata?fields=* //每个node的fielddata在内存中的占用情况
GET /_nodes/stats/indices/fielddata?level=indices&fields=* //每个node中的每个索引的fielddata在内存中的占用情况
查询各索引占用的内存大小
查看各个索引占用的es内存大小:
GET _cat/indices?v&h=i,pri.memory.total,memory.total&s=memory.total:desc
命令简写: GET _cat/indices?v&h=i,pri.memory.total,tm&s=tm:desc
帮助命令:GET _cat/indices?help
health | h | current health status
status | s | open/close status
index | i,idx | index name
uuid | id,uuid | index uuid
pri | p,shards.primary,shardsPrimary | number of primary shards
rep | r,shards.replica,shardsReplica | number of replica shards
docs.count | dc,docsCount | available docs
docs.deleted | dd,docsDeleted | deleted docs
creation.date | cd | index creation date (millisecond value)
creation.date.string | cds | index creation date (as string)
store.size | ss,storeSize | store size of primaries & replicas
pri.store.size | | store size of primaries
memory.total | tm,memoryTotal | total used memory
pri.memory.total | | total user memory
GET _cat/indices?v&h=i,p,r,dc,ss,tm,cds,ss
强制段合并 forcemerge
POST index/_forcemerge
POST index/_forcemerge?max_num_segments=1
POST index/_forcemerge?only_expunge_deletes=true
强制合并API接受以下请求参数:
max_num_segments:合并到的段数。要完全合并索引,请将其设置为1。默认值是将段数目合并为一半。
only_expunge_deletes:
在Lucene中,不会从段中删除文档,而只是将其标记为已删除。在段的合并过程中,将创建一个没有这些删除的新段。
此标志仅允许合并具有删除的段。默认为false。请注意,这不会超过 index.merge.policy.expunge_deletes_allowed 阈值。
index.merge.policy.expunge_deletes_allowed:默认值为10,该值用于确定被删除文档的百分比,当执行expungeDeletes时,该参数值用于确定索引段是否被合并。
flush:强制合并后是否应该执行刷新。默认为 true。
查看索引默认参数信息
GET index/_settings?include_defaults=true