当前位置:首页 » 操作系统 » es的算法

es的算法

发布时间: 2023-02-01 22:07:34

㈠ 求工程进度中ES、EF、LS、LF、TT、FT的计算方法,通俗易懂些,呵呵,谢谢

先解释一下这几个的意思

ES:最早开始
EF:最早结束
LS:最迟开始

LF:最迟完成
DU:活动历时
FT:总时差

然后说一下他们之间的换算

EF(最早结束)=ES(最早开始)+DU(活动历时)
LF(最迟完成)=LS(最迟开始)+DU(活动历时)
FT(总时差)=LF(最迟完成)-EF(最早结束)

㈡ ES集群原理与搭建

查看集群健康状况:URL+ /GET _cat/health

Cluster

代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的。

Shards

代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。

replicas

代表索引副本,es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡。

Recovery

代表数据恢复或叫数据重新分布,es在有节点加入或退出时会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动时也会进行数据恢复。

(2)、ES为什么要实现集群

在单台ES服务器节点上,随着业务量的发展索引文件慢慢增多,会影响到效率和内存存储问题等。

我们可以采用ES集群,将单个索引的分片到多个不同分布式物理机器上存储,从而可以实现高可用、容错性等。

ES集群中索引可能由多个分片构成,并且每个分片可以拥有多个副本。通过将一个单独的索引分为多个分片,我们可以处理不能在一个单一的服务器上面运行的大型索引,简单的说就是索引的大小过大,导致效率问题。不能运行的原因可能是内存也可能是存储。由于每个分片可以有多个副本,通过将副本分配到多个服务器,可以提高查询的负载能力。

(3)、ES是如何解决高并发

ES是一个分布式全文检索框架,隐藏了复杂的处理机制,内部使用 分片机制、集群发现、分片负载均衡请求路由。

Shards 分片:代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。

Replicas分片:代表索引副本,es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡。

1、每个索引会被分成多个分片shards进行存储,默认创建索引是分配5个分片进行存储。每个分片都会分布式部署在多个不同的节点上进行部署,该分片成为primary shards。

注意:索引的主分片primary shards定义好后,后面不能做修改。

2、为了实现高可用数据的高可用,主分片可以有对应的备分片replics shards,replic shards分片承载了负责容错、以及请求的负载均衡。

注意: 每一个主分片为了实现高可用,都会有自己对应的备分片,主分片对应的备分片不能存放同一台服务器上。主分片primary shards可以和其他replics shards存放在同一个node节点上。

3、documnet routing(数据路由)

当客户端发起创建document的时候,es需要确定这个document放在该index哪个shard上。这个过程就是数据路由。

路由算法:shard = hash(routing) % number_of_primary_shards

如果number_of_primary_shards在查询的时候取余发生的变化,无法获取到该数据

注意:索引的主分片数量定义好后,不能被修改

高可用视图分析(下图所示:上面的图,如果节点1与节点2宕机了,es集群数据就不完整了。下面图,如果节点1与节点2宕机了,es集群数据还是完整的)

(1)、服务器环境

准备三台服务器集群

| 服务器名称 | IP地址 |
| node-1 | 192.168.212.182 |
| node-2 | 192.168.212.183 |
| node-3 | 192.168.212.184 |

(2)、关闭防火墙

(3)、**** http://192.168.212.185:9200/_cat/nodes?pretty

*号表示为master节点

注意:

注意克隆data文件会导致数据不同步

报该错误解决办法 :

failed to send join request to master

因为克隆导致data文件也克隆呢,直接清除每台服务器data文件。

㈢ 工程进度中ES、EF、LS、LF、TT、FT的计算方法是什么

先解释一下这几个的意思 ES:最早开始 EF:最早结束 LS:最迟开始 LF:最迟完成 DU:活动历时 FT:总时差 然后说一下他们之间的换算 EF(最早结束)=ES(最早开始)+DU(活动历时) LF(最迟完成)=LS(最迟开始)+DU(活动历时) FT(总时差)=LF(最迟完成)-EF(最早结束)

㈣ ET LT ES EF LS LF TF FF 8个时间参数怎么算

ES、EF:

采用正向计算(从项目开始的活动逐项计算到项目结束)

ES=Latest EF(所有紧前活动项的EF)

LS、LF:

采用逆项计算(从项目结束的活动逐项计算到项目开始)

LF=Earliest (所有紧后活动项的LS)

总时差:Float=LF-EF=LS-ES

计算方法

