另一个分片分配相关的属性是cluster.routing.allocation.disk.threshold_enabled。如果该属性设备为true(默认值),在分配分片到一个节点时将会把可用的磁盘空间算入配额内。关闭该属性会导致ES可能分配分片到一个磁盘可用空间不足的节点,从而影响分片的增长。
当打开时,分片分配会将两个阀值属性加入配额:低水位和高水位。
低水位定义ES将不再分配新分片到该节点的磁盘使用百分比。(默认是85%)高水位定义分配将开始从该节点迁移走分片的磁盘使用百分比。(默认是90%)
这两个属性都可以被定义为磁盘使用的百分比(比如“80%”表示80%的磁盘空间已使用,或者说还有20%未使用),或��最小可用空间大小(比如“20GB”表示该节点还有20GB的可用空间)。
如果有很多的小分片,那么默认值就非常保守了。举个例子,如果有一个1TB的硬盘,分片是典型的10GB大小,那么理论上可以在该节点上分配100个分片。在默认设置的情况下,只能分配80个分片到该节点上,之后ES就认为这个节点已经满了。
为得到适合的配置参数,应该看看分片到底在变多大之后会结束他们的生命周期,然后从这里反推,确认包括一个安全系数。在上面的例子中,只有5个分片写入,所以需要一直确保有50GB的可用空间。对于一个1TB的硬盘,这个情形会变成95%的低水位线,并且没有安全系数。额外的,比如一个50%的安全系数,意味着应该确保有75GB的可以空间,或者一个92.5%的低水位线。
小贴士8:Recovery属性允许快速重启
ES有很多恢复相关的属性,可以提升集群恢复和重启的速度。最佳属性设置依赖于当前使用的硬件(硬盘和网络是最常见的瓶颈),我们能给出的最好建议是测试、测试、还是测试。
想控制多少个分片可以在单个节点上同时恢复,使用:
cluster.routing.allocation.node_concurrent_recoveries恢复分片是一个IO非常密集的操作,所以应当谨慎调整该值。在5.x版本中,该属性分为了两个:
cluster.routing.allocation.node_concurrent_incoming_recoveries cluster.routing.allocation.node_concurrent_outgoing_recoveries想控制单个节点上的并发初始化主分片数量,使用:
cluster.routing.allocation.node_initial_primaries_recoveries想控制恢复一个分片时打开的并行流数量,使用:
indices.recovery.concurrent_streams与流数量密切相关的,是用于恢复的总可用网络带宽:
indices.recovery.max_bytes_per_sec除了所有这些属性,最佳配置将依赖于所使用的硬件。如果有SSD硬盘以及万兆光纤网络,那么最佳配置将完全不同于使用普通磁盘和千兆网卡。
以上所有属性都将在集群重启后生效。
小贴士9:线程池属性防止数据丢失
ElasticSearch节点有很多的线程池,用于提升一个节点中的线程管理效率。
在Loggly,索引时使用了批量操作模式,并且我们发现通过threadpool.bulk.queue_size属性为批量操作的线程池设置正确的大小,对于防止因批量重试而可能引起的数据丢失是极其关键的。
threadpool.bulk.queue_size: 5000这会告诉ES,当没有可用线程来执行一个批量请求时,可排队在该节点执行的分片请求的数量。该值应当根据批量请求的负载来设置。如果批量请求数量大于队列大小,就会得到一个下文展示的RemoteTransportException异常。
正如上文所述,一个分片包含一个批量操作队列,所以这个数字需要大于想发送的并发批量请求的数量与这些请求的分片数的乘积。例如,一个单一的批量请求可能包含10个分片的数据,所以即使只发送一个批量请求,队列大小也必须至少为10。这个值设置太高,将会吃掉很多JVM堆空间(并且表明正在推送更多集群无法轻松索引的数据),但确实能转移一些排队情况到ES,简化了客户端。
既要保持属性值高于可接受的负载,又要平滑地处理客户端代码的RemoteTransportException异常。如果不处理该异常,将会丢失数据。我们模拟使用一个大小为10的队列来发送大于10个的批处理请求,获得了以下所示异常。
RemoteTransportException[[<Bantam>][inet[/192.168.76.1:9300]][bulk/shard]]; nested: EsRejectedExecutionException[rejected execution (queue capacity 10) on org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction$AsyncShardOperationAction$1@13fe9be];为2.0版本以前的用户再赠送一个小贴士:最小化Mapping刷新时间
如果你仍在使用2.0版本以前的ES,且经常会更新属性mapping,那么可能会发现集群的任务等待队列有一个较大的refresh_mappings请求数。对它自身来说,这并不坏,但可能会有滚雪球效应严重影响集群性能。
如果确实遇到这种情况,ES提供了一个可配置参数来帮助应对。可按下述方式使用该参数:
indices.cluster.send_refresh_mapping: false那么,这是怎么个意思,为什么可以凑效?