【分布式】数据冗余

当我们拥有了许多的存储服务器,且通过将数据在网关进行一致性哈希或者哈希桶的分发之后,我们拥有了一个具有基本负载均衡的系统,但是,此时我们又有新的问题产生了:我们所有的数据只有一份,如果这一份数据丢失了,将造成不可逆的后果,因此,我们要考虑将数据冗余。

1. 多副本模式

3副本模式的时候,任何一个交换机下的节点宕机,都不会影响读写操作 。

1.1 基于强一致协议的多副本

学习完raft之后,我们发现,使用强一致性协议可以完美实现三副本模式,本质上就是结点之间同步日志的过程,一致性的展现行为就是数据冗余。

这里不再啰嗦,我们只需要使用raft实现一个具有1主2从的集群即可。这也是我们Dsjourney提供的存储系统中使用的冗余实现原理。

但是,数据冗余并不是直接等价于“一致性协议”的,很多初学者在入门分布式的时候会误解这一点(包括笔者)。使用强一致协议固然实现简单,但是考虑到强一致性的低性能问题,大多数时候,我们不会在实际生产环境选择强一致协议,可能退而且其次选择其他的一致性模型,这一种变化会导致我们的冗余策略发生变化。

这里我们介绍两种比较有名的数据冗余解决方案:

1.2 ceph (了解)

ceph中的事件分发是通过CRUSH算法去做的,也就是通过从master集群中获取的inode我们可以计算出一个pgid,通过pgid可以得到一组OSD的信息,此时就可以通过map得到它们的真实存储信息了。

OSD列表的第一个结点为Primary,剩下的都是Replica。客户端完成所有的写到主OSD上的对象PG中(主host),这些对象和PG被分配新的版本号,然后写到副本OSD上,当每个复制都完成并响应给主节点,主节点完成更新,客户端写完成。这里是一个两阶段的提交,当副本都写到内存中时回复Ack,主节点收到全部的Ack就可以回复,当副本都提交到磁盘时还会回复Commit,主节点收到全部的Commit时还会给Client一个回复,这样大大减小了客户端的响应速度

客户端读就直接在主节点读,这个方法节省了客户端的副本之间的复杂同步和序列化。这种方法可见的W配置的就是全部结点,意味着错误恢复的时候都可可靠的保持副本一致性。当然倘若某个Replica出现故障,操作就会失败了,因为没办法收到所有的回复

此时(超时以后)就可以重新计算OSD,进而重新复制,在OSD恢复时会加入原来的伙伴关系中,同时也会基于PG最近的变化日志去同步日志,这样就保证了一致性

在这里插入图片描述


1.3 GFS(了解)

GFS的数据冗余来源于两个方面,一个是Master结点的状态副本,一个ChunkServer的数据副本。这其中又涉及到一个问题,即选主,前者通过Chubby进行可靠的选主(获取一把锁),后者通过Master发放的leases确定主节点,我们看到,两种方法都没有使用一致性协议,但都可以唯一的指定主节点

其实对于master的冗余paper中对于实现并没有太多的描述,但是提到了Master服务器所有的操作日志和checkpoint文件都被复制到多台机器上。且对Master服务器状态的修改操作能够提交成功的前提是,操作日志写入到Master服务器的备节点和本机的磁盘。这样的话当主服务器宕机时一旦通过Chubby选主成功,那么这些数据非常全的副本就可以很快的切换到正常的运行状态,因为其拥有原主节点的全部数据,且已经入盘。

初次之外,GFS中还有一种服务器称为影子服务器,这些影子服务器在“主”Master服务器宕机的时候提供文件系统的只读访问。它们是影子,而不是镜像,所以它们的数据可能比“主”Master服务器更新要慢,通常是不到1秒。这样的操作使得就算是“主”master下线也不会使得服务整体下线,因为影子还可以提供原数据的读取。对于那些不经常改变的文件、或者那些允许获取的数据有少量过期的应用程序,影子服务器能够提高读取的效率,且提升整个系统的可用性

为什么一般影子的数据会慢一些呢?因为Chunk的信息是由影子自己与Chunk通信维护的,但是副本的创建和修改只能由master来完成,如果修改是选择先通知影子,收到回复后再更新可能会导致影子的数据新于master,这是不可忍受的,所以GFS中影子选择读取一份当前正在进行的操作的日志副本,并且依照和主Master服务器完全相同的顺序来更改内部的数据结构,一次保证一致性,不过当然会有一个同步的时间,导致数据稍微旧一点

