分布式特性
es 支持集权模式,是一个分布式系统,好处有二:
- 增大系统容量,磁盘 内存 使得 es集群可以支持pb级别的业务
- 提高系统可用性 即使部分节点停止服务 整个集群可以正常使用
es集群由多个es实例组成
- 不同的集群通过集群名称组成,通过 cluster.name 定义
- 每个es实例本质上是一个jvm进程,且有自己的名字 通过 node.name定义
构建集群
启动一个节点
bin/elasticsearch -E cluster.name=my_cluster -E node.name=node1
cluster state
es集群的相关数据称为 cluster state 主要记录如下信息:
- 节点信息 节点名称 连接地址等
- 索引信息 索引名称 配置等
master node
可以修改 cluster state 的节点称为 master 节点 一个集群只能有一个
cluster state 存储在每个节点上,master 维护最新版本并同步给其他节点
master节点通过集群中所有节点选举产生,可以被选举的节点称为master eligible节点
node.master=true
分片
- 如何将数据分簿于所有节点上
引入分片解决问题 分片是es支持pb事务的基石
- 分片存储了部分数据,可以分布于任意节点上
- 分片数在索引创建时指定,且后续不允许更改,默认为五个
- 分片有主分片和副本分片的区别,实现数据高可用
- 副本分片数据由主分片同步,可以有多个,从而提高吞吐量
- 继续增加节点是否提高索引的数据容量?
不能,只有三个分片,新增节点上的资源无法被利用 - 继续增加副本数能否提高索引的数据吞吐量?
不能,新增副本还是分布在已有节点上,资源并没有增多
健康状态
通过api GET _cluster/health 可以查看集群的健康状况,包括三种:
- green 健康 指所有的主副分片都正常
- yellow 指所有的主分片都正常 但是有副本分片未正常分配
- red 所有分片都未分配
故障转移
node1 所在的集器宕机,集群会如何处理?
- node2 发现主分片p0未分配,将R0提升为主分片,此时由于所有的主分片都正常,集群状态为yellow
- node2 为p0和p1生成新的副本,集群状态为绿色
分布式存储
- 使用映射算法将文档均匀的分布在所有的分片上,以充分利用资源
- es 使用 shard = hash(routing)%number_of_primary_shards
- hash算法可以保证将数据均匀的分布在分片中
- routing 默认为文档id
文档创建流程
- client向node3发起文档创建请求
- node3通过routing计算出该文档应该存储在shard1上,查询cluster state后确认主分片在p1
在node2中,转发创建请求到node2上 - p1接收并创建文档,将同样的请求发送到副本分片r1
- r1接收并执行创建文档请求后通知p1创建成功
- p1接收副本分片结果后,通知node3创建成功
- node3将结果返回给client
文档读取流程
- client向node3发起读取文档1的请求
- node3通过routing计算该文档在shard1上,查询cluster state后获取shard1的主副分片列表,然后轮询获取shard,例如R1,转发请求到node1
- R1接收并执行读取文档,将结果返回node3
- node3返回结果给client
脑裂问题
- 当集群中出现网络网体,node2 与 node3 重新组成集群选举一个master,并更新cluster state
- node1 自己组成集群后,也会更新cluster state
- 同一个大集群有两个master 并且有两个 cluster state 网络恢复后无法决定哪个是正确的master 和 cluster state
解决 增加选举条件 可被选举为master-eligible节点数大于等于quorum 时才可以进行master选举
- quorum=master-eligible 节点数/2+1 例如三个master-eligible节点时,quorum为2
- 设定 discovery.zen.minimum_master_nodes为quorum可避免脑裂
shard
倒排索引不可变更
- 倒排索引一旦生成,不能更改
- 不用考虑并发写文件的问题,避免锁机制带来的性能问题
- 可以充分利用缓存,载入一次,多次读取
- 利于对文件进行压缩存储,节省磁盘和内存存储空空间
- 写入新文档时,必须重新构建倒排索引文件,然后替换老文件,新文档才会被检索,实时性差
文档搜索实时性
- lucene构建单个倒排索引称为segment 合在一起称为index,与 es 中的index不同,es中一个shard对应一个lucene index。
- lucene 会有一个专门的文件来记录所有的segment信息,称为commit point。
文档搜索实时性 - refresh
- segment 写入缓存,并开放查询,该过程称为refresh
- 在refresh前文档会先存储在一个buffer中,refresh时将buffer中的所有文档清空并生成segment
- es默认每一秒执行一次refresh,因此文档的实时性被提高到1秒,这也是es被称为近实时的原因
translog
如果缓存中segment还没写入磁盘时发生宕机怎么办?
- es 引入 translog机制,写入到buffer时,同时将操作写入translog。
- translog文件会即时写入磁盘fsync,6.X默认每个请求都会落盘,可以修改每五秒一次,这个风险为丢失五秒内数据,祥光配置为index.translog.*
- es 启动时会检查translog文件,并且从中恢复数据
flush
flush 负责将内存中的segment 写入磁盘
- 将translog 写入磁盘
- 将index buffer 清空,其中的文档生成新的segment 相当于refresh操作
- 更新 commit point并写入磁盘
- 执行fsync操作 将内存中的segment写入磁盘
- 删除旧的translog
删除与更新文档
- lucene专门维护一个 .del文件,记录所有的已经删除的文档,.del上记录的文芳时lucene内部的文档id
- 在分会查询结果前会过滤掉.del中的文档
- 更新文档等于先删除,在创建新文档
segment merging
- 随和segment增多 一次查询的segment过多 查询速度变慢
- es 定时在后台进行 segment merge 减少segment数量
- 通过force_mergeapi 可以手动 merge操作
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。