(1)以终点节点为完成节点的工作,其总时差应等于计划工期与本工作最早完成时间之差。

(2)其他工作的总时差等于其紧后工作的总时差加本工作与该紧后工作之间的时间间隔所得之和的最小值。

总时差。双代号时标网络图总时差,教材中的计算公式=紧后工作的总时差+本工作与该紧后工作之间的时间间隔所得之和的最小值。

以上内容参考:网络-总时差

㈤ ES选举-类Bully算法

bully算法是一个分布式系统中动态选择master节点的算法,进程号最大的非失效的节点将被选为master。
算法用三种消息类型:

当一个进程P从失败中恢复,或者接收到主节点失效信息,进程P将做以下事情:

我看的源码是5.6版本的。因此以下的解释都是依据5.6的源码来说的。
当master节点失效之后,各个节点find master的过程如下:
1)每个节点会ping配置文件中discovery.zen.ping.unicast.hosts的IP,找到所有存活的节点并过滤
2)找到非本身的active master

3)找到所有的可成为master的节点集合masterCandidates ,包含自己

4)如果activeMasters 为空,也就是说不存在活着的master节点,同时当前活着的节点满足配置中discovery.zen.minimum_master_nodes的数量,那么就从masterCandidates 挑出ID最小的节点,让其成为master节点。如果activeMasters 不为空,则从中选择最小的ID成为Master节点即可。

electMaster.electMaster方法和electMaster.tieBreakActiveMasters方法则都是从集合中选取最小节点的ID:

如果当前不存在active master,那么activeMasters 一定为空,则从masterCandidates 从选出id最小的节点即可。
如果当前存在active master,且当前节点不是active maste,那么从activeMasters 中选出id最小的节点。
如果当前存在active master,且当前节点是active maste,那么activeMasters 为空,从masterCandidates 中选出id最小的节点即自己。

在我的感觉中,当前active master的个数要么为空,要么为1,这边不知道为什么要用一个链表。。。为了防止脑裂情况出现吗??

㈥ es深入搜索之全文检索

  我们之前介绍过结构化搜索的简单使用,接下来,我们来看怎样在全文字段中搜索最相关的文档。

  全文搜索包括两个最重要的方面:

  1. 查询与结果的相关性,并根据相关性对结果进行排名。
  2. 分析,将数据转化为有区别的、规范化的的过程。

  所有的查询都或多或少的会进行相关度计算,但不是所有的查询都会有分析阶段,文本查询可以分为两个部分:
  1. 基于词项的查询,如 term 或 fuzzy 这样的查询是没有分析阶段的。他们对单个词项进行操作。
  2. 基于全文的查询,比如match, 它们会先了解字段映射的信息,判断字段是否被分词,是否是日期还是数字等, 再根据映射信息,构建要查询的词项列表,根据列表进行查询。

  匹配查询 match 是个核心查询。无论需要查询什么字段, match 查询都应该会是首选的查询方式。使用方式如下:

es执行上列步骤的过程如下:

  如果一次只能搜索一个词语,那么全文搜索会不太灵活,幸运的是 match 也支持多词查询 。

以上查询其实先后执行了两次 term 查询,使用 bool 进行包含,然后将结果进行合并返回。

  以上查询其实会导致出现不相关的结果,我们只想搜索包含words1 和 words2 的文档,而不是 or 的结果。match 查询还可以接受 operator 操作符作为输入参数,默认情况下该操作符是 or 。

这种操作还是有些不妥,在 and 和 or 中间选择太过绝对,如果用户给出了5个词项,我们想只要满足其中4 个 就表示匹配,match 也提供了 minimum_should_match 参数,他是一个最小匹配参数,我们可以控制满足的词项超过改值则表示匹配,最好是使用百分比,因为你也不知道用户提供了多少个词项。该参数的设置非常灵活,完整的信息参考文档,请看 https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-minimum-should-match.html#query-dsl-minimum-should-match

如果我们使用 bool 查询黑色、大屏、手机,其中should 语句匹配得越多表示文档的相关度越高,但是我们想要手机所占的权重比较大,内容包括手机的文档排名靠前,可以使用 boost 设置相对权重,注意是相对权重,默认是1。

在说相关度被破坏的原因之前,我们先看看es对于相关度是如何计算的

es 的相似度算法被定义为检索词频率/反向文档频率, TF/IDF ,包括以下内容:

有时,我们索引了一些文档,然后检索发现有些相关度较低的返回排名靠前?

  出现上述原因的情况是因为es由于性能原因,不会计算所有索引该文档的节点的IDF,比如我们索引了10个文档, 其中6个文档中包含 foo ,而由于es是分布式的,一个索引会被分为多个分片,有可能分片一包含的5 个文档,有 4 个包含foo, 而另外一个在分片二中,所以会导致结果有差异。

  在实际应用中,不会出现该问题,因为本局和全局的IDF差异会随着文档数量的增加逐渐降低。如果想要自己处理该问题,可以在搜索请求之后增加 ?search_type=dfs_query_then_fetch ,他会使得es先计算各个分片的 IDF, 然后在求出全局的 IDF, 生产环境中不要使用。因为只要有足够的数据就可以使得差异减少。

㈦ ES原理之选主流程

分布式系统的集群方式大致可以分为主从模式(Master-Slave)和无主模式。

常用的选举算法有比较简单的Bully算法和复杂而强大的Paxos算法。

每个节点有一个唯一ID,然后对集群中所有的节点ID进行排序,选取其中最小的ID所属的节点作为Master。
Bully算法的问题: 假设当前Master因为负载过重而假死,然后ID第二大的被选举为新的Master,这时旧的Master恢复然后又被选举为Master然后又会因为负载过重而假死......

Paxos实现起来非常复杂,但非常强大,尤其在什么时机,以及如何进行选举方面的灵活性比简单的Bully算法有很大的优势,因为在现实生活中,存在比网络链接异常更多的故障模式。
ES使用的是Bully算法,并对其做了一些优化:

㈧ es源码笔记-7.x 选主流程

Discovery模块负责发现集群中的节点,以及选择主节点。ES支持多种不同Discovery类型选择,内置的实现有两种:Zen Discovery和Coordinator,其他的包括公有云平台亚马逊的EC2、谷歌的GCE等。

它假定所有节点都有一个唯一的ID,使用该ID对节点进行排序。任何时候的当前Leader都是参与集群的最高ID节点。该算法的优点是易于实现。但是,当拥有最大ID的节点处于不稳定状态的场景下会有问题。例如,Master负载过重而假死,集群拥有第二大ID的节点被选为新主,这时原来的Master恢复,再次被选为新主,然后又假死
ES 通过推迟选举,直到当前的 Master 失效来解决上述问题,只要当前主节点不挂掉,就不重新选主。但是容易产生脑裂(双主),为此,再通过“法定得票人数过半”解决脑裂问题

1、多数派原则:必须得到超过半数的选票才能成为master。
选出的leader一定拥有最新已提交数据:在raft中,数据更新的节点不会给数据旧的节点投选票,而当选需要多数派的选票,则当选人一定有最新已提交数据。在es中,version大的节点排序优先级高,同样用于保证这一点。

正确性论证:raft是一个被论证过正确性的算法,而ES的算法是一个没有经过论证的算法,只能在实践中发现问题,做bug fix,这是我认为最大的不同。

是否有选举周期term:raft引入了选举周期的概念,每轮选举term加1,保证了在同一个term下每个参与人只能投1票。ES在选举时没有term的概念,不能保证每轮每个节点只投一票。
选举的倾向性:raft中只要一个节点拥有最新的已提交的数据,则有机会选举成为master。在ES中,version相同时会按照NodeId排序,总是NodeId小的人优先级高。

2、Paxos算法
Paxos非常强大,尤其在什么时机,以及如何进行选举方面的灵活性比简单的Bully算法有很大的优势,因为在现实生活中,存在比网络连接异常更多的故障模式。但 Paxos 实现起来非常复杂

本篇只讨论内置的Zen Discovery

整体流程可以概括为:选举临时Master,如果本节点当选,则等待确立Master,如果其他节点当选,则尝试加入集群,然后启动节点失效探测器。

如果集群刚启动则参与选主,否则加入集群
org.elasticsearch.node.Node.start()

选举过程的实现位于 org.elasticsearch.discovery.zen.ZenDiscovery.findMaster() ,该函数查找当前集群的活跃 Master,或者从候选者中选择新的Master。如果选主成功,则返回选定的Master,否则返回空

上面选择临时主节点非常简单,
首先需要判断当前候选者人数是否达到法定人数,否则选主失败。

取列表中的最小值,比较函数通过compareNodes实现,只是对节点 ID 进行排序

选举出的临时Master有两种情况:该临时Master是本节点或非本节点。

(2)超时(默认为30秒,可配置)后还没有满足数量的join请求,则选举失败,需要进行新一轮选举。

