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

对于倒排索引是非常适合用来进行搜索的
它的结构:
(1)包含这个关键词的document list
(2)包含这个关键词的所有document的数量:IDF(inverse document frequency)
(3)这个关键词在每个document中出现的次数:TF(term frequency)
(4)这个关键词在这个document中的次序
(5)每个document的长度:length norm
(6)包含这个关键词的所有document的平均长度
其实本质上主要是为了计算相关度分数

_score = boost * idf * tf
此时boost = 2.2, idf = 0.18232156, tf = 0.5116279 idf = log( + (N - n + 0.5) / (n + 0.5))
此时n = (n, number of documents containing term),
N = (N, total number of documents with field) tf = freq / (freq + k1 * ( - b + b * dl / avgdl))
此时freq = (freq, occurrences of term within document),
k1 = 1.2(k1, term saturation parameter),
b = 0.75(b, length normalization parameter),
d1 = (dl, length of field),
avgdl = 5.5(avgdl, average length of field)

倒排索引的不可变好处

(1)不需要锁,提升了并发能力,避免锁的问题
(2)数据不变,一直保存在OS cache中,只要cache内存足够
(3)filter cache一直驻留在内存
(4)可以压缩,节省cpu和io开销
这个对应的就是primary shard的数量不变,不能修改field的属性(将date改成text)

倒排索引不可变的坏处

(1)每次都需要重新构建整个索引

document写入原理

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

下面做几点说明:

1、在Elasticsearch中,底层用的是lucene,lucene底层的index是分为多个segment的,每个segment都会存放部分数据。
2、如果是删除操作,每次commit的时候,就会生成一个.del文件,标明哪个index segment的哪个document被删除了。
3、如果是更新操作,实际上是将的doc标记为deleted,然后将新的document写入新的index segment中。下次search过来的时候,也许会匹配到一个document的多个版本,但是之前的版本已经被标记为deleted了,所以只会返回最新版本的doc
4、如果搜索请求过来,在index segment中,匹配到了id=1的doc,此时会发现在.del文件中已经被标识为deleted了,这种数据就会被过滤掉,不会作为搜索结果返回。
图示如下:

写入流程近实时NRT(filesystem cache,refresh)

现有的流程的问题,每次都必须等待fsync将segment刷入磁盘,才能将segment打开供search使用,这样的话,从一个document写入,到它可以被搜索,可能会超过1分钟,这也就不是近实时的搜索了。主要的瓶颈在于fsync从磁盘IO写数据进磁盘是很耗时的。
ES写入流程的改进:
(1)数据写入buffer
(2)每个一定时间,buffer中的数据被写入segment文件,但是先写入OS cache
(3)只要segment写入OS cache,那就直接打开供search使用,不立即执行commit
数据写入OS cache,并被打开供搜索的过程,叫做refresh,默认是每隔一秒refresh一次,也就是说,每隔一秒就会将buffer中的数据写入OS cache中,写入一个新的index segment file。所以ES是近实时的,数据写入到可以被搜索,默认是1秒。
一般不用修改,让ES自己搞定就好了,要修改的话,通过refresh_interval参数即可
格式:

写入流程的实现 durability可靠存储(translog,flush)

最终流程:

()数据写入buffer缓存和translog日志文件
()每隔一秒,buffer中的数据被写入新的segment file,并进入os cache,此时segment被打开并供search使用
()buffer被清空
()重复1~,新的segment不断添加,buffer不断被清空,而translog中的数据不断累加
()当translog长度达到一定程度的时候,commit操作发生
(5.1)buffer中的所有数据,写入一个新的segment,并写入os cache,打开供使用
(5.2)buffer被清空
(5.3)一个commit point被写入磁盘,标明了所有的index segment
(5.4)filesystem cache中的所有index segment file缓存数据,被fsync强制刷到磁盘上
(5.5)现有的translog被清空,创建一个新的translog

translog

对Lucene的更改仅在Lucene提交期间持久保存到磁盘,这是一项相对昂贵的操作,因此无法在每次索引或删除操作后执行。如果进程退出或硬件发生故障,Lucene将在一次提交之后和另一次提交之前发生的更改将从索引中删除。

因为Lucene提交对于每个单独的更改都执行起来太昂贵,所以每个分片副本还有一个事务日志,称为与之关联的translog。所有索引和删除操作在由内部Lucene索引处理之后但在确认之前写入translog。在发生崩溃的情况下,最新的已确认但尚未包含在上一个Lucene提交中的事务可以在分片恢复时从translog中恢复。

