在AWS中使用MySQL触发器在更新和插入时清空缓存

6
我正在AWS上构建一个架构,其中有多个EC2实例作为Web服务器和一个中央MySQL数据库(RDS)。 EC2实例安装了Redis以缓存单个数据库行。 当MySQL中的行更改时,我希望每个实例也更新相应的缓存条目。
在AWS环境中,最好的方法是什么?
2个回答

5
不要使用触发器来处理此事。确保事务已正确提交(而不是回滚),然后在应用程序层中刷新缓存。
如果不这样做,可能会出现并发请求重新使用旧数据填充缓存的情况(因为它们还没有看到新数据),因为在SQL触发器中该数据将被删除。

这个解决方案的问题在于,有多个应用程序可以访问数据库。我的最初想法是,在触发器被触发时使用亚马逊SNS向所有已注册的缓存实例发送通知。但我不知道如何在RDS中实现这一点。 - Thomas
如果你真的想把它作为触发器,你可以争辩说扩展mysql并在SQL函数中包装libmemcached(这样的库可能已经存在),但是我玩过pg-memcached后,我强烈建议不要这样做。处理一个缓存,它持有部分损坏的值数小时比拥有部分无效的缓存数据一瞬间更糟糕。 - Denis de Bernardy
我的意思是libredis,或者在你的情况下叫什么都可以。就我所知,在postgres中,我通过填充一个(基于内存的,未记录的)表来处理更棘手的缓存刷新需求,该表使用事务ID绑定关键字引用。不幸的是,简单的搜索显示这在mysql中是不可能的 - 尽管连接ID可能是足够好的代理。 - Denis de Bernardy
感谢您的建议。libmemcached/redis扩展能够处理多个独立的缓存实例吗?每个EC2 Web服务器实例都有自己独立运行的Redis实例。我的想法是使用SNS并自己刷新实例。为此,我需要向SNS RESTful Web服务发送POST请求。这是否可以在触发器内完成? - Thomas
我认为你最好的选择是填充某种needs_flush表。这可以很容易地通过触发器完成。在提交之后,逐个处理并且丢弃它们。在提交之前刷新会导致两种问题:缓存污染和死锁,因为写入需要同时锁定行,而事务持续时间过长。 - Denis de Bernardy
拥有一个关于刷新的表格是一个好建议。我的最初想法是推送有关缓存实例更改的消息,而不是让实例从数据库中拉取。当然,对Web服务的调用应该在更改后触发器中完成。 - Thomas

1
如果您正在使用队列服务器(Amazon SQS、Redis PubSub等),您可以为每个要过期的记录将条目放入队列中,并有一个工作程序监听队列,当它收到一条消息告诉它要使哪个记录无效时,它将连接到缓存并使该记录过期。
如果您只有一个缓存服务器或多个缓存服务器,这种方法都适用,您只需要为每个缓存服务器拥有一个工作程序,或者一个工作程序可以连接到每个缓存服务器。使用多个工作程序可以提高可扩展性。

谢谢您的建议,这正是我想做的。但是如何在SQL触发器中将消息推送到队列中呢? - Thomas
@Thomas 你必须使用触发器吗?你能在代码层面之外完成吗? - Ken Cochrane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接