龙空技术网

一首周杰伦《发如雪》带你入门 Elasticsearch

数据猿温大大 265

前言:

此刻兄弟们对“bully 算法”大致比较关注,各位老铁们都想要学习一些“bully 算法”的相关内容。那么小编在网络上网罗了一些对于“bully 算法””的相关文章,希望咱们能喜欢,小伙伴们快快来了解一下吧!

导语

小猴周末在家看了综艺节目《王牌对王牌》,对里面的猜歌曲环节饶有兴趣,主持人随便说一个字或词语,选手必须唱出包含该字或者词语的歌曲。小猴觉得太有意思了,今天上班准备和他猴哥过两招。

Elasticsearch 倒排索引

Elasticsearch是一个基于Lucene的搜索服务器, 它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。

Elasticsearch 能快速的匹配关键词,是因为它做了上面提到的倒排索引,

将 “狼牙月, 伊人憔悴, 我举杯饮尽了风雪” 将内容进行切词,key 与 value如下

Elasticsearch 切词

传统 Elasticsearch 内置了一些分词器

Standard Analyzer 。按词切分,将词小写Simple Analyzer。按非字母过滤(符号被过滤掉),将词小写WhitespaceAnalyzer。按照空格切分,不转小写

同时 分词器由 3部分组成:

Character Filters(文本过滤器,去除HTML)Tokenizer(按照规则切分,比如空格)TokenFilter(将切分后的词进行处理,比如转成小写) 因为 Elasticsearch 是国外友人开发的,现在中文分词器用的最多的就是IKElasticsearch 数据存储结构

下面就是完整的倒排索引,例:索引 “月” 除了能对应value《发如雪》,还对应了value 《月亮惹的祸》等等。

真实的 Elasticsearch 存储结构可不是这样的,结构如下:

1、ES对文字进行切词(月/狼/牙/伊人/憔悴...),这些词存在Term Dictionary, 通过分词找到对应的歌曲名称,歌曲名称对应存在磁盘下,但ES存有磁盘对应的记录就是上面的 Posting List

2、当分词很多时,就像古巨基《情歌王》的词那么多时,我们需要会分词进行排序,中文则根据拼音首字母排序,查找的时候就可以通过二分来查找,不需要遍历整个 Term Dictionary

3、这还不够,当你遇到比《情歌王》还长的歌曲时,比如《Organ2/ASLSP》需要演奏639年(度娘告诉我的),不可能把Term Dictionary全部放到内存中,排序也没用了,这种情况ES也考虑到了这种情况,它有抽象了一层 Term Index,这部分存储 词的前缀,我们只需要把 Term Dictionary 中首字符根据二分法存在Term Index中。

4、Term Index在内存中以 FST(Finite State Transducers)的形式保存的,有以下2个优点: 1)空间占用小。通过对词典中单词前缀和后缀的重复利用,压缩了存储空间; 2)查询速度快。O(len(str))的查询时间复杂度。

5、同时 PostingList 会使用 Frame Of Reference(FOR)编码技术对数据进行压缩,节约磁盘空间

6、由于 PostingList 里面存的是文档id, 我们需要对文档id结果进行去重操作,这里 PostingList 使用 Roaring Bitmaps 对文档id进行去重

本章节我们来总结下:

Elasticsearch 术语与架构

在 Elasticsearch 中有 Index\Type\Document\Field\Mapping\DSL 术语:

Index:对应 数据库的 Tabletype:在最新的7.0已经废弃了该字段了,之前版本中1个index支持对应多个typeDocument:对应 数据库中 一行数据Field:对应 数据库的 columnMapping:对应 数据库的 SchemaDSL:对应 数据库的 SQ

通过上图就更好理解它的术语了,这时我们再来看看它的架构,一个ES集群拥有很多Elasticsearch节点,一个Elasticsearch节点其实就是上面运行了Elasticsearch进程的机器。

Elasticsearch 谁当老大

