一, 背景
面对着业务的发展, 不管是在线, 近线还是离线系统, 其所需要的存储规模以及存储成本, 成倍上涨. 如果还是采取传统的分散式存储管理方式, 除了高昂的管理分散式存储的成本, 还会增加存储成本.
因此, 我们极需一种既高效又省成本的数据存储以及存储管理方式. 自然地, 我们把目光聚焦到了分布式存储系统上.
从目前行业发展趋势来看, 各大互联网公司都设计或者维护了自己的分布式存储系统. 如 Google 的 GFS(Colossus 为 GFS 第二代分布式存储系统),Facebook 和 LinkedIn 的 HDFS 等. 由此可见, 分布式存储也是大势所趋.
同样在阿里, 我们今年对数据库进行计算存储分离, 面临的难度也非常大. 因此, 我们也对各种分布式存储进行了许多研究, 开源的如 Ceph, 还有阿里云的盘古等.
我们紧跟业界以及开源社区, 并不断吸收其优秀成果; 同时也做了大量的研究, 测试和验证. 根据集团业务的特性, 我们进行了许多软件层面, 甚至软硬件结合的优化, 为集团业务的发展赋能.
分布式存储系统所具备的优点就是为了克服传统存储方式的缺点. 那么, 它将会给我们带来哪些收益呢?
二, 分布式存储的收益
分布式存储系统所带来的收益主要体现在以下几个方面. 总体上来讲, 主要是降低存储成本, 同时也提高了资源的分配效率, 助力计算资源的弹性调度.
2.1 解除机型配比
一般性的, 我们将服务器分为两部分, 计算资源和存储资源. 计算资源如 CPU 和内存, 计算资源的特点就是无状态, 资源分配比较灵活. 存储资源有状态, 需要保证数据的一致性和持久性, 资源分配比较固定, 会涉及到数据的迁移. 如果数据量太大, 就会遇到迁移性能的问题.
传统的存储方式, 是单台服务器类型的, 将计算资源与存储资源 (HHD 和 SSD 等存储设备) 绑定在一起. 因此一台机器 CPU, 内存与存储设备比值都是固定的. 这带来的一个问题, 就是我们会比较频繁的改变我们的机型, 因每年我们的计算资源与存储资源的配比都在变化, 业务数据的增长非常快. 这也在某种程度上提高了每年采购机器的成本.
引入分布式存储系统后, 解除了这两者紧密耦合的现状, 使得降低存储成本成为了可能. 计算资源和存储资源解耦后, 各自可以按不同的策略进行过保, 在一定程度上降低了成本.
2.2 解决存储碎片
传统分散式的存储模型, 必然会有存储碎片问题的存在. 因为每台服务器都会为线上业务预留一定的存储空间, 以满足将来业务数据增长的需要. 但是采用预留空间的方式会有一个问题, 就是我们无法准确地评估真实的实际空间需求, 往往预留的会比较多, 业务实际需求与预留空间这两者的差距就是存储空间浪费量.
这些服务器残留了独立的 10G,20G 的空间碎片, 在一定程度上也并不能满足业务实例申请的规格, 但将这些碎片合并在一起就能满足业务所需.
引入分布式存储系统后, 大大减少这种碎片, 业务实际的数据存储空间按需进行动态分配. 我们引入数据增长趋势分析, 每天或者每周进行存储在线动态扩容, 以提高管理效率, 降低存储成本.
2.3 计算资源弹性
传统资源配置下, 我们的计算资源调度水平受限于单台机器的存储容量. 在制定 Docker 容器化规格时, 连同存储容量一起考虑, 其调度和资源分配算法异常复杂. 当 CPU, 内存以及存储容量这三者在某种程度上发生冲突时, 往往会牺牲一定的存储资本, 来达成 Docker 实例规格的妥协.
将计算资源与存储资源分离后, 计算资源得到解脱. 我们在安排机器的过保时, 采用不同的策略, 降低机器采购成本.
另外, 计算资源是无状态的, 独立之后, 进行容器化, 就可以方便的进行调度, 提高效率. 更重要的是, 让离在线混布成为一种可能或者让其更高效.
2.4 解决差异化需求
某些新兴业务, 往往会呈现爆发式增长. 自然而然, 其数据量也会呈跳跃式的爆炸. 此时对存储的规格的需求就会比较大, 因为业务短时间内往往来不及做架构优化, 或者做数据分片来降低单机的数据存储容量. 这会给传统的存储模型带来很大的挑战, 因为传统的分散式的单台服务器的存储容量已经不能满足需求.
分布式存储系统破除了这种大存储容量实例规格的天花板限制, 业务不再关心底层存储的实现, 我们根据业务数据的增长趋势分析, 动态扩展存储空间.
三, 面临的问题
尽管分布式存储有上述的诸多优点, 然而如何设计其高可用性, 如何减少数据丢失的概率, 是摆在我们面前必须要去克服的问题. 那么我们又是如何来架构和设计的呢?
3.1 数据丢失
在分布式存储系统中, 为了防止单机故障而造成数据丢失, 往往会引入多个数据副本, 我们称之为 replica set. 此 replica set 中数据的副本个数用 R 来表示. 一般的, R 等于 3, 就表示是这份数据的存储份数是 "3", 也就是我们通常所说的 3-way replication.
在随机的模式下, 有可能 replica set 的 3 份数据位于同一个 rack 中, 那么当此 rack 掉电就会导致数据丢失, 对线上业务造成影响. 随着集群规模的变大, 如果有超过 1% 的数据节点遭遇断电, 并且断电之后又有一部分机器重起失败, 或者进程异常导致数据文件损坏; 那么其影响都将随着集群规模的增长而变得异常严重, 成为分布式存储系统致命的问题.
当然, 我们可能通过增加数据的副本数即 "replica set size", 来降低数据丢失的概率. 又或者提高底层 IDC 以及网络的高可用性, 减少断网或者网络故障发生的概率. 但是这些方法都是绕开问题的本质来优化的, 另外带来的存储成本的增长也是不能接受的.
早期, Facebook 和 LinkedIn 在使用 HDFS 时, 也同样面临这样的问题, 也做了这方面不少的验证和测试. 最终较为一个合理的方案就是通过合理安排 replica set 中数据存储的位置来降低数据丢失的可能性.
3.2 数据散射度
为了能够更好的理解数据副本存储位置 (data locality), 我们引入数据散射度(scatter width) 的概念. 怎么来理解数据散射度?
假设一个集群, 有 N 个节点, 数据副本 replica set size 为 R, 那么数据散射度最差的情况就是从 N 个节点中任意取 R 个的组合数, 也就是 C(N,R). 我们假定 N 为 "9",R 为 "3".
举个例子: 我们定义三个 copy set(存放的都是不同的数据):{1,2,3},{4,5,6},{7,8,9}. 任意一组 copy set 中存放的数据没有重复, 也就是说一份数据的三个副本分别放置在:{1,4,7}或者 {2,5,8} 或者{3,6,9}. 那么这个时候, 我们称之为其数据散射度 S 为 "3", 远小于随机组合的 C(9,3).
随机组合时, 任意 3 台机器 Down 机都会存在数据丢失. 而采用 Copy Set 方案后, 只有当 {1,4,7} 或者 {2,5,8} 或者 {3,6,9} 其中的任意一个组合不可用时, 才会影响高可用性, 才会有数据丢失.
综上可知, 我们引入 copy set 的目标就是尽量的降低数据散射度 "S".
但是现实远非这么简单, 当我们降低数据散射度后, 其数据恢复速度变小, 也就是说恢复时间变长. 因此, 我们必须在数据散射度 "S" 和恢复速度中找到一个平衡.
四, 高可用性设计
一般地, 业务统一用 N 个 "9" 来表示一个分布式系统的高可用性. 一般业界做得好的, 都已经能达到 9 个 "9". 那么, 我们的分布存储系统又如何来设计, 又能达到多个 "9" 呢?
4.1 OSD Domain
默认的 OSD 节点 bucket 是基于 Host 的, 也就是说取决于一台机器上存储设备的数量. 如下图所示, 一台 Host 上面有 4 个 OSD(device, 如 HDD 或 SSD 等). 所以在集群存储数据时, 会寻找数据存放位置.
首先会将 Primary 放入到 Host0 的四个节点中, 即{0,1,2,3}. 同一组中的 OSD 会根据权重进行平衡. 另外两个副本按同样的权重计算方法放到 Host1 和 Host2 中. 从总上来看, 就是三份数据分别放到 Host0,Host1 和 Host2 上面, 在每一个 Host 中数据均匀的分布在 4 个 OSD 节点上.
当 Host0 中的 OSD 0 节点 (存储设备) 挂掉, 会做两个事情:
会从 Host0 中剩余的 OSD 节点中, 找可替代节点, 将新增数据写到剩余的节点中
当 OSD 0 恢复时, 会将 Host0 其它 OSD 节点中刚才新增的数据 copy 回 OSD 0, 这个叫 recovery 的 backfill 过程
我们的目的, 就是减少 recovery 时 backfill 的时间. 所以如果一个 Host 下面的 OSD 节点越多, 就会有越多的节点参加 backfill, 恢复速度就会越快. 一般单台机器的存储设备挂载都是有限制的, 我们很快就会遇到瓶颈. 另外, 目前的 SSD 128K 的写入速度也在 400-500M/s 之间, 跟我们的目标相比, 并不算太高.
基于此, 我们计了 OSD domain, 它摆脱了单台机器的设备挂载量限制. 如下所示, 其中黄色虚线框中的 OSD 都在同一个 OSD domain 中. 一个 OSD domain 中包含 4 台机器, 每台机器有 4 个 OSD 节点(存储设备). 此时, 当一个 OSD 挂掉后, 会有 15 个 OSD 参加新增数据的平衡和 recovery 的 backfill, 大大缩短了恢复时间.
在这些 OSD Domain 中, 故障是隔离的, 所以一般也称 OSD Domain 为故障隔离域.
4.2 Replica Domain
在第三个章节中, 我们提到了数据散射度问题, 数据散射度越大, 可用性越差, 丢失数据的可能性越高. 因此, 我们怎么来解决这个问题呢?
这需要结合 copy set 的原理来做合理架构与设计, 再基于上面 OSD domain 的设计, 我们再新增 replica domain, 将三个不同 rack 中的 OSD domain 组成三个 copy set, 用于存放 replica set 的三个数据副本.
具体架构图如下, 这样部署后, copy set 做到了一个非常低的水平.
另外, 为了节省 IDC 机架位资源, 我们在一个集群下分为两个 replica domain, 每个 replica domain 下面又有 3 个 OSD domain:
4.3 泊松分布
到这里, 我们的副本存放拓扑结构设计差不多完成了, 那么接下来, 我们来计算下这种部署能做到多个 "9" 呢?
在分布式存储集群中, X 个磁盘发生故障的事件是独立的, 其概率是符合泊松分布的.
拿磁盘来讲, 其 MTTF 为 1million, 因此 AFR 为 "1-(24*365/1million)= 0.98832", 约为 "0.99". 泊松分布中, 两个重要的变量因还素 X 和 Mean 我们都确定了.
对于分布式存储池来讲, X 就是 replica set size "R",Mean 就是 "0.99".
我们存储集群的高可用性可以简单的按以下函数来量化: P = f(N, R, S, AFR), 其中:
P: 丢失所有副本的概率
R: 副本数, 也就是 replica set size
S: 单组 OSD Domain 中 OSD 的个数
N: 整个集群中 OSD 的总数
AFR: 磁盘的年平均故障率
进行演化后, 我们得到可用性公式: P = Pr * M / C(N,R), 其中:
Pr: 为 R 个数据副本同时失效的概率, 相当于是 Primary 在做 recovery 恢复时, 其它 R-1 个副本也 Fault 掉了.
M: 为可能的 Copy set 数目
R: 为 replicat set size, 即副本数
N: 为集群 OSD 总数
C(N,R): 为 N 个 OSD 节点中, 取 R 个副本的组合数
从上面的高可用性公式可以看出, 一般在给定集群 OSD 节点数和副本数 "R" 后, C(N,R)也就确定了. 那么, 为了提高可用性, 我们必须想办法降低 Pr 和 M 的值.
存储节点的拓扑结构, 基于以上分析, 做的最终架构优化:
为了降低 Pr, 我们引入了 OSD domain, 默认基于 Host 单机, 无法发挥网络 "多打一" 的优势, 我们引入 OSD domain, 提高单个 OSD 恢复的速度. 将原来三个 OSD 节点扩大到 16 个, 恢复速度提高了 5 倍以上.
为了降低 M, 也就是 copy set 的 size, 我们引入了 replica domain. 同一个 PG 中所有的 OSD 必须在同一个 replica domain 中, 降低了数据丢失的概率了, 提高了高可用性.
以下经我们架构设计后, 再根据泊松分布计算出来的高可用性:
根据这个架构设计, 在同一个 IDC 内, 我们基本上能做到接近于 10 个 "9" 的高可用性. 比之于默认的算法, 高可用性整整提高了将近 100 倍.
4.4 网络拓扑结构
根据上面的分布式拓扑结构设计, 再结合现有的网络拓扑结构, 我们的架构设计最终方案为:
一个存储集群 24 台机器, 两个 replica domain, 每个 replica domain 中有三个 OSD domain, 每个 OSD domain 中 4 台机器, 因此计算公式如下:
2(一般为两个, 由网络交换机下挂的机器数决定)* 3(replica set,replica domain) * 4(scatter width,OSD domain)= 24
原则性的, replica domain 的机器位于三个不同的 rack 时, 这三个 rack 不能在同一个 port 中. 一个交换设备下挂 16 台机器, 两个 OSD domain, 这两个 OSD domain 属于不同的 replica domain.
在实际生产中, 为了高可用性, 我们建议至少部署 4 个 rack 集群. 另外, 在集群扩容时, 建议按一组 replica domain 的规模来扩容.
每一组 OSD domain 中, 存储机器数目也可以是 4 台或者 8 台不等, 可以按单台的机器容量来进行动态规划, 但是计算公式可大致参考以上的部署策略.
五, 总结与展望
目前, 软硬件结合的分布式存储 IO stack 也在不断的优化 (SPDK,NVMe 等) 中, 网络基础架构 RDMA 的网络设计也在验证和 POC 中. 这些新的思路与整个业界的生态体系发展趋势一致.
在可预见的将来, 存储技术上将会有不断的融合与补益, 这也有利于存储技术的更新换代, 也更好的支撑业务的快速发展; 最终具备, 技术扩展业务边界以及业务向技术拿红利的能力.
计算存储分离更多细节, 将在以后的篇章中讲述.
来源: http://stor.51cto.com/art/201805/574482.htm