本文分享自天翼云开发者社区《Ceph的crush算法与一致性hash对比介绍》,作者:l****n

首先,我们先回顾下一致性hash以及其在经典存储系统中的应用。

一致性hash的基本原理

一致性hash的基本思想是,有一个hash函数,这个hash函数的值域形成了一个环(收尾相接:the largest hash value wraps around to the smallest hash value),然后存储的节点也通过这个hash函数随机的分配到这个环上,然后某个key具体存储到哪个节点上,是由这个key取hash函数对应到环的一个位置,然后沿着这个位置顺时针找到的第一个节点负责这个key的存储。这样环上的每个节点负责和它前面节点之间的这个区间的数据的存储。

如上图所示,hash函数的总区间是[A, Z],有3个存储节点分别对应到F、M和S的位置上,那么hash值为A或者Z的key将会顺时针查找它遇到的第一个节点,因此会存储到节点1上,同理hash值为K的key存储到第二个节点上。咱们再观察下一致性hash在增删节点的时候,数据迁移的情况,在上图的场景中,如果删除节点2的话,节点1上面的不会发生变化,原来存储在节点2上的(F,M]区间会迁移存储到节点3上;在上图的场景中,如果在U位置增加一个节点的话,原来存储到节点1上的(S, F]区间会分割成两个区间其中(S, U]会存储到新的节点上,而(U, F]不发生变化还是存储到节点1上。从上面的例子中可以看到,一致性hash在增删节点的时候,只影响与其相邻的节点,并且需要迁移的数据最少。

上面这种朴素的一致性hash有两个问题,第一个问题是如果节点较少,节点在环上的分布可能不均匀,导致每个节点的负载不均衡,比如上图中场景,如果节点3故障被剔除的话,节点1和节点2的负载会非常的不均衡;第二个问题是不支持异构的机型,比如如果有的存储节点是4TB的,有的存储节点是8TB的,每个节点对应环上的一个位置,无法感知到节点的权重。为了解决这两个问题,一般都是把每个节点对应到环上的多个位置,称为vnode,vnode足够多的话,可以认为是均衡打散的,如果有节点故障下线的话,这个节点在环上对应的vnode存储的数据就可以均匀分给其他的vnode,最终存储到对应的node上,因此在增删节点的时候,负载都是在所有的节点中均匀分摊。另外针对异构的机型,比如说4TB和8TB的节点,8TB的节点的vnode是4TB节点的2倍就可以了。

如果vnode节点和环上的点一一对应的话,可以认为是一致性hash的一个特殊的场景,比如说上图中的例子,这个hash环一个有A到Z 25个点(A、Z重合了),如果有25个vnode和其对应的话,这样一致性hash只需要记录每个物理node节点到vnode的映射关系就可以了,会非常的简单。开源swift对象存储使用的是这种一致性hash,参考:https://docs.openstack.org/swift/latest/ring_background.html

在分布式系统中为了保障可靠性一般都是多副本存储的,在dynamo存储系统中,用一致性hash算法查找到第一个vnode节点后,会顺序的向下找更多vnode节点,用来存储多副本(中间会跳过同台机器上的vnode,以达到隔离故障域的要求),并且第一个vnode是协调节点。在开源swift对象存储系统中,节点会先分组,比如3个一组,形成一个副本对,然后vnode会分配到某组机器上,一组机器上会有很多的vnode,并且这组机器上的vnode的leader节点在3台机器上会打散,分摊压力。

crush算法的核心思想

crush算法是一个伪随机的路由选择算法,输入pg的id,osdmap等元信息,通过crush根据这个pool配置的crush rule规则的伪随机计算,最终输出存储这个pd的副本的osd列表。由于是伪随机的,只要osdmap、crush rule规则相同,在任意的机器上,针对某个pg id,计算的最终的osd列表都是相同的。

