ES 的分布式架构原理
存储数据的基本单位是索引,每个索引拆分成多个 shard,每个 shard 存储部分数据
每一份 shard 都有其副本 replica,而且 replica 不在同一台机器上
在写入数据时,会将 primary shard 的数据同步到 replica shard,数据分布式存储
数据结构:index->type->mapping->docment->field
index:相当于一张表
type: 一个 index 有多个 type,每个 type 的字段差不多,可以有细微差别
mapping:表结构
docment:表中的一行数据
field:字段
es 集群有多个节点,会自动选举出 master 节点,作用有维护索引元数据,切换 primary shard 和 replica shard 等等。
- master 宕机会重新选举出新 master,新 master 上的属于宕机节点的 replica shard 会被提拔成 primary shard。宕机故障修复后,取消宕机机器的 master 身份,将宕机机器上的 primary shard 降级至 replica shard。
- 非 master 宕机,master 会将宕机节点上的 primary shard 转移到其他机器的 replica shard。故障修复后,宕机机器上的 primary shard 降级至 replica shard,并同步数据。
ES 写入查询数据的工作原理
- 写数据总体原理
- 客户端选择一个节点发送请求,这个节点会变成 coordinating node(协调节点)
- 协调节点对请求进行路由,将请求转发到对应的节点(有 primary shard)
- 实际收到请求的节点的上的 primary shard 处理请求,并将数据同步到其他 replica
- 协调节点发现数据已经在 primary shard 和所有 replica shard 上,返回响应给客户端
- 写数据到 shard 原理
- 先将数据写入内存 buffer,并将数据写入 translog 日志文件
- 如果内存 buffer 或者每隔一段时间(默认 1s),将 buffer 数据refesh到新的 segment file(磁盘文件)中,当 segment file 越来越多时,会定时执行merge操作,如果 buffer 没有数据则不会执行 refresh 操作。
- 写入 segment file 磁盘文件前会先写入 os cache(操作系统缓存)
- 每写入一条数据到 buffer,同时每隔 5s 写入日志到 translog,会导致 translog 文件不断变大,当 translog 大到一定程度,会进行commit操作
- commit 操作(默认每隔 20min)(ES api 中的flush操作)
- 将现有数据 refresh 到 os cache 中,清空 buffer
- 将 commit point 写入磁盘,里面标识 commit point 对应的所有 segment file
- 强行将 os cache 中所有数据 fsync 到磁盘文件中
- 将现有的 translog 清空,重新启用一个 translog
- es 丢数据问题
- 准实时,数据每隔 1s 才能搜索到
- 有 5s 的数据停留在 buffer,translog os cache,segment os cache 中,不在磁盘中,有机会导致 5s 的数据丢失。
- 删除数据原理
- 将数据写入.del 文件,标识数据被删除,客户端搜索出某条数据,一旦发现数据在.del 文件中已经标识成已删除,就不会出现在搜索结果
- 物理删除。每次执行 merge 操作时,会将多个 segment file 合并成一个,同时将标识成 delete 的数据物理删除掉,然后将新的 segment file 写入磁盘,同时写一个 commit point,标识所有新的 segment file,打开 segment file 供搜索使用,删除旧的 segment file。
- es 读数据过程
- GET 某条数据,写入某个 document,这个 document 分配一个全局唯一 id,同时根据 doc id 进行 hash 路由到对应的 primary shard,也可以手动指定 doc id。
- 可以通过 doc id 查询,根据 doc id 进行 hash,判断 doc id 在哪个 shard 上面,从其中查询。
- es 全文搜索
- 客户端发送请求到协调节点
- 协调节点将请求发送到所有 shard 对应的 primary shard 或者 replica shard
- query phase:每个 shard 将自己的搜索结果(doc id)返回给协调节点,有协调节点进行数据合并,排序,分页等操作,产出最终结果
- fetch phase:协调节点根据 doc id 去各节点拉取实际 document 数据,返回给客户端
ES 在数据量很大的情况下(数十亿级别)如何提高查询性能
filesystem cache
根据节点内控制 es 数据量。仅仅将少数检索字段放入 es,其他字段写入 hbase(适用于海量数据的在线存储,根据 id 查询)或者直接放 mysql
数据预热(手动搜索热数据)
冷热分离(字段水平拆分,冷热数据分开放到不同的索引)
document 结构,尽量不适用复杂的关联查询,在写入 es 前就进行关联操作,将关联好的数据写入 es
分页性能优化
不允许深度分页,规定最大页数
scroll 游标获取下一页数据,但是不能指定页数
ES 生产集群部署架构?每个索引的数据量大小?每个索引有多少分片?
- 5 台集机器,6 核 64g,总内存 320g
- 日增量数据大概 2000 万条,数据量 500mb,月增量 6 亿,15g,系统运行了几个月,es 集群有 100g 数据
- 线上有 5 个索引,每个索引的数据量大概有 200g,每个索引分配 8 个 shard,比默认 5 个 shard 多 3 个 shard