立下帮规如下(帮规是基于bully算法的改进算法):

1、团体中的 候选老大人数 >= 设定最小候选数

a.候选老大人数设置:(master_eligible_nodes / 2) + 1,

b.最小候选数设置: 通过discovery.zen.minimum_master_nodes 设置

2、看每个的在江湖上的排名,即节点启动顺序,越早出来混的,排名越靠前,越有资格当老大

3、若出现2个帮派,得小数人的帮派的加入大多数的帮派,毕竟人多说了算,即避免出现 ES上说的脑裂

举个例子:现在要从 10 个人中选一个老大

1、如果10个人是1个团体,候选老大人数就是6 ((10 / 2) + 1=6)

最小候选数设为4(即:discovery.zen.minimum_master_nodes=4),6>4说明该团体选举的master node 是有效的。

2、假设出现了10个人出现2个团体,团体A有4个人(node1~node4),团体B有6个人(node5~node9)

3、团体A中排名第一的是:node2,

4、团体B中排名第一的是:node6

5、由于团体A 候选老大人数:3( 4/2+1 =3),不符合帮规要求大于等于4票,所以团体A中node2不能当老大

6、由于团体B 候选老大人数:4(6/2+1=4),最终在选中node6作为集群的master node,

7、团体A最终只能加入团体B,否者不能纳入到ES环境内

最终在ES集群环境里面选出一个master node, 如果 master node 挂了,会选举出一个新的 master node

master node 主要维护元数据、切换主 副本分片身份(后面会细讲) 普通node 用于存储数据,包括node上面的主分片、副本分片(后面会细讲)

Elasticsearch 切片

前面提到ES里面的index等同于一张数据表,数据分发到不同的Node上进行存储,这个操作就叫做分片 ,如下图 一张index数据被存储到不同的note1、note2、note3、note4 节点上,等同于划分了4个分片,

数据写入的时候是写到主分片,副本分片会复制主分片的数据,读取的时候主分片和副本分片都可以读

本章节我们来总结下:

Elasticsearch 写入流程

客户端写入一条数据,ES这边是由节点进行处理,并且每个节点都是一个coordinating node(协调节点),协调节点该节点可以作为路由进行转发:

路由协议:node4接收到请求发现请求给node1的,所以转给node1路由算法:shard = hash(document_id) % (num_of_primary_shards)),例:node4接受document_id 是 10 (假设:num_of_primary_shards设置为 3),10%3 = 1(node1),即:请求会转发到 node1 节点上.node1接收请求,并进行写入流程

写入流程:

1、当收到写入请求,首先写入 内存缓存(memory buffer)

2、接着将数据写入 日志缓存(translog buffer)

3、每隔1秒从 内存缓存(memory buffer) 写入 文件缓存(fileSystemCache) ,接着生成 片段(segment) 文件,这时就能通过索引查询了。

4、接着**刷新 内存缓存(memory buffer)。

5、每隔5秒,从 日志缓存(translog buffer) 中写入到 日志文件(translog)

6、定期/定量 日志文件(translog)超过30分钟 写入 磁盘(data),并将 文件缓存(fileSystemCache) 中 片段(segment) 文件异步刷到磁盘中。

主分片写完写入成功,副分片写=1个node节点写完,全部node节点写完ack给协调节点,协调节点返回ack给客户端, 最终完成写入

本章节我们来总结下:

Elasticsearch 查询流程

Elasticsearch 查询分为2种,根据doc ID查询内容、根据Search(搜索词)查询内容:

 public TopDocs search(Query query, int n); public Document doc(int docID);
根据ID查询大致流程: 检索内存的Translog文件 检索硬盘的Translog文件 检索硬盘的Segment文件根据Search匹配查询doc大致流程: 同时去查询内存和硬盘的Segment文件

比较常用的是QUERY_THEN_FETCH,大致流程:

更多干货,关注公众号:数据猿大大

标签: #bully 算法