马上注册,结交更多数据大咖,获取更多知识干货,轻松玩转大数据
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
前面在Elasticsearch原理(一):实时架构中已经介绍了关于Elasticsearch的实时部分架构,这片文章主要作为对前面Elasticsearch原理系列文章的补充,从Elasticsearch整体架构设计来深入了解Elasticsearch。
性能
首先是关于性能问题,前文也提到了Elasticsearch是可以做到近乎实时,这里就不过多介绍了,有兴趣的可以去上一篇实时架构了解。
索引文件的更新
数据写入Elasticsearch,形成索引文件(segments),索引文件用看来支持用户查询。Elasticsearch默认每一秒会形成一个segment,就是说一个小时会有3600个segments。这些segments组成完整的数据分片。
merge
对于新的数据,增加segment可以实现数据的写入。而对于修改和删除,同样是依赖新生成的segment来进行修改/删除。因为Lucene的segment一旦形成,是不允许再进行修改的,所以Elasticsearch中所谓的删除是通过在新的segment中打标记实现的,修改则是通过新segment中通过对已有doc的_version来控制的。只有在触发segments merge,对多个segments进行合并成一个大的segment时,才会真正意义上删除掉数据。
segments merge
Elasticsearch自己有一个算法会自动触发segments merge,因为每一秒生成一个文件意味着会有很多很多文件,这是受文件句柄数限制的,所以必定要进行merge。
归并流程:
通过算法触发segments merge,将多个小的segments合并成一个大的segment。这个过程由独立线程完成,对Elasticsearch的功能没有影响。
合并过程中删除掉执行delete/update操作的原始doc。
刷新新的segment到磁盘。
检索请求从小的segment转移到大的segment中。
等待所有请求都转移成功后,删除小的segments。
force merge
Elasticsearch也提供了API支持我们手动强制merge,但是要慎用,因为merge会占用很大的系统开销。
[AppleScript] 纯文本查看 复制代码 curl -XPOST "http://localhost:9200/library/_forcemerge?max_num_segments=1
参数说明:
max_num_segments 期望merge到多少个segments,1的意思是强行merge到1个segment
only_expunge_deletes 只做清理有deleted的segments,即瘦身
flush 清理完执行一下flush,默认是true
归并
上面介绍了,无论是主动merge还是被动merge,在merge的过程中对Elasticsearch的功能是不会有影响的,但即便如此,也要谨慎使用merge功能。因为merge过程需要消耗大量的磁盘io和cpu,对集群的性能影响非常大,在一个高峰期触发一个merge很有可能导致崩溃。
归并线程大小
5.x之前的版本,Elasticsearch对于归并的这个线程,做了限速处理,配置indices.store.throttle.max_bytes_per_sec,默认是20MB。对于转速很高的磁盘像SSD,建议配置100M以上。
5.x之后的版本,使用了 Lucene 的 CMS(ConcurrentMergeScheduler) 的 auto throttle 机制。已经不再需要indices.store.throttle.max_bytes_per_sec这个配置了。
归并线程数
配置index.merge.scheduler.max_thread_count,默认:Math.min(4, Runtime.getRuntime().availableProcessors() / 2))。意思就是当cpu核数的一半大于4时,最多启动4个线程,否则启动cpu核数一半的线程数。如果觉得性能吃紧,就降低点线程数。
参考:
https://github.com/elastic/elast ... ules/merge.asciidoc
早期版本默认值是:Math.min(3, Runtime.getRuntime().availableProcessors() / 2)
归并策略
归并线程是按照一定的运行策略来挑选 segment 进行归并的。主要有以下几条:
index.merge.policy.floor_segment
默认 2MB,小于这个大小的 segment,优先被归并。
index.merge.policy.max_merge_at_once
默认一次最多归并 10 个 segments
index.merge.policy.max_merge_at_once_explicit
默认 force merge 时一次最多归并 30 个 segments
index.merge.policy.max_merged_segment
默认 5 GB,大于这个大小的 segment,不用参与归并。force merge 除外。
从这里我们可以看出,对于实时性要求不高的场景,加大flush的间隔(默认1秒),让每次生成的segment都很大,这样能够减少merge的次数,从而实现是能上的调优。
routing
前面系列文章中已经介绍了Elasticsearch通过routing来对Lucene实现分布式,但并没有具体介绍是怎么通过routing来计算得出写拿个分片的,在这里做补充。
公式:
[AppleScript] 纯文本查看 复制代码 shard = hash(routing) % number_of_primary_shards
routing即我们写入数据时指定的_routing值,如过没有指定则按照_id值来计算。从公式上很容易看出首先是对routing进行hash,然后除以主分片数取余。得到的结果就是要写入的分片。
公式很简单但也造成了弊端,就是number_of_primary_shards,一旦在创建index时指定就不能再进行修改,否则计算结果就会发生变化,整个数据就乱了。
数据一致性
Elasticsearch实现了对Lucene的分布式架构,并加入的副本机制来保障数据的安全性。但Elasticsearch时如何保证主分片与副本分片之间数据一致呢?
如图:
首先一个写入请求发到node1,当然也可以发送到集群中的任何一个节点,这里拿node1举例。
node1接收到请求,根据_routing或_id来计算数据该写到哪个分片上,并且根据集群状态中的信息找到该分片的主分片在哪个节点上。找到知道发送数据到该节点。这里发送到node3。
node3接收到请求的时候,开始往主分片里写数据。
主分片写入完成后,转发请求到该分片的副本分片所在节点(node1、node2),并等待返回结果。
副本分片接收到请求后,开始写入,写入成功后会返回结果给主分片节点。
主分片节点(node3)接收到返回请求后,会把写入成功返回给node1。
这里有几个配置是可以控制上诉行为的。
wait_for_active_shards
等待副本分片返回个数,并不一定要等待所有副本分片全部返回。如果设置为1,则只要主分片写入成功,即返回给请求节点(node1),这个时候同时会转发请求给副本节点,但不再关系副本是否写入成功。
默认值是:int( (primary + number_of_replicas) / 2 ) + 1。
timeout
超时时间,可以理解为等待返回的超时时间。一般情况下等待返回不会太久,但如果集群出现问题,已经有部分分片不可用,很有可能就会超时。
默认值:60s
分片的分配
分片分配在哪个节点上并不是固定的,某种触发条件下,会导致分片所在节点变化。
创建index
删除index
副本分片数修改
节点数修改
第一个还好说,新建的索引一般数据量很少。后三个操作在数据量很大的情况下,会造成严重的性能影响。
Elasticsearch同样有参数来控制分片分配行为的,由于篇幅较长,这里另起一篇文章详细介绍。
参考:Elasticsearch干货(四):深入理解分片分配
集群自动发现
Elasticsearch集群采用的是peer-to-peer模式,使用gossip协议。除了集群状态的请求之外,像写入/查询这种请求是可以发送到任何一个节点上的。
Elasticsearch2.X之前,同一个集群使用一个cluster.name配置进行识别,拥有相同cluster.name的节点视为同一个集群。
Elasticsearch2.X之后,为了数据安全考虑,进行了优化调整,改采用unicast的方式,就是单播。这样我们需要在每个节点的配置文件上指定集群节点的ip。
discovery.zen.ping.unicast.hosts=[ip1:port,ip2:port]
以下是关于集群节点发现和检测的相关配置:
discovery.zen.ping_timeout
参数仅在加入或者选举 master 主节点的时候才起作用;
discovery.zen.fd.ping_timeout
参数则在稳定运行的集群中,master 检测所有节点,以及节点检测 master 是否畅通时长期有用。
discovery.zen.fd.ping_interval: 10s
重试间隔
discovery.zen.fd.ping_retries: 10
重试次数
discovery.zen.minimum_master_nodes
节点需要看到具有Master资格的节点最小个数
discovery.zen.ping.unicast.hosts
配置具有Master资格的节点地址
更多:Elasticsearch深入理解专栏
——————————————————————————————————
作者:桃花惜春风
原文地址:
https://blog.csdn.net/xiaoyu_BD/article/details/82427289
|