草庐IT

分布式系统的磁盘均衡策略

YRCloudFile 2023-03-28 原文
分布式系统设计中的一大挑战,是对磁盘的均衡使用,这在一个全新的集群中,是比较容易实现的。关键问题在于,随着时间的推移,我们需要在集群中不断地新增或者移除设备,在分布式文件存储系统 YRCLoudFile 产品中,我们可能会使用冷热分层策略将文件下刷至对象存储,这些行为都可能会导致集群内的磁盘使用不均,从而产生访问热点、资源利用率低等问题。

数据分布算法决定了磁盘均衡的最终效果,一个良好的分布策略,往往需要完成数据分布均匀的基本目标,同时在此基础上兼顾节点异构和故障域隔离。

  • 节点异构 —— 存储节点间的容量或性能差异
  • 故障域隔离 —— 例如不同数据中心、机房、机柜、交换机、机器等,均可以组成一个故障域,尽量使主备磁盘落在不同的故障域中
常见的分布算法,可根据是否单独存储元数据分成两大类,对于不单独存储元数据的类别而言,常见的分布算法有以下几种。

01 哈希分布

最直接的哈希算法,通过数据中某个特征值,利用哈希函数进行计算,从而建立起数据与节点间的映射关系。

通过一个散布良好的哈希函数,可以将数据均匀地分布到各个节点中去,保证数据均衡,并且只要根据数据的特征值,即可直接快速地计算出数据所在的节点。这个方法的具体效果取决于哈希函数本身的优劣,并且设备的添加或删除,会导致原来的映射关系失效,需要将所有的映射关系进行重新计算,并且根据新的关系来移动数据。

哈希分布

02 一致性哈希分布

为了解决上述哈希分布在节点增加或删除时导致的大量数据迁移的问题,我们在哈希分布的基础上引入了一致性哈希算法。一致性哈希算法的核心数据结构是哈希环,哈希值分布在这个哈希环上,首尾相接,通常范围是[0 ~ 2^32-1]。我们将数据根据特征值通过哈希计算得到其在哈希环上的对应位置如下:

数据映射至哈希环

再将服务器根据特征值(例如IP或主机名)通过 hash 函数映射到哈希环上,数据将会落在哈希环上顺时针的邻近节点。

数据落盘

这样的设计很大程度上解决了在节点移除或增加时的数据迁移量,只会对相邻节点的数据进行迁移。

Node3 移除时的数据迁移

03 带有虚拟节点的一致性哈希

一致性哈希解决了普通哈希算法中大量数据迁移的问题,但也引入新的问题,就是数据盘的使用不均,而这实际上是数据分布的基本目标。

我们可以假设,哈希算法使数据落在哈希环上每一个位置的概率都是均等的,但是数据节点的数量却远小于哈希环的点数量,此时极有可能每个节点所覆盖的哈希环范围是不均匀的,那么这就会导致某些节点被集中落盘;此外,如果在新加入节点后,其距离已有节点的距离较近,且处于靠后位置,那么新加入的节点不但对于集群带宽没有提升,反倒降低了集群的磁盘利用率。

为了解决以上这些问题,我们在哈希环中引入了虚拟节点,以节点的磁盘大小和性能为权重,将虚拟节点分配到每个物理节点上,即每个物理节点对应一组虚拟节点,并由此决定数据落盘的实际位置。

带虚拟节点的一致性哈希

以上是不单独存储元数据时,我们常见的数据分布算法,对于分布式文件系统而言,我们往往将元数据与数据分开存放,元数据中保存了关于数据落盘的相关信息。在这种场景下,常见的落盘算法分别是 Round-Robin Available Space

  • Round-Robin —— 轮巡选择可用磁盘
  • Available Space —— 基于可用空间进行优先选盘

显然,在长期运行的集群中,轮巡算法会导致数据分布不均,而基于可用空间的优先选盘策略,则会导致例如节点扩容的场景中,数据集中涌入相同磁盘的问题,这在一定时间内会成为集群的性能瓶颈。

04 YRCloudFile 的数据分布策略

从上述内容可见,无论是基于哈希表的数据分布算法还是基于可用空间的落盘算法,都有各自的局限性。在 YRCloudFile 整体架构上,从高可用和高性能的角度出发,取百家之长,做出了一系列的设计来保证磁盘的使用均衡和数据安全。

  • 集群部署:在集群部署时,副本模式下,对于磁盘主备分组时,可以考虑从不同故障域中选择节点上的磁盘进行成组。

  • 容量水线:YRCloudFile 算法根据百分比可用容量(可根据配置动态调整)结合实际可用容量对磁盘进行分组,将磁盘划分为 L0-L3 共四个组别,选盘优先级依次降低,并且设定了保护水线,不再分配达到保护位的磁盘。

  • 数据切片:YRCloudFile 将文件根据数据切片数量来选择落盘,在默认未设置落盘偏好的情况下,利用 straw 算法,从高优先级的上述水线组中根据磁盘可用容量,磁盘负载等计算权重来选择落盘。当高优先级的组中磁盘数量不足以分配时,再向低级组中去补足。同时,支持用户自定义落盘偏好,以满足特殊的用盘需求。
  • 在线数据均衡:在极端的情况下,如果仍有磁盘数据不均的问题时,YRCloudFile 还有最后一个修补措施,那就是“在线数据均衡”功能,YRCloudFile 支持通过触发数据迁移,在保证集群在线正常服务的前提下,手动均衡磁盘数据,并且可以根据集群负载情况,决定数据迁移的工作负载,避免影响正常业务的进行。
