Elasticsearch由浅入深(十一)内核原理
倒排索引组成结构以及索引不可变原因
对于倒排索引是非常适合用来进行搜索的
它的结构:
(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由浅入深(十一)内核原理的更多相关文章
- 《Linux内核原理与设计》第十一周作业 ShellShock攻击实验
<Linux内核原理与设计>第十一周作业 ShellShock攻击实验 分组: 和20179215袁琳完成实验及博客攥写 实验内容: Bash中发现了一个严重漏洞shellshock, ...
- 2019-2020-1 20199329《Linux内核原理与分析》第十一周作业
<Linux内核原理与分析>第十一周作业 一.本周内容概述: 学习linux安全防护方面的知识 完成实验楼上的<ShellShock 攻击实验> 二.本周学习内容: 1.学习& ...
- 2020-2021-1 20209307 《Linux内核原理与分析》第十一周作业
这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)> 这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第十一周作业> 这个作业的目标 ...
- Elasticsearch由浅入深(六)批量操作:mget批量查询、bulk批量增删改、路由原理、增删改内部原理、document查询内部原理、bulk api的奇特json格式
mget批量查询 批量查询的好处就是一条一条的查询,比如说要查询100条数据,那么就要发送100次网络请求,这个开销还是很大的如果进行批量查询的话,查询100条数据,就只要发送1次网络请求,网络请求的 ...
- 《Linux内核原理与分析》第一周作业 20189210
实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...
- 20169207《Linux内核原理及分析》第十三周作业
第一周作业::对Linux的基本知识进行了了解,并对基本操作进行熟悉和应用. 第二周作业::了解了冯诺依曼体系结构.各种寄存器的功能和汇编指令的作用和功能. 第三周作业::这周主要了解了Linux系统 ...
- 2017-2018-1 20179205《Linux内核原理与设计》第七周作业
<Linux内核原理与设计>第七周作业 视频学习及操作分析 创建一个新进程在内核中的执行过程 fork.vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_for ...
- 2017-2018-1 20179209《Linux内核原理与分析》第七周作业
一.实验 1.1task_struct数据结构 Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个进程所需的所有信息.它定义在linux-3.18.6 ...
- Elasticsearch 技术分析(九):Elasticsearch的使用和原理总结
前言 之前已经分享过Elasticsearch的使用和原理的知识,由于近期在公司内部做了一次内部分享,所以本篇主要是基于之前的博文的一个总结,希望通过这篇文章能让读者大致了解Elasticsearch ...
- 2019-2020-1 20199303<Linux内核原理与分析>第二周作业
2019-2020-1 20199303第二周作业 1.汇编与寄存器的学习 寄存器是中央处理器内的组成部份.寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令.数据和位址.在中央处理器的控制部件中 ...
随机推荐
- Kubernetes RBAC授权普通用户对命名空间访问权限
Kubernetes RBAC授权普通用户对命名空间访问权限 官方文档:https://www.cnblogs.com/xiangsikai/p/11413970.html kind: Role ap ...
- 升级 ASP.NET Core 3.0 设置 JSON 返回 PascalCase 格式与 SignalR 问题
由于一些 JS 组件要求 JSON 格式是 PascalCase 格式,新版本 ASP.NET Core 3.0 中默认移除了 Newtonsoft.Json ,使用了微软自己实现的 System.T ...
- 2019-11-25-win10-uwp-通过命令行脚本开启旁加载
原文:2019-11-25-win10-uwp-通过命令行脚本开启旁加载 title author date CreateTime categories win10 uwp 通过命令行脚本开启旁加载 ...
- .NET Core跨平台部署于Docker(Centos)- 视频教程
(双击全屏播放) 往期教程: .NET开发框架(一)-框架介绍与视频演示 .NET开发框架(二)-框架功能简述 .NET开发框架(三)-高可用服务器端设计 .NET开发框架(四)-服务器IIS实践教程 ...
- 4、Ext.NET 1.7 官方示例笔记 - 树
<%@ Page Language="C#" %> <%@ Import Namespace="System.Collections.Generic&q ...
- es7之修饰器
什么是修饰器 修饰器其实就是一个普通的函数,用来修饰类以及类的方法. 比如: @test class DecoratorTest { } function test(target) { target. ...
- nodejs块级作用域
现在让我们了解3个关键字var.let.const,的特性和使用方法. var JavaScript中,我们通常说的作用域是函数作用域,使用var声明的变量,无论是在代码的哪个地方声明的,都会提升到当 ...
- opencv::KMeans方法概述
KMeans方法概述 . 无监督学习方法 . 分类问题,输入分类数目,初始化中心位置 . 硬分类方法,以距离度量 . 迭代分类为聚类 //---------- //迭代算法的终止准则 //--- ...
- Spring登录实例
Spring登录实例 项目结构 首先看一下整个项目的目录结构,如下: 导入Jar包 工欲善必先利其器,导入一下Jar包 配置文件 web.xml 配置 web.xml配置文件,如下: xmlns:xs ...
- 达能依靠Matrikon进行数据存储和分析
达能是一家致力于通过食品实现健康的公司,业务遍及五大洲130多个国家.在罗马尼亚,达能每天在布加勒斯特的工厂生产100万瓶酸奶.由于质量和产品安全在达能最为重要,因此监控和分析工业过程需要非常高效才能 ...