7

我正在考虑使用带有只读副本的Amazon RDS来扩展我们的数据库。

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

从理论上讲,这听起来不错。但是后来我无意中打开了复制滞后的概念,它基本上说副本可以落后于主服务器几秒钟。

让我们想象一下以下用例:

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

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

4

2 回答 2

2

我使用了使用伪垂直分区的应用程序。由于只有少数数据是时间敏感的,因此应用程序通常仅在选定的情况下从从属设备和主设备获取。

举个例子:当用户更新他们的密码时,应用程序总是会要求主人提供身份验证提示。当更改非时间敏感数据(如用户首选项)时,它会显示成功对话框以及可能需要一段时间才能更新所有内容的信息。

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

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

无论您选择什么解决方案,请记住它是CAP Theorem的主题。

于 2013-08-08T09:55:38.090 回答
1

这是一个难题,并且有很多潜在的解决方案。一种可能的解决方案是看看facebook 做了什么,

TLDR - 读取请求被路由到只读副本,但是如果您进行写入,那么在接下来的 20 秒内,您的所有读取都将发送到可写主机。

我们必须解决的另一个主要问题是只有我们在加利福尼亚的主数据库才能接受写操作。这一事实意味着我们需要避免提供从弗吉尼亚进行数据库写入的页面,因为每个页面都必须跨越国家到我们在加利福尼亚的主数据库。幸运的是,我们最常访问的页面(主页、个人资料、照片页面)在正常操作下不会进行任何写入。因此,问题归结为,当用户请求页面时,我们如何确定发送到弗吉尼亚是否“安全”或是否必须路由到加利福尼亚?

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

然而,这个问题还有另一个问题。假设您去editprofile.php 更改您的家乡。此页面未标记为安全,因此它会被路由到加利福尼亚,然后您进行更改。然后你去查看你的个人资料,因为它是一个安全的页面,我们把你送到弗吉尼亚。但是,由于我们前面提到的复制滞后,您可能看不到刚刚所做的更改!这种体验对于用户来说是非常混乱的,并且还会导致重复发布。每当您向我们的数据库写入内容时,我们通过在您的浏览器中设置一个带有当前时间的 cookie 来解决这个问题。负载均衡器还会查找该 cookie,如果它注意到您在 20 秒内写了一些东西,它将无条件地将您发送到加利福尼亚。然后当 20 秒过去了,我们'

于 2013-08-02T04:19:45.443 回答