复制滞后问题

复制滞后问题

主从复制要求所有写请求都经由主节点,而任何副本只能接受只读查询。对于读操作密集的负载,是一个不错的选择:创建多个从副本,将读请求分发给这些从副本,从而减轻主节点负载并允许读请求就近满足。

在这种扩展体系下,只需要添加更多的从副本,就可以提高读请求的服务吞吐量。但是,这种方法实际上只能用于异步复制,如果试图同步复制所有的从副本,则单个节点故障或者网络中断将使整个系统无法写入。

不幸的是,如果一个应用正好从一个异步的从节点读取数据,而该副本落后于主节点,则应用可能会得到过期的信息。这会导致数据库中出现明显的不一致:由于并非所有的写入都反映在从副本上,如果同时对主节点和从节点发起相同的查询,可能会得到不同的结果。这种不一致只是一个暂时的状态,如果停止写数据库,经过一段时间后,从节点最终会赶上并与主节点保持一致。这种效应也被称为最终一致性。

写后读一致性

保证用户总能看到自己所提交的最新数据。

如果用户在写入不久即查看数据,则新数据可能尚未到达从节点。这样看起来似乎是刚刚提交的数据丢失了。

  • 如果用户访问可能会被修改的内容,从主节点读取;否则,在从节点读取。例如,社交网络上的用户首页信息通常只能由所有者编辑,而其他人无法编辑。因此,可以这样:总是从主节点读取用户自己的首页配置文件,而在从节点读取其他用户的配置文件。
  • 如果应用的大部分内容都可能被所有用户修改,那么上述方法将不会太有效,它会导致大部分内容都必须经过主节点,这就丧失了读操作的扩展性。此时需要其他方案来判断是否从主节点读取。例如,跟踪最近更新的时间,如果更新后一分钟之内,则总是从主节点读取;并监控从节点的复制滞后程度,避免从那些滞后时间超过一分钟的从节点读取。
  • 客户端还可以记住最近更新的时间戳,并附带在读请求中,据此信息,系统可以确保对该用户提供服务时都应该至少包含了该时间戳的更新。

复制滞后问题_第1张图片

单调读

用户在某个时间点读到数据之后,保证此后不会出现比该时间点更早的数据。

例子:用户刷新知乎,读请求可能被随机路由到某个从节点。用户先后从两个从节点上执行了两次完全相同的查询(先是少量滞后的节点,然后是滞后很大的从节点),则很有可能出现以下情况。第一个查询返回了最近另一个用户添加的评论,但第二个查询因为滞后的原因,还没有收到更新因而返回结果是空。实际上,第二个查询结果代表了更早时间点的状态。所以看起来就是用户1看到用户2的评论后,紧接着评论又消失了。

实现单调读的一种方式是,确保每个用户总是从固定一个副本执行读取(而不同的用户可以从不同的副本读取)。例如,基于用户ID的哈希的方法而不是随机选择副本。但如果该副本发生实效,则用户的查询必须重新路由到另一新副本。

复制滞后问题_第2张图片

前缀一致读

保证数据之间的因果关系,例如,总是以正确的顺序先读取问题,然后再看到回答。

一个解决方案是确保任何具有因果顺序关系的写入都交给一个分区来完成。

复制滞后问题_第3张图片

你可能感兴趣的:(数据库技术,分布式,数据库)