转载:http://www.infoq.com/cn/articles/anatomy-of-an-elasticsearch-cluster-part02
共识——裂脑问题及法定票数的重要性
共识是分布式系统的一项基本挑战。它要求系统中的所有进程/节点必须对给定数据的值/状态达成共识。已经有很多共识算法诸如Raft、Paxos等,从数学上的证明了是行得通的。但是,Elasticsearch却实现了自己的共识系统(zen discovery),Elasticsearch之父Shay Banon在这篇文章中解释了其中的原因。zen discovery模块包含两个部分:
- Ping: 执行节点使用ping来发现彼此
- 单播(Unicast):该模块包含一个主机名列表,用以控制哪些节点需要ping通
Elasticsearch是端对端的系统,其中的所有节点彼此相连,有一个master节点保持活跃,它会更新和控制集群内的状态和操作。建立一个新的Elasticsearch集群要经过一次选举,选举是ping过程的一部分,在所有符合条件的节点中选取一个master,其他节点将加入这个master节点。ping间隔参数ping_interval
的默认值是1秒,ping超时参数ping_timeout
的默认值是3秒。因为节点要加入,它们会发送一个请求给master节点,加入超时参数join_timeout
的默认值是ping_timeout
值的20倍。如果master出现问题,那么群集中的其他节点开始重新ping以启动另一次选举。这个ping的过程还可以帮助一个节点在忽然失去master时,通过其他节点发现master。
注意:默认情况下,client节点和data节点不参与这个选举过程。可以在elasticsearch.yml配置文件中,通过设置discovery.zen.master_election.filter_client
属性和discovery.zen.master_election.filter_data
属性为false
来改变这种默认行为。
故障检测的原理是这样的,master节点会ping所有其他节点,以检查它们是否还活着;然后所有节点ping回去,告诉master他们还活着。
如果使用默认的设置,Elasticsearch有可能遭到裂脑问题的困扰。在网络分区的情况下,一个节点可以认为master死了,然后选自己作为master,这就导致了一个集群内出现多个master。这可能会导致数据丢失,也可能无法正确合并数据。可以按照如下公式,根据有资格参加选举的节点数,设置法定票数属性的值,来避免爆裂的发生。
discovery.zen.minimum_master_nodes = int(# of master eligible nodes/2)+1
<iframe id="iframe_0.6585984430275857" style="box-sizing: border-box; border-style: none; border-width: initial; width: 1019px; height: 502px;" src="data:text/html;charset=utf8,%3Cstyle%3Ebody%7Bmargin:0;padding:0%7D%3C/style%3E%3Cimg%20id=%22img%22%20src=%22http://cdn2.infoqstatic.com/statics_s2_20170228-0434_4/resource/articles/anatomy-of-an-elasticsearch-cluster-part02/zh/resources/05.jpeg?_=6506885%22%20style=%22border:none;max-width:1291px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.6585984430275857',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no"></iframe>
这个属性要求法定票数的节点加入新当选的master节点,来完成并获得新master节点接受的master身份。对于确保群集稳定性和在群集大小变化时动态地更新,这个属性是非常重要的。图a和b演示了在网络分区的情况下,设置或不设置minimum_master_nodes
属性时,分别发生的现象。
注意:对于一个生产集群来说,建议使用3个节点专门做master,这3个节点将不服务于任何客户端请求,而且在任何给定时间内总是只有1个活跃。
我们已经搞清楚了Elasticsearch中共识的处理,现在让我们来看看它是如何处理并发的。
并发
Elasticsearch是一个分布式系统,支持并发请求。当创建/更新/删除请求到达主分片时,它也会被平行地发送到分片副本上。但是,这些请求到达的顺序可能是乱序的。在这种情况下,Elasticsearch使用乐观并发控制,来确保文档的较新版本不会被旧版本覆盖。
每个被索引的文档都拥有一个版本号,版本号在每次文档变更时递增并应用到文档中。这些版本号用来确保有序接受变更。为了确保在我们的应用中更新不会导致数据丢失,Elasticsearch的API允许我们指定文件的当前版本号,以使变更被接受。如果在请求中指定的版本号比分片上存在的版本号旧,请求失败,这意味着文档已经被另一个进程更新了。如何处理失败的请求,可以在应用层面来控制。Elasticsearch还提供了其他的锁选项,可以通过这篇来阅读。
当我们发送并发请求到Elasticsearch后,接下来面对的问题是——如何保证这些请求的读写一致?现在,还无法清楚回答,Elasticsearch应落在CAP三角形的哪条边上,我不打算在这篇文章里解决这个素来已久的争辩。
<iframe id="iframe_0.463839526521042" style="box-sizing: border-box; border-style: none; border-width: initial; width: 457px; height: 318px;" src="data:text/html;charset=utf8,%3Cstyle%3Ebody%7Bmargin:0;padding:0%7D%3C/style%3E%3Cimg%20id=%22img%22%20src=%22http://cdn2.infoqstatic.com/statics_s2_20170228-0434_4/resource/articles/anatomy-of-an-elasticsearch-cluster-part02/zh/resources/06.jpeg?_=6506885%22%20style=%22border:none;max-width:1291px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.463839526521042',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no"></iframe>
但是,我们要一起看下如何使用Elasticsearch实现写读一致。
一致——确保读写一致
对于写操作而言,Elasticsearch支持的一致性级别,与大多数其他的数据库不同,允许预检查,来查看有多少允许写入的可用分片。可选的值有quorum、one和all。默认的设置为quorum,也就是说只有当大多数分片可用时才允许写操作。即使大多数分片可用,还是会因为某种原因发生写入副本失败,在这种情况下,副本被认为故障,分片将在一个不同的节点上重建。
对于读操作而言,新的文档只有在刷新时间间隔之后,才能被搜索到。为了确保搜索请求的返回结果包含文档的最新版本,可设置replication为sync(默认),这将使操作在主分片和副本碎片都完成后才返回写请求。在这种情况下,搜索请求从任何分片得到的返回结果都包含的是文档的最新版本。即使我们的应用为了更高的索引率而设置了replication=async,我们依然可以为搜索请求设置参数_preference为primary。这样,搜索请求将查询主分片,并确保结果中的文档是最新版本。
我们已经了解了Elasticsearch如何处理共识、并发和一致,让我们来看看分片内部的一些主要概念,正是这些特点让Elasticsearch成为一个分布式搜索引擎。
Translog(预写日志)
因为关系数据库的发展,预写日志(WAL)或者事务日志(translog)的概念早已遍及数据库领域。在发生故障的时候,translog能确保数据的完整性。translog的基本原理是,变更必须在数据实际的改变提交到磁盘上之前,被记录下来并提交。
当新的文档被索引或者旧的文档被更新时,Lucene索引将发生变更,这些变更将被提交到磁盘以持久化。这是一个很昂贵的操作,如果在每个请求之后都被执行。因此,这个操作在多个变更持久化到磁盘时被执行一次。正如我们在上一篇文章中描述的那样,Lucene提交的冲洗(flush)操作默认每30分钟执行一次或者当translog变得太大(默认512MB)时执行。在这样的情况下,有可能失去2个Lucene提交之间的所有变更。为了避免这种问题,Elasticsearch采用了translog。所有索引/删除/更新操作被写入到translog,在每个索引/删除/更新操作执行之后(默认情况下是每5秒),translog会被同步以确保变更被持久化。translog被同步到主分片和副本之后,客户端才会收到写请求的确认。
在两次Lucene提交之间发生硬件故障的情况下,可以通过重放translog来恢复自最后一次Lucene提交前的任何丢失的变更,所有的变更将会被索引所接受。
注意:建议在重启Elasticsearch实例之前显式地执行冲洗translog,这样启动会更快,因为要重放的translog被清空。POST /_all/_flush命令可用于冲洗集群中的所有索引。
使用translog的冲洗操作,在文件系统缓存中的段被提交到磁盘,使索引中的变更持久化。现在让我们来看看Lucene的段。
Lucene的段
Lucene索引是由多个段组成,段本身是一个功能齐全的倒排索引。段是不可变的,允许Lucene将新的文档增量地添加到索引中,而不用从头重建索引。对于每一个搜索请求而言,索引中的所有段都会被搜索,并且每个段会消耗CPU的时钟周、文件句柄和内存。这意味着段的数量越多,搜索性能会越低。
为了解决这个问题,Elasticsearch会合并小段到一个较大的段(如下图所示),提交新的合并段到磁盘,并删除那些旧的小段。
<iframe id="iframe_0.15634890017099679" style="box-sizing: border-box; border-style: none; border-width: initial; width: 906px; height: 597px;" src="data:text/html;charset=utf8,%3Cstyle%3Ebody%7Bmargin:0;padding:0%7D%3C/style%3E%3Cimg%20id=%22img%22%20src=%22http://cdn2.infoqstatic.com/statics_s2_20170228-0434_4/resource/articles/anatomy-of-an-elasticsearch-cluster-part02/zh/resources/07.jpeg?_=6506885%22%20style=%22border:none;max-width:1291px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.15634890017099679',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no"></iframe>
这会在后台自动执行而不中断索引或者搜索。由于段合并会耗尽资源,影响搜索性能,Elasticsearch会节制合并过程,为搜索提供足够的可用资源。
相关推荐
总结,`elasticsearch-5.0.1-core-main` 源码涵盖了 Elasticsearch 的核心功能,通过深入研究这些源码,开发者可以更深入地了解 Elasticsearch 如何处理搜索、索引、集群管理和分布式协调,这对于优化使用和开发相关...
Elasticsearch 是一个基于 Lucene 的开源全文搜索引擎,它以其分布式的实时特性和强大的数据分析能力,广泛应用于日志分析、监控、搜索、信息检索等多个领域。本项目课程将深入探讨 Elasticsearch 的核心概念、工作...
Elasticsearch 是一个流行的、开源的全文搜索引擎,它基于 Lucene 库构建,提供了一个分布式、RESTful 风格的搜索和分析引擎服务。在5.3.2这个版本中,Elasticsearch 已经具备了相当成熟的功能和优化,包括强大的...
Elasticsearch是一个开源的全文搜索引擎,它以分布式、RESTful接口和实时性为特点,广泛应用于数据搜索、分析和监控。这份"**Elasticsearch实战与原理解析 源代码**"的压缩包文件提供了关于这个强大工具的实践案例和...
Elasticsearch,简称ES,是当今最流行的大数据搜索引擎之一,尤其在日志分析、实时数据分析和全文检索领域有着广泛的应用。它是一个基于Lucene的开源分布式搜索和分析引擎,设计目标是提供一个高可用性、可扩展且近...
Elasticsearch(ES)是基于Lucene构建的分布式全文搜索引擎,它以其强大的搜索功能、实时分析性能以及易于扩展性在大数据领域广受欢迎。本书提供了全面的指导,无论你是初学者还是经验丰富的开发者,都可以从中受益...
Elasticsearch作为一个强大的分布式搜索和分析引擎,广泛应用于全文检索、结构化检索和数据分析。它基于Lucene构建,目前是开源搜索引擎领域的重要选择。 在58集团的数据库部门中,Elasticsearch被用于多个业务场景...
Elasticsearch 是一个分布式、开源的全文搜索引擎,其设计目标是提供实时、可扩展的数据搜索和分析能力。在深入探讨源码之前,我们先了解下 Elasticsearch 的基本架构和工作原理。 1. **分布式架构** - **Sharding...
Elasticsearch 是一个分布式搜索引擎,其数据存储方式和管理优化对于高效检索和稳定运行至关重要。在Elasticsearch中,数据存储的基本单位是段(segment),每个段都是一个倒排索引,由Lucene生成。每次数据写入后,...
Elasticsearch的节点(Node)通过网络相互连接,形成一个集群(Cluster),每个节点可以存储和处理数据,并参与索引和搜索操作。 二、文档索引过程 1. **索引API**:Elasticsearch提供索引API,用于将文档添加到...
Elasticsearch 是一个开源的全文搜索引擎,被广泛应用于日志分析、实时监控、数据可视化和复杂查询场景。它基于 Lucene 库,提供了分布式、可扩展、高可用性的搜索和分析服务。版本号 8.11.3 表示这是 Elasticsearch...
Elasticsearch 是一款强大的开源搜索与分析引擎,基于 Lucene 开发,适用于大规模数据处理场景。它以其分布式架构、实时搜索能力、高度可扩展性以及丰富的功能集(如全文搜索、复杂查询、聚合分析等)而闻名。其中,...
Kibana是ELK stack中的可视化工具,允许用户通过图形界面来查看和分析Elasticsearch中的数据。 K3对比K4: - K3和K4的对比:介绍Kibana的不同版本间的区别。 K3: - Kibana3入门:如何开始使用Kibana3。 - Config....
Elasticsearch(简称ES)是一款开源的、基于Lucene的全文搜索引擎,被广泛应用于大数据分析、日志收集、实时监控等多种场景。它的核心特性包括分布式、RESTful接口、自动分词、高可扩展性以及实时分析。 **一、...
**Elasticsearch** 是一个基于Lucene的开源分布式搜索引擎,它提供了丰富的功能和高度可扩展的能力,适用于多种场景下的数据检索与分析。其主要特点包括但不限于: - **近实时索引**:能够快速地将新数据加入索引,...
总的来说,Elasticsearch是一个高效、灵活的搜索和分析平台,它充分利用了分布式架构的优势,提供实时、高可用的数据存储和检索解决方案,广泛应用于大数据环境中的信息检索、日志分析和实时监控等多个领域。
《ELK中文指南1》是关于Logstash、Elasticsearch和Kibana(ELK stack)的入门教程,旨在帮助用户理解和使用这个强大的日志管理和分析工具。 **1. Logstash** Logstash是一款用于处理和收集事件及日志的工具。它的...
这些引擎各有特点,例如Elasticsearch因其分布式、高可用性、丰富的插件和社区支持而被广泛采用。 【Elasticsearch的选择与构建】 Elasticsearch是构建搜索引擎的一个热门选择,它是一个面向文档的存储系统,无需...