超时后直接return,当非临时节点加入集群不成功时,重新发起选主流程
org.elasticsearch.discovery.zen.ZenDiscovery.innerJoinCluster()

(3)成功后发布新的clusterState。
实现如下:

submitStateUpdateTask最终通过TaskBatcher# submitTasks来提交任务。执行任务并发布集群状态的总体过程在 MasterService#runTasks 方法中实现。

(2)向Master发送加入请求,并等待回复。超时时间默认为1分钟(可配置),如果遇到异常,则默认重试3次(可配置)。这个步骤在joinElectedMaster方法中实现。

最终当选的Master会先发布集群状态,才确认客户的join请求,因此,joinElectedMaster返回代表收到了join请求的确认,并且已经收到了集群状态。所以如果返回不成功,则重新发起选主流程
(3)检查收到的集群状态中的Master节点如果为空,或者当选的Master不是之前选择的节点,则重新选举。

1、es通过主从模式以及发现机制保证节点之间的负载均衡,但是es使用量的急剧增加暴露了很多问题,例如,Zen的minimum_master_nodes设置经常配置错误,这会使群集更容易出现裂脑和丢失数据的风险
2、7.x以上版本Coordinator提供了安全的亚秒级的master选举时间,而Zen可能要花几秒钟来选择一个新的master
3、es的master挂了,数据节点在这区间还能对外提供服务吗?
参考
Elasticsearch分布式一致性原理剖析

㈨ es使用与原理6 -- 聚合分析剖析

有些聚合分析的算法,是很容易就可以并行的,比如说max

有些聚合分析的算法,是不好并行的,比如说,count(distinct),并不是说,在每个node上,直接就出一些distinct value,就可以的,因为数据可能会很多,假设图中的协调节点3百万个数据去重后还剩下100万distinct的数据,那么内存需要来存储这100万条数据,这是不可能的

es会采取近似聚合的方式,就是采用在每个node上进行近估计的方式,得到最终的结论,cuont(distcint),100万,1050万/95万 --> 5%左右的错误率
近似估计后的结果,不完全准确,但是速度会很快,一般会达到完全精准的算法的性能的数十倍

precision_threshold优化准确率和内存开销

brand去重,如果brand的unique value,在100个以内,小米,长虹,三星,TCL,HTL。。。
在多少个unique value以内,cardinality,几乎保证100%准确
cardinality算法,会占用precision_threshold * 8 byte 内存消耗,100 * 8 = 800个字节
占用内存很小。。。而且unique value如果的确在值以内,那么可以确保100%准确
100,数百万的unique value,错误率在5%以内
precision_threshold,值设置的越大,占用内存越大,1000 * 8 = 8000 / 1000 = 8KB,可以确保更多unique value的场景下,100%的准确
field,去重,count,这时候,unique value,10000,precision_threshold=10000,10000 * 8 = 80000个byte,80KB

doc value正排索引
搜索+聚合 是怎么实现的?
假设是倒排索引实现的

倒排索引来实现是非常不现实的,因为我们搜索的那个字段search_field 有可能是分词的,这就需要去扫描整个索引才能实现聚合操作,效率是及其低下的。
正排索引结构:
doc2: agg1
doc3: agg2
1万个doc --> 搜 -> 可能跟搜索到10000次,就搜索完了,就找到了1万个doc的聚合field的所有值了,然后就可以执行分组聚合操作了
doc value原理

1、doc value原理

(1)index-time生成

PUT/POST的时候,就会生成doc value数据,也就是正排索引

(2)核心原理与倒排索引类似

正排索引,也会写入磁盘文件中,然后呢,os cache先进行缓存,以提升访问doc value正排索引的性能
如果os cache内存大小不足够放得下整个正排索引,doc value,就会将doc value的数据写入磁盘文件中

(3)性能问题:给jvm更少内存,64g服务器,给jvm最多16g

es官方是建议,es大量是基于os cache来进行缓存和提升性能的,不建议用jvm内存来进行缓存,那样会导致一定的gc开销和oom问题
给jvm更少的内存,给os cache更大的内存
64g服务器,给jvm最多16g,几十个g的内存给os cache
os cache可以提升doc value和倒排索引的缓存和查询效率

2、column压缩

doc1: 550
doc2: 550
doc3: 500

合并相同值,550,doc1和doc2都保留一个550的标识即可
(1)所有值相同,直接保留单值
(2)少于256个值,使用table encoding模式:一种压缩方式
(3)大于256个值,看有没有最大公约数,有就除以最大公约数,然后保留这个最大公约数

