选举
众所周知ElasticSearch是个天生的分布式存储系统,而分布式系统的共识性是分布式系统中的基本挑战。共识性的意思是分布式系统中的所有节点或者进程都必须对同一个数据或者状态达成一致。可以通过raft(etcd),paxos(zookeeper)等算法来达到共识的目的。
而ElasticSearch集群是怎么处理节点之间的共识性的呢?ElasticSearch的创作者把这个机制称作zen discovery。 zen discover共有两个模块:
- ping:进程用来发现其他节点
- Unicast:一个主机名列表,用来控制ping哪些节点
ElasticSearch集群的分布式网络,本质上是一个对等网络系统。也就是任意节点都可以充当对外服务节点,而且可以与该系统中的其他节点通信。ElasticSearch集群就是通过这种相互之间的通信来选举出master节点来的。要知道一个稳定的master节点对于ElasticSearch集群来说是非常重要的,master节点负责一些集群范围内的轻量级操作,比如创建/删除索引,跟踪节点集群状态,决定分片被分配到哪个节点。
ElasticSearch的节点启动参数中有多个参数能够影响节点的选举:
- ping_interval:ping的间隔,默认1秒,如果此值设置过大,会延迟发送ping请求的时机,导致master踢出异常节点过慢,集群出现异常数据。如果该值设置的过小,又可能导致原本正常的节点被错误的踢出集群,让节点失效。
- ping_timeout: 单次ping的超时时间,默认3秒。可想而知,如果此值设置过大,踢出异常节点的速度过慢,同样会导致集群出现异常数据。如果该值设置的过小,同样会导致集群踢出真长的节点。
- join_timeout: 此值是发起ping请求的节点加入集群的超时时间。默认是ping_timeout的20倍。如果主节点失效,集群的节点会重新开始 ping 并发起新一轮的选举。ping 过程在当一个节点意外误以为主节点失效并通过其他节点发现主节点时也会有帮助。
- minimum_master_nodes:默认值为1,该属性值的意思是已该节点的视角出发,需要看到的最小的具有master角色的节点数量。该值推荐设置为 (预定的master节点数量/2 + 1)。生产环境的集群,推荐使用三个master节点,这三个节点不存储数据,也不接受任何客户端请求,仅全职负责master角色的任务。
乐观锁
ElasticSearch支持并发式请求,当多个请求到达节点,请求送达到处理分片时是乱序的。ElasticSearch通过乐观锁来控制旧数据不会覆盖新的数据。ElasticSearch中的每一条数据都有个版本概念,每次操作都会自增这个版本号。允许高版本覆盖低版本,但是遇到低版本数据尝试覆盖高版本数据,那么该次操作就会失败,证明已经有请求改动了该条数据,这时可以在应用程序层面处理这个问题。
读写一致性
ElasticSearch提供参数来设置是否让写入到一半节点的数据实时查询生效。如果采用缺省设置(sync),那么必须等到该次操作都写入主备完毕后才会使查询请求查询到最新的数据。这样吞吐效率可能差一点,毕竟要保证主备分片的一致性。如果将缺省值改为只查询主分片,那么就会牺牲主备分片的数据一致性,提升吞吐效率。此时查询主分片的数据一定是最新的,但是查询副本分片可以就会查询到旧数据。
对于写一致性来说,ElasticSearch的默认做法是,提供一个默认的节点集合,只有这个集合中的节点都提供了写入,那么这次写入才会被集群接受。换句话来说就是只有大部分节点都能写入了,才能开始写入操作。(如果这个时候副本分片写入失败,会在其他节点上重建该副本)