最具影响力的数字化技术在线社区

168大数据

 找回密码
 立即注册

QQ登录

只需一步,快速开始

1 2 3 4 5
打印 上一主题 下一主题
开启左侧

[ES] Elasticsearch架构设计

[复制链接]
跳转到指定楼层
楼主
发表于 2019-7-3 13:48:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多数据大咖,获取更多知识干货,轻松玩转大数据

您需要 登录 才可以下载或查看,没有帐号?立即注册

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  

楼主热帖
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖 赞 踩

168大数据 - 论坛版权1.本主题所有言论和图片纯属网友个人见解,与本站立场无关
2.本站所有主题由网友自行投稿发布。若为首发或独家,该帖子作者与168大数据享有帖子相关版权。
3.其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和168大数据的同意,并添加本文出处。
4.本站所收集的部分公开资料来源于网络,转载目的在于传递价值及用于交流学习,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
5.任何通过此网页连接而得到的资讯、产品及服务,本站概不负责,亦不负任何法律责任。
6.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源,若标注有误或遗漏而侵犯到任何版权问题,请尽快告知,本站将及时删除。
7.168大数据管理员和版主有权不事先通知发贴者而删除本文。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

关于我们|小黑屋|Archiver|168大数据 ( 京ICP备14035423号|申请友情链接

GMT+8, 2024-5-3 14:23

Powered by BI168大数据社区

© 2012-2014 168大数据

快速回复 返回顶部 返回列表