在将Amazon RDS与只读副本一起使用时,您如何处理最终的不一致?

时间:2014-12-28 18:41:01

标签: java php node.js amazon-rds eventual-consistency

考虑用户购物车和结帐:客户可以执行addItemToCart操作,该操作将由主数据库实例处理。但是,可能会对只读副本执行getUserCartItems操作,并且由于副本滞后,它可能不包含第一个操作的结果。即使我们试图最大限度地减少这种滞后,仍然有可能遇到这种情况,所以我想知道你在生产中尝试了哪些解决方案?

根据@Henrik answer,我们有3个选项:

1. Wait at user till consistent.

这意味着我们需要在客户端上执行轮询(常规或长轮询)并等到副本服务器将接收更新。但是,我认为副本延迟不应超过1-5秒。此外,副本滞后越少,我们的性能就越低。

2. Ensure consistency through 2PC. 

如果我理解正确,我们需要将addItemToCart insert和getUserCartItems select合并到后端的一个聚合操作中,并将getUserCartItems作为addItemToCart响应返回。但是,由于滞后,下一个请求可能仍然无法获得更新信息...是的,它会立即返回有关成功操作的确认,并且应用程序可以继续,但是要结帐,需要用户购物车项目才能正确显示价格,因此我们不会修复问题无论如何。

3. Fool the client.

应用程序存储/缓存都成功发送数据并将其用于显示。是的,这是一个解决方案,但它肯定需要实现其他业务逻辑:

Perform getUserCartItems request;

if (getUserCartItems returned success)
  Store addItemToCart in local storage; 
else 
  Show error and retry;

Perform getUserCartItems request;

if (getUserCartItems contains addItemToCart ID)
  Update local storage / cache and proceed with it. 
else       
  Use existing data from local storage; 

你如何处理最终的不一致?

1 个答案:

答案 0 :(得分:1)

正确的答案是,如果数据需要立即可用,则不要向读取从设备发送SELECT查询。

您应该构建应用程序,以便所有实时请求都会命中您的主服务器,并且所有其他请求都会命中您的一个读取从服务器。

对于您不需要实时结果的内容,您可以使用AJAX请求或websockets等方式很好地欺骗用户(websockets将使您的应用程序更加资源友好,因为您赢了&#39 ;用多个AJAX请求锤击你的后端服务器。)