ES写入机制剖析
1.术语回顾
master node
资源要求:中高CPU;中高内存;中低磁盘
一般在生产环境中配置3台
一个集群只有1台活跃的主节点,负责分片管理,索引创建,集群管理等操作
整个集群的管理者,索引管理,分片管理,以及整个集群的状态的管理,master节点是从master候选节点中选出的.
data node
数据节点保存数据并执行数据相关操作,如CRUD、搜索和聚合。
资源要求:CPU、内存、磁盘要求都高
primary shard(主分片)
每个文档都存储在一个主分片中。当您对文档进行保存时,它首先在主分片上进行保存,然后在主分片的所有副本上进行保存。
默认情况下,索引有5个主分片。您可以指定更少或更多的主分片来缩放索引可以处理的文档数量。
注意:创建索引后,不能更改索引中主分片的数量,此处影响后续的扩容流程,数量需评估充分。
shard = hash(orderId) % number_of_primary_shards
Refresh
在 Elasticsearch 中,写入和打开一个新段的轻量的过程叫做 refresh 。 默认情况下每个分片会每秒自动刷新一次。这就是为什么我们说 Elasticsearch 是近实时搜索: 文档的变化并不是立即对搜索可见,但会在一秒之内变为可见。
将文档先保存在Index buffer中,以refresh_interval为间隔时间,定期清空buffer,生成 segment,借助文件系统缓存的特性,先将segment放在文件系统缓存中,并开放查询,以提升搜索的实时性。
性能开销巨大:CPU、内存、磁盘。
segment
段是索引中存储索引数据的内部存储元素,并且是不可变的。较小的段会定期合并到较大的段中,以保持索引大小不变,并消除删除。
由于自动刷新流程每秒会创建一个新的段 ,这样会导致短时间内的段数量暴增。而段数目太多会带来较大的麻烦。 每一个段都会消耗文件句柄、内存和cpu运行周期。更重要的是,每个搜索请求都必须轮流检查每个段;所以段越多,搜索也就越慢。
Translog
Segment没有写入磁盘,即便发生了当机,重启后,数据也能恢复,从ES6.0开始默认配置是每次请求都会落盘。
对Lucene的更改仅在Lucene提交期间持久化到磁盘,这是一个相对繁重的操作,因此无法在每次索引或删除操作之后执行。如果进程退出或硬件故障,在一次提交之后和另一次提交之前发生的更改将丢失。
为了防止这种数据丢失,每个碎片都有一个与其相关的事务日志或预写日志。任何索引或删除操作都会在内部Lucene索引处理后写入translog。
在发生崩溃的情况下,当碎片恢复时,可以从事务日志中回放最近的事务。
Elasticsearch刷新是执行Lucene提交并启动新translog的过程。它是在后台自动完成的,以确保事务日志不会增长太大,这将使恢复过程中重播其操作需要相当长的时间。
index.translog.flush_threshold_size
默认 512 MB ,到达阀值,自动触发一次段合并操作。
5s刷新一次
2.计算机系统存储层次
磁盘缓存
由于目前磁盘的 I/O 速度远低于对主存的访问速度,因此将频繁使用的一部分磁盘数据 和信息,暂时存放在磁盘缓存中,可减少访问磁盘的次数。磁盘缓存本身并不是一种实际 存在的存储介质,它依托于固定磁盘,提供对主存储器存储空间的扩充,即利用主存中的 存储空间,来暂存从磁盘中读出(或写入)的信息。主存也可以看做是辅存的高速缓存,因为, 辅存中的数据必须复制到主存方能使用;反之,数据也必须先存在主存中,才能输出到 辅存。