设为首页 加入收藏

TOP

每一个shard都需要有个家(二)
2018-04-30 06:06:46 】 浏览:817
Tags:一个 shard 需要
replica shard包含有和primary shard同样的数据。如下面两幅图所示,第一幅,master把需要初始化replica shard c0的ClusterState广播到整个集群;第二幅,node2探测到自己被分配了一个新的shard


当replica shard分配完成后,需要理解的很重要的一点是,我们会从primary shard复制所有缺失的数据到replica shard,数据复制完成后,master才会把replica shard的状态标注为”started”,并且向集群中广播一个新的ClusterState。如下面动图所示

场景二、 是时候移动shard了

有时你的集群可能需要在集群内部移动已经存在的shard。这可能会有很多原因

1. 用户配置

这方面最常见的一个例子就是Hot/Warm配置,当数据老化时,会根据Hot/Warm配置把数据移动到访问速度较慢的磁盘上。如下图所示

 

2. 用户使用命令显式移动shard

用户通过cluster re-route命令来使得elasticsearch将shard从一个地方移到另一个地方

3. 磁盘相关的配置

存在与磁盘使用空间相关的以下两个设置,分配决定器会根据这些设置的阈值来移动shard

  1. cluster.routing.allocation.disk.watermark.low
  2. cluster.routing.allocation.disk.watermark.high

超过低水位阈值时,elasticsearch将阻止我们写入新的shard。同样,超过高水位阈值时,elasticsearch会把此节点上shard重新分配到其他节点上,直到当前节点的磁盘占用低于高水位阈值。如下图所示

4. 集群添加节点

可能你的集群已经达到最大容量,于是你添加了一个新的节点,此时elasticsearch会重新平衡(rebalance)整个集群。如下图所示

 

Shard可能会包含很多G的数据,因此,在集群间移动它们可能产生极大的性能影响。为使这个过程对用户透明,移动shard必须在后台运行。也就是尽可能的降低移动shard对elasticsearch其他方面的影响。为此,引入了一个抑制参数(indices.recovery.max_bytes_per_sec/cluster.routing.allocation.node_concurrent_recoveries) ),以保证移动shard期间依然可以继续向这些shard索引数据。如下图所示

记住:elasticsearch的所有数据都是通过Lucene存储的。Lucene使用被称为segment的一组文件来存储一组倒排索引。给定的tokens/words时,倒排索引结构可以方便的告诉你这些tokens/words包含在哪些文档中,出现在文档中的什么位置。当Lucene索引文档时,文档暂存于内存中的indexing buffer。当indexing buffer满或,elasticsearch发出refresh操作(从而引发lucene flush)时,indexing buffer中的数据就被强制写入被称为segment的倒排索引中。如下图所示

随着我们继续索引文档,我们会用同样的方式创建新的segment。关于segment,一个重要的事情就是segment是不可变的(immutable)。这意味着,一旦写了一个segment,这个segment就永远不会改变了。如果你发出删除或任何改变,这些动作将发生在新的segment上,在新的segment上同样发生合并过程。如下图所示

既然数据是存储在内存的,理论上在数据提交到segment文件之前(译注:即使已写入segment也可能会丢失,因为segment写入filesystem时,只是写入了内存即filesystem cache,只有调用filesystem的fsync后,内容才真正写入了磁盘。而出于性能考虑,filesystem是周期性而不是实时的调用fsync的),数据是有可能丢失的。elasticsearch使用transaction log来缓解这种情况。每当文档索引进Lucene时,文档也会被写入transaction log。如下图所示


Transaction log是顺序写入的,最后一个请求位于文件的末尾。借助transaction log,我们就可以恢复尚未写入Lucene中的文档。elasticsearch的持久化模型如下图所示


生成segment时可能并未执行fsync,此时segment会暂存于filesystem cache内存中,OS会暂缓刷新数据到磁盘。这么作是出于性能原因,因此,必须要把filesystem cache内存中的segment写入到磁盘,同时清空transaction log,这个工作是通过elasticsearch flush来完成的
当发出elasticsearch flush(从而引发lucene commit)命令时,会做两件事情

  1. 把indexing buffer中的数据写入磁盘,从而生成一个新的segment
  2. 遍历所有的segment文件,请求filesystem使用fsync将所有segment写入磁盘

执行elasticsearch flush就把内存中所有数据(即indexing buffer中的数据以及filesystem cache内存中的segment),统统写入了磁盘,并且清空了transaction log,这确保我们不会丢失任何数据。对于重新安置(relocation)shard,如果我们捕获并保存一组给定的segment,则我们得到一个时间点一致且数据不可变的数据快照

译注:参考Elasticsearch: 权威指南–>持久化变更了解文档写入过程。梗概总结如下图所示

 

以下面动图为例,集群想要把node4上的a0移动到node5,于是master标注a0为正在从node4重新安置到node5,node5收到请求后在node5上初始化一个shard。对这个行为,有一个非常重要的事情需要注意,当进行重新平衡时,看起来replica shard正在从node4移动到node5,但事实上,重新安置shard时总是从primary shard复制数据的(即:node1上的a0)

 

以下面动图为例,我们来演示“把node1上的primary shard重新安置到node5”。记住我们前面所说的两种数据存储机制,transaction log和lucene segment
此例中node5是空节点,node1上有primary shard。全部步骤如下

  1. master向node5发送了一个modified ClusterState,master要求node5初始化一个新的shard
  2. node5探测到自己被分配了一个新的shard
  3. node5向node1(node1上有primary shard)发送请求,请求开始恢复过程
  4. node1收到node5的请求,然后,node1验证它自己知道node5发送的请求
  5. node1验证通过,于是在node1上,elasticsearch固定tra
首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Kafka 源码分析2 : Network相关 下一篇高并发风控技术解密(下)

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目