读书笔记-ElasticSearch权威指南

来源:互联网 发布:yum gcc c 4.9 编辑:程序博客网 时间:2024/05/29 17:19

ES是如何保证实时性的?

ES的每个示例都拥有一个luence,在luence中有一个段的概念,索引由一或多个段组成,每个段都是索引中可被单独检索的一部分。
当ES的flush事件触发时,新的数据会被ES作为一个新的段加入索引,于是新的数据就可以被检索到了。默认的flush间隔时1s。
那么问题来了,每次刷新都新增一个段,会不会造成查询的段过多,影响查找效率呢?
一般是不会的,ES会静默的对段进行合并,这个操作由于ES的资源控制,并不会影响到索引和查询操作。

那luence为什么要引入段的概念?

段是数据组织的单元,如果将所有的数据都直接保存在一个单元中,那么当有新数据加入的时候有两个选择:
1. 文件加锁,原地更新。有锁的开销,影响查询性能
2. 构建新索引,新索引替换旧索引。新增和修改开销巨大,实时性不能保证
于是,以段来组织索引是再正常不过的事情。

luence是如何应对删除或再索引操作的?

由于luence的数据是由段组织的,当有数据被删除时,只是将原内容标记为被删除,并没有真正的触发删除操作。
当有新内容时,是加入了一个新的段。更新操作也就自然而然的是先删除,再新增。

既然luence并没有操作原数据进行更新,那么依赖luence的ES是如何保证原子性的?

ES保证原子性的操作有两种,第一种为借用内置_version使用悲观锁的控制,这种适合总量固定的更新,比如库存。
另一种为冲突重试,这种适合对总量没有特别要求的更新,比如页面浏览量。
第一种如果_version落后于ES中数据的_version,会有异常抛出,可以反馈给业务。
第二种可以允许客户端指定重试次数,重试结束后返回异常。

ES提倡的索引切换方案是怎样的?

在ES中,允许给索引制定别名。所以鼓励的索引切换方案是利用alias。
比如实际索引名是raw0,在线上实际alias后的索引为ops。
现需要将raw0中索引的数据进行一定的变化,因此建了索引raw1.
在所以操作的时候,只需取消raw0的alias,加入raw1的alias即可。
由于上述操作开销很小,而且是原子性的,因此可以用来做索引切换。

ES多节点时,如何完成符合条件数据的汇总,会不会匹配数过多造成集群崩溃?

每个节点按相同的条件和限制进行查询,返回结果进行汇总。在分页的页面不大的情况下,不会崩溃。
举个栗子:
- 已知A、B、C三个数据节点和Client节点,要以id顺序取出所有数据中的前5个
- Client节点向三个基点分别发出查询:以id顺序取出所有数据中的前5个。
- Client将得到的所有文档按id顺序,取出前5个返回。
为什么Client节点要向每个数据节点都发出原始的查询请求呢?考虑下面的case:
1. A中的ID:[1, 2, 3, 4, 5],B中的ID:[6, 7, 8, 9, 10],C中的ID:[11, 12, 13, 14, 15]。此类情况(数据集中在少数的几个节点)必须向所有节点发送查询请求
2. A中的ID:[1],B中的ID:[2],C为空。此类情况(符合要求的条目不足)仍然需要向所有节点发送查询请求
归根结底,向所有节点发送查询消息的原因是不能保证在任意查询条件下,所有查询数据都按照相同的规则分布在所有节点中。
那么一次查询需要选出的文档数便可以确定了:选出的文档总数 = 节点数 * 单个分页数
由此可以看出,在单个分页数不大的情况下,崩溃时比较困难的

0 0
原创粉丝点击