ElasticSearch
文章目录
1.ElasticSearch是什么
●SQL:使用SQL进行模糊搜索只能使用like %内容%(这类查询不走索引),如果是大数据环境下特别慢。关系型数据库相当于把一个对象解析为各个字段,存在数据库,查询时再重新构造出对象,mysql基于B+树索引,来实现快速索引。
●ElasticSearch:用来进行全文索引(InnoDB不支持哦),尤其擅长模糊搜索,不建议当成数据库使用(一般在大型数据环境下使用),是一个开源的高扩展的分布式全文检索+分析引擎,大数据下能达到高速搜索。Es是文档存储,把对象原原本本的放进去,取出来时直接取出,并且基于倒排索引,再性能和空间上都更加有优势。
●能做什么(为什么非要用ES)
■数据库本身就是为了提供存储功能而涉及的,只是顺便附带了搜索的功能。而使用数据库搜索时,更多的是基于精确匹配的搜索,而与精确匹配相对,模糊匹配更贴近人的思维方式(可以修正并理解你的真实意图)
■维基百科,百度,全文检索。
■Github,全文检索
■日志数据分析:logstash采集日志,Es进行复杂的数据分析,ELK技术(ElasticSearch + logStash + kibana)
■商品价格监控,用的也是这个的数据分析功能。
2.ElasticSearch核心概念
●之前了解的MySQL是关系行数据库,Redis是基于key-value的,而ElasticSearch是面向文档的,二者对比如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UuNan6AK-1651745614474)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/263.png)]
●ElasticSearch(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下面又包含了多个文档(行),每个文档中又包含多个字段(列)
●ElasticSearch中的一切数据都是json。
●物理设计:ElasticSearch在后台把每个索引划分成多个分片,每分分片可以在集群中的不同服务间迁移。
●逻辑设计:一个索引类型中,包含多个文档,比如文档1,文档2,当我们索引一篇文档时,可以通过这样的顺序找到他:索引->类型->文档id,通过这个组合能具体所引导某个具体的文档(ID是一个字符串)
●文档(JSON格式):索引和搜索的最小单位,有以下几个重要特点:
■自我包含:一篇文档同时包含字段和对应的值,即key:value
■可以嵌套:文档中包含文档{json本身可以转化为对象嘛}
■结构灵活:在关系型数据库中,要提前定义好字段才能使用,但在elasticSearch中,字段非常灵活,我们有时可以忽略字段或者添加一个字段。(机关我们可以随意新增或者忽略某个字段,但是字段的类型还是非常重要,比如年龄的字段类型,可以是字符串或整形。因为ElasticSearch会保存字段和类型之间的映射以及其他的设置,这种映射具体到每种映射的类型。)
■文档主要元信息:所属索引名:所属类型名(有点像类名哦),文档id,存储的json数据,文档的版本信息,相关性打分。
●类型:类型是文档的逻辑容器,就像是关系型数据库中,表是行的容器。类型中对于字段的定义称为银蛇,比如name映射为字符串类型。我们说文档是无模式的,他们不需要拥有映射中所定义的所有字段,比如新增一个字段(ES自动将新的字段加入映射,但是这个字段不确定是什么类型,ES会自己去猜,eg 值为18,那么ES会认为他是整形,但ES也可能猜错,所以最安全的方式还是提前定义好所需要的映射)
●索引:索引是映射类型的容器,ES中的索引是一个非常大的文档集合,索引存储了映射类型的字段与其他设置,然后他们被存到各个分片上,每个索引有自己的Mappings,用于定义文档的字段名和字段类型(对于mysql中的一张表,ES中可以根据各个属性建立多条索引);每个索引通过自己的Settings用于定义不同数据的分布,即索引使用分片情况。
●总结:相当于一个索引,存了各种映射类型,相当于SQL中数据库存了一张表,表中的行都是一个格式的,所以这个类型中的文档也都是一个格式的(应当可以理解为类下的json对象都是一个格式的吧)。SQL通过数据库>表>行找数据,而ES通过索引>类型>文档找数据。
●集群:ES集群部署使其可以随时使用并按需扩容(集群是如何部署的,往常的HTTP服务的话大都是通过Nginx,xhs使用的RPC方式通过注册中心,看这个服务下有多少个实例,每个实例的地址端口都是什么,在哪个节点上(每个实例就是一个节点),权重(负载均衡使用),注:通过cluster.name设置集群名称)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SzOkcLjU-1651745614475)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/264.png)]
●节点:一个节点就是一个服务进程实例,一个集群可以有多个节点,通过node.name定义节点的名称
■Data节点:保存分片数据的节点
■Coordinationg节点:接受客户端请求,将请求分发到适合的节点,最后再对结果进行汇聚,每个节点默认都是Coordinationg节点。
●分片:索引中的数据都分布在分片上,一个分片就是一个Lucene实例,分片分为主分片和副分片,一般主分片和副分片应该分布到不同节点上。
■主分片:用于解决数据水平扩展的问题,主分片的数目在索引创建后指定,后续不能更改
■副分片:用于提高数据可用性,是主分片是拷贝,数量可以动态调整。
3.ElasticSearch中节点和分片如何工作
●一个集群至少有一个节点,而一个节点就是ES进程,节点可以有多个索引分片,我们创建一个索引,这个索引会有五个主分片(p0-p4),每个主分片又会有一个副本(r0-r4)。如下图一个索引五个主分片,五个副本分片,以集群三个节点为例,主分片和复制分片不在同一个节点内,这样就算某个节点挂了,数据也不会丢失。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FkTCXhHJ-1651745614475)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/265.png)]
●实际上每一个分片都是一个Lucene索引,即一个包含倒排索引的文件目录,倒排结构使得ES在不扫描全部文档的情况下就能告诉我们哪些文档包含特定关键字。(下面重点看下什么是倒排索引,就懂了为啥ES这么快)
■ES中默认会对文档中的每个字段做倒排索引,但可以强行指定不对哪些字段设置倒排索引。
■一个索引由文档中所有不重复的列表组成,对于每一个词,都有一个包含它的文档的列表,eg如下两个文档包含以下内容
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zGkiicxq-1651745614475)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/266.png)]
■为了创建倒排索引,首先需要将每个文档拆分为独立的词(tokens),然后创建一个包含所有不重复的token的排序列表,然后列出每个token出现在哪些文档中。(上面说了对每个字段都创建倒排索引,所以这里应用于ES的话,应该是将每个字段的内容拆分为独立的词吧,所有文档的相同字段建立一个索引)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jj0xk9Es-1651745614476)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/267.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fduNLSNJ-1651745614477)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/268.png)]
■我们可以看到两个文档都匹配,但是第一个文档匹配的程度更高,下面主要观察一下正排和倒排的区别:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6wThXe4c-1651745614478)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/269.png)]
■原始是正排,可以看到如果搜python标签的文章我们要对所有文档进行遍历,效率很低,但是倒排是根据标签(这个标签此时问文档的一个字段)去找文章,我们只要根据这个字段的索引去找文章,效果就会很快。
●在ES中,索引被分为很多片,每个分片都是一个luncene索引,所以可以说一个ES索引是由多个Luncene索引组成的。
4.ES底层数据结构
●ES查询的这么快,必然离不开其底层数据结构的支持(词典+倒排表)
●首先输入进来之后会经过分词(中文最好的就是ik分词),分词后所有词汇总的结果我们作为一个term dictionary,而我们需要通过分词找到对应的记录,将这些文档ID保存在一个postinglist中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NL1sFzkY-1651745614478)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/270.png)]
●由于Term dictionary中的词特别多,所以我们通常对齐进行排序,查找的时候采用二分查找,就无须遍历整个dictionary了。
●此外Term dictionary中的词实在是太多了,不可能把所有的词都放到内存中,所以ES还抽象了一层叫Term Index(FST形式),这层只存词的前缀,将这个保存到内存中(后面Luence有详细介绍)
■FST形式占用空间小,通过对词典中单词前缀和后缀的重复利用,压缩了空间
■查询速度快
●PostingList也会使用FOR编码技术对里面的数据(文档ID)进行压缩,节省空间。
■主要思路是将32位无符号整数按照高16位分桶,即最多2^16个桶,存储数据时,按照数据的高16位找到对应桶,然后将低16位也放入桶中(也可以不按16来分,毕竟有点时候文档ID不一定是32位,可以都和一个数取余之类的,思想不变)
●因为我们查出来的文档ID往往要做交集和并集操作,所以PostingList采用RoaringBitmaps(可以节省空间,快速得到结果)对文档进行交集并集操作。
●下面详细说一下这两部分的数据结构
■词典:词典使用的是FST(Finite State Transducers,有限状态传感器)结构,内存存放共享前缀索引,磁盘存放后缀磁块。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZXTA1dZP-1651745614479)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/271.png)]
■注:FST要求输入有序,Lucene会将解析出来的文档单词预先排序,具体原因见下面例子。
■tip部分,每列一个FST索引,所以会有很多个FST,每个FST存放前缀和后缀块指针,这里前缀就是a,ab,ac
■tim部分存放后缀块和词的其他信息,如倒排表指针等
■doc文件里就是每个词的倒排表
■检索流程如下
▼内存加载tip文件,通过FST匹配前缀找到后缀词块文职
▼根据词块位置,读取磁盘中tim文件中后缀词块,并找到后缀和相应倒排表位置信息。
▼根据倒排表位置去doc文件加载倒排表
■前缀如何计算的呢,后缀如何写磁盘并通过FST定位呢,下图为FST构建过程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-um1RXtDk-1651745614480)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/272.png)]
▼插入abd时,没有输出(未与当前存在的元素找到公共前缀)
▼插入abe时,计算出前缀ab,但此时不知道后续还会不会有其他以ab为前缀的单词,所以也无输出
▼插入acf时,因为有序(这里显示出了有序的重要性,否则加上acf后,后面再出现以ab为前缀的,就没法补了),知道不会再有以ab为前缀的单词了,这时候就可以写tip和tim了,tim中写入后缀d,e和他们的倒排表位置ip_e,ip_d,tip中写入a,b和以ab为前缀的后缀词块位置fp_b
▼插入acg时,计算出和acf共享前缀ac,这时输入已经结束了,所有数据写入磁盘。tim中写入后缀词块f,g以及相对应的倒排表位置,tip中写入c和以ac为前缀的后缀词块位置
■倒排表结构:倒排表就是文档号集合,现在的数据结构叫Frame of reference,有以下两个特点:
▼数据压缩:可以通过下图看出,怎么将6个数字由原来的24bytes压缩到7bytes(因为是有序的,所以后面的数减去前面的,留下较小的数,然后分组,用组中最大的bit位存(比如图中第一组最大227,要用8位存,所以就3个8位的))
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RIjAaOLr-1651745614481)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/273.png)]
■眺表加速合并
▼正向文件(原始文件):fdt文件就是原始文件,占了索引库90%的空间,fdx文件为索引文件,通过文档号快速得到文档的位置,文件结构如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WDJlG9sY-1651745614482)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/274.png)]
▼fnm中为元信息,存放了各字段类型,字段名,存储方式等信息
▼fdt为文档值,里面一个chunk就是一个块,lucene索引文档时,先缓存文档,缓存大于16KB就会压缩,一个chunk包含了该chunk起始文档,多少个文档,压缩后的文档内容
▼fdx为文档索引号,倒排表存放的是文档号,通过fdx能迅速定位到文档位置即chunk位置。为眺表结构,首先把1024个chunk归为一个block,每个block记载了起始文档值,block相当于一级眺表。
■查找文档的三步:
▼二分查找block,定位属于哪个block
▼从block里根据每个chunk起始文档号,找到属于哪个chunk和chunk的位置
▼加载fdt的chunk找到文档。
●可以看出Lucene对原始文件的存放是行式存储
●列式存储-DocValues
■倒排索引能够解决从词到文档的快速映射,但当我们需要对检索结果分类,排序,计算等聚合操作时,需要文档到值的快速映射,这无论是倒排还是行式都不能直接满足。
■之前是通过按列逆转来实现(但肯定会造成大量内存占用)
■现在使用DocValues方法来解决,虽然比之前慢一些,但是稳定性极大提升
■ElasticSearch对其应用体现在聚合功能上(sum,min,分组等),基于这些功能ElasticSearch不再仅限于解锁。
■下图展示了ES如果就倒排索引和DocValues实现等价SQL的:
▼从倒排表中找到销售部门的倒排表
▼根据倒排表去性别的DocValues里取出每个人对应的性别,进行分组
▼根据分组情况和年龄DocValues,计算各分组人数和平均年龄
▼因为ElasticSearch是分区的,所以对每个分区的返回结果合并就是最终的结果。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f86rKTA0-1651745614483)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/275.png)]
5.ES架构(可能重复,但多看看吧)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J1ccvKkn-1651745614483)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/276.png)]
●一个集群可能会有很多个节点,即运行着ElasticSearch的机器
●众多节点中有一个master node,负责维护索引元数据,切换主分片和从分片身份,如果挂了要重新选举。
●ES最外层就是Index,一个Index我们可以发到不同的Node上存储,这个操作就叫做分片,比如下面分到四个节点上存储,就有四个分片,四个分片的数据合起来就是索引的数据。
■为什么分片:如果只有一个分片,那么只在一个节点上存储,随着数据量增大,一个节点未必能容纳。并且多个分片在写入或者查询的时候可以并行操作,提高吞吐量。
■副分片:用来防止主分片数据丢失。而且同一主副分片不在同一节点。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U4C8W0kr-1651745614484)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/277.png)]
6.ES写入流程
●我们写入ES的时候都是写到主分片上的,下面详述一下过程:
■客户端写入一条数据,到ES集群里面就是由节点来处理这次请求。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HUZHZ5mP-1651745614484)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/278.png)]
■集群上的每一个节点都是coordinating node(协调节点),协调节点表明这个节点可以做路由。如果节点1接收到来请求,但发现这个请求的数据应该是由节点2处理(因为主分片在节点2上),就会把请求转发到节点2.(协调节点通过hash算法计算出在哪个主分片上,然后路由到相应节点)
■路由到对应节点以及主分片后,依次执行以下事情
▼将数据写到内存缓冲区
▼将数据写到translog区
▼每隔1s数据从buffer中refresh到fileSystemCache中,生成segment文件,一旦生成segment文件,就能通过索引查到了。
▼refresh完,memory buffer就清空了
▼每隔5s,translog从buffer flush到磁盘中
▼定期/定量从FileSysteemCache中,结合translog内容flush index到磁盘
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EJ2W5d2y-1651745614485)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/279.png)]
●等到主分片写完了,会将数据并行发送到副本节点上,等到所有节点写入成功节返回ack给协调节点,协调节点返回给客户端,完成写入。
7.ES更新和删除
●首先二者都是要给对应的doc打上.del标识,如果是更新就打完标识后重新写入一条
●前面插入的时候说过,每隔1s会refresh缓冲区到fileSystemCache,生成segment文件,那segment文件会越来越多,ES会有一个merge任务,把多个segement文件合并为一个,合并过程中,会把delete状态的doc给物理删除。
8.ES查询
●查询方式无非就是根据ID查doc;根据query查doc,下面意义介绍。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3WjlhKXC-1651745614485)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/280.png)]
●根据ID查doc(下图中的Get):挨个检索就行了,实时查询
■检索内存中的Translog文件
■检索硬盘中的Translog文件
■检索硬盘中的segment文件
●根据query匹配doc(下图中的search):近实时查询,因为segment文件是隔1s生成一次的
■同时查询内存和硬盘中的segment文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oNtfbZlQ-1651745614486)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/281.png)]
●换个角度ES查询又可以分为三种
■query——and——fetch(查询完就返回整个Doc内容):只适合于只需要查一个分片的请求
■query——then——fetch(先查询出对应doc id,然后根据doc id去匹配文档)
■DFS——query——then——fetch(先算分,再查询,分指的是词频率和文档的频率,相关性)
■最常见的为第二种:整体流程为:
▼客户端请求发送到集群的某个节点上。
▼因为每个节点都是coordinate node,协调节点将所搜请求发到所有分片上(主/副都可)
▼每个分片将自己搜索出的结果(doc id)返回给协调节点,由协调节点进行数据的合并和排序等操作
▼接着协调节点根据doc id 去各个节点上拉取实际的document数据,最终返回给各个客户端。
9.ES如何保证数据一致性,实时性
●数据一致性:多个副本是否能保持一致的特性。对系统的一个数据更新成功后,如果所有页都能读到最新的值,该系统就被认为具有强一致性。(分布式系统不可能同时满足CAP特性)
●MySQL中数据一致性通过原子性,隔离性,持久性来保证,而ES也是通过一些来保证
■原子性:一个写入或者更新操作,要么成功要么失败,没有中间状态(Add和Delete直接调用Luence的接口进行原子操作,update通过DeleteThenAdd完成,在Delete操作前会加refreshLock,禁止Refresh,等Add完成后才释放,保证原子性)
■持久性:数据写入成功后,数据持久存在,不会回滚丢失,通过replica和Translog两种机制保证。
■隔离性:多个写入并发操作互不影响。采用Version和局部锁来保证更新的是特定版本的数据。
■一致性:数据写入成功后,查询时保证读取到最新数据。数据写入成功后,需要完成refresh操作之后才可读,由于无法保证主和副分片同时refresh,所以存在查询不稳定情况,这里只保证最终一致性。
●ES集群数据同步机制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jPwVMIy6-1651745614486)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/282.png)]
■ES采用一主多从的复制方式,index由多个分片组成,每个分片又分为一个主的和多个副的。数据写入的时候,首先根据routing规则对路由参数进行hash,确认要写入的分片,然后从集群中找出该分片的主分片,写入数据,主分片写入数据后,将请求同时发送给多个副分片,请求在全部副分片上执行,若都执行成功则响应主分片,主分片返回结果给客户端。
■primary要等全部的replica返回才能返回给客户端,所以延迟就会受到最慢的replica的影响。写入延迟等于primary write + max(replicas write)。副本的存在虽然降低了写入效率,但可以避免单机或磁盘故障导致的数据丢失。
■replica写入失败,primary会执行一些充实策略,尽可能保证replica写入成功,如果一个replica写入失败,primary会将replica节点报告给Master,然后Master更新Meta中的配置,将词replica从中移除,移除后此replica不再承担读请求了。在Meta更新到各个Node之前(可能很多节点从该Replica处读呢),用户可能还会读到这个replica的数据。考虑ES本身就是近实时的,可以接受短期内读到旧数据。
●ES数据并发冲突控制是基于乐观锁和版本号机制:
■一个doc第一次创建的时候,他的Version内部版本号就是1;以后,每次对这个doc进行修改或者删除,都会对这个version版本号加一。
■客户端对es数据进行更新的时候,带上了版本号,带的版本号与es中的版本号一致才能修改成功,否则抛出异常。如果客户端没有带上版本号,首先会读取最新版本号再尝试更新,这个尝试CAS操作,可能要尝试很多次才能成功。
■ES节点更新后会向副本节点同步更新数据(同步写入),直到所有副本都更新了才返回成功。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NRkPD7l4-1651745614487)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/283.png)]
●master节点的功能:
■主节点负责ping所有的其他节点,判断是否有节点已经挂掉
■创建或删除索引
■决定分片在节点间分配
●ES主节点的选举算法-Bully:bully是一个分布式系统中动态选择master节点的算法,进程号最大的非失效节点为master。
■算法用三种消息类型
▼选举消息(Election Message:宣布要进行选举)
▼应答消息(Answer /Alive Message:Responds to the Election Message)
▼选举成功消息(Coordinator(Victory)Message:被选举人宣布选上了)
■当一个进程p从失败中恢复,或者接收到主节点失效信息,进程p会做以下事情:
▼如果p有最大进程ID,那么它会像其他节点广播Coordinator Message。否则就是P向进程号比它大的进程发送Election Message。
▼如果进程p发送Election Message后,没有接收到应答,就会向其他节点广播Coordinnator Message(比我大的都挂了,我赢了)并成为。
▼如果进程P接收到进程号比他高的进程的Answer Message,那么P本次选举就失败了,等待接收其他节点的Coordinnator Message。
▼如果进程P接收到比它进程号高的Election Message,那么它就会向该节点返回一个Answer Message,并启动选举进程,向比他更高的进程发送Election Message。
▼如果进程P收到Corrdinator Message,那么它就会把发送这条消息的节点看做master进程。
■选举过程
▼当master失效以后,各个节点会ping discovery.zen.ping.unicast.hosts的IP,找到存活的节点并过滤。
▼过滤:找到所有可能成为master节点的集合masterCandidates-包含自己。
▼如果activeMasters为空,即不存在活着的节点,同时当前或者的节点满足中minimum_master_nodes的数量,那么就从masterCandidates挑出ID最大的节点,让其成为master节点。如果activeMaster不为空,则在其中选ID最大的节点即可。
●ES如何保证实时性
■通常来讲,一个index由若干个分片组成,搜索的时候按分片搜索,我们索引一个分片后,每个分片都会通过fsync(文件同步)操作持久化到硬盘,而fsync操作比较耗时,如果每索引一条数据都做一个full Commit操作,提交和查询的延迟都非常大,不可能做到实时搜索。
■FileSystemCache 和refresh:ES和磁盘之间引入了一层叫FileSystemCache的系统缓存,通过这层cache使得es拥有实时响应能力。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mk7isaph-1651745614487)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/284.png)]
■Es中新增的doc会被收集到indexing buffer 区后被重写为一个segment,然后直接写入fileSystem,因为这个操作是非常轻量级的,耗时较少,经过有一段时间间隔或者达成某种条件后,才会reflush到磁盘上,这个操作非常耗时。但只要segment文件被写入cache后,这segment就可以打开和查询,从而确保在短时间内就可以搜到。
■在Es中,这个轻量级的写入和打开一个Cache中的segment的操作叫refresh,默认情况下es集群中的每个分片会隔1s自动refresh一次,这就是我们为什么说es是近实时,也就是说索引给插入一条数据后,我们需要等待1s才能搜到这条数据,这是es对写入和查询一个平衡的设置方式,Flush时间间隔太长,可靠性就会降低,太短就失去了意义。
■为了避免segment从内存flush到磁盘这段时间节点crash掉,导致数据丢失,数据经过lucene引擎处理后会写入Translog,当节点重启后会根据Translog恢复到checkPoint。(每次flush后都会清空旧的TransLog)
10.ELK
●ElasticSearch + LogStash + Kibana:是一套开源的日志管理方案,可以用它搭建可视化的日志分析平台。
●ElasticSearch:这个在前面说到过,就是一个分布式搜索,分析引擎。(数据来源于MySQL,Redis,HIDB等数据库,经过离线模块处理后,放到ES中)
●LogStash:是一个管理日志的工具,可以用它去收集日志,转换日志,解析日志,并将其转换为数据提供给其他模块调用,例如将数据提供给ES使用。
●Kibana:开源的数据可视化工具,为ES提供友好的日志分析Web界面,帮助汇总,分析和搜索重要数据日志。