CockroachDB架构——复制层

CockroachDB架构的复制层在节点间拷贝数据并通过我们的共识算法确保这些拷贝间的一致性。
--注意:
1)如果您还没准备好,我们建议阅读架构概览部分。
一.概览
高可用性要求数据库能容忍节点下线而不会中断应用服务。这意味着节点间的复制确保数据保持可访问。
确保离线节点的一致性是一个挑战,很多数据库都失败了。为了解决这个问题,CockroachDB用了共识算法要求某个范围的更新在提交前副本的法定人数必须一致同意这些更新。因为3(即,3个中的2个)是能获得法定人数的最小数,所以,CockroachDB的高可用性(称为多活可用性)要求3个节点。
能容忍的失败数等于(Replication factor - 1)/2。例如:用3x复制,可以容忍一个失败;用5x复制,可以容忍两个失败等等。您可以在集群、数据库和表级别用复制域控制复制因子(replication factor)。
虽然失败发生,CockroachDB自动识别节点停止应答并对数据进行重新分布以继续最大化生存性。该过程还可以反过来进行:当新节点加入集群时,数据自动重新平衡到该节点,以确保负载被均匀分布。
1.与其他层的交互
CockroachDB中,复制层与其他层的关系如下:
1)从复制层接收请求并向其反馈信息。
2)将接受的请求写到存储层。

二.组件
1.Raft
Raft是一个共识协议——一个确保数据被安全存储到多个机器上的算法,即使其中的一些机器临时断开了,那些机器也都同意当前的状态。
Raft将包含某个范围副本的所有节点组织成一个组——不出所料地称为Raft组。Raft组中的每个副本是"领导者(leader)"或"追随者(follower)"。
由Raft选举并长期存活的领导者,协调对该Raft组的所有写。其周期性对追随者进行心跳操作并保持它们的复制日志。没有心跳的情况下,追随者在随机选举超时后称为候选人,并继续进行新领导者选举。
一旦某个接到一个其包含的某个范围的BatchRequests,其将那些KV操作转换为Raft命令。这些命令被提交给Raft组领导者并将其写入Raft日志——这是使租约持有者和Raft领导者合二为一的理想条件。
为了更好地了解Raft,我们推荐《数据的秘密生活》。
2.Raft日志
当写收到一个法定人数,并被Raft组领导者提交时,它们被附加到Raft日志。这提供一套副本集都同意的有序命令,这实际上是一致性复制的真实来源。
因为该日志被串行化处理,其能被重演以便将某个节点从过去状态带到当前状态。该日志也让临时下线的节点"获取"当前状态,而无需以快照形式接收现有数据的拷贝。
3.快照
每个副本能"获取快照",其拷贝特定时间戳(因为MVCC而可用)的所有数据。重平衡事件中,该快照能被送到其他节点来加快复制。
加载快照后,节点通过重演来自获取快照后发生的Raft组日志的所有活动来获取最新信息。
4.租约(Leases)
Raft组内的单个节点充当租约持有者,其是为Raft组领导者提供读写服务的唯一节点(这些活动能从DiskSender作为BatchRequests接收)。
当提供读服务时,租约持有者绕过Raft;对已经在第一位置提交的租约持有者的写,其必须已获得共识,因此,同样数据无需第二个共识。这因避免了Raft需要的网络往返而获益,且大大增加了读的速度(不牺牲一致性)。
CockroachDB试图选举一个同时也是Raft组领导者的租约持有者,这将会优化写性能。
如果没有租约持有者,接收请求的任何节点试图变为该范围的租约持有者。为了阻止两个节点获得租约,请求者包括一个其拥有的最近有效租约的拷贝;如果另一个节点变为租约持有者,其请求被忽略。
1)与Raft领导层的协同定位
范围租约与Raft领导层是完全分离的,因此,没有进一步努力,Raft领导层和范围租约也许不会被同一副本持有。但是,我们能通过使Raft领导者和租约持有者为同一节点来优化查询性能;接收请求的租约持有者能仅将Raft命令提交给自己而非与其他节点通信,来减少网络往返。
为了实现这点,每个租约更新或转换也试图对它们进行配置。实际上,那意味着这种不匹配很罕见,并且能迅速自我修复。
2)基于时代(Epoch-based)的租约(表数据)
为了管理表数据租约,CockroachDB实施了一个"时代(epoches)"的概念,其被定义为某个节点加入集群和某个节点从集群断开间的期间。为了扩展其租约,每个节点必须定期更新其活动记录,该记录存储于系统范围键中。当节点断开时,其停止更新活动记录,并认为该时代已发生改变。这导致该节点立即丢失去所有的租约。
因为直到节点从集群断开租约才会过期,租约持有者不必单独续签其租约。将租约生命期与节点活动期捆绑的方式消除了大量的交通和Raft处理,以及每个范围租约的跟踪,否则,这将会发生。
3)基于过期的租约(元范围和系统范围)
一张表的元范围和系统范围(在分不曾详述)被当做常规键值数据处理,所以,租约正像表数据。
但是,不像表数据,系统范围不能使用基于时代的租约,因为那将创建循环依赖:系统范围已被用于实施表数据基于时代的租约。所以,系统范围用基于过期的租约。基于过期的租约在特定时间戳会过期(通常会在数秒后)。但是,只要节点继续提交Raft命令,其将继续扩展其租约的期限。否则,包含该范围某个副本的下一个节点试图读写该范围时将变为租约持有者。
4)租约持有者在平衡
因为CockroachDB从范围的租约持有者进行读,如果最接近主要流量地理来源的副本持有租约,将有利于集群的性能。但是,由于集群的流量在一天中不断变化,您可能希望动态地改变持有租约的节点。
--注意:
1)该特点我们文档中称为负载跟随(Follow-the-Workload)。
周期性地(默认巨大集群每十分钟,但小集群更频繁),每个租约持有者通过下列输入考虑是否应该将租约转让给另一个副本:
1)来自每个地点的请求数。
2)每个节点租约数。
3)地点间的延迟。

