在我目前的申请中,我们正在处理一些很少改变的信息。对于性能优化,我们希望将它们存储在缓存中。但问题是在更新这些对象时无效。我们还没有最终确定缓存产品。当我们在Azure上构建此应用程序时,我们可能会使用' Azure redis缓存'。一种策略可能是在“更新API”中添加代码。这将使缓存中的对象无效。我不确定这是否干净。我们不希望根据时间使用缓存过期。你能否建议一些其他用于缓存失效的策略?
答案 0 :(得分:18)
在更新阶段使缓存无效是一种可行的方法,并且在过去非常常用。这里有两个选项:您可以尝试在UPDATE发生时设置新值,或者只删除旧值并在读取操作期间更新。如果你想要一个LRU缓存,那么UPDATE可能只是删除旧值,并且第一次获取对象时,你将在从实际数据库读取后再次创建它。但是,如果您知道缓存非常小并且您正在使用另一个主数据库来处理与数据大小不同的问题,则可以在UPDATE期间直接更新。
然而,这一切还不足以完全一致。当您写入数据库时,Redis缓存可能会在几秒钟内不可用,因此数据在两者之间保持不同步。你在那种情况下做了什么?您可以同时使用多种选项。
所以del-cache-on-update和write-cache-on-read是基本策略,但你可以使用其他额外的系统来最终修复不一致。
实际上还有另一个选项,而不是使用上面的选项,即如果存在不一致,则使用Redis SCAN
进行后台处理以按键验证密钥。此过程可能很慢,可以针对数据库的副本运行。
正如你在这里看到的那样,主要思想总是一样的:如果对缓存的更新失败,请不要将其永久保留在那里,让它有机会在以后修复自己
答案 1 :(得分:0)
我认为lambda(ish)体系结构适用于您的用例。
对于实时更新,您将必须在应用程序的代码库上进行工作,才能将数据写入数据库和缓存。
对于批量数据加载,您可以查看数据提取工具,例如logstash / fluentd,以从数据库中“抽取”最新数据。可以根据始终递增的列(ID号或时间戳)来完成此操作。
我最后有Oracle数据库。 Logstash JDBC插件在提取最新记录方面做得不错。 logstash输出可以格式化并打印到Redis可以使用的文件中。我写了一个小的bash脚本来对此进行编排。测试了300万条记录并可以正常工作。
答案 2 :(得分:-2)
除了TTL(生存时间,例如在给定时间段后删除密钥),通常的策略是LRU(最近最少使用):当您需要删除某些条目时(例如,当您达到最大内存限制时) ,删除最旧的条目。
但是,要确切知道哪个条目是最早的条目很长,所以Redis使用统计方法,只需要几个(默认为3个)条目,并删除最近最少使用的条目。