我正在开发一个分布式Java应用程序,需要检查每个请求的黑名单用户ID列表。
如果请求在某些资格规则上失败,系统应将userid(请求参数)添加到黑名单。
我正在尝试为黑名单实施找到合适的缓存解决方案。我的要求是;
他们是两种可能的解决方案;
选项1 :我可以使用redis存储黑名单数据。每当请求在资格规则上失败时,我都可以轻松地将userid添加到redis缓存中。 - 优点:查询速度极快,易于实现 - 缺点:尽管可行,但信任redis持久性,它是一种缓存解决方案,而不是一个持久层。
选项2 :我可以使用redis存储黑名单数据,同时我可以在RDBMS上维护db表以获取黑名单。每当请求在资格规则上失败时,我都可以将userid添加到redis缓存和rdbms表中。 - 优点:极快的查询,从db重新加载redis缓存的能力(可能性) - 缺点:redis和db表之间存在一致性问题。
选项3 :我可以使用hazelcast作为休眠L2缓存,当我将任何用户ID添加到黑名单时,它都被添加到缓存和数据库中。
我对选项3有疑问
和最后一个问题 - 您对此类用例有任何其他建议吗?
编辑:
黑名单中将有100万条记录,我有一些黑名单。
我的阅读表现非常重要。我需要在黑名单~100ms
答案 0 :(得分:3)
Ygok,
仍在等待查询要求的澄清,但我可以假设它是按键查找(因为你提到Redis和Redis没有查询语言.Hazelcast确实有Distributed Query / Predicate API)。 通过密钥查找是一个非常快速的Hazelcast操作。
在选项2 中,您需要维护RDBMS和Redis缓存之间的数据一致性。使用Hazelcast MapLoader
/ MapStore
,您可以实现write-through
- / read-through
- 缓存概念。您只需将条目放入缓存,Hazelcast会立即将其保留,或者将配置的延迟(通过批处理)保存到RDBMS。
就性能而言,请随时熟悉最近的Hazelcast / Redis benchmark。
如果您有任何问题,请与我们联系。
答案 1 :(得分:2)
之前我有过类似的问题,首先,您想要存储多少数据并花费多少内存?你需要多快查询每秒?什么数据结构,只有userId作为键?
Hazelcast查询在我的测试中不是很快(你可以自己做),但它可以存储大量的内存数据。 Hazelcast使用Java 默认序列化,它耗费了大量内存和IO。
Hazelcast提供hibernate二级缓存,缓存数据存储 Hazelcast(仅查询缓存),因此重启您的应用程序不会影响 缓存。
Redis提供内存数据持久性(DUMP和AOF),也许是一个 服务器崩溃时,数据位将丢失,但速度非常快。
如果您不想丢失任何数据,请存储在多个MySQL上 server(由userId将数据拆分到不同的服务器,但你应该 在添加新服务器时考虑问题),同时,你可以 添加本地缓存(例如Ehcache或google CacheBuilder)并设置一个 到期时间,可以促进表现。
答案 2 :(得分:0)
使用Redisson框架可以保持Redis缓存和RDBMS之间的一致性。它使用write-through
和read-through
对象为Map对象提供MapWriter
和MapLoader
策略,这些对象需要在您的案例中使用。