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


How do you deal with eventual inconsistency when using Amazon RDS with Read Replica?

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

根据@Henrik答案,我们有 3 个选择:

1. Wait at user till consistent.

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

2. Ensure consistency through 2PC. 

如果我理解正确,我们需要将addItemToCart插入和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; 

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

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

您应该构建您的应用程序,以便所有实时请求都命中您的主站,而所有其他请求命中您的一个读取从站。

对于不需要实时结果的事情,你可以使用AJAX请求或websockets之类的东西很好地愚弄用户(websockets将使你的应用程序对资源更加友好,因为你不会用多个AJAX请求来锤击后端服务器)。