Elasticsearch flush是执行Lucene提交并启动新的translog的过程。在后台自动执行刷新以确保translog不会变得太大,这将使得在恢复期间重放其操作需要相当长的时间。手动执行刷新的能力也通过API公开,尽管很少需要。

translog设置

translog中的数据仅在fsync编辑和提交translog时持久保存到磁盘 。如果发生硬件故障,自上次translog提交以来写入的任何数据都将丢失。

默认情况下,fsync如果index.translog.durability设置为async或request 在每个索引,删除, 更新或 批量请求结束时设置为(默认),则Elasticsearch会每隔5秒提交一次translog 。更确切地说,如果设置为request,则fsync在主数据库和每个已分配的副本服务器上成功编辑和提交translog之后,Elasticsearch将仅向客户端报告索引,删除,更新或批量请求的成功 。

以下可动态更新的每索引设置控制translog的行为:

index.translog.sync_interval
fsync无论写入操作 如何,translog都经常被写入磁盘并提交。默认为5s。小于的值100ms是不允许的。
index.translog.durability
是否fsync在每个索引,删除,更新或批量请求之后提交translog。此设置接受以下参数:
request
(默认)fsync并在每个请求后提交。如果发生硬件故障,所有已确认的写入都已提交到磁盘。
async
fsync并在每个背景中提交sync_interval。如果发生硬件故障,将丢弃自上次自动提交以来的所有已确认写入。
index.translog.flush_threshold_size
translog存储尚未安全保存在Lucene中的所有操作(即,不是Lucene提交点的一部分)。尽管这些操作可用于
读取,但如果要关闭并且必须恢复,则需要重新编制索引。此设置控制这些操作的最大总大小,以防止恢复时间
过长。达到最大大小后,将发生刷新,生成新的Lucene提交点。默认为512mb。
index.translog.retention.size
要保留的translog文件的总大小。保留更多的translog文件会增加在恢复副本时执行基于同步操作的机会。如
果translog文件不足,副本恢复将回退到基于文件的同步。默认为512mb
index.translog.retention.age
保留translog文件的最长持续时间。默认为12h。
PUT /my_index/_settings
{
"index.translog.durability": "async",
"index.translog.sync_interval": "5s"
}

图示如下:

数据恢复

假设os cache中囤积了一些数据,但是此时不巧,宕机了,os cache中的数据全部丢失,那么我们怎么进行数据恢复呢?
我们知道写doc的时候也会写入translog,那么translog就存储了上一次flush直到现在最近的数据变更记录。机器被重启之后,disk上的数据并没有丢失,此时就会将translog文件中的变更记录进行回收,重新执行之前的各种操作,在buffer中执行,在重新刷一个一个的segment到os cache中,等待下一次commit发生即可。

海量磁盘文件的合并(segment merge,optimize)

每秒一个segment file,会导致文件过多,而且每次search都要搜索所有的segment,很耗时。所以在Elasticsearch内部会默认在后台执行segment merge操作(forcemerge),在merge的时候,被标记为deleted的document也会被彻底物理删除掉。
每次merge的操作流程:
(1)选择一些有相似大小的segment,merge成一个大的segment
(2)将新的segment flush到磁盘上去
(3)写一个新的commit point,包括了新的segment,并且排除旧的那些segment
(4)将新的segment打开供搜索
(5)将旧的segment删除

POST /my_index/_optimize?max_num_segments=,尽量不要手动执行,让它自动默认执行就可以了

