如何正确处理异步数据库复制?
我正在考虑使用Amazon RDS和只读副本来扩展我们的数据库。
我们的Web应用程序中的一些控制器是可读/写的,其中一些是只读的。 我们已经有了一种自动识别哪些控制器是只读的方法,因此,我的第一种方法是在请求读/写控制器时打开与主控制器的连接,或者在请求读取控制器时打开与只读副本的连接,只有控制器。
理论上,这听起来不错。 但后来我偶然发现了复制滞后概念,它基本上说复制品可能会在主人后面几秒钟。
我们来想象下面的用例:
/create-account
,这是读/写的,因此连接到主服务器 /member-area
/member-area
,它是只读的,因此连接到副本。 如果副本甚至稍微落后于主服务器,则用户帐户可能还不存在于副本上,因此会导致错误。 您如何在应用程序中真实地使用只读副本,以避免这些潜在问题?
这是一个难题,并且有很多潜在的解决方案。 一个可能的解决方案是看看Facebook做了什么,
TLDR - 读取请求会被路由到只读副本,但是如果您执行写入操作,那么在接下来的20秒内,您的所有读取都将转到可写入主机。
我们必须解决的另一个主要问题是只有加州的主数据库才能接受写入操作。 这一事实意味着我们需要避免提供来自弗吉尼亚州的数据库写入页面,因为每个页面都必须通过加利福尼亚州的国家数据库。 幸运的是,我们最常访问的页面(主页,配置文件,照片页面)在正常操作下不会进行任何写入。 因此,问题归结为,当用户提出一个页面请求时,我们如何确定发送给弗吉尼亚是“安全”还是必须发送到加利福尼亚?
这个问题原来有一个相对直接的答案。 用户请求Facebook访问的第一台服务器之一称为负载平衡器; 这台机器的主要责任是挑选一台Web服务器来处理请求,但它也有其他一些目的:防止拒绝服务攻击和复用用户连接等等。 此负载均衡器能够在第7层模式下运行,可以检查用户请求的URI并根据该信息做出路由决策。 这个功能意味着很容易告诉负载均衡器我们的“安全”页面,并且可以根据页面名称和用户的位置决定是否将请求发送到弗吉尼亚州或加利福尼亚州。
然而,这个问题还有另一个问题。 假设你去editprofile.php来改变你的家乡。 此页面未被标记为安全,因此它被路由到加利福尼亚州,并且您进行了更改。 然后你去查看你的个人资料,因为这是一个安全的页面,我们会送你到弗吉尼亚州。 但是,由于之前提到的复制滞后,您可能看不到您刚刚做出的更改! 这种体验对用户来说非常混乱,也会导致双重发布。 我们通过在您的浏览器中使用当前时间设置Cookie来解决此问题,无论您何时向数据库中写入内容。 负载平衡器还会查找该cookie,如果它注意到您在20秒内写入了某些内容,则会无条件地将您发送到加利福尼亚州。 然后,当20秒过去了,我们确信数据已经复制到弗吉尼亚州,我们将允许您返回安全页面。
我使用伪垂直分区的应用程序工作。 由于只有少数数据对时间敏感,因此应用程序通常仅在特定情况下从从属设备和主设备获取。
举个例子:当用户更新他们的密码时,应用程序总是要求主人提供认证。 当更改非时间敏感数据(如用户首选项)时,它会显示成功对话框以及可能需要一段时间才能更新所有内容的信息。
其他一些可能或不可能取决于环境的想法:
无论您选择哪种解决方案,都要记住它是CAP定理的主题。
链接地址: http://www.djcxy.com/p/14597.html上一篇: How to properly handle asynchronous database replication?
下一篇: Rectangle class functions getX(), getY(), etc. return in double precision