基于磁盘容量的shard分配策略(Disk-based shard allocation)默认就是开启的,其机制也非常简单,主要就是3条非常重要的分水线(watermark):
low watermark:默认值是85%。磁盘使用超过这个阈值,就认为“危险”快来了,这个时候就不会往该节点再分配replica shard了,但新创建的索引的primary shard还是可以分配。特别注意必须是新创建的索引(什么是“老的”?比如再平衡时其它节点上已经存在的primary shard就算老的,这部分也是不能够迁移到进入low watermark的节点上来的)。high watermark:默认值是90%。磁盘使用超过这个阈值,就认为“危险”已经来了,这个时候不会再往该节点分配任何shard,即primary shard和replica shard都不会分配。并且会开始尝试将节点上的shard迁移到其它节点上。flood stage watermark:默认值是95%。磁盘使用超过这个阈值,就认为已经病入膏肓了,需要做最后的挽救了,挽救方式也很简单——断臂求生:将有在该节点上分配shard的所有索引设置为只读,不允许再往这些索引写数据,但允许删除索引(index.blocks.read_only_allow_delete)。
大概总结一下:
当进入low watermark的时候,就放弃新创建的索引的副本分片数据了(即不创建对应的shard),但还是允许创建主分片数据;当进入high watermark的时候,新创建索引的主分片、副本分片全部放弃了,但之前已经创建的索引还是可以正常继续写入数据的;同时尝试将节点上的数据向其它节点迁移;当进入flood stage watermark,完全不允许往该节点上写入数据了,这是最后一道保护。只要在high watermark阶段,数据可以迁移到其它节点,并且迁移的速度比写入的速度快,那就不会进入该阶段。一些相关的配置如下:
cluster.routing.allocation.disk.threshold_enabled:是否开启基于磁盘的分配策略,默认为true,表示开启。cluster.info.update.interval:多久检查一次磁盘使用,默认值是30s。cluster.routing.allocation.disk.watermark.low:配置low watermark,默认85%。cluster.routing.allocation.disk.watermark.high:配置high watermark,默认90%。cluster.routing.allocation.disk.watermark.flood_stage:配置flood stage watermark,默认95%。
后面3个配置阈值的配置项除了可以使用百分比以外,也可以使用具体的值,比如配置为low watermark为10gb,表示剩余空闲磁盘低于10gb的时候,就认为到low watermark了。但是需要注意,要么3个配置项都配置百分比,要么都配置具体的值,不允许百分比和具体的值混用。
最后,如果节点进入flood stage watermark阶段,涉及的索引被设置成read-only以后,如何恢复呢?第一步当然是先通过删数据或增加磁盘/节点等方式让磁盘使用率降到flood stage watermark的阈值以下。然后第二步就是恢复索引状态,取消只读。在7.4.0及以后版本,一旦检测到磁盘使用率低于阈值后,会自动恢复;7.4.0以前的版本,必须手动执行以下命令来取消只读状态:
// 恢复单个索引PUT /索引名称/_settings{ "index.blocks.read_only_allow_delete": null}// 恢复所有索引PUT _settings{ "index": { "blocks": {"read_only_allow_delete": null} }}// curl命令curl -XPUT -H "Content-Type: application/json" http://localhost:9200/_all/_settings -d '{"index.blocks.read_only_allow_delete": null}'
PUT _cluster/settings{ "transient": { "cluster.routing.allocation.disk.watermark.low": "800mb", "cluster.routing.allocation.disk.watermark.high": "600mb", "cluster.routing.allocation.disk.watermark.flood_stage": "500mb", "cluster.info.update.interval": "10s" }}# 检查下磁盘使用GET _cat/nodes?v&h=n,dt,du,dupn dt du dupnode-43 1gb 328kb 0.03node-42 1gb 328kb 0.03
参考链接:http://niyanchun.com/es-disk-based-shard-allocation.html