通过上述的设计,YRCloudFile 尽最大可能地保证了数据的分布均衡,同时兼顾了节点异构和故障域隔离,在保证高可用高性能的同时,让集群的空间得到最大程度的利用。

05 关于 YRCloudFile 未来设计的展望

未来 YRCloudFile 还将针对无限追加写导致空间不均的场景进行优化,我们根据文件大小来决定切片的数量,例如针对小于 1G 的文件,采用 4 分片,1~10G 采用 8 分片,10~100G 采用 16 分片,100G~1T 采用 32 分片,直至单个文件占满整个集群。

此外,未来我们的存储还会根据介质,引入池化的机制,使得同一套集群既有能力对接大容量命名空间,也可以支持高性能命名空间。

有关分布式系统的磁盘均衡策略的更多相关文章

  1. ruby - 分布式事务和队列,ruby,erlang,scala - 2

    我有一个涉及多台机器、消息队列和事务的问题。因此,例如用户点击网页,点击将消息发送到另一台机器,该机器将付款添加到用户的帐户。每秒可能有数千次点击。事务的所有方面都应该是容错的。我以前从未遇到过这样的事情,但一些阅读表明这是一个众所周知的问题。所以我的问题。我假设安全的方法是使用两阶段提交,但协议(protocol)是阻塞的,所以我不会获得所需的性能,我是否正确?我通常写Ruby,但似乎Redis之类的数据库和Rescue、RabbitMQ等消息队列系统对我的帮助不大——即使我实现某种两阶段提交,如果Redis崩溃,数据也会丢失,因为它本质上只是内存。所有这些让我开始关注erlang和

  2. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  3. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  4. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  5. ruby - 在没有基准或时间的情况下用 Ruby 测量用户时间或系统时间 - 2

    因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实

  6. ruby - 以毫秒为单位获取当前系统时间 - 2

    在Ruby中,以毫秒为单位获取自纪元(1970)以来的当前系统时间的正确方法是什么?我试过了Time.now.to_i,好像不是我想要的结果。我需要结果显示毫秒并且使用long类型,而不是float或double。 最佳答案 (Time.now.to_f*1000).to_iTime.now.to_f显示包含十进制数字的时间。要获得毫秒数,只需将时间乘以1000。 关于ruby-以毫秒为单位获取当前系统时间,我们在StackOverflow上找到一个类似的问题:

  7. ruby-on-rails - 如何构建复杂的 Rails 系统 - 2

    关闭。这个问题需要更多focused.它目前不接受答案。想改进这个问题吗?更新问题,使其只关注一个问题editingthispost.关闭8年前。Improvethisquestion我们有以下(以及更多)系统,我们将数据从一个应用推送/拉取到另一个:托管CRM(InsideSales.com)Asterisk电话系统(内部)横幅广告系统(openx,我们托管)潜在客户生成系统(自行开发)电子商务商店(spree,我们托管)工作板(本土)一些工作网站抓取+入站工作提要电子邮件传送系统(如Mailchimp,自主开发)事件管理系统(如eventbrite,自主开发)仪表板系统(大量图表和

  8. ruby-on-rails - Rails 3,在RAILS_ROOT上方显示来自本地文件系统的jpg图片 - 2

    我正在尝试找出一种方法来显示来自不在RAILS_ROOT下(在RedHat或Ubuntu环境中)的已安装文件系统的图像。我不想使用符号链接(symboliclink),因为这个应用程序实际上是通过Tomcat部署的,而当我关闭Tomcat时,Tomcat会尝试跟随符号链接(symboliclink)并删除挂载中的所有图像。由于这些文件的数量和大小,将图像放在public/images下也不是一种选择。我查看了send_file,但它只会显示一张图片。我需要在一个格式良好的页面中显示6个请求的图像。由于膨胀,我宁愿不使用Base64编码,但我不知道如何将图像数据与呈现的页面一起传递下去。

  9. ruby - 我可以从 Ruby 中的系统调用中获得连续输出吗? - 2

    当您在Ruby脚本中使用系统调用时,您可以像这样获得该命令的输出:output=`ls`putsoutput这就是thisquestion是关于。但是有没有办法显示系统调用的连续输出?例如,如果您运行此安全复制命令,以通过SSH从服务器获取文件:scpuser@someserver:remoteFile/some/local/folder/...它显示随着下载进度的连续输出。但是这个:output=`scpuser@someserver:remoteFile/some/local/folder/`putsoutput...不捕获该输出。如何从我的Ruby脚本中显示正在进行的下载进度?

  10. ruby-on-rails - 覆盖 Controller 中的 protect_from_forgery 策略 - 2

    我想使用两种不同的protect_from_forgery策略构建一个Rails应用程序:一种用于Web应用程序,一种用于API。在我的应用程序Controller中,我有这行代码:protect_from_forgerywith::exception为了防止CSRF攻击,它工作得很好。在我的API命名空间中,我创建了一个继承self的应用程序Controller的api_controller,它是API命名空间中所有其他Controller的父类,我将上面的代码更改为:protect_from_forgery:null_session.遗憾的是,我在尝试发出POST请求时遇到错误:“

随机推荐