a)地点内(Intra-locality)
如果所有副本在同一地点,决定完全取决于包含副本的每个节点上的组约数,尽力在这些节点间保持大致相等的租约分布。这意味着分布并非完全相等;其有意在节点间容忍小的偏差以防止抖动(即,尽力达到均衡而进行的过度调整)。
b)地点间(Inter-locality)
如果副本在不同位置,CockroachDB试图计算哪个副本作为租约持有者最好,即,提供最低的延迟。
为了开启动态租约持有者再平衡,范围的当前租约持有者会跟踪其收到每个地点的请求数,作为一个指数权重移动平均线。该计算结果为最近已请求该范围最频繁、被分配权重最大的地点。如果另一个地点接着开始很频繁的请求该范围,该计算将转移分配该第二个区域最大的权重。
当检查租约持有者再平衡因素时,租约持有者将通过检查地点间的相似度,对每个请求地点的权重与每个分本的地点进行关联(即,最近请求的比例)。例如,如果租约持有者从地点country=us,region=central的网关节点收到了请求,CockroachDB将下列权重分配给下联地点的副本:
副本地点                    副本再平衡权重
country=us,region=central    100%因为其是精确匹配
country=us,region=east        50% 因为仅第一个地点匹配
country=aus,region=central    0%因为第一个地点不匹配
租约持有者接着评估其自己相对其他副本的权重和延迟,以决定一个调整因子。权重间的差别越大,地点间的延迟越大,CockroachDB更喜欢权重大很多的地点的节点。
检查租约持有者重平衡因素时,当前的租约持有者评估最大权重地点每个副本的重平衡权重和调整因子。如果移动租约持有者是有益和可行,当前租约持有者将把租约转给最好的副本。
c)控制租约持有者重平衡
您能通过kv.allocator.load_based_lease_rebalancing.enabled和kv.allocator.lease_rebalancing_aggressiveness集群设置控制租约持有者再平衡。取决于您的部署需求,通过配置复制区域,您可以对租约和副本的位置进行其他控制。
5.成员改变:再平衡/修复
无论何时集群节点数发生变化,Raft组成员改变,为了确保最优生存性和性能,需要对副本进行再平衡。具体情况随成员改变是增加节点或节点下线而变化。
1)增加节点:新节点将有关自己的信息通知其他节点,并指示其有可用空间。集群接着会将一些副本再平衡到新节点上。
2)节点下线:如果一个Raft组成员停止回应,五分钟后,集群通过复制下线节点持有的数据到其他节点来开始再平衡。
通过使用来自租约持有者的副本的快照实现再平衡,接着通过gRPC将数据发送到另一个节点。传输完成后,存储新副本的节点加入该范围的Raft组;接着,其将探测到其最近时间戳落后于Raft日志中最近项目,并重演其Raft日志中的所有活动。
1)基于负载的副本再平衡
除了节点加入或离开时发生的再平衡,副本还会基于集群中节点上相对负载进行自动在平衡。更多信息,请参考kv.allocator.load_based_rebalancing和kv.allocator.qps_rebalance_threshold集群设置。
取决于您的部署需求,您能通过配置复制区域对租约和副本的位置进行另外的控制。 

