Elasticsearch部分节点不能发现集群(脑裂)问题处理

什么是脑裂?

让咱们看一个有两个节点的elasticsearch集群的简单状况。集群维护一个单个索引并有一个分片和一个复制节点。节点1在启动时被选举为主节点并保存主分片(在下面的schema里标记为0P),而节点2保存复制分片(0Rnode

如今,若是在两个节点之间的通信中断了,会发生什么?因为网络问题或只是由于其中一个节点无响应(例如stop-the-world垃圾回收),这是有可能发生的。git

两个节点都相信对方已经挂了。节点1不须要作什么,由于它原本就被选举为主节点。可是节点2会自动选举它本身为主节点,由于它相信集群的一部分没有主节点了。在elasticsearch集群,是有主节点来决定将分片平均的分布到节点上的。节点2保存的是复制分片,但它相信主节点不可用了。因此它会自动提高复制节点为主节点。github

如今咱们的集群在一个不一致的状态了。打在节点1上的索引请求会将索引数据分配在主节点,同时打在节点2的请求会将索引数据放在分片上。在这种状况下,分片的两份数据分开了,若是不作一个全量的重索引很难对它们进行重排序。在更坏的状况下,一个对集群无感知的索引客户端(例如,使用REST接口的),这个问题很是透明难以发现,不管哪一个节点被命中索引请求仍然在每次都会成功完成。问题只有在搜索数据时才会被隐约发现:取决于搜索请求命中了哪一个节点,结果都会不一样。算法

如何避免脑裂问题

elasticsearch的默认配置很好。可是elasticsearch项目组不可能知道你的特定场景里的全部细节。这就是为何某些配置参数须要改为适合你的需求的缘由。这篇博文里全部提到的参数均可以在你elasticsearch安装地址的config目录中的elasticsearch.yml中更改。安全

要预防脑裂问题,咱们须要看的一个参数就是 discovery.zen.minimum_master_nodes。这个参数决定了在选主过程当中须要 有多少个节点通讯。缺省配置是1.一个基本的原则是这里须要设置成 N/2+1, N是急群中节点的数量。 例如在一个三节点的集群中, minimum_master_nodes应该被设为 3/2 + 1 = 2(四舍五入)。服务器

让咱们想象下以前的状况下若是咱们把 discovery.zen.minimum_master_nodes 设置成 2(2/2 + 1)。当两个节点的通讯失败了,节点1会失去它的主状态,同时节点2也不会被选举为主。没有一个节点会接受索引或搜索的请求,让全部的客户端立刻发现这个问题。并且没有一个分片会处于不一致的状态。网络

咱们能够调的另外一个参数是 discovery.zen.ping.timeout。它的默认值是3秒而且它用来决定一个节点在假设集群中的另外一个节点响应失败的状况时等待多久。在一个慢速网络中将这个值调的大一点是个不错的主意。这个参数不止适用于高网络延迟,还能在一个节点超载响应很慢时起做用。elasticsearch

两节点集群?

若是你以为(或直觉上)在一个两节点的集群中把minimum_master_nodes参数设成2是错的,那就对了。在这种状况下若是一个节点挂了,那整个集群就都挂了。尽管这杜绝了脑裂的可能性,但这使elasticsearch另外一个好特性 - 用复制分片来构建高可用性 失效了。spa

若是你刚开始使用elasticsearch,建议配置一个3节点集群。这样你能够设置minimum_master_nodes为2,减小了脑裂的可能性,但仍然保持了高可用的优势:你能够承受一个节点失效但集群仍是正常运行的。code

但若是已经运行了一个两节点elasticsearch集群怎么办?能够选择为了保持高可用而忍受脑裂的可能性,或者选择为了防止脑裂而选择高可用性。为了不这种妥协,最好的选择是给集群添加一个节点。这听起来很极端,但并非。对于每个elasticsearch节点你能够设置 node.data 参数来选择这个节点是否须要保存数据。缺省值是“true”,意思是默认每一个elasticsearch节点同时也会做为一个数据节点。

在一个两节点集群,你能够添加一个新节点并把 node.data 参数设置为“false”。这样这个节点不会保存任何分片,但它仍然能够被选为主(默认行为)。由于这个节点是一个无数据节点,因此它能够放在一台便宜服务器上。如今你就有了一个三节点的集群,能够安全的把minimum_master_nodes设置为2,避免脑裂并且仍然能够丢失一个节点而且不会丢失数据。

结论

脑裂问题很难被完全解决。在elasticsearch的问题列表里仍然有关于这个的问题, 描述了在一个极端状况下正确设置了minimum_master_nodes的参数时仍然产生了脑裂问题。 elasticsearch项目组正在致力于开发一个选主算法的更好的实现,但若是你已经在运行elasticsearch集群了那么你须要知道这个潜在的问题。

如何尽快发现这个很重要。一个比较简单的检测问题的方式是,作一个对/_nodes下每一个节点终端响应的按期检查。这个终端返回一个全部集群节点状态的短报告。若是有两个节点报告了不一样的集群列表,那么这是一个产生脑裂情况的明显标志。

 

 

服务启动过程当中,因为未能发现集群,本身选举本身为master
致使该问题有可能网络缘由。由于discovery.zen(es 中一个集群的服务)超时了尚未找到集群则选举本身为master。
修改设置 discovery.zen.ping_timeout: 120s,原来120s 重启es1发现正常了。 

discovery.zen.minimum_master_nodes: 2
discovery.zen.fd.ping_retries: 6
discovery.zen.fd.ping_interval: 20s
discovery.zen.ping_timeout: 120s
client.transport.ping_timeout: 120s

总结:

es服务启动后到发现集群的时间有点长,若是超时时间设得短则发现不了。这个缘由还未知。只是经过修改设置让他尽量能找到了集群了。

相关文章
相关标签/搜索