了解ES之前应该先了解他的底层luncene参考我这篇文章
luncene写入流程
首先luncene的写入数据流程是每一条数据先写入buffer中然后生成一个segment,将每一个segment文件flush到硬件系统。再buffer写入到文件系统生成segment时是会先生成一个translog文件来保证文件写入的成功性。当失败则通过translog文件从新写入。每一个segment文件都会记录在 commit文件中。至于什么时候写入到本地文件取决于seg的条数或者translog的大小等自定义。每次 index、bulk、delete、update 完成的时候,一定触发刷新 translog 到磁盘上。如果不保证靠可行而提高性能考虑可以设置
{
"index.translog.durability": "async"
}
ElasticSearch写入流程
而对于ES而言首先就是对于集群而言,而不是单个机器。这时index就是面向集群,而一个单个机器的index就是现在的shard.可知每一个buffer就是一个sengment这时就会影响存储和建索的性能。对于ES而言就是合并segment及归并操作,策略可以通过segment的大小和个数来合并。当然合并 的次数也会降低系统的性能因此可以通过forcemerge 接口来人为的设置合并的次数.
ElasticSearch确认数据位置
数据的存储规则时
shard = hash(routing) % number_of_primary_shards
及每条数据都有一个id然后通过分片的次数来确定数据存储的位置。
然后设计到集群还会有另一个概念就是副本来确保数据的一致性,这里可以理解为hadoop中的namenode和secondnamenode.
ES参数详细控制
cluster.routing.allocation.enable
该参数用来控制允许分配哪种分片。默认是 all。可选项还包括 primaries 和 new_primaries。none 则彻底拒绝分片。该参数的作用,本书稍后集群升级章节会有说明。
cluster.routing.allocation.allow_rebalance
该参数用来控制什么时候允许数据均衡。默认是 indices_all_active,即要求所有分片都正常启动成功以后,才可以进行数据均衡操作,否则的话,在集群重启阶段,会浪费太多流量了。
cluster.routing.allocation.cluster_concurrent_rebalance
该参数用来控制集群内同时运行的数据均衡任务个数。默认是 2 个。如果有节点增减,且集群负载压力不高的时候,可以适当加大。
cluster.routing.allocation.node_initial_primaries_recoveries
该参数用来控制节点重启时,允许同时恢复几个主分片。默认是 4 个。如果节点是多磁盘,且 IO 压力不大,可以适当加大。
cluster.routing.allocation.node_concurrent_recoveries
该参数用来控制节点除了主分片重启恢复以外其他情况下,允许同时运行的数据恢复任务。默认是 2 个。所以,节点重启时,可以看到主分片迅速恢复完成,副本分片的恢复却很慢。除了副本分片本身数据要通过网络复制以外,并发线程本身也减少了一半。当然,这种设置也是有道理的——主分片一定是本地恢复,副本分片却需要走网络,带宽是有限的。从 ES 1.6 开始,冷索引的副本分片可以本地恢复,这个参数也就是可以适当加大了。
indices.recovery.concurrent_streams
该参数用来控制节点从网络复制恢复副本分片时的数据流个数。默认是 3 个。可以配合上一条配置一起加大。
indices.recovery.max_bytes_per_sec
该参数用来控制节点恢复时的速率。默认是 40MB。显然是比较小的,建议加大。
也可以通过reroute 接口去人为的控制分片。
Elasticsearch冷热数据的读写分离
Elasticsearch 集群一个比较突出的问题是: 用户做一次大的查询的时候, 非常大量的读 IO 以及聚合计算导致机器 Load 升高, CPU 使用率上升, 会影响阻塞到新数据的写入, 这个过程甚至会持续几分钟。所以,可能需要仿照 MySQL 集群一样,做读写分离。
实施方案
N 台机器做热数据的存储, 上面只放当天的数据。这 N 台热数据节点上面的 elasticsearc.yml 中配置 node.attr.tag: hot
之前的数据放在另外的 M 台机器上。这 M 台冷数据节点中配置 node.attr.tag: stale