我开始为分布式系统实现缓存,我的系统运行在许多独立的服务和多种语言(C#,Java,AngularJS等)。
在检查了几个解决方案后,我选择使用Redis实现缓存部分。 在缓存解决方案的设计过程中,我注意到我有很多缓存依赖,最简单的解决方法是保存一个管理所有依赖关系的表(key - >需要删除的项的多值\在缓存上更新每次关键变化)。 问题是它是否是实现缓存依赖的正确方法? 我想在每个使用缓存的软件都遇到了缓存依赖的挑战,所以我确信这是一个更好的解决方案。
缓存依赖的示例 - 如果所有用户的缓存句柄列表,以及某人删除或向系统添加新用户,如果用户未在缓存上更新,则系统将显示错误的列表用户。
感谢。
答案 0 :(得分:2)
缓存失效是一个超级难题。但是,有很多解决方案。保留缓存对象的集合(在Redis或其他地方)以及可能更新的关联域对象是一种合理的方法。
对于复杂的相互依赖的缓存,有许多方法,包括俄罗斯娃娃缓存和key-based caching。
基于密钥的缓存的基本概念是拥有一个复杂的缓存密钥,其中包含固定标识符和动态标识符。
例如,如果您要为User#123缓存一个名为“user_navigation_bar”的对象/片段,则可以将缓存写入user_nav_bar:123:201705071122
之类的密钥。最后一部分是用户更新时的时间戳。这是动态部分,每次用户都会改变。要读取缓存,您只需要用户ID和更新时间戳。对于示例中的用户列表,您可以为所有用户使用最新创建/更新的时间戳,或者拥有一个UserList对象,您可以在创建/更新用户时更新时间戳。
使用这种方法,您永远不会更新或删除任何内容。对缓存的所有写入都是全新的密钥。
您不应该自己删除缓存项目。如果将redis配置为最大内存大小和LRU eviction policy(最近最少使用),它将自动清除未访问时间最长的缓存项。当像“user_navigation_bar”这样的项目被更新并写入具有新时间戳的新对象时,旧的时间戳将不再被访问并最终被清除。
如果您使用redis作为缓存对象以外的东西,您可能希望运行多个实例。一个配置为LRU缓存,具有固定的最大内存大小,可能没有持久性。另一个更像是默认的redis安装,没有永久对象的最大内存和持久性。
如果您使用单个redis实例,则可以为缓存对象设置长期到期,并使用volatile-lru
驱逐策略,以便redis仅清除设置了到期日期的密钥。如果您使用这种方法,请确保将最大内存设置得足够高,以便它有足够的空间容纳所有永久数据。
你的问题非常广泛,但希望这会有所帮助。