三.与其他层的交互
1.复制和分布层
复制层从它和其他节点的DistSender接收请求。如果该节点为范围的租约持有者,其接收该请求;否则,其返回一个指向它认为是租约持有者节点指针的错误。这些KV请求接着被转换成Raft命令。
复制层将BatchResponses送回到分布层的DistSender。
2.复制层和存储层
提交的Raft命令被写入Raft日志并最终通过存储层存储到磁盘上。
租约持有者通过RocksDB实例提供读服务,其位于存储层。

四.个人观点
1)复制层完成数据的复制和平衡;
2)复制层在所有NewSQL数据库中都是基础和关键的逻辑层,遵从的原理和实现机制也是大同小异,这里不再多说。

CockroachDB (蟑螂数据库)是一个可伸缩的、支持地理位置处理、支持事务处理的数据存储系统,和谷歌的F1系统类似,支持分布式事务等特性。。CockroachDB 提供两种不同的的事务特性,包括快照隔离(snapshot isolation,简称SI)和顺序的快照隔离(SSI)语义,后者是默认的隔离级别。        为了保证在线的百万兆字节流量业务的质量,Google开发了Spanner系统,这是一个可扩展的,稳定的,支持事务的系统。许多参与开发CockroachDB的团队现在都服务于开源社区。就像真正的蟑螂(cockroach)一样,CockroachDB可以在没有数据头、任意节点失效的情况下正常运行。这个开源项目有很多富有经验的贡献者,创始人们通过社交媒体、Github、网络、会议和聚会结识他们并鼓励他们参与其中    蟑螂是一个分布式的K/V数据仓库,支持ACID事务,多版本值存储是其首要特性。主要的设计目标是全球一致性和可靠性,从蟑螂的命名上是就能看出这点。蟑螂数据库能处理磁盘、物理机器、机架甚至数据中心失效情况下最小延迟的服务中断;整个失效过程无需人工干预。蟑螂的节点是均衡的,其设计目标是同质部署(只有一个二进制包)且最小配置。    蟑螂数据库实现了单一的、巨大的有序映射,键和值都是字节串形式(不是unicode),支持线性扩展,理论上支持4EB的逻辑数据)。映射有一个或者多个Range组成,每一个Range对应一个把数据存储在RocksDB(LevelDB的一个变种,Facebook贡献)上的K/V数据库,并且复制到三个或者更多蟑螂服务器上,Range定义为有开始和结束键值的区间。Range可以合并及分裂来维持总大小在一个全局配置的最大最小范围之间。Range的大小默认是64M,目的是便于快速分裂和合并,在一个热点键值区间快速分配负载。Range的复制确定为分离的数据中心来达到可靠性(比如如下分组:{ US-East, US-West, Japan }, { Ireland, US-East, US-West}, { Ireland, US-East, US-West, Japan, Australia })    Range有一种变化,通过分布式一致性算法实例来调节确保一致性,蟑螂所选择使用Raft一致性算法。所有的一致性状态存在于RocksDB中。项目官网地址:http://www.cockroachdb.cn/ 标签:蟑螂数据库  国人开源
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lhdz_bj

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

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

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

打赏作者

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

抵扣说明:

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

余额充值