本文翻译自blog.trifork.com的博文
地址是http://blog.trifork.com/2013/10/24/how-to-avoid-the-split-brain-problem-in-elasticsearch/ ,可以复制后在浏览器观看。

我们都遇到过这个 - 在我们开始准备一个elasticsearch集群的时候,第一个问题就是“集群需要有多少节点?”。我想大家都知道,这个问题的答案取决于很多因素,例如期望的负载,数据大小,硬件等。这篇博文不会深入解释如何调整集群大小的细节,而是去关注另一个同样重要的事情 - 如何避免脑裂问题。

什么是脑裂?

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

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

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

现在我们的集群在一个不一致的状态了。打在节点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秒并且它用来决定一个节点在假设集群中的另一个节点响应失败的情况时等待多久。在一个慢速网络中将这个值调的大一点是个不错的主意。这个参数不止适用于高网络延迟,还能在一个节点超载响应很慢时起作用。

两节点集群?

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

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

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

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

结论

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

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


文章来自微信平台「麦芽面包」
微信公众号「darkjune_think」
转载请注明。
如果觉得文章有趣,微信扫二维码关注我

[译]如何防止elasticsearch的脑裂问题的更多相关文章

  1. 如何防止ElasticSearch集群出现脑裂现象(转)

    原文:http://xingxiudong.com/2015/01/05/resolve-elasticsearch-split-brain/ 什么是“脑裂”现象? 由于某些节点的失效,部分节点的网络 ...

  2. Elasticsearch笔记八之脑裂

    Elasticsearch笔记八之脑裂 概述: 一个正常es集群中只有一个主节点,主节点负责管理整个集群,集群的所有节点都会选择同一个节点作为主节点所以无论访问那个节点都可以查看集群的状态信息. 而脑 ...

  3. 如何防止ElasticSearch集群出现脑裂现象

    什么是“脑裂”现象? 由于某些节点的失效,部分节点的网络连接会断开,并形成一个与原集群一样名字的集群,这种情况称为集群脑裂(split-brain)现象.这个问题非常危险,因为两个新形成的集群会同时索 ...

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

    **现象描述** es1,es2,es3三台es组成一个集群,集群状态正常, 当es1 服务器重启后,es1不能加到集群中,自己选举自己为master,这就产生了es集群中所谓的“脑裂” , 把es1 ...

  5. 脑裂是什么?Zookeeper是如何解决的?

    什么是脑裂 脑裂(split-brain)就是"大脑分裂",也就是本来一个"大脑"被拆分了两个或多个"大脑",我们都知道,如果一个人有多个大 ...

  6. Zookeeper集群的"脑裂"问题处理 - 运维总结

    关于集群中的"脑裂"问题,之前已经在这里详细介绍过,下面重点说下Zookeeper脑裂问题的处理办法.ooKeeper是用来协调(同步)分布式进程的服务,提供了一个简单高性能的协调 ...

  7. mfs分布式文件系统,分布式存储,高可用(pacemaker+corosync+pcs),磁盘共享(iscsi),fence解决脑裂问题

    一.MFS概述 MooseFS是一个分布式存储的框架,其具有如下特性:(1)通用文件系统,不需要修改上层应用就可以使用(那些需要专门api的dfs很麻烦!).(2)可以在线扩容,体系架构可伸缩性极强. ...

  8. es的脑裂

    一个正常es集群中只有一个主节点,主节点负责管理整个集群,集群的所有节点都会选择同一个节点作为主节点:所以无论访问那个节点都可以查看集群的状态信息. 而脑裂问题的出现就是因为从节点在选择主节点上出现分 ...

  9. [梁山好汉说IT] 如何理解脑裂问题

    [梁山好汉说IT] 如何理解脑裂问题 这个系列是通过梁山好汉的例子来阐述一些IT概念. 1. 问题描述 Split-brain, 就是在集群环境中,因为异常情况发生后,产生两个子集群.每个子集群都选出 ...

随机推荐

  1. Python 学习第十九天 django知识

    一,django 知识总结 1,同一个name属性的标签,多个值获取 <form action="/login/" method="POST" encty ...

  2. Nginx - Linux下按天分割日志

    待完善. 可参考:https://www.iteblog.com/archives/1244

  3. ionic build Android错误记录未解决

    1.try itcordova -v cordova create testing cd testing cordova plugin add cordova-plugin-sim cordova p ...

  4. iOS之TimeLine(时间轴)的实现

    这是一个关于OC时间轴的简单实现,我认为重要的是思路. 感谢作者:Cyandev 的文章<iOS 实现时间线列表效果>给的思路.这里先附上Objective-C的代码实现,有时间再去试试S ...

  5. [ACM训练] 算法初级 之 搜索算法 之 广度优先算法BFS (POJ 3278+1426+3126+3087+3414)

    BFS算法与树的层次遍历很像,具有明显的层次性,一般都是使用队列来实现的!!! 常用步骤: 1.设置访问标记int visited[N],要覆盖所有的可能访问数据个数,这里设置成int而不是bool, ...

  6. 【BZOJ】4056: [Ctsc2015]shallot

    题意 在线.可持久化地维护一条二维平面上的折线,支持查询与任意一条直线的交点个数. 点的个数和操作个数小于\(10^5\) 分析 一条折线可以用一个序列表示,可持久化序列考虑用可持久化treap. 如 ...

  7. 【异常】Caused by: java.lang.ClassNotFoundException: org.springframework.dao.DataIntegrityViolationException

    Caused by: java.lang.ClassNotFoundException: org.springframework.dao.DataIntegrityViolationException ...

  8. tungsten抽取和应用mysql binlog

    首先举例说明 api的基本使用方式 首先进行配置 , 可以看到源数据库和目的数据库 TungstenProperties tp=new TungstenProperties(); tp.setStri ...

  9. js get browser vertion (js获取浏览器信息版本)

    1问题:js get browser vertion (js获取浏览器信息版本) 2解决方案 Copy this script into your JavaScript files. It works ...

  10. vue 学习笔记

    使用vue框架做了一个项目,在这个过程中,摸索学习了vue,把过程学习到技术整理放在这里,供以后查看.