Elasticsearch由浅入深(十一)内核原理的更多相关文章

  1. 《Linux内核原理与设计》第十一周作业 ShellShock攻击实验

    <Linux内核原理与设计>第十一周作业 ShellShock攻击实验 分组: 和20179215袁琳完成实验及博客攥写 实验内容:   Bash中发现了一个严重漏洞shellshock, ...

  2. 2019-2020-1 20199329《Linux内核原理与分析》第十一周作业

    <Linux内核原理与分析>第十一周作业 一.本周内容概述: 学习linux安全防护方面的知识 完成实验楼上的<ShellShock 攻击实验> 二.本周学习内容: 1.学习& ...

  3. 2020-2021-1 20209307 《Linux内核原理与分析》第十一周作业

    这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)> 这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第十一周作业> 这个作业的目标 ...

  4. Elasticsearch由浅入深(六)批量操作:mget批量查询、bulk批量增删改、路由原理、增删改内部原理、document查询内部原理、bulk api的奇特json格式

    mget批量查询 批量查询的好处就是一条一条的查询,比如说要查询100条数据,那么就要发送100次网络请求,这个开销还是很大的如果进行批量查询的话,查询100条数据,就只要发送1次网络请求,网络请求的 ...

  5. 《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

  6. 20169207《Linux内核原理及分析》第十三周作业

    第一周作业::对Linux的基本知识进行了了解,并对基本操作进行熟悉和应用. 第二周作业::了解了冯诺依曼体系结构.各种寄存器的功能和汇编指令的作用和功能. 第三周作业::这周主要了解了Linux系统 ...

  7. 2017-2018-1 20179205《Linux内核原理与设计》第七周作业

    <Linux内核原理与设计>第七周作业 视频学习及操作分析 创建一个新进程在内核中的执行过程 fork.vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_for ...

  8. 2017-2018-1 20179209《Linux内核原理与分析》第七周作业

    一.实验 1.1task_struct数据结构 Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个进程所需的所有信息.它定义在linux-3.18.6 ...

  9. Elasticsearch 技术分析(九):Elasticsearch的使用和原理总结

    前言 之前已经分享过Elasticsearch的使用和原理的知识,由于近期在公司内部做了一次内部分享,所以本篇主要是基于之前的博文的一个总结,希望通过这篇文章能让读者大致了解Elasticsearch ...

  10. 2019-2020-1 20199303<Linux内核原理与分析>第二周作业

    2019-2020-1 20199303第二周作业 1.汇编与寄存器的学习 寄存器是中央处理器内的组成部份.寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令.数据和位址.在中央处理器的控制部件中 ...

随机推荐

  1. zabbix 自定义mysql监控

    一.配置zabbix-agent 编辑 /etc/zabbix/zabbix_agentd.conf文件  增加如下两个配置 1.vim /etc/zabbix/zabbix_agentd.conf ...

  2. LINQ之 Join 与 GroupJoin

    声明:本文为www.cnc6.cn原创,转载时请注明出处,谢谢! 一.编写Person与City类,如下: class Person { public int CityID { set; get; } ...

  3. WPF Button IsMouseOver Background

    https://stackoverflow.com/questions/17259280/how-do-you-change-background-for-a-button-mouseover-in- ...

  4. 【机器学习笔记】Python机器学习基本语法

    本来算法没有那么复杂,但如果因为语法而攻不下就很耽误时间.于是就整理一下,搞python机器学习上都需要些什么基本语法,够用就行,可能会持续更新. Python四大类型 元组tuple,目前还没有感受 ...

  5. 部署 asp.net 网站到 Azure

    部署asp.net网站到Azure 前言 前些天一直在写一个单页面web应用程序,终于完成了,于是考虑发布到云服务器.本人没有AWS账号,遂本打算使用谷歌云.参考文档后发现官方文档给出的方式为在vis ...

  6. win10 net framework 3.5提示错误代码0x800f081f

    重装了win10系统,碰到以下几个问题 1.安装本地iis -启动或关闭windonws功能- 安装net framework 3.5的时候 提示错误代码0x800f081f 2.安装SqlServe ...

  7. Git多账号配置

    在一台电脑上配置多个不同的 ssh key 前言 如果拥有多个Git远程仓库,尤其是其中一个是工作中使用的仓库,只使用一个ssh key安全性很低,建议为不同Git远程仓库配置不同的ssh key. ...

  8. 妹纸对网易严选的Bra是什么评价?

    声明:这是一篇超级严肃的技术文章,请本着学习交流的态度阅读,谢谢! 一.网易商品评论爬取 1.评论分析 进入到网易严选官网,搜索“文胸”后,先随便点进一个商品. 在商品页面,打开 Chrome 的控制 ...

  9. DOIS2019大会,腾讯 DevOps 测试中台探秘

    WeTest 导读 腾讯WeTest受邀参加2019年DevOps 国际峰会,由WeTest产品负责人-殷柱伟老师分享了腾讯DevOps测试中台的实践经验与心得, 议题受到了现场听众及行业媒体的关注与 ...

  10. 004-OpenStack-计算服务

    OpenStack-计算服务 [基于此文章的环境]点我快速打开文章 1.控制节点(controller) 1.1 创库授权  nova_api, nova, 和 nova_cell0 mysql CR ...