您的位置:首页 > 其它

读书笔记-ElasticSearch权威指南

2016-05-27 15:48 316 查看

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为空。此类情况(符合要求的条目不足)仍然需要向所有节点发送查询请求

归根结底,向所有节点发送查询消息的原因是不能保证在任意查询条件下,所有查询数据都按照相同的规则分布在所有节点中。

那么一次查询需要选出的文档数便可以确定了:选出的文档总数 = 节点数 * 单个分页数

由此可以看出,在单个分页数不大的情况下,崩溃时比较困难的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息