使用 Hazelcast / Redis 满足数据库支持的缓存需求

Using Hazelcast / Redis for DB backed cache requirement

我正在开发一个分布式 Java 应用程序,它需要根据每个请求检查黑名单用户 ID 列表。

如果请求在某些资格规则上失败,系统应该将userid(请求的一个参数)加入黑名单。

我正在尝试为黑名单实施找到合适的缓存解决方案。我的要求是;

这是两个可能的解决方案;

方案1:我可以用redis存储黑名单数据。每当请求在资格规则上失败时,我都可以轻松地将用户标识添加到 redis 缓存中。 - 优点:查询速度极快,易于实现 - 缺点:信任 redis 持久性,尽管它有效,但它是一种设计缓存解决方案,而不是持久层。

方案2:我可以使用redis来存储黑名单数据,同时我可以在RDBMS上为黑名单维护db tables。每当请求在资格规则上失败时,我可以将 userid 添加到 redis 缓存和 rdbms table 中。 - 优点:极快的查询,能够(可能)从数据库重新加载 redis 缓存 - 缺点:redis和db之间存在一致性问题table.

选项 3:我可以使用 hazelcast 作为休眠 L2 缓存,当我将任何用户 ID 添加到黑名单时,它都会被添加到缓存和数据库中。

我对选项 3 有疑问

最后一个问题 - 对于这样的用例,您还有其他建议吗?

编辑:

我之前也有类似的问题,首先你要存储多少数据,占用多少内存?您需要每秒多快的查询速度?数据结构是什么样的,只有 userId 作为键?

  • Hazelcast 查询在我的测试中不是很快(你可以自己做),但它可以存储大内存数据。使用 Java 的 Hazelcast 默认序列化,占用大量内存和IO。

  • Hazelcast提供hibernate L2缓存,缓存数据存储在 Hazelcast(仅查询缓存),因此重新启动您的应用程序不会影响 缓存。

  • Redis提供内存数据持久化(DUMP和AOF),也许是 服务器崩溃时会丢失一些数据,但速度非常快。

  • 如果您不想丢失任何数据,请存储在 multi MySQL 服务器(按userId将数据拆分到不同的服务器,但你应该 考虑添加新服务器时的问题),同时,您可以 添加本地缓存(例如 Ehcache 或 google CacheBuilder)并设置 过期时间,可以提升性能。

伊戈克,

仍在等待查询要求的澄清,但我可以假设它是按键查找(因为你提到了 Redis,而 Redis 没有查询语言。Hazelcast 确实有 Distributed Query / Predicate API)。 使用 Hazelcast 进行按键查找是一项非常快速的操作。

选项 2 中,您需要保持 RDBMS 和 Redis 缓存之间的数据一致性。使用 Hazelcast MapLoader / MapStore 你可以实现 write-through- / read-through- 缓存概念。您需要做的就是将条目放入缓存,Hazelcast 会立即将其持久化或以配置的延迟(通过批处理)持久化到 RDBMS。

在性能方面,请随意熟悉最近的Hazelcast / Redis benchmark

如果您有任何问题,请告诉我。

可以使用 Redisson 框架保持 Redis 缓存和 RDBMS 之间的一致性。它为使用 MapWriterMapLoader 对象的 Map 对象提供 write-throughread-through 策略,这些对象需要在您的案例中使用。

请阅读此documentation section