0

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

根据@Henrik 的回答,我们有 3 个选项:

1. Wait at user till consistent.

这意味着我们需要在客户端上执行轮询(定期或长轮询)并等待 Replica 收到更新。但是,我认为副本延迟不应超过 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; 

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

4

1 回答 1

4

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

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

对于不需要实时结果的事情,您可以使用诸如 AJAX 请求或 websockets 之类的东西很好地欺骗用户(websockets 将使您的应用程序对资源更加友好,因为您不会敲打后端服务器有多个 AJAX 请求)。

于 2014-12-28T19:17:50.187 回答