然后我们说说ChunkServer的数据冗余,以下是更新流程:

在这里插入图片描述
GFS使用租约机制来保持多个副本间变更顺序的一致性。Master节点为Chunk的一个副本建立一个租约,这个副本叫做主Chunk。主Chunk对Chunk的所有更改操作进行序列化,所有的副本都遵从这个序列进行修改操作。

可以在paper的3.1节中看出数据的拷贝是一个强一致性的过程,因为任何副本产生的任何错误都会返回给客户机,首先数据肯定在主chunk执行成功了,不然不会产生一个操作顺序,所以倘若有任何一个Replica执行操作序列失败都会把这个消息传递给主chunk,此时客户请求被认为是失败的,且此时这些数据处于不一致的状态,客户端通过重复执行失败的操作来处理这样的错误。

至于为什么使用租约保证多个副本之间的一致性而使用租约,paper中给出的解释是这样的:设计租约机制的目的是为了最小化Master节点的管理负担。这个其实并不太好理解,我的想法是这样的,应该说是为了更为高效的管理chunk。因为在GFS眼中Chunk的管理是一个动态的过程,master对于chunk的管理包括但不局限于如下几点

  1. master检查当前的副本分布情况,然后移动副本以便更好的利用硬盘空间、更有效的进行负载均衡
  2. 对于新Chunk的选择选择和创建时类似:平衡硬盘使用率、限制同一台Chunk服务器上的正在进行的克隆操作的数量、在机架间分布副本
  3. 当Chunk的有效副本数量少于用户指定的复制因数的时候,Master节点会重新复制它

2. 纠删码

2.1 纠删码简介

与多副本将数据完整复制多份进行分布式存储不同,纠删码将一份数据拆分进行分布式存储,这是如何为做到的呢?

删码的英文全称是Erasure Code,所以有时我们也会简称为EC。它可以将 n 份原始数据,增加 m 份数据,并能通过 n+m 份中的任意 n 份数据,还原为原始数据。即如果有任意小于等于 m 份的数据失效,仍然能通过剩下的数据还原出来,在Hadoop3.X中已经支持了该功能

当然以上计算只是一个简化的方案,目的是帮助大家理解,真正存储中用的校验方式会比这个复杂得多,但效果是类似的。

2.2 纠删码原理

纠删码的原理很简单,主要使用线性代数的方法,假设有四块:D1,D2,D3,D4,校验数据两块P1,P2.组成下面方程组:

(1)X1=D1

(2)X2=D2

(3)X3=D3

(4)X4=D4

(5)X1+X2+X3+X4=P1

(6)X1+2X2+4X3+8*X4=P2

根据上面的6个方程任意两个缺失都可以根据其他四个将丢失的两个计算出来。这就是纠删码的基本原理,当然在实现的时候不是直接使用方程组,实际应用是使用矩阵

方程(1),(2),(3),(4)正好对应单位矩阵:
在这里插入图片描述
除此之外还有两个校验数据需要构造,一般使用范德蒙矩阵(使用柯西矩阵要快一些),为什么使用范德蒙矩阵是因为涉及到逆矩阵,只有当逆矩阵存在的前提下才可以恢复丢失的数据,而范德蒙矩阵恰好满足这个条件。我们的得到完整的编码矩阵

在这里插入图片描述

  • 编码

编码就是根据编码矩阵,计算出校验数据,将校验数据和原始数据一起保存。

还是以上面为例,根据编码矩阵可以求得P1和P2
在这里插入图片描述
应该注意的编码之后是原始数据块和校验数据块大小相同,因此这里的矩阵乘法是在伽罗华有限域(GF)内进行。简单来说,校验数据就是让P和所有或者部分原始数据都发生关系,这样在有数据块损坏时可以根据方程求解出损坏部分的数据

  • 解码

假设有一个数据数据损坏,我们希望能用其他数据将损坏的部分恢复出来。最大允许损坏校验数据P个数这么多数据。

