原理
写数据原理
- req send to cordinating node
- cordinating node find primary shard
- primary shard write data
- replica shard sync data from primary shard
- all data write are completed, response send to cordinating node
- cordinating node send res to client
读数据原理
- req send to cordinating node
- cordinating node send req to primary shard and replica shards, 随机轮训算法
- query phase: all shard return doc id base on search req to cordinating node, cordinating node merge, sort all doc id
- fetch phase: cordinating node get res from shards by doc ids got by query phase
- cordinating node send res to client
写数据底层过程
- memory buffer: data frist wirte into memory buffer and translog file
- os cache(filesystem cache)/refresh: every 1s, data will be refreshed into os cache, data in os cache can be searched
- translog/flush: every 5s system will check whether translog need to be flush
- segement file: data in translog can be flush into segement file, base on size or timer. data in os cache also can be fsync into segement file
优化
filesystem cache
elasticsearch search 的高性能查询是基于 filesystem cache 的,查询性能的高低取决于有多少 index 数据在 filesystem cache 中。
在机器内存无法无限扩大的前提下,合理的规划设计索引是比较关键的。一般来讲,es 中可以存储仅仅需要检索的字段,其他的字段可以通过检索 db 来实现,即在架构上采取 es + db 的方式。
数据预热
对于经常需要访问的数据,可以采用数据预热的方式,定时将热数据加载到 filesystem cache 中
冷热分离
将热数据和冷数据分别存储在不同的 index 中,优先保障热数据的查询都是走 filesystem cache,保证 90% 的查询都是较快。
Document 设计
- 模型不可太过于复杂
- parent/join 等查询效率较低
分页优化
es 是基于 shards 来设计的,同一 index 数据也可能分布在不同的 shards 上。
那么对于需求: “取第 2 页 10 条数据”,在 es 中分页的实现方式为:
- 按 order 条件,分别在每个 shards 上,取 20 条数据
- cordinating node merge and order data,最终确定满足条件 10 条数据的 doc id
- 根据 doc id 分别到对应的 shard 上查询
- cordinating node merge data and resturn
因此,按照上述实现方式,es 分页会随着深度的加深,性能会大幅的下降、
对于分页的优化,有如下方式:
- 在业务需求上,不允许深度分页
- 采用 scroll api 来分页,即仅支持滑动分页
Ref
- https://mp.weixin.qq.com/s/G6cM4w-xikGBONa2zMWAeQ
- https://bbs.huaweicloud.com/blogs/143363