es查询方式:主节点、备节点都可以查询到数据。根据轮询方式确定查询接口
es写入方式:通过路由算法找到对应分片的主节点,在主节点上写入数据。主从同步到备节点上
持久化方式:
refresh操作所以近实时搜索:写入和打开一个新段(一个追加的倒排索引)的轻量的过程叫做 refresh 。每隔一秒钟把buffer中的数据创建一个新的segment,这里新段会被先写入到文件系统缓存--这一步代价会比较低,稍后再被刷新到磁盘--这一步代价比较高。不过只要文件已经在缓存中, 就可以像其它文件一样被打开和读取了,内存buffer被清空。此时,新segment 中的文件就可以被搜索了,这就意味着document从被写入到可以被搜索需要一秒种,如果要更改这个属性,可以执行以下操作
PUT /my_index
{
"settings": {
"refresh_interval": "30s"
}
}
3)https://www.elastic.co/guide/cn/elasticsearch/guide/current/translog.html
flush操作导致持久化变更:执行一个提交并且截断 translog 的行为在 Elasticsearch 被称作一次 flush。刷新(refresh)完成后, 缓存被清空但是事务日志不会。translog日志也会越来越多,当translog日志大小大于一个阀值时候或30分钟,会出发flush操作。
- 所有在内存缓冲区的文档都被写入一个新的段。
- 缓冲区被清空。
- 一个提交点被写入硬盘。(表明有哪些segment commit了)
- 文件系统缓存通过
fsync
到磁盘。 - 老的 translog 被删除。
分片每30分钟被自动刷新(flush),或者在 translog 太大的时候也会刷新。也可以用_flush命令手动执行。
translog每隔5秒会被写入磁盘(所以如果这5s,数据在cache而且log没持久化会丢失)。在一次增删改操作之后translog只有在replica和primary shard都成功才会成功,如果要提高操作速度,可以设置成异步的
PUT /my_index
{
"settings": {
"index.translog.durability": "async" ,
"index.translog.sync_interval":"5s"
}
}
所以总结是有三个批次操作,一秒做一次refresh保证近实时搜索,5秒做一次translog持久化保证数据未持久化前留底,30分钟做一次数据持久化。
2.基于translog和commit point的数据恢复
在磁盘上会有一个上次持久化的commit point,translog上有一个commit point,根据这两个commit point,会把translog中的变更记录进行回放,重新执行之前的操作
3.不变形下的删除和更新原理
https://www.elastic.co/guide/cn/elasticsearch/guide/current/dynamic-indices.html#deletes-and-updates
一个文档被 “删除” 时,它实际上只是在 .del
文件中被 标记 删除。一个被标记删除的文档仍然可以被查询匹配到, 但它会在最终结果被返回前从结果集中移除。
文档更新也是类似的操作方式:当一个文档被更新时,旧版本文档被标记删除,文档的新版本被索引到一个新的段中。 可能两个版本的文档都会被一个查询匹配到,但被删除的那个旧版本文档在结果集返回前就已经被移除。
段合并的时候会将那些旧的已删除文档 从文件系统中清除。 被删除的文档(或被更新文档的旧版本)不会被拷贝到新的大段中。
4.merge操作,段合并
https://www.elastic.co/guide/cn/elasticsearch/guide/current/merge-process.html
由于每秒会把buffer刷到segment中,所以segment会很多,为了防止这种情况出现,es内部会不断把一些相似大小的segment合并,并且物理删除del的segment。
当然也可以手动执行
POST /my_index/_optimize?max_num_segments=1,尽量不要手动执行,让它自动默认执行就可以了
5.当你正在建立一个大的新索引时(相当于直接全部写入buffer,先不refresh,写完再refresh),可以先关闭自动刷新,待开始使用该索引时,再把它们调回来:
PUT /my_logs/_settings { "refresh_interval": -1 } PUT /my_logs/_settings { "refresh_interval": "1s" }