crush算法支持在crush rule上配置故障域,crush会根据故障域的配置,沿着osdmap,搜索出符合条件的osd,然后由这些osd抽签来决定由哪个osd来存储这个pg,crush算法内部核心是这个称为straw2的osd的抽签算法。straw2的名字来源于draw straw(抽签:https://en.wikipedia.org/wiki/Drawing_straws)这个短语,针对每个pg,符合故障域配置条件的osd来抽检决定谁来存储这个pg,osd抽签也是一个伪随机的过程,谁抽到的签最长,谁赢。并且每个osd的签的长度,都是osd独立伪随机计算的,不依赖于其他osd,这样当增删osd节点时,需要迁移的数据最少。

如上图的一个示例,这是针对某个pg的一次抽签结果,从图中可以看到osd.1的签最长,所以osd.1赢了,最终osd.1会存储这个pg,在这个时候,如果osd.4由于故障下线,osd.4的故障下线并不会影响其他osd的抽签过程,针对这个pg,最终的结果还是osd.1赢,因此这个pg不会发生数据的迁移;当然,在上图从场景中,如果osd.1下线的话,osd.1上的pg会迁移到其他的osd上。增加osd节点的情况类似,比如在上图的场景中,如果新增加一个osd.5节点的话,每个osd都是独立抽签,只有osd.5赢的那些pg才会迁移到osd.5上,对其他的pg不会产生影响。因此,理论上,crush算法也和一致性hash一样,在增加删除osd节点的时候,需要迁移的数据最少。

另外straw2抽签算法也是支持异构的机型的,比如有的osd是4TB,有的osd是8TB,straw2的抽签算法会保证,8TB的osd抽签赢的概率是4TB的osd的两倍。背后的原理是,每个osd有个crush weight,crush weight正比于osd的磁盘大小,比如8TB的osd的crush weight是8左右,4TB的osd的crush weight是4左右。然后每个osd抽签的过程是,以osd的crush weight为指数分布的λ,产生一个指数分布的随机数,最后再比大小。

另外在ceph中,每个osd除了crush weight,还有个osd weight,osd weight的范围是0到1,表示的含义是这个osd故障的概率,crush算法在伪随机选择pg放置的osd的时候,如果遇到故障的osd,会进行重试。比如说某个osd weight是0的话,说明这个osd彻底故障了,通过上面straw2步骤计算出来的pg会retry重新分配到其他的osd上,如果某个osd的osd weight是0.8的话,这个osd上20%的pg会被重新放置到其他的osd上。通过把osd weight置为0,可以把某个osd节点从集群中临时剔除,通过调整osd weight也可以微调osd上的pg的分布。

总结

ceph分布式存储系统数据分布的基石crush算法,是一个伪随机的路由分布算法,对比一致性hash,它的核心的优点是元数据少,集群增删osd节点时,要迁移的数据少,并且crush算法支持异构的机型,支持各种级别的故障域的配置,它的缺点是在实际应用中发现,由于pg会占用一定的资源,一般每个osd最多200个pg左右,导致整个集群中pg数并不会特别的多,pg在osd上分布并不是非常的均衡,经常需要微调。

参考:

https://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf

https://github.com/ceph/ceph/pull/20196

https://docs.openstack.org/swif

Ceph的crush算法与一致性hash对比介绍的更多相关文章

  1. Ceph剖析:数据分布之CRUSH算法与一致性Hash

    作者:吴香伟 发表于 2014/09/05 版权声明:可以任意转载,转载时务必以超链接形式标明文章原始出处和作者信息以及版权声明 数据分布是分布式存储系统的一个重要部分,数据分布算法至少要考虑以下三个 ...

  2. Ceph之数据分布:CRUSH算法与一致性Hash

    转自于:http://www.cnblogs.com/shanno/p/3958298.html?utm_source=tuicool 数据分布是分布式存储系统的一个重要部分,数据分布算法至少要考虑以 ...

  3. 【数据结构与算法】一致性Hash算法及Java实践

    追求极致才能突破极限 一.案例背景 1.1 系统简介 首先看一下系统架构,方便解释: 页面给用户展示的功能就是,可以查看任何一台机器的某些属性(以下简称系统信息). 消息流程是,页面发起请求查看指定机 ...

  4. Hash算法和一致性Hash算法

    Hash算法 我们对同一个图片名称做相同的哈希计算时,得出的结果应该是不变的,如果我们有3台服务器,使用哈希后的结果对3求余,那么余数一定是0.1或者2,正好与我们之前的服务器编号相同,如果求余的结果 ...

  5. 【算法】一致性Hash算法

    一.分布式算法 在做服务器负载均衡时候可供选择的负载均衡的算法有很多,包括: 轮循算法(Round Robin).哈希算法(HASH).最少连接算法(Least Connection).响应速度算法( ...

  6. 11.redis cluster的hash slot算法和一致性 hash 算法、普通hash算法的介绍

    分布式寻址算法 hash 算法(大量缓存重建) 一致性 hash 算法(自动缓存迁移)+ 虚拟节点(自动负载均衡) redis cluster 的 hash slot 算法 一.hash 算法 来了一 ...

  7. ceph 的crush算法 straw

    很多年以前,Sage 在写CRUSH的原始算法的时候,写了不同的Bucket类型,可以选择不同的伪随机选择算法,大部分的模型是基于RJ Honicky写的RUSH algorithms 这个算法,这个 ...

  8. 一致性Hash简单介绍和使用

    背景: 一致性Hash用于分布式缓存系统,将Key值映射到详细机器Ip上,而且添加和删除1台机器的数据移动量较小,对现网影响较小 实现: 1 Hash环:将节点的Hash值映射到一个Hash环中.每一 ...

  9. 对一致性Hash算法,Java代码实现的深入研究

    一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读一文中"一致性Hash算法"部分,对于为什么要使用一致性Hash算法.一致性 ...

  10. Java实现一致性Hash算法深入研究

    一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读一文中”一致性Hash算法”部分,对于为什么要使用一致性Hash算法和一致性Hash算法的算法原 ...

随机推荐

  1. 【Azure 环境】从网络包中分析出TLS加密套件信息

    问题描述 在抓取到网络包之后,如何来获取TLS信息呢?比如使用的是是么加密套件呢? 因为在应用层面,获取的错误信息非常简单: An TLS 1.2 connection request was rec ...

  2. NetBox使用教程1-组织架构

    前言 本教程用于学习NetBox的基础使用,练习可使用官方Demo:https://demo.netbox.dev/ NetBox 使用教程系列:https://songxwn.com/tags/ne ...

  3. Myeclipse优化:自动转义字符串中的特殊字符

    在Myeclipse或者Eclipse中,将一段带引号(或其他的需要转义)字符串黏贴到引号中,双引号默认不会自动转义,手工一个一个去转义(变成\")的话实在是费事,这里记录一下让Myecli ...

  4. 曾经做的一个JS小游戏——《Battle City》

    今天改网盘密码时,找到了个很久前的东西:JavaScript版的坦克大战.07年的夏天制作花了好多个夜晚制作,那段着迷JS游戏的疯狂时光.但因为后来众多浏览器的出现,导致了游戏兼容性大大的下降,最终放 ...

  5. Windows之子系统WSL

    [安装] 安装参考:https://learn.microsoft.com/zh-cn/windows/wsl/install-manual#step-4---download-the-linux-k ...

  6. qiankun 的 JS 沙箱隔离机制

    为什么需要JS沙箱 想象一下 当一个应用(比如应用 A)加载时,可能会对 window 对象的属性进行修改或添加.如果不加控制,这些修改会影响到之后加载的其他应用(比如应用 B),就会导致属性读写冲突 ...

  7. Kafka Streams 在监控场景的应用与实践

    作者:来自 vivo 互联网服务器团队- Pang Haiyun 介绍 Kafka Streams 的原理架构,常见配置以及在监控场景的应用. 一.背景 在当今大数据时代,实时数据处理变得越来越重要, ...

  8. simpleui

    目录 一.simpleui 1.1 使用步骤 1.2 功能介绍 1.3 展示大屏 一.simpleui 之前公司里,做项目前后端结合,要使用权限,要快速搭建后台管理,使用djagno的admin直接搭 ...

  9. bridge模式下 所有容器的 网关 都是 宿主机docker0网卡的ip

    bridge模式下 所有容器的 网关 都是 宿主机docker0网卡的ip

  10. 利用H2的自定义函数更好的支持测试

    在写DAO层的单元测试时,用mock的写法意义不大,因为DAO层的测试更多的关注是Java对象的传递和生成SQL的正确性,所以需要链接真实的数据库. 但是对于单元测试,真实的数据库是很重的,还要依赖于 ...