重点:
对分词的field,直接执行聚合操作,会报错,大概意思是说,你必须要打开fielddata,然后将正排索引数据加载到内存中,才可以对分词的field执行聚合操作,而且会消耗很大的内存
先修改 字段的fielddata属性为true,再查 就能查找到数据

当然,我们也可以使用内置field(keyword)不分词,对string field进行聚合,如果对不分词的field执行聚合操作,直接就可以执行,不需要设置fieldata=true

分词field+fielddata的工作原理

doc value --> 不分词的所有field,可以执行聚合操作 --> 如果你的某个field不分词,那么在index-time,就会自动生成doc value --> 针对这些不分词的field执行聚合操作的时候,自动就会用doc value来执行
分词field,是没有doc value的。。。在index-time,如果某个field是分词的,那么是不会给它建立doc value正排索引的,因为分词后,占用的空间过于大,所以默认是不支持分词field进行聚合的
分词field默认没有doc value,所以直接对分词field执行聚合操作,是会报错的

对于分词field,必须打开和使用fielddata,完全存在于纯内存中。。。结构和doc value类似。。。如果是ngram或者是大量term,那么必将占用大量的内存。。。

如果一定要对分词的field执行聚合,那么必须将fielddata=true,然后es就会在执行聚合操作的时候,现场将field对应的数据,建立一份fielddata正排索引,fielddata正排索引的结构跟doc value是类似的,
但是只会讲fielddata正排索引加载到内存中来,然后基于内存中的fielddata正排索引执行分词field的聚合操作

如果直接对分词field执行聚合,报错,才会让我们开启fielddata=true,告诉我们,会将fielddata uninverted index,正排索引,加载到内存,会耗费内存空间

为什么fielddata必须在内存?因为大家自己思考一下,分词的字符串,需要按照term进行聚合,需要执行更加复杂的算法和操作,如果基于磁盘和os cache,那么性能会很差

我们是不是可以预先生成加载fielddata到内存中来???
query-time的fielddata生成和加载到内存,变为index-time,建立倒排索引的时候,会同步生成fielddata并且加载到内存中来,这样的话,对分词field的聚合性能当然会大幅度增强

㈩ es查询数据的工作原理是什么

查询,GET某一条数据,写入了某个document,这个document会自动给你分配一个全局唯一的id,doc id,同时也是根据doc id进行hash路由到对应的primary shard上面去。也可以手动指定doc id,比如用订单id,用户id。

我们可以通过doc id来查询,会根据doc id进行hash,判断出来当时把doc id分配到了哪个shard上面去,从那个shard去查询

1)客户端发送请求到任意一个node,成为coordinate node(协调结点)
2)coordinate node进行hash后对document进行路由,将请求转发到对应的node,此时会使用round-robin 随机轮询算法 ,在primary shard以及其所有replica node中 随机选择一个 ,让读请求负载均衡
3)接收请求的node返回document给coordinate node
4)coordinate node返回document给客户端

es最强大的是做全文检索,就是比如你有三条数据

java真好玩儿啊
java好难学啊
j2ee特别牛

你根据java关键词来搜索,将包含java的document给搜索出来

es就会给你返回:java真好玩儿啊,java好难学啊

1)客户端发送请求到一个coordinate node
2)协调节点 将搜索请求转发到 所有的shard 对应的primary shard或replica shard
3)query phase: 每个shard将自己的搜索结果 (其实就是一些 doc id ), 返回给协调节点 ,由协调节点进行数据的 合并、排序、分页 等操作,产出最终结果
4)fetch phase:接着由 协调节点,根据doc id去各个节点上拉取实际的document数据 ,最终返回给客户端

尤其要注意的这里是先拿的id哟

热点内容
c盘删除缓存文件对系统有影响吗 发布:2024-05-17 04:27:47 浏览:339
python不能输入中文 发布:2024-05-17 04:27:34 浏览:110
小米电视密码设置在哪里 发布:2024-05-17 04:06:12 浏览:426
java正则sql 发布:2024-05-17 04:05:52 浏览:620
51单片机c语言教程郭天祥 发布:2024-05-17 03:46:13 浏览:890
c语言程序特点 发布:2024-05-17 03:41:13 浏览:461
2014二级c语言考试大纲 发布:2024-05-17 03:23:20 浏览:418
到店系统源码 发布:2024-05-17 03:18:34 浏览:758
解编程解密 发布:2024-05-17 02:57:26 浏览:48
c语言掷骰子 发布:2024-05-17 02:11:05 浏览:489