gpt4 book ai didi

php - 缓存节点故障导致数据不一致

转载 作者:可可西里 更新时间:2023-11-01 12:57:33 26 4
gpt4 key购买 nike

我遇到了数据库中的数据恢复到旧状态的问题。我想我已经将问题缩小到这种情况。

想象一下像这样发生的两次购买序列:

  • 所有缓存节点都在工作
  • 用户登录(他们的数据从数据库中提取并存储在 memcached 中)
  • 缓存节点宕机
  • 用户继续浏览(由于在缓存中找不到他们的数据,因此从数据库中提取数据并存储在 memcached 中)
  • 用户执行一些操作来转换他们的记录[例如升级](他们的记录在缓存和数据库中更新)
  • 缓存节点恢复
  • 我们再次从缓存中拉取用户的数据,它来自之前宕机的原始缓存节点
  • 现在我们遇到了一个问题:缓存中的节点已过时!
  • 用户进行了另一个改变他们记录的操作
  • 这保存在缓存和数据库中,但由于它基于过时的记录,因此它会踩踏之前的更改并有效地恢复它

我们现在丢失了数据,因为数据库记录被部分过时的信息重写了。

如何使用具有持久连接的 PHP5 和 libmemcached 来防止这种情况发生?我想我想要的是缓存节点根本不进行故障转移;它应该只是无法读取和写入该节点,但不会将其从池中删除,这样我就不会得到重复的记录。

当一个节点出现故障时,这会使我的数据库负载增加 1/n(其中 n 是缓存节点的总数),但这比以不一致的数据结束要好。

不幸的是,我无法理解应该更改哪些设置才能获得此行为。

最佳答案

我喜欢 versioning and optimistic lock approach在 Doctrine ORM 中实现。你也可以做到的。它不会增加数据库的负载,但需要进行一些重构。

基本上,您向缓存的所有表添加一个版本号,更改您的update 查询以增加版本version = version + 1 并添加where version =$version 条件(请注意 $version 来自您的 php/memcache)。您将需要检查受影响的行数,如果为 0 则抛出异常。

如何处理此类异常由您决定。您可以只使该记录的缓存无效,并要求用户重新提交表单,或者您可以尝试合并更改。此时,您有来自缓存的陈旧数据、来自用户输入的更新和来自数据库的新数据,因此唯一不可恢复的情况是同一列有 3 个不同的值。

关于php - 缓存节点故障导致数据不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34679425/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com