分布式存储的一些概念
一致性哈希
哈希是调度和负载均衡的常用策略,对于目标资源O,通过hash(O) = O mod n找到资源所在。一个问题是:当增加或删除一台cache server时(n发生了变化),所有资源对应的hash值发生改变,致使策略失效,cache servers需要全部更新。
一致性哈希是一种特殊的哈希算法,可以避免上述情况发生,当n发生变化时,一致性哈希保证平均K/n个关键字重新映射(k为资源总数,n为机器数),而不是所有映射都变化,减少系统动荡。
实现:
哈希算法确保节点数变化时将原先的key映射到新节点上,每个节点对应一个或多个hash值区间。转载几张图,来解释一致性哈希的实现。
1.一个节点对应1个区间(实现中,可以一台物理机上保存多个节点),key=>hash value=>district=>node
2.新增节点:新节点截断原有区间,cache3-cache5之间的对象映射到cache5。
3.删除节点:旧节点值映射到下一节点,cache2-cache3区间合并到cache4上。
算法要求:冗余少(分散性低),负载均衡,过渡平滑,key单调
CAP定理
分布式系统中,数据或者服务都面临着如下的问题:
- 一致性(Consistency):所有节点在同一时间具有相同的数据
- 可用性(Availability):保证每个请求不管成功或者失败都有响应
- 分隔容忍(Partition tolerance):系统中任意信息的丢失或失败不会影响系统的继续运作,也就是可扩展性
一致性分为:
- 强一致性:任何时刻,所有节点上的数据都是最近一次更新后的版本。
- 最终一致性:一个数据更新成功后,各副本会逐步更新,最终达到完全一致。
- 会话一致性:用户在一次会话内读到数据的一个版本后,在这次会话过程中将不会读到更旧的值。
- 单调一致性:任何时刻,用户读到数据的一版本后,此后再也不会读到更旧的值。
- 弱一致性:一个数据更新后,不保证其他副本上能读到更新值。
Paxos 算法
Paxos用于让整个集群的节点对某个值的变更达成一致。Paxos算法基本上来说是个民主选举的算法——大多数的决定会成个整个集群的统一决定。任何一个点都可以提出要修改某个数据的提案,是否通过这个提案取决于这个集群中是否有超过半数的结点同意(所以Paxos算法需要集群中的节点是单数)。介绍如下:
第一阶段:Prepare阶段
A把申请修改的请求Prepare Request发给所有的结点A,B,C。注意,Paxos算法会有一个Sequence Number(你可以认为是一个提案号,这个数不断递增,而且是唯一的,也就是说A和B不可能有相同的提案号),这个提案号会和修改请求一同发出,任何结点在“Prepare阶段”时都会拒绝其值小于当前提案号的请求。所以,结点A在向所有节点申请修改请求的时候,需要带一个提案号,越新的提案,这个提案号就越是是最大的。
如果接收节点收到的提案号n大于其它节点发过来的提案号,这个节点会回应Yes(本结点上最新的被批准提案号),并保证不接收其它<n的提案。这样一来,结点上在Prepare阶段里总是会对最新的提案做承诺。
优化:在上述 prepare 过程中,如果任何一个结点发现存在一个更高编号的提案,则需要通知 提案人,提醒其中断这次提案。
第二阶段:Accept阶段
如果提案者A收到了超过半数的节点返回的Yes,然后他就会向所有的节点发布Accept Request(同样,需要带上提案号n),如果没有超过半数的话,那就返回失败。
当节点们收到了Accept Request后,如果对于接收的节点来说,n是最大的了,那么,它就会修改这个值,如果发现自己有一个更大的提案号,那么,节点就会拒绝修改。
A把申请修改的请求Prepare Request发给所有的结点A,B,C。注意,Paxos算法会有一个Sequence Number(你可以认为是一个提案号,这个数不断递增,而且是唯一的,也就是说A和B不可能有相同的提案号),这个提案号会和修改请求一同发出,任何结点在“Prepare阶段”时都会拒绝其值小于当前提案号的请求。所以,结点A在向所有节点申请修改请求的时候,需要带一个提案号,越新的提案,这个提案号就越是是最大的。
如果接收节点收到的提案号n大于其它节点发过来的提案号,这个节点会回应Yes(本结点上最新的被批准提案号),并保证不接收其它<n的提案。这样一来,结点上在Prepare阶段里总是会对最新的提案做承诺。
优化:在上述 prepare 过程中,如果任何一个结点发现存在一个更高编号的提案,则需要通知 提案人,提醒其中断这次提案。
第二阶段:Accept阶段
如果提案者A收到了超过半数的节点返回的Yes,然后他就会向所有的节点发布Accept Request(同样,需要带上提案号n),如果没有超过半数的话,那就返回失败。
当节点们收到了Accept Request后,如果对于接收的节点来说,n是最大的了,那么,它就会修改这个值,如果发现自己有一个更大的提案号,那么,节点就会拒绝修改。
NWR模型
Amazon Dynamo提出了NWR模型确保数据永远可写,数据冲突留给用户来解决(提供数据版本)。NWR主要保证系统的可用性和可扩展性(C和P)。
N代表N个备份,W代表要写入至少W份才认为成功,R表示至少读取R个备份,R+W>N确保用户至少读取到一个最新的版本。当需要高可写的环境,配置(W=1 ,R=N), 这时只要写任何节点成功就认为成功,但读的时候必须从所有的节点都读出数据。如果要求读的高效率,配置 (W=N,R=1),这个时候任何一个节点读成功就认为成功,但是写的时候必须写所有三个节点成功才认为成功。
Dynamo引进了数据版本和Vector Clock,每个节点各自记录自己的版本信息,对于同一个数据,需要记录下更新人和版本号。节点自己拒绝版本号小的更新,节点间数据的冲突留给用户处理。