(5)数据复制

多台机器保存相同副本:使数据在地理位置上更接近用户,降低延迟,提高吞吐量、可用性。

概要:1主从(同/异步):配新从、处理失效节点、复制日志

           2复制滞后:读自己写、单调读、前缀一致读

           3多主:适用场景、处理写冲突(特定中心、唯一id/时间戳、应用层解决)

           4无主:读修复反熵、w+r>n、宽松Quorum、跨中心、5、检测并发写

一、主与从节点

全同步全异步:使用相对广泛,提高吞吐量,但会滞后,用于节点多,分布地域广场景

半同步:一个从节点同步,其他从异步,同步从节点性能下降或不可用,其他从升级为同步模式。ps:主节点 +  同步从节点有最新副本

1、配置新从节点

    1)某时间点对主节点副本产生一致性快照,避免长时间锁db

    2)将快照拷贝到新从节点

    3)从连到主节点,并请求快照点后更改日志(mysql binlog coordinates)

    4)获得日志,追赶,继续处理主节点新变化,重复1-4

2、处理失效节点

从节点失效:崩溃后又重启,追赶主节点

主节点失效:切换节点,切换过程中问题:

    1)如用异步复制,失效前新主 没收到 原主 所有 数据,原主重新上线,写冲突。丢弃原主解决

    2)如其他系统用db内容,丢弃特别危险:从提升为主,新原主没完全同步,db用自增计数器,重新用原主分配的主键,恰好这些主键被redis引用。导致redis mysql不一致?如何解决

    3)脑裂,都认为自己是主,强制关闭一个或都关

    4)   设置何时的超时时间,来检测主节点失效,避免必要的切换

3、复制日志

1、预写日志wal:追加写上去,1)对于日志结构存储引擎(sstable、lsm-tree),日志是主要存储方式,日志段在后台压缩 并 支持垃圾回收    2)对于覆盖写磁盘的btree,修改预先写日志,崩溃通过索引更新方式恢复。3)除了写日志,也可发给从节点(如数据格式不一样,从无法运行)

2、行的逻辑日志:binlog,复制与存储逻辑剥离,如一条事务更新多行,多条日志,后面一行记录,该事务已提交

3、触发器复制:不涉及任何代码,写事务,触发器记录到单独表中,开销高,更容易出错,高度灵活时用。

二、复制滞后问题

完全同步实际反而非常不可靠,正常主从延迟不足1秒,实践不会太大影响

2.1读自己写 

用户查看自己提交的,可能读从时新没到达从,影响用户体验。方案:

1.只从主节点读自己(从节点读其他用户),可能被修改数据(需有方法知道被修改信息)如:社交网络用户首页信息,但大多数用户都修改时,并不好。

2.跟踪更新时间一分钟内,读主节点,并监控从节点滞后程度,避免滞后时间>1分钟的读从

3.客户端请求中包含时间戳(或日志序列号),保证读时都包含该时间戳,没有,则交给副本处理。

ps:如多设备访问(web、手机),不能用时间戳方法(无法知道其他设备),要1)元数据全局共享    2)不同设备路由到,同一数据中心

2.2 单调读 

A向主节点,B第一次读的从已写第二次读的从没写,仿佛回滚了。

解决:用户读固定从,不随机

2.3 前缀一致读 

分区数据,经多副本复制后,出现不同程度滞后,观察者先看到果,后看到因

解决:因果关系写入,一个分区完成

三、多主节点复制

3.1、适用场景

1)多数据中心:为容灾和近用户考虑(就近写)。中心内主从。中心间,主主交换(异步)。缺点:会有写冲突(不同数据中心,修改相同数据)

2)离线客户端操作:离线时,用户对本地数据任意更改(相当于主节点),再次上线,与其他设备同步(多主复制)。

例:协作编辑:减小可编辑的粒度,会导致多主复制

3.2、处理写冲突

(1)避免冲突:总是通过同一个主节点。如个人信息特定数据中心修改,对于用户相当于主从复制。

(2)收敛于一致状态:多主节点,没有绝对一致的写入顺序,副本按它看到的写入顺序执行,最终不一致。解决:

    1)基于时间戳/用户id确定,最后写入/id最高 获胜,易丢数据

    2)副本唯一id,定优先级,易丢数据

    3)写入的值合并

(3)自定义解决(靠应用层)

    1)写入时执行:复制变更日志时检测到冲突,调用应用层冲突处理

    2)读取时执行:写入值全部暂存。读时返回多版本,提示用户或自动解决

四、无主节点复制

去中心复制,放弃主节点。节点失效时写入db,不需切换。重新上线读到过期数据。

解决:客户端读多个副本,版本号确定哪个值更新

1、修复失效节点:

读修复:新旧值都读到,更新值写入落后节点。缺点:很少读的数据,无法检测到

反熵过程:后台进程不断找副本间差异

2、Quorum确定读成功

n个副本,w个节点确认,至少查询r个节点

要w+r>n。读取的节点一定包含最新值。w和r可以置,多写少w=n,r=1

3、宽松Quorum

响应节点数>w认为写成功,不一定能从r个节点读到新

4、跨数据中心操作:

    1)向所有副本发送,只等本地中心确认

    2)只和本地交互,中心间多主复制

5、检测并发写

多副本收敛于相同的问题:

1、最后写入胜。写请求附加时间戳,丢弃早的数据,牺牲持久性。

2、因果和并发关系:Happens-Before关系。互相不需知道,就是并发关系

解决:

1、确认前后关系

    1)主键版本号,写入递增

    2)客户端读主键,服务器返回所,有主键值服务器版本号

    3)客户端写主键包含读到版本号,和新值合并用此版本号返回服务器。

    4)服务器收到写入时,覆盖版本号和更低版本所有值

2、合并同时写入的值:合并版本号,去掉重复部分。删除标记,并在合并时剔除

3、版本矢量 :多副本中,保存副本和主键版本号。可一个副本读,另一个副本写,db决定应该覆盖还是保留并发值

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容