无论何种分布式存储,其本质都需要节点间的复制,实践中主要的实现方式有基于语句的复制、基于WAL的复制、基于行的逻辑复制、基于触发器的复制。
分布式系列文章,首发请关注公众号【伟达实验室】
复制的实现原理
对于分布式存储,上节中我们提到主从同步、多主同步、无主同步,都是从分布式系统整体角度来理解分布式的复制。而无论哪种同步方式,其最终都是依赖于节点间的文件复制。
实践中,主要的复制实现方式有:基于语句的复制、基于WAL预写式日志的复制、基于行的逻辑复制、基于触发器的复制。
基于语句的复制
简单来说,主节点会将执行的每个写请求记录(操作语句)记录下来,并将操作语句作为日志发送给从节点。比如mysql,会将每个insert、update、delete语句记录并发送给从节点,从节点按照顺序分析并执行这些语句。
语句复制方式,是比较简单的一种实现方式,会直接保存客户端对节点的写语句,将其发送给从节点。但是一些动态操作语句,比如时间、自增列、有副作用的语句(触发器、存储过程、UDF)会导致不同副本出现副作用。
基于WAL-预写式日志的复制
WAL的中心概念是数据文件(存储着表和索引)的修改必须在这些动作被日志记录之后才被写入,即在描述这些改变的日志记录被刷到持久存储以后。其中心思想是先写日志,再写数据,数据文件的修改必须发生在这些修改已经记录在日志文件中之后。
这样主节点和从节点的数据同步就完全可以采用日志文件传输的方式来实现。
基于行的逻辑日志复制
基于行的逻辑日志复制方式,采用与复制和存储引擎不同的日志格式,且与存储逻辑相剥离。
对于关系型数据库,通常根据不同种类的写请求来记录描述数据表行级别的数据:
-
对于行插入,日志会包含所有相关表的最新值;
-
对于行删除,日志里会存储足够的信息来标识已删除的行。
-
对于行更新,日志里会有足够信息来唯一标识需要更新的行,同时会包含所有需要更新的列的最新值,或者包含所有列的最新值。
基于触发器的复制
基于触发器的复制:更高的灵活性,例如仅复制部分数据,到另一种数据库复制,冲突解决逻辑,这些场景可能需要将复制上升到应用层来解决。基于触发器的复制通常比其他复制方法具有更大的开销,并且比数据库的内置复制更容易出现错误和限制。然而,由于其灵活性,它仍然是有用的。
分布式专题,持续更新中~
收发请关注公众号: 伟达实验室