(一:原理2)深入理解Elasticsearch读写过程

ElasticSearch的数据读写流程

elasticsearch系统及读写调优

1:Elasticsearch的写入

1.1:Elasticsearch的写入设计

1:分布式设计

Elasticsearch引入分片的概念,一个索引被分成多个分片,每个分片可以有一个主分片和多个副本分片,每个分片副本都是一个具有完整功能的lucene实例。

  • 分片路由设计
    默认根据消息的id进行hash到主分片上进行写入,每个分片都有自己的编号。也可以指定routing字段
    shard_num = id hash(\routing) % num_primary_shards
2:实时性refresh

refresh操作的时间间隔由refresh_interval参数控制,默认为1s, 当然还可以在写入请求中带上refresh表示写入后立即refresh,根据refresh从内存刷新到内存缓存区segment上。

3:可靠性
  • 1:引入translog
    ES增加了translog, 当进行文档写操作时会先将文档写入Lucene,然后写入一份到translog,每个索引有自己的translog。写入translog是落盘的(如果对可靠性要求不是很高,也可以设置异步落盘,可以提高性能,由配置index.translog.durability和index.translog.sync_interval控制),这样就可以防止服务器宕机后数据的丢失。由于translog是追加写入,因此性能比较好。与传统的分布式系统不同,这里是先写入Lucene再写入translog,原因是写入Lucene可能会失败,为了减少写入失败回滚的复杂度,因此先写入Lucene.
  • 2:flush操作
    另外每30分钟或当translog达到一定大小(由index.translog.flush_threshold_size控制,默认512mb), ES会触发一次flush操作,此时ES会先执行refresh操作将buffer中的数据生成segment,然后调用lucene的commit方法将所有内存中的segment fsync到磁盘。此时lucene中的数据就完成了持久化,会清空translog中的数据(6.x版本为了实现sequenceIDs,不删除translog)
    在这里插入图片描述
  • 3:merge合并操作
    由于refresh默认间隔为1s中,因此会产生大量的小segment,为此ES会运行一个任务检测当前磁盘中的segment,对符合条件的segment进行合并操作,减少lucene中的segment个数,提高查询速度,降低负载。不仅如此,merge过程也是文档删除和更新操作后,旧的doc真正被删除的时候。用户还可以手动调用_forcemerge API来主动触发merge,以减少集群的segment个数和清理已删除或更新的文档。
  • 4:多副本机制
    另外ES有多副本机制,一个分片的主副分片不能分片在同一个节点上,进一步保证数据的可靠性。
  • 5 :部分更新
    lucene支持对文档的整体更新,ES为了支持局部更新,在Lucene的Store索引中存储了一个_source字段,该字段的key值是文档ID, 内容是文档的原文。当进行更新操作时先从_source中获取原文,与更新部分合并后,再调用lucene API进行全量更新, 对于写入了ES但是还没有refresh的文档,可以从translog中获取。另外为了防止读取文档过程后执行更新前有其他线程修改了文档,ES增加了版本机制,当执行更新操作时发现当前文档的版本与预期不符,则会重新获取文档再更新

1.2:ES的写入流程

任何节点都可以接受写入请求。根据_routing字段(不指定时默认id字段进行shard_num = id hash(\routing) % num_primary_shards)找到对应的主分片,后将请求转发给primary shard, 主分片完成写入后,将写入并发发送给各副本, 副本执行写入操作后返回给主, 主再将请求返回给协调节点(接受请求节点)。大致流程如下图:
在这里插入图片描述
1:接受bulk请求,接受请求节点根据请求按照routing按照shard分开,同一个shard上的请求聚合到一起,构建BulkShardRequest
2:把请求路由到primary shard所在节点
3:主分片所在节点根据请求方式,mapping进行字段解析写入,先写入内存缓存区再写入translog
4:达到translog时间进行落盘,默认1S。对数据可靠性和数据实时性要求不高可以提高参数,也能大幅提高写入性能
5:主分片写入完成后转发请求到副本所在节点进行写入
6:主副本都写入完成,协调节点返回结果给客户端
7:达到refresh时间将内存缓冲区数据刷到一个新的segment file中此时可被查询到。主分片写入完成

2:数据读取流程

1)客户端发送请求到任意一个node(没有协调节点时任一数据节点),成为coordinate node(协调节点)
2)协调节点将请求转发到对应的node,查询会广播到索引中每一个分片拷贝(主分片或者副本分片)。 每个分片在本地执行搜索并构建一个匹配文档的 优先队列。此时会使用随机轮询算法,在primary shard(主分片)以及其所有replica中随机选择一个,让读请求负载均衡
3)接收请求的node返回一个轻量级的结果列表到协调节点,它仅包含文档 ID 集合以及任何排序需要用到的值,例如 _score给协调节点,协调节点进行数据的合并、排序、分页等操作,产出最终结果id
4)接着由协调节点,根据最终doc id去发送请求给同样处理查询阶段的分片副本。拉取实际的document数据,最终返回给客户端
4)建议不要使用深度翻页,基本10页以后不会去使用,返回更少的数据可提高查询性能,必须返回大量数据可以使用scroll查询

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值