ElasticSearch内核原理

1. 倒排索引组成结构以及其索引不可变原因

1.1 倒排索引的结构

  1. 包含这个关键词的document list
  2. 包含这个关键词的所有document的数量: 【IDF】
  3. 这个关键词在每个document中出现的次数: 【TF】
  4. 这个关键词在这个document中的次序
  5. 每个document的长度: 【length norm】
  6. 包含这个关键词的所有document的平均长度

1.2 倒排索引不可变的好处

  1. 不需要锁,提升并发能力,避免锁问题
  2. 数据不变,一致保存在os cache中
  3. filter cache一直留在内存
  4. 可以压缩,节省cpu和io开销
  5. 坏处:每次都要重新构建整个索引

2. Document写入原理

  • 关键词
    • buffer
    • commit
    • segment
    • os cache
    • os disk

2.1 写入过程

  1. 数据写入buffer
  2. commit point
  3. buffer中的数据写入新的index segment
  4. 等待在os cache中的index segment被fsync强制刷到磁盘os disk上
  5. 新的index segment被打开,供search使用
  6. buffer被清空

2.2 删除过程

  1. 每次commit时会生成del文件
  2. 表明哪个index segment中的哪个document被删除了
  3. 假设 del中,doc id=1被删除了
  4. 搜索请求过来,在index segment中,匹配到了id=1的doc,此时会发现在del文件中已经被标识为deleted了,这种数据就会被过滤掉

2.3更新过程

  1. 将现有的doc标记为deleted
  2. 然后将新的document写入新的index segment中
  3. 下次search过来时,将匹配到一个document的多个版本
  4. 但之前的版本已经标记为deleted了
  5. 最终只返回最新版本的doc

3. 优化写入流程实现NRT

  • 关键词

    • filesystem
    • cache
    • refresh
  • 问题:每次等待fsync 写到磁盘才可以写入,中间等待写磁盘很慢,所以以上写入流程有问题

3.1 改进版-写入流程

  1. 数据写入buffer中
  2. 每隔一段时间(1s),将buffer写入新的index segment
    1. 每秒都会产生新的index segment
  3. index segment立即被刷到os cache中
  4. 立刻就可以被打开搜索
  • 数据写入os cache,并被打开供搜索的过程,叫做refresh
  • 手动refresh post /my_index/_refresh
  • 如果时效性比较低,只要求一条数据写入es,一分钟后才被搜索可以调整
#PUT /index
{
    "settings":{
        "refresh_interval":"30s"
    }
}

4. 写入流程实现durability可靠存储

  • 关键词
    • translog
    • flush
  • 问题:以上优化版本仅仅将数据写到了os cache中,如果机器宕机将使es变得不可靠

4.1 改进版-写入流程

  1. document将数据写入buffer中,同时将document写入translog日志文件中
  2. 每秒写入一个新的index segment file中
  3. 立即将index segment file 写入 os cache,并打开供搜索
  4. 将buffer清空
  5. 此时,os cache、translog会不断累积变大
  6. 当累积到一定程度,触发commit
  7. 将会写一个commit point文件到磁盘上,标明有哪些index segment
  8. 然后将os cache刷到os disk中去
  9. 清空os cache、translog日志文件
  • fsync+清空translog,就是flush,默认每隔30分钟flush一次,或者当translog过大时也会flush

4.2 基于translog和commit point进行数据恢复

  1. os disk中存放了上一次 commit point位置,所有segment file都fsync到磁盘中
  2. 机器被重启,disk总数居没有丢失
  3. 此时会见translog文件中的变更记录进行回访,重新执行之前的各种操作,在buffer中执行
  4. 重新写入一个个的segment
  5. 等待下一次commit即可
4.2.1 translog的存储方式
  1. translog每个5秒被fsync一次到磁盘上
  2. 再一次增删改操作之后,当fsync在primary shard和replica shard都成功之后,那次增删改才会成功
  3. 这种一次增删改强行fsync translog可能会导致部分操作比较耗时
  4. 如果可以容忍5秒数据丢失即可设置:
  5. 可以通过设置异步fsync translog
PUT /index/_settings
{
    "index.translog.durability":"async",
    "index.translog.sync_interval":"5s"
}

5.最后优化写入流程实现海量磁盘文件合并

  • 关键词
    • segment merge
    • optimize

5.1 合并过程

  1. 选择大小相似的segment进行合并成一个大的
  2. 将合并的segment flush到磁盘上去
  3. 写入新的commit point,包括了新的segment,并且排除旧的那些segment
  4. 将新的segment打开供搜索
  5. 将旧的segment进行物理删除
  • 手动执行合并 POST /index/_optimize?max_num_segments=1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值