假设D4数据损坏:

  1. 求解解码矩阵,在原编码矩阵中去掉对应损坏的数据那行,从上到下取n=4行,组成一个新矩阵这个矩阵就是解码矩阵:
    在这里插入图片描述

  2. 解码矩阵乘原始数据正好得到剩余完好的数据:
    在这里插入图片描述

  3. 根据A*A-1=E,两边同乘解码矩阵的逆矩阵

在这里插入图片描述

  1. 只要求出解码矩阵的逆矩阵即可求得损坏的数据D4

    求解逆矩阵首先要判断是否存在逆矩阵,判断逆矩阵是否存在的常用的两种方法:

    1. 原矩阵的行列式的值是不等于0,这是由逆矩阵定义可知
    2. 原矩阵的秩等于矩阵阶数。


3. 多副本与纠删码的比较

在这里插入图片描述

在可用容量上,纠删码的优势是较大的,比如4+2纠删码的利用率是66%,但3副本只有33%,两者差了2倍,8+2纠删码更可以做到80%,这是多副本远远无法相比的

在读写性能上,多副本往往会更高,因为纠删码在写入时涉及数据校验,而且可能会产生写惩罚,在读取时更会横跨多个节点。比如4+2纠删码在读取1个数据时,需要从4个节点分别读取4个分片再进行拼接,任何1个节点时延过高,都会对性能造成很大影响。而多副本只需要读取1个完整的分片即可,不涉及节点的数据拼接。这两者的性能差异在小块IO时会较为明显,但如果IO块比较大的话,比如1MB,那么两者的性能差距就会逐渐缩小,因为这时候写惩罚较少,纠删码也能很好发挥多个节点并发的优势,这一局多副本略胜一筹

在重构性能上,多副本也会有明显优势,因为不涉及数据校验,只是单纯的数据拷贝,所以速度比较快。而纠删码的重构涉及反向校验的计算过程,所需要的读写数据量和CPU计算消耗都会更大,这一局多副本同样略胜一筹

在可靠性上,多副本和纠删码的故障冗余程度往往差别不大,比如3副本和4+2纠删码都可以允许任意2个节点故障而数据不丢失。但我们也需要注意两点,一是多副本的重构性能往往比纠删码更快,所以硬盘故障恢复也更快,会带来一些可靠性上的优势。二是纠删码可以采用+3、+4的策略来容忍更多节点故障,而且空间利用率并不会太低,但如果多副本采用4副本、5副本的话代价就太大了,所以这一点上纠删码有优势

综合来看,如果用户更关注性能,尤其是小IO的场景,多副本往往是更好的选择,如果用户更关注可用容量,而且是大文件场景的话,纠删码会更合适

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
分布式数据存储是指将数据存储在多个物理节点上,以实现高可靠性、高扩展性和高性能的数据存储系统。分布式数据存储系统的设计需要考虑以下几个方面的理论分析: 1. 数据分布策略:数据分布策略指的是将数据如何分散到不同节点上的规则。常见的分布策略有哈希分布、范围分布和副本分布等。哈希分布根据数据的哈希值进行分布,范围分布根据数据的键值范围进行分布,副本分布则是在多个节点上保存相同的数据副本以提高可靠性。 2. 一致性协议:由于数据存储在多个节点上,需要一致性协议来保证数据的一致性。常见的一致性协议有Paxos、Raft和ZAB等。这些协议通过选主、投票和日志复制等机制来保证数据的一致性。 3. 数据可用性:数据可用性指的是在节点故障或网络分区等情况下,系统仍能够提供可靠的数据访问。为了提高系统的可用性,可以采用数据冗余、负载均衡、故障转移等技术。 4. 数据安全性:分布式数据存储系统中的数据可能面临各种安全威胁,如数据泄露、篡改和丢失等。因此,需要采取数据加密、访问控制、备份和灾难恢复等措施来保障数据的安全性。 5. 性能优化:分布式数据存储系统的性能对于应用程序和用户体验至关重要。为了提高系统的性能,可以采用数据缓存、预取、分片和异步复制等技术。 6. 系统监控和管理:分布式数据存储系统需要实时监控和管理,以便快速发现和解决各种问题。为了实现系统的监控和管理,可以采用日志记录、实时监控、告警和自动化管理等技术。 总体来说,分布式数据存储系统的设计需要综合考虑以上几个方面的理论分析,以实现高可靠性、高扩展性和高性能的数据存储系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ornamrr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值