对于一个分布式存储系统来说,数据是分散存储在多个节点上的。如何让数据均衡的分布在不同节点上,来保证其高可用性?所谓均衡,是指系统中每个节点的负载是均匀的,并且在发现有不均匀的情况或者有节点增加/删除时,能及时进行调整,保持均匀状态。本文将探讨Elasticsearch的数据分布方法,文中所述的背景是Elasticsearch 5.5。
  在Elasticsearch中,以Shard为最小的数据分配/迁移单位。数据到节点的映射分离为两层:一层是数据到Shard的映射(Route),另一层是Shard到节点的映射(Allocate)。

  一方面,插入一条数据时,ES会根据指定的Key来计算应该落到哪个Shard上。默认Key是自动分配的id,可以自定义,比如在我们的业务中采用CompanyID作为Key。因为Primary Shard的个数是不允许改变的,所以同一个Key每次算出来的Shard是一样的,从而保证了准确定位。

shard_num = hash(_routing) % num_primary_shards
1
  另一方面,Master会为每个Shard分配相应的Data节点进行存储,并维护相关元信息。通过Route计算出来的Shard序号,在元信息中找到对应的存储节点,便可完成数据分布。Shard Allocate的映射关系并不是完全不变的,当检测到数据分布不均匀、有新节点加入或者有节点挂掉等情况时就会进行调整,称为Relocate。那么,Elasticsearch是根据什么规则来为Shard选取节点,从而保证数据均衡分布的?概括来看,主要有三方面的影响:节点位置、磁盘空间、单个节点上的Index和Shard个数。

节点位置
   对于一个ES节点来说,它可能是某台物理机器上的一个VM,而这个物理机器位于某个Zone的某个机架(Rack)上。通过将Primary Shard和Replica Shard分散在不同的物理机器、Rack、Zone,可以尽可能的降低数据丢失和系统不可用的风险,这一点几乎在所有的分布式系统中都会考量。

   Elasticsearch是通过设置awareness.attribute对集群中的节点进行分组,从而实现Rack和Zone的发现。比如按照下列方式对elasticsearch.yml进行配置,再启动相应的节点,即可实现Zone的区分。

// elasticsearch.yml
cluster.routing.allocation.awareness.attributes: zone

// 启动ES
./bin/elasticsearch -Enode.attr.zone=zone_one
./bin/elasticsearch -Enode.attr.zone=zone_two

  实践中,如果使用了这样的Awareness机制,应该保证不同分组类的机器个数一致,不会发生倾斜。比如,在Zone Awareness下,如果集群有10台机器,应该保证每个Zone各有5台机器(2个Zone)。

磁盘空间
  磁盘空间是制约存储的硬性条件,单机的可用磁盘空间决定了能否继续往这个节点写入新数据、分配新Shard以及是否需要迁移数据等。在ES中,有三个参数用来控制与此相关的特性,默认每30秒检查一次。

cluster.routing.allocation.disk.watermark.low: 默认为85%,超过这个阈值后,就不允许往这个节点分配Shard。
cluster.routing.allocation.disk.watermark.high:默认为90%,超过这个阈值后,就需要将该节点的Shard迁移出去。
cluster.routing.allocation.disk.watermark.flood_stage:默认为95%,超过这个阈值后,与该节点上的Shard有关的Index都变成只读,不允许写入数据。

单个节点上的Index和Shard个数
  在满足节点位置和磁盘空间的条件后,单个节点上的Index和Shard个数是否均匀,决定了Shard可以分配/迁移到哪个节点。ES通过计算权值来量化这样的分配方式。
  以检测某个Shard是否需要迁移到其他节点为例,ES会先计算该Shard所在节点(A)的权值,然后依次跟其他节点的权值比较,如果与节点B的差值(Delta-A)超过了阈值,再进一步计算节点A去掉该Shard后的权值与节点B增加该Shard后的权值之间的差值(Delta-B),如果Delta-A大于Delta-B,则表明Shard可以迁移到节点B。
  这里的权值计算简化如下,其中indexBalance与shardBalance分别由参数控制,而阈值由cluster.routing.allocation.balance.threshold设置,默认为1.0f。当然,这里只描述了核心思想,详细逻辑请阅读BalancedShardsAllocator.java中的源码。通过调整三个参数,可以控制策略的松紧。

// indexBalance = cluster.routing.allocation.balance.index, default is 0.55f
// shardBalance = cluster.routing.allocation.balance.shard, default is 0.45f

float sum = indexBalance www.ysyl157.com+ shardBalance;
float theta0 = shardBalance / sum;
float theta1 = indexBalance / sum;

private float weight(Balancer balancer, ModelNode node, String index, int numAdditionalShards) {
final float weightShard = node.numShards(www.dfgjpt.com) +www.chaoyueyule.net/ numAdditionalShards - balancer.avgShardsPerNode();
final float weightIndex www.jimeiyulept.com= node.numShards(index) + numAdditionalShards - balancer.avgShardsPerNode(index);
return theta0 * weightShard www.ylouyi3.com+ theta1 * weightIndex;

Primary与Replica分布
  最初关注Elasticsearch的数据分布,是因为在性能调优时遇到了一个与Primary/Replica分布有关的问题。背景是这样的,为了能够复用单个节点上的Disk Cache,我们对查询请求进行了限制,只允许其访问Primary Shard。然而总是有那么一两台机器的查询会被Queue住,通过调研发现,这些机器上面的Primary Shard比其他机器多(对某一个Index而言),即下图中左边所示,而我们希望的是右图所示的均匀分布。
  引起这个问题的根源是,Elasticsearch中的Shard均匀分布是针对Primary+Replica整体而言的,也就是说没法做到只针对Primary Shard单方面做均匀分布,所以才会出现下图左边所示,某个节点上有3个Primary Shard,而另一个节点只有1个。目前尚未发现可以调节的地方。

  本文探讨了Elasticsearch的数据分布方法,其思想对很多其他分布式存储系统是通用的,而了解相关原理是做很多调优工作的前提。
---------------------

谈Elasticsearch下分布式存储的数据分布的更多相关文章

  1. 谈一谈Elasticsearch的集群部署

      Elasticsearch天生就支持分布式部署,通过集群部署可以提高系统的可用性.本文重点谈一谈Elasticsearch的集群节点相关问题,搞清楚这些是进行Elasticsearch集群部署和拓 ...

  2. [原创]浅谈NT下Ring3无驱进入Ring0的方法

    原文链接:浅谈NT下Ring3无驱进入Ring0的方法 (测试环境:Windows 2000 SP4,Windows XP SP2.Windows 2003 未测试) 在NT下无驱进入Ring0是一个 ...

  3. 浅谈 IE下innerHTML导致的问题

    原文:浅谈 IE下innerHTML导致的问题 先来看个demo吧: <!DOCTYPE html> <html> <head> <meta charset= ...

  4. []转帖] 浅谈Linux下的五种I/O模型

    浅谈Linux下的五种I/O模型 https://www.cnblogs.com/chy2055/p/5220793.html  一.关于I/O模型的引出 我们都知道,为了OS的安全性等的考虑,进程是 ...

  5. 浅谈Vue下的components模板

    浅谈Vue下的components模板在我们越来越深入Vue时,我们会发现我们对HTML代码的工程量会越来越少,今天我们来谈谈Vue下的 components模板的 初步使用方法与 应用 我们先来简单 ...

  6. 浅谈Linux下/etc/passwd文件

    浅谈Linux 下/etc/passwd文件 看过了很多渗透测试的文章,发现在很多文章中都会有/etc/passwd这个文件,那么,这个文件中到底有些什么内容呢?下面我们来详细的介绍一下. 在Linu ...

  7. 搜索浅谈(Elasticsearch和Lucene4分享)

    刚刚过去的双11,真是给线下运营商好好上了一课.当今的互联网真是炙手可热,大家对互联网的热情是如此之高.相信电商之间的竞争将更加的激烈和残酷,不过,搜索,作为用户体验很重要的一点,各大电商也做的越来越 ...

  8. centos6.7下安装mvn 、安装elasticsearch下ik分词

    先说一下安装mvn步骤,如果已安装可以忽略: 在tmp目录下 1.建立mvn目录 mkdir mvn cd /tmp/mvn 2.下载 wget http://apache.fayea.com/mav ...

  9. 浅谈Linux下如何修改IP

    linux 下命令之浅谈//cd ..  //返回上一级//创建文件夹touch test.txt//Linux不区分大小写//往一个文件中追加内容echo "****" > ...

随机推荐

  1. github入门之分支操作--5

    1.显示分一览表 2.创建.切换分支 2.1.切换到feature-A分支并进行提交 2.1.1.执行下面的命令,创建名为feature-A的分支 实际上,执行以命令也能收到同样的效果,但是我习惯使用 ...

  2. Azure 进阶攻略 | 关于Java 和事件中心的那不得不说的事

    物联网技术辣么火,虽然之前有说过不少,但今天,仍有一个憋在我心里已久,不得不说的话题:基于Azure 的物联网平台必不可少,你可能已经在使用,但也许并没有意识到的服务:Azure 事件中心. 啊?事件 ...

  3. Linux远程连接及常用指令

    一.远程连接 一般,服务器都是特别庞大的,会把它们用一个独立的小屋进行存放,如果有时候需要对服务器进行一些操作,离得近还好,离的远就会破费一些周折了,所以,这个时候我们就需要用到远程连接软件了.推荐使 ...

  4. Servlet和JSP之有关Servlet和JSP的梳理(一)

    大二第一学期的时候有学JSP的课,但是因为在开学之前做过JSP的小项目,所以一个学期的课也没听,直到期末考试成绩出来了,才回想JSP的内容还有多少记得,没想到模模糊糊也记不起多少,赶紧回头学回来.接下 ...

  5. 【GIMP学习】抠图方法二则

    之前抠图都比较二,懒人我尝试过在线抠图软件.以及在线PS简易版,真的都很不好用,前者简单粗暴,后者我遇到各种储存不能的bug. 在ubuntu的环境下有一个功能可以和PS相媲美的功能强大图片处理软件G ...

  6. SpringAOP 设计原理

    1.  设计原理 引入了,代理模式. java 程序执行流: 如果从虚拟机的角度看,整个程序的过程就是方法的调用,我们按照方法的执行顺序,将方法调用成一串. 在方法之间有着Join Point 连接点 ...

  7. myna代码

    https://github.com/TalkingData/Myna/tree/master/Dataset https://github.com/TalkingData/Myna

  8. CPP-基础:关于多态

        类的多态特性是支持面向对象的语言最主要的特性,有过非面向对象语言开发经历的人,通常对这一章节的内容会觉得不习惯,因为很多人错误的认为,支持类的封装的语言就是支持面向对象的,其实不然,Visua ...

  9. javase(2)_递归&迭代

    一.递归  程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题 ...

  10. html制作简单框架网页 实现自己的音乐驿站 操作步骤及源文件下载 (播放功能限mp3文件)

    使用HTML语言来设计制作 Hyper Text Markup Language 超文本标记语言 这门语言的特点就是标记,就是把所有的命令单词用<>标记起来,就可以发挥作用 还有一个特点, ...