ElasticSearch

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界面,帮助汇总,分析和搜索重要数据日志。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值