elastisearch 浅淡的原理

elasticsearch 分布式工作原理

节点交互原理

在这里插入图片描述
P1有两个R1和R1的副分片

P0有两个R0和R0的副分片

es写是在分片上,而不是节点上 ,先写在主分片,主分片在同步给副分片,因为主分片可以分布在不同的节点上,所以当集群只有一个master节点的情况下,即使流量的增加它也不会成为瓶颈,就算它挂了,任何节点都有机会成为主节点

写入文档

在这里插入图片描述

  1. 客户端想node-1发送新增文档请求
  2. 通过文档的路由算法确定该文档属于主分片的-P0,因为主分片-P0在node-3,所以这个请求经过node-1转发到node-3,新增的文档写在P0上面
  3. 主分片P0写完以后,找到对应的副分片,是node-1和node-2的副分片RO上面,就会把数据同步给node-1和node-2上面,写完以后会通知node-3,我已经同步完了,node-3收到所有分片写完的结果,在把结果在给node-1这个操作写完了,node-1收到node-3操作写完的结果,在告诉客户端我的请求结束了

读取文档

在这里插入图片描述

  1. 客户端向node-1发送读取文档请求
  2. 在处理读取请求时,node-1在每次请求的时候都会通过轮询所有的副本分片来达到负载均衡
  3. 如果压力很大那么建立更多副分片,会分摊到不同的分片上,那么负载就平衡了

elasticsearch 文档的路由原理

当新增一个文档的时候,文档会被存储到一个主分片中,Elasticsearch如何知道一个文档应该存放到哪个分片中呢? 当我们创建文档时,它如何决定这个文档应当被存储在分片1还是分片2中呢?

路由策略算法 默认是文档id((_routing) ) 哈希运算取余
shard_num = hash(_routing) % num_primary_shards 主分片

routing 是一个可变值,默认是文档的_id,也可以设置成一个自定义的值。routing通过hahs函数生成一个数字,然后这个数字在除以number_of_primary_shards(主分片的数量)后得到余数。这个分布在0到number_of_primary_shards 之间的余数 分片是从0开始算起的 1%3=1 实在第一个分片

primary(prai me rei) shards(sha zi)

每个索引,指名主分片的数量 通过number_of_shards 主分片不能增加 分母不能变

副本分片就是对主分片的拷贝 ,当主分片挂掉,副本分片还能起作用

主与副的区别?
1、索引建立后可以增加
2、写操作必须要在主分片上运行才能复制到副本分片

节点和分片的数量的关系
2* 1+1
最大的节点 = 主分片数量*(副本分片+1)

当前有2个节点,索引指名2个分片,

shard 是分片

在这里插入图片描述
主分片2上 ,这样查找就知道哪个分片和节点上

elasticsearch 的乐观锁

悲观锁

每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞,直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在操作之前先上锁

乐观锁

每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,比如使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,因为我们elasticsearch一般业务场景都是写少读多,所以通过乐观锁在控制并发的情况下又能有效的提高系统吞吐量

版本号乐观锁

Elasticsearch 中对文档的index,GET和delete请求时,都会返回一个_version,当文档被修改时版本号递增。

所有文档的更新或删除API,都可以接受_version参数,这允许你在代码中使用乐观的并发控制,这里要注意的时版本号要大于旧的版本号,并且加上version_type=external

修改的时候只有大的版本号,才能修改老的版本号

在这里插入图片描述

倒排索引

如果单词作为分组,把每一个单词作为序号

在这里插入图片描述
我们把这个5个球员的名字进行分词,每个分词转成小写字母,并且以每个分词分组,统计它所在的文档的位置

在这里插入图片描述

在这里插入图片描述

单词首字母进行排序的

elasticsearch的分词原理

PUT test /_doc/1
{
	“msg”: "乔丹时篮球之神"
}

在这里插入图片描述

msg_chinese是中文分词器

POST test/_doc/1
{
	"msg": "乔丹时篮球之神"
	"msg_chinese":"乔丹时篮球之神"
}

分词器的原理

写时分词

我们写入文档的时候,把这个词给分词了 ,通过倒排索引存起来

POST test/_analyze
{
	"field":“msg”,
	"text": "乔丹时篮球之神"
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
standard(si dan de) 分词器 就是 msg形式一样的 (每一个词作为一个分词)

读时分词

读时分词器要和写时分词器一致的

深入分析

分析器(analyzer) 有三部分组成

  • char filter :字符过滤器
  • tokenizer: 分词器
  • token filter : token 过滤器

在这里插入图片描述

char filter(字符过滤器)

  • 字符过滤器以字符流的形式接收原始文本,并可以通过添加、删除或更改字符来转换该流。一个分析器可能会有0个或者多个字符过滤器

tokenizer(分词器)

  • 一个分词器接收一个字符流,并将其拆分单个token(通常时个单词),并输出一个token流

在这里插入图片描述

token filter (token过滤器)

token过滤器接受token流,并且可能会添加、删除或者更改tokens。比如一个lowercase token filter可以将所有的token转成小写。一个分析器可能有0个或多个token过滤器,它们按顺序应用

在这里插入图片描述

ES脑裂

“脑裂”问题可能的成因

  1. 网络问题:集群间的网络延迟导致一些节点访问不到master,认为master挂掉了从而选举出新的master,并对master上的分片和副本标红,分配新的主分片
  2. 节点负载:主节点的角色既为master又为data,访问量较大时可能会导致ES停止响应造成大面积延迟,此时其他节点得不到主节点的响应认为主节点挂掉了,会重新选取主节点。
  3. 内存回收:data节点上的ES进程占用的内存较大,引发JVM的大规模内存回收,造成ES进程失去响应。

脑裂问题解决方案:

1.减少误判:discovery.zen.ping_timeout节点状态的响应时间,默认为3s,可以适当调大,如果master在该响应时间的范围内没有做出响应应答,判断该节点已经挂掉了。调大参数(如6s,discovery.zen.ping_timeout:6),可适当减少误判。

2.选举触发 discovery.zen.minimum_master_nodes:1

该参数是用于控制选举行为发生的最小集群主节点数量。

当备选主节点的个数大于等于该参数的值,且备选主节点中有该参数个节点认为主节点挂了,进行选举。官方建议为(n/2)+1,n为主节点个数(即有资格成为主节点的节点个数)

增大该参数,当该值为2时,我们可以设置master的数量为3,这样,挂掉一台,其他两台都认为主节点挂掉了,才进行主节点选举。

3.角色分离:即master节点与data节点分离,限制角色

主节点配置为:

node.master: true node.data: false

从节点配置为:

node.master: false node.data: true

实际解决办法

最终考虑到资源有限,解决方案如下:

增加一台物理机,这样,一共有了三台物理机。在这三台物理机上,搭建了6个ES的节点,三个data节点,三个master节点(每台物理机分别起了一个data和一个master),3个master节点,目的是达到(n/2)+1等于2的要求,这样挂掉一台master后(不考虑data),n等于2,满足参数,其他两个master节点都认为master挂掉之后开始重新选举,

master节点上

node.master = true
node.data = false
discovery.zen.minimum_master_nodes = 3 (设置为基数) 最小master节点数
data节点上

node.master = false
node.data = true
方案分析

理解Elasticsearch写入过程原理
深入理解Elasticsearch写入过程
Elasticsearch 之 commit point | Segment | refresh | flush 索引分片内部原理
Segments in Lucene基本概念
How to avoid the split-brain problem in elasticsearch

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟伟哦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值