使用 Hazelcast / Redis 满足数据库支持的缓存需求
Using Hazelcast / Redis for DB backed cache requirement
我正在开发一个分布式 Java 应用程序,它需要根据每个请求检查黑名单用户 ID 列表。
如果请求在某些资格规则上失败,系统应该将userid(请求的一个参数)加入黑名单。
我正在尝试为黑名单实施找到合适的缓存解决方案。我的要求是;
- 查询黑名单应该很快
- 黑名单持久化技术应该是可扩展的
- 所有黑名单数据都应保存在 RDBMS 上,也用于故障转移/重新加载目的。
这是两个可能的解决方案;
方案1:我可以用redis存储黑名单数据。每当请求在资格规则上失败时,我都可以轻松地将用户标识添加到 redis 缓存中。
- 优点:查询速度极快,易于实现
- 缺点:信任 redis 持久性,尽管它有效,但它是一种设计缓存解决方案,而不是持久层。
方案2:我可以使用redis来存储黑名单数据,同时我可以在RDBMS上为黑名单维护db tables。每当请求在资格规则上失败时,我可以将 userid 添加到 redis 缓存和 rdbms table 中。
- 优点:极快的查询,能够(可能)从数据库重新加载 redis 缓存
- 缺点:redis和db之间存在一致性问题table.
选项 3:我可以使用 hazelcast 作为休眠 L2 缓存,当我将任何用户 ID 添加到黑名单时,它都会被添加到缓存和数据库中。
我对选项 3 有疑问
- hazelcast L2 缓存是否适合table 以保留这样的黑名单用户列表?
- hibernate 是否管理缓存和数据库之间的一致性问题?
- 应用重启时,二级缓存是如何重新加载的?
最后一个问题
- 对于这样的用例,您还有其他建议吗?
编辑:
黑名单里会有100m的记录,我有几个比较合适的黑名单。
我的读取性能很重要。我需要查询黑名单中是否存在密钥 ~100ms
我之前也有类似的问题,首先你要存储多少数据,占用多少内存?您需要每秒多快的查询速度?数据结构是什么样的,只有 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 之间的一致性。它为使用 MapWriter
和 MapLoader
对象的 Map 对象提供 write-through
和 read-through
策略,这些对象需要在您的案例中使用。
我正在开发一个分布式 Java 应用程序,它需要根据每个请求检查黑名单用户 ID 列表。
如果请求在某些资格规则上失败,系统应该将userid(请求的一个参数)加入黑名单。
我正在尝试为黑名单实施找到合适的缓存解决方案。我的要求是;
- 查询黑名单应该很快
- 黑名单持久化技术应该是可扩展的
- 所有黑名单数据都应保存在 RDBMS 上,也用于故障转移/重新加载目的。
这是两个可能的解决方案;
方案1:我可以用redis存储黑名单数据。每当请求在资格规则上失败时,我都可以轻松地将用户标识添加到 redis 缓存中。 - 优点:查询速度极快,易于实现 - 缺点:信任 redis 持久性,尽管它有效,但它是一种设计缓存解决方案,而不是持久层。
方案2:我可以使用redis来存储黑名单数据,同时我可以在RDBMS上为黑名单维护db tables。每当请求在资格规则上失败时,我可以将 userid 添加到 redis 缓存和 rdbms table 中。 - 优点:极快的查询,能够(可能)从数据库重新加载 redis 缓存 - 缺点:redis和db之间存在一致性问题table.
选项 3:我可以使用 hazelcast 作为休眠 L2 缓存,当我将任何用户 ID 添加到黑名单时,它都会被添加到缓存和数据库中。
我对选项 3 有疑问
- hazelcast L2 缓存是否适合table 以保留这样的黑名单用户列表?
- hibernate 是否管理缓存和数据库之间的一致性问题?
- 应用重启时,二级缓存是如何重新加载的?
最后一个问题 - 对于这样的用例,您还有其他建议吗?
编辑:
黑名单里会有100m的记录,我有几个比较合适的黑名单。
我的读取性能很重要。我需要查询黑名单中是否存在密钥 ~100ms
我之前也有类似的问题,首先你要存储多少数据,占用多少内存?您需要每秒多快的查询速度?数据结构是什么样的,只有 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 之间的一致性。它为使用 MapWriter
和 MapLoader
对象的 Map 对象提供 write-through
和 read-through
策略,这些对象需要在您的案例中使用。