Elasticsearch应用(十二)
1.单机ES面临的问题
- 海量数据存储问题
- 单点故障问题
2.ES集群如何解决上面的问题
- 海量数据存储解决问题: 将索引库从逻辑上拆分为N个分片(Shard),存储到多个节点
- 单点故障问题: 将分片数据在不同节点备份(Replica)
3.ES集群核心概念
总览
集群(Cluster)
介绍
包含一个或多个启动着的ES实例的机器群。通常一台机器起一个ES实例
默认集群
同一网络下,集群名一样的多个ES实例自动组成集群,自动均衡分片等行为。默认集群名为“elasticsearch”
集群名称修改方式
集群名通过配置文件修改,或者在命令行中 -E cluster.name=es-cluster进行设定
集群状态(Cluster State)
介绍
维护了一个集群中,必要的信息,包括:所有的节点信息,所有的索引和其相关的Mapping与Setting信息,分片的路由信息
Master节点负责维护并且更新Cluster State
状态
- Green:主分片与副本都正常分配
- Yellow:主分片全部正常分配,有副本分片未能正常分配
- Red:有主分片未能分配。例如,当服务器的磁盘容量超过85%时,去创建了一个新的索引
CAT API查看集群信息
GET /_cat/nodes?v #查看节点信息
GET /_cat/health?v #查看集群当前状态:红、黄、绿
GET /_cat/shards?v #查看各shard的详细情况
GET /_cat/shards/{index}?v #查看指定分片的详细情况
GET /_cat/master?v #查看master节点信息
GET /_cat/indices?v #查看集群中所有index的详细信息
GET /_cat/indices/{index}?v #查看集群中指定index的详细信息
节点(Node)
介绍
每个ES实例称为一个节点。节点名自动分配,也可以手动配置
节点名称配置方式
节点名称通过配置文件配置,或者启动时候 -E node.name=node1指定
UID存储目录
每一个节点在启动之后,会分配一个UID,保存在data目录下
常见的Node类型以及介绍
Master-eligible nodes(合格节点)
介绍
每个节点启动后,默认就是一个Master-eligible节点
可以设置node.master: false禁用
合格节点与选举
- Master-eligible节点可以参加选举主节点流程,成为Master节点
- 当第一个节点启动时候,它会将自己选举成Master节点
Master Node(主节点)
介绍
负责索引的创建与删除,决定分片被分配到哪个数据节点,维护并且更新Cluster State
当第一个节点启动的时候,它会将自己选举成Master节点
每个节点上都保存了集群的状态,只有Master节点才能修改集群的状态信息
最佳实践
Master节点非常重要要考虑解决单点的问题,为一个集群设置多个Master节点每个节点只承担Master的单一角色
Data Node(数据节点)
可以保存数据的节点
ES实例默认就是数据节点,可以通过node.data: false来改变
Coordinating Node(协调节点)
负责接受Client的请求,将请求分发到合适的节点上,最终把结果汇集到一起返回
每个节点默认都是协调节点
Ingest Node
数据前置处理转换节点,支持pipeline管道设置,可以使用ingest对数据进行过滤、转换等操作
Hot&Warm Node(冷热节点)
不同硬件配置的Data Node,用来实现Hot&Warm架构,降低集群部署的成本
Machine Learning Node(机器学习节点)
负责跑机器学习的Job,用来做异常检测
Tribe Node(部落节点|家族节点)
- 5.3之后开始使用Cross Cluster Search
- Tribe Node可以连接到不同的ES集群,并且支持将这些集群当做一个单独的集群处理
核心概念之分片(Primary Shard & Replica Shard)
介绍
Index数据过大时,将Index里面的数据,分为多个Shard,分布式的存储在各个服务器上面。可以支持海量数据和高并发,提升性能和吞吐量,充分利用多台机器的CPU
主分片
- 能正常提供查询和插入的分片我们叫做主分片(Primary Shard)
- 用以解决数据水平扩展的问题。通过主分片,可以将数据分布到集群内的所有节点之上
- 一个分片是一个运行的Lucene的实例
- 主分片数在索引创建时指定,后续不允许修改,除非Reindex
副本分片
- 用以解决数据高可用的问题。 副本分片是主分片的拷贝
- 副本分片数,可以动态调整
- 增加副本数,还可以在一定程度上提高服务的可用性(读取的吞吐)
指定索引的主分片和副本分片数
PUT /blogs
{
settings": {
"number_of_shards": 3,
"number_of_replicas": 1
}
}
分片的数量设置过大或过小的影响
- 分片数设置过小:
- 导致后续无法增加节点实现水平扩展
- 单个分片的数据量太大,导致数据重新分配耗时
- 分片数设置过大,7.0 开始,默认主分片设置成1,解决了over-sharding(分片过度)的问题
- 影响搜索结果的相关性打分,影响统计结果的准确性
- 单个节点上过多的分片,会导致资源浪费,同时也会影响性能
5.ES集群的完全体
6.节点发现流程详解
介绍
- 发现是集群形成模块查找与之形成集群的其他节点的过程
- 发现是主机未知的情况下(例如,节点刚启动时或先前的主机发生故障时),节点之间互相查找的过程
- 节点之间的通信是使用传输层(transport)完成的
发现的流程
- 从seed hosts providers获取种子地址列表,以及最后一个已知群集中任何符合主机资格的节点的地址开始
- 每个节点通过连接到每个地址来检测并尝试识别连接到的节点,并验证他是否具有主机资格
- 如果验证成功,它将与远程节点共享其所有已知的符合主机资格的对等方的列表。并且远程节点将依次与其对等方进行响应。然后,该节点将探查刚刚发现的所有新节点,请求其对等节点,依此类推
- 如果该节点不符合主节点资格,则它将继续此发现过程,直到发现了当选的主节点为止。如果未发现任何当选的主节点,则该节点将重试,之后discovery.find_peers_interval默认为1s
- 如果该节点是符合资格的主机,则它将继续此发现过程,直到它发现了一个选定的主节点,或者它已经找到了足够的无主机资格的节点来完成选举。如果这些操作都没有足够快地发生,则该节点将重试,之后 discovery.find_peers_interval默认为1s
发现流程总结
- 获取种子地址列表
- 连接节点并验证
- 如果验证成功则共享地址,并交叉请求节点
- 如果验证失败则继续
- 直到找到主节点或找到了足够的具有主机资格的节点来完成选举
Seed hosts providers(提供种子节点列表)
- 默认情况下,有两种方式来提供种子节点列表
- 基于设置的和基于文件的
基于设置的
- 这些地址可以指定为主机名或IP地址
- 主机列表是使用discovery.seed_hosts 静态设置设置的
- 如果未指定transport.profiles.default.port,transport.port则使用默认端口
- 如果主机名解析为多个IP地址,Elasticsearch将尝试连接到每个解析的地址
discovery.seed_hosts:
- 192.168.1.10:9300
- 192.168.1.11
- seeds.mydomain.com
基于文件的
- 是通过外部文件配置主机列表
- 当文件更改时,Elasticsearch会重新加载该文件
discovery.seed_providers: file
具体使用
- 在ES的config目录下创建unicast_hosts.txt
- unicast_hosts.txt每一行包含一个节点地址
- 每个节点地址均由主机名或IP地址和可选的port组成
- 如果未指定端口号,Elasticsearch将隐式使用transport.profiles.default.port或transport.port,所给定的端口范围内的第一个端口
- IPv6地址必须在端口的方括号中,如果需要,应在方括号之后
- 您也可以在此文件中添加注释。所有注释都必须以其开头出现#在行上(即注释不能在行中间开始)
10.10.10.5
10.10.10.6:9305
10.10.10.5:10005
# an IPv6 address
[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:9301
7.搭建ES3节点集群
配置文件elasticsearch.yml
# 指定集群名称3个节点必须一致
cluster.name: es‐cluster
# 指定节点名称,每个节点名字唯一
node.name: node‐1
# 是否有资格为master节点,默认为true
node.master: true
#是否为data节点,默认为true
node.data: true
# 绑定ip,开启远程访问,可以配置0.0.0.0
network.host: 0.0.0.0
#指定web端口
#http.port: 9200
#指定tcp端口
#transport.tcp.port: 9300
#用于节点发现
discovery.seed_hosts: ["es‐node1", "es‐node2", "es‐node3"]
#7.0新引入的配置项,初始仲裁,仅在整个集群首次启动时才需要初始仲裁。
#该选项配置为node.name的值,指定可以初始化集群节点的名称
cluster.initial_master_nodes: ["node‐1","node‐2","node‐3"]
#解决跨域问题
http.cors.enabled: true
http.cors.allow‐origin: "*"
节点1配置文件elasticsearch.yml
cluster.name: es‐cluster
node.name: node‐1
node.master: true
node.data: true
network.host: 0.0.0.0
discovery.seed_hosts: ["es‐node1", "es‐node2", "es‐node3"]
cluster.initial_master_nodes: ["node‐1","node‐2","node‐3"]
http.cors.enabled: true
http.cors.allow‐origin: "*"
节点2配置文件elasticsearch.yml
cluster.name: es‐cluster
node.name: node‐2
node.master: true
node.data: true
network.host: 0.0.0.0
discovery.seed_hosts: ["es‐node1", "es‐node2", "es‐node3"]
cluster.initial_master_nodes: ["node‐1","node‐2","node‐3"]
http.cors.enabled: true
http.cors.allow‐origin: "*"
节点3配置文件elasticsearch.yml
cluster.name: es‐cluster
node.name: node‐3
node.master: true
node.data: true
network.host: 0.0.0.0
discovery.seed_hosts: ["es‐node1", "es‐node2", "es‐node3"]
cluster.initial_master_nodes: ["node‐1","node‐2","node‐3"]
http.cors.enabled: true
http.cors.allow‐origin: "*"
验证集群
http://192.168.65.174:9200/_cat/nodes?pretty
6.ES集群的脑裂问题
默认情况下,每个节点都是master eligible节点,因此一旦master节点宕机,其它候选节点会选举一个成为主节点。当主节点与其他节点网络故障时,可能发生脑裂问题
为了避免脑裂,需要要求选票超过(eligible节点数量+1 )/2才能当选为主,因此eligible节点数量最好是奇数。对应配置项是discovery.zen.minimum_master_nodes,在es7.0以后,已经成为默认配置,因此一般不会发生脑裂问题
7.ES集群原理
路由原理
当新增文档时,应该保存到不同分片,保证数据均衡,那么coordinating node如何确定数据该存储到哪个分片呢?Elasticsearch会通过hash算法来计算文档应该存储到哪个分片:
# 1._routing默认是文档id
# 2.算法与分片数量有关,因此索引库一旦创建,分片数量不能修改
shard = hash(_routing) % number_of_shards
新增文档原理
分布式查询原理
新增文档是根据ID来的,如果查询不是通过ID就叫分布式查询
集群故障转移
集群的Master节点会监控集群中的节点状态,如果发现有节点宕机,会立即将宕机节点的分片数据迁移到其它节点,确保数据安全,这个叫做故障转移