起因:在项目开发过程中,要使用到搜索 引擎来对一些关键字实现逆向查询,如果仅用模糊搜索,那么搜索的时间会根据数据量的增大而增大,对比之下就学了elasticsearch,也记录一下,常常回顾。
1. Elasticsearch集群构建及分片原理分析
分布式搜索引擎,如果是单机,那既不能HA,也不能实现分布式
-
HA
-
海量数据的水平扩展
-
高并发访问
分片机制
-
通俗来讲就是一个放数据的盒子
-
每个索引都会被分片
-
创建索引的时候会要求制定主分片和副本分片的数量
分片的逻辑
-
副本分片不允许和主分片在同一个机器上
-
主分片挂了,还有副本分片来进行数据访问
-
所以单机的时候,副本分片不会制定机器
1.1. ES集群搭建
在elasticsearch.yml里进行配置
# elasticsearch.ymk
# 是我们的集群名称,每个集群的机器如果要加入同一个集群,这个名字必须一样
cluster.name: icoding-es
# 节点名,这个必须都不一样
node.name: es-node-1
# 存储路径
path.data: /usr/local/elasticsearch/esdata
path.logs: /usr/local/elasticsearch/eslogs
http.port:9200
# 主节点,设置后在主节点挂掉后有机会升级为master
node.master: true
# 数据节点
node.data: true
# 可以配置ip和域名,配置后ES会通过9300-9305的端口进行数据连接
discovery.seed_hosts: ["192.168.0.146", "192.168.0.147", "192.168.0.148"]
# 集群初始化设置的master节点
cluster.initial_master_nodes: ["es-node-1"]
image-20200219230127642.png
星:代表主节点
圆圈:代表从节点!
1.2. ES集群节点宕机测试
image-20200219230903697.png2. Elasticsearch集群脑裂问题分析
集群中有一个master节点:相当于一个管理节点
Node:elasticsearch的服务节点,安装ES的机器(主,从)
Index:是我们数据的一个逻辑集合,他拥有数据的结构,以及提前做好的分词内容,主要用来搜索的的对象
Shard:物理分片,进行数据的实际物理存储和管理的地方(主分片数不能修改,但副本分片可以增加)
image-20200220201623593.png当原来的Master因为网络问题无法和其他slave链接,就出现了其他slave选举出新的master的情况
-
只要最小投票人数1个就能把节点投为master
-
由于和其他节点连接不上,这个节点就把自己投成master
脑裂的解决方案
master主节点应该要经过多个有资格成为master(node.master=true)的节点选举后才能成为新的节点,不是你一个人自己选自己就能决定
-
discovery.zen.minimum_master_nodes=(N/2)+1
-
N就是有资格成为master的节点数
-
这个值默认是1
-
在ES7.x以前是这样的
-
-
在ES7.x版本中,这个参数已经被移除了,这块的内容完全由ES自身做管理,避免了多个脑裂的情况,选举也非常快
3. Elasticsearch集群中文档读写原理
3.1. 文档的写原理
image-20200220203755592.png-
客户端连接的时候,首先要连接一个协调节点controller node
-
协调节点会根据客户端写入的数据来hash判断是写入P0还是P1,P2,只要主分片才能写入数据
-
如果hash后写入到P2分片,会由协调节点来路由转发数据到P2分片
-
P2分片数据写入完成后会同步到R2备份分片,会将完成写入的响应返回到协调节点
-
协调节点收到完成操作后返回给客户端,完成了这次写入的操作了
-
客户端每次连接的协调节点controller node可能会变
3.2. 文档的读原理
-
客户端读请求会先选择一个协调节点
-
由协调节点根据数据的请求hash得知是放在哪个分片上的
-
由于数据在主从分片上都有,并且数据一模一样,读取操作在主从上是采用轮询的方式
-
因此副本分片多了后会提升分片的负载能力
-
数据查询完毕后返回给协调节点,协调节点返回客户端
4. 如何合理设置集群中分片数和副本数
当你在Elasticsearch中将index的分片设置好后,主分片数量在集群中是不能进行修改的,即便是你发现主分片数量不合理也无法调整,那怎么办?
-
分配分片时主要要考虑的问题
-
数据集的增长趋势
-
很多用户认为提前放大分配好分片的量就能确保以后不会出现新的问题,比如分1000个分片
-
-
要知道分配的每个分片都是由额外的成本的
-
每个分片其实都是要存数据的,并且都是一个lucene的索引,会消耗文件句柄已经CPU和内存资源
-
当你进行数据访问时,我们的index就会去到所有的分片上去取数据
-
如果要取100条,如果你有100个分片,就会从100个分片上各取出100个数据然后进行排序给出最终的排序结果,取了100*100条数据
-
-
主分片数据到底多少为宜呢?
-
根据你的节点数来进行分片,3个Node,N*(1.5-3)
-
我们现在3个节点,主分片数据:5-9个分片
-
总结
-
分片是有相依消耗的,并且持续投入
-
当index拥有多个分片时,ES会查询所有分片然后进行数据合并排序
-
分片数量建议:node*(1.5-3)
# 创建索引过程中进行分片设置
PUT /index_test
{
"settings": {
"number_of_shards": 5,
"number_of_replicas": 1
}
}
# 修改副本分片数量
# 副本分片如果过多在写入的时候会消耗更多时间来复制数据
PUT /index_test/_settings
{
"number_of_replicas": 2
}
5. ES集群分片容灾的机制
集群所有Node都启动的状态
image-20200220211206482.png我要kill掉es-node-1,es-node-2和es-node-3上的副本分片就升级为主分片
image-20200220211350285.png过了一会,刚升级的主分片复制出副本分片
image-20200220211603183.png启动刚刚kill掉的es-node-1,数据还没有复制过来
image-20200220212202600.png过了一会数据进行了移动,通过9300内部通信端口进行数据的传输的
image-20200220212232618.png不要以为每天把功能完成了就行了,这种思想是要不得的,互勉~!
网友评论