Elasticsearch集群如何实现高可用和一致性
Elasticsearch集群如何实现高可用和一致性
Elasticsearch (ES) 的高可用性是指集群在部分节点或分片出现故障时,仍能确保数据的持续可用和集群的稳定运行。ES 通过分片机制、主从结构、分配策略、故障恢复和分布式一致性等多种机制实现高可用。
1. 分片机制和副本
ES 通过 分片 和 副本 实现数据的备份和容错,其分片和副本机制是基于索引的。
- 主分片 (Primary Shard):每个索引在创建时会定义若干个主分片。主分片用于存储数据,并负责处理写请求。每个文档只能存在于一个主分片中。
- 副本分片 (Replica Shard):副本是主分片的完全拷贝,提供冗余和负载均衡。副本分片能够接收读请求,并且当主分片不可用时,副本可以提升为主分片继续承担写操作。
分片分配与负载均衡
- ES 会尽量将主分片和副本分片分布在不同的节点上,以防止节点宕机导致数据不可用。副本不仅用于数据备份,也用于负载均衡,处理查询请求。
分片数和副本数配置
在创建索引时,可以指定主分片和副本数量,示例配置如下:
PUT /my_index
{
"settings": {
"number_of_shards": 5, # 主分片数量
"number_of_replicas": 1 # 副本分片数量
}
}
2. 分配策略与故障恢复
ES 提供了多种分片分配策略和故障恢复机制,确保集群在节点宕机或加入新节点时能够自动调整。
自定义分配策略
ES 支持通过节点的自定义属性(如磁盘空间、机房等)来影响分片的分配。使用 node.attr.<attribute>
配置节点属性,在创建索引时通过 cluster.routing.allocation
属性来控制分配策略。实例如下
机房感知:当集群跨多个机房部署时,可以通过配置机房感知(node.attr.dc
)来优化分片分配,确保主副分片分布在不同机房,从而避免单一机房故障影响整个集群。
node.attr.dc: dc1 # 设置节点所在的机房
在创建索引时使用:
PUT /my_index
{
"settings": {
"cluster.routing.allocation.awareness.attributes": "dc", # 根据机房分配
"cluster.routing.allocation.awareness.force.dc.values": "dc1,dc2" # 强制分配到不同机房
}
}
3. Zen2 协议与主节点选举
Elasticsearch 7.x 引入了 Zen2 协议来自动化主节点选举,确保集群的一致性和高可用性。Zen2 协议通过基于 term
和 epoch
的一致性机制,解决了传统选举方式中的脑裂问题。
主节点选举机制
- 多数决原则:Zen2 协议采用 多数决机制,即主节点必须获得集群超过一半节点的支持才能当选。当主节点宕机时,集群会自动进行选举,并选出新的主节点。
- 投票与一致性:选举过程中,集群中的节点通过交换
term
和epoch
值来投票,确保一致性。只有获得多数节点支持的主节点才能继续集群管理工作。
term
是一个递增的整数值,用来表示当前集群的 “任期”。每次主节点选举时,都会生成一个新的term
,并且所有的选举和集群状态变更都将与该term
相关联。也就是说节点的term越大,证明其参与选举的次数越多,数据越新。
epoch
是与选举过程和投票相关的另一个标识符,表示一个特定的选举周期。每个节点都在选举中持有一个epoch
,表示它所在的选举周期或阶段。防止多个节点处在不同的选举周期中,导致选举过程错乱。
当节点宕机时,ES集群会从green状态变为red或yellow,这取决于本次宕机是否异常集群的写入功能,也就是主分片的副分片是否存在并成功升级为主分片。如果是yellow,ES会自动将宕机节点上的主分片的副本提升为主分片,保证写操作的持续性,并重新分配剩余的副本分片。
- 副本分片升级:如果主分片所在的节点宕机,副本分片会被提升为新的主分片,继续承载写操作。系统会保持副本数量一致,并重新分配副本分片。
- 分片重新分配:当节点恢复时,ES 会尝试将丢失的副本分片分配到其他节点,并确保数据冗余。
防止脑裂
当出现网络分区时,可能会出现一个小集群中包含主节点,另一个大集群中不包含主节点,但由于可选举节点超出既定值,可以完成选举,导致出现两个主节点,当网络分区消失后,两个主节点相遇,Zen2 协议通过使用 term
值来避免这种脑裂问题,term大的一方证明是新选举的主节点,则会成为真正的主节点,确保集群中只有一个有效的主节点。
Voting-only 节点
Elasticsearch 允许将某些节点配置为 Voting-only 节点,这些节点只能参与投票,不能被选举为主节点。这有助于保证选举的稳定性,防止某些节点因网络问题而成为主节点候选。
4. 集群健康与故障恢复
ES在接受到写入操作时,会讲写入指令优先存入事务日志,当一条数据被加载进内存并写入日志后,则会返回写入成功。这一操作可以提高ES的写入效率,无需等待ES持久化完数据在进行下一步操作,并且可以在故障恢复时,执行事务日志内容来恢复数据,从分片也会从事务日志同步数据。
Elasticsearch 集群中各个节点通过心跳机制确认对方的存活,当集群中过半的节点都无法连接某个节点时则认为这个节点宕机,在遭遇节点宕机或故障时,会通过以下机制进行恢复:
- 节点故障处理:当节点宕机时,ES 会自动重新分配该节点的分片,提升副本为主分片,保证集群的写操作继续进行。
- 恢复过程:当故障节点恢复时,ES 会同步集群中其他节点的事务日志内容用于恢复数据,确保节点数据与集群状态一致。若节点长时间宕机,ES 会根据副本分片的可用性自动进行数据恢复。
- 自动分配与重平衡:在新节点加入或节点宕机时,ES 会触发分片的重新分配,保持集群的负载均衡。
ES并不会马上将数据写入磁盘,而是定期的将内存中的数据刷新到磁盘中的Lucene 索引中。Lucene索引文件是用于搜索的文件,其中包含了数据和倒排索引等。ES还会定期生成快照文件用于故障恢复。快照和事务日志是保证数据不丢失且能快速相应的一种手段。有点类似于Redis的rdb和aof。
5. 写入一致性与确认
Elasticsearch 支持根据写入一致性级别来确保数据的可靠性。
- 写入一致性:通过配置
index.write.wait_for_active_shards
,可以控制写操作的确认级别。例如,设置为all
时,写操作需要等待所有副本分片确认后才算成功。 - 同步写操作:ES 支持同步和异步写操作。用户可以根据需求选择合适的一致性级别,在确保一致性的同时,平衡系统的性能与可靠性。