如何正确处理异步数据库复制?

时间:2013-06-30 21:37:26

标签: scalability database-replication amazon-rds

我正在考虑将Amazon RDSread replicas一起使用来扩展我们的数据库。

我们的Web应用程序中的一些控制器是可读/写的,其中一些是只读的。我们已经有了一种自动识别哪些控制器是只读的方法,因此我的第一种方法是在请求读/写控制器时打开与主站的连接,否则在请求读取时打开与读取副本的连接。只有控制器。

从理论上讲,这听起来不错。但后来我偶然发现了复制滞后概念,它基本上说复制品可能比主控器落后几秒钟。

让我们假设以下用例:

  • 浏览器发布到/create-account,这是读/写,因此连接到主
  • 创建帐户,提交交易,浏览器重定向到/member-area
  • 浏览器打开/member-area,它是只读的,因此连接到副本。如果副本甚至稍微落后于主副本,则副本上的用户帐户可能尚不存在,从而导致错误。

如何在应用程序中实际使用只读副本,以避免这些潜在问题?

2 个答案:

答案 0 :(得分:2)

我使用的是使用伪 - vertical partitioning的应用程序。由于只有极少数数据是时间敏感的,因此应用程序通常仅在选定的情况下从从站和主站获取。

作为示例:当用户更新其密码时,应用程序始终会询问 master 以获取身份验证提示。更改非时间敏感数据(如“用户首选项”)时,它将显示成功对话框以及可能需要一段时间才能更新所有内容的信息。

根据环境可能会或可能不会起作用的其他一些想法:

  • 更新计算实体校验和后,将其存储在应用程序缓存中,并且在获取数据时始终要求符合校验和
  • 使用浏览器商店/ cookie存储增量确保用户始终可以看到最新版本
  • 添加"最新"在更新之前/之后,在每个从节点上同步标记和无效

无论您选择何种解决方案,请记住CAP Theorem的主题。

答案 1 :(得分:1)

这是一个难题,并且有很多潜在的解决方案。一个可能的解决方案是查看facebook did

TLDR - 读取请求被路由到只读副本,但如果您进行写入,则在接下来的20秒内,所有读取都将转到可写主服务器。

  

我们必须解决的另一个主要问题是只有我们的主人   加州的数据库可以接受写操作。这个事实意味着   我们需要避免提供从中进行数据库写入的页面   弗吉尼亚,因为每个人都必须越过我们的国家   加州的主数据库。幸运的是,我们最频繁   访问过的页面(主页,配置文件,照片页面)不做任何写入   正常运转。因此,问题归结为用户   请求页面,我们如何确定发送是否“安全”   到弗吉尼亚州还是必须前往加利福尼亚州?

     

这个问题的答案相对简单。   用户请求Facebook命中的第一个服务器之一称为a   负载均衡器;这台机器的主要职责是选择网络   服务器来处理请求,但它也服务于其他许多   用途:防范拒绝服务攻击和   多路复用用户连接仅举几例。这个负载均衡器有   能够在第7层模式下运行,它可以检查URI a   用户正在请求并根据该决策做出路由决策   信息。此功能意味着很容易告诉负载均衡器   关于我们的“安全”页面,它可以决定是否发送请求   根据页面名称和用户的说明到弗吉尼亚州或加利福尼亚州   位置。

     

然而,这个问题还有另一个问题。让我们说你去   editprofile.php改变你的家乡。此页面未标记为   安全,所以它被送到加利福尼亚,你做出改变。那么你   去查看您的个人资料,因为它是一个安全的页面,我们会发送给您   弗吉尼亚州。由于我们之前提到的复制滞后,   但是,您可能看不到刚刚做出的改变!这段经历   对用户来说非常混乱,也导致双重发布。我们有   通过在浏览器中设置cookie来解决这个问题   当你向我们的数据库写东西时的当前时间。负载   平衡器也会查找该cookie,如果它注意到您编写的话   20秒内的东西,将无条件送你到   加利福尼亚。然后20秒过去了,我们肯定了   数据已复制到弗吉尼亚州,我们将允许您回去安全   页。