过滤Redis哈希条目

| 我正在使用redis存储每个哈希有约100k条记录的哈希。我想实现过滤(刻面)给定哈希值内的记录。请注意,哈希条目可以属于n个过滤器。 看完这个,看起来我应该: 对每个过滤器实施排序的SET。 SET中的值对应于HASH中的键。 从给定的过滤器SET中检索HASH键。 一旦我从SET中获得HASH键,就从HASH中获取相应的条目。这应该给我所有属于过滤器的条目。 首先,上述方法在较高水平上是否正确? 假设方法还可以,我所缺少的是检索HASH条目的最有效的实现方式是什么?一旦有了HASH键,我是否在思考,然后应该使用PIPELINE对通过每个HASH键传递的多个HGETALL命令进行排队?有没有更好的方法? 我对使用PIPELINE的担心是,我认为它将在服务该命令的同时阻止所有其他客户端。我将分页筛选结果,每页显示500个结果。使用多个基于浏览器的客户端执行过滤时,更不用说填充SET和HASH的后端进程了,如果PIPELINE确实阻塞了,这听起来可能会引起很多争用。有人可以对此提供意见吗? 如果这有助于我使用2.2.4 Redis,则对于Web客户端使用predis,对于后端使用servicestack。 谢谢, 保罗     
已邀请:
Redis是无锁的非阻塞异步服务器,因此在使用流水线操作时不会增加争用。 Redis会在收到每个操作后立即愉快地处理它们,因此在实践中可以处理多个流水线操作。本质上,redis-server确实不在乎操作是否已流水线化,它只是在接收到每个操作时对其进行处理。 流水线化的好处是减少了客户端延迟,而不是在发送下一个操作之前不必等待redis服务器对每个操作的响应,而是只需一次写入一次即可泵送所有操作,然后再读回所有响应。单读。 这方面的一个例子是在我的Redis mini StackOverflow克隆中,每次单击都会调用ѭ0because,这是因为操作已管道化,因此在1个Socket写入调用中发送了所有操作,并在1个Socket阻塞读取中读取了结果,这比使用Socket阻塞更有效。阻止每次通话读取: https://github.com/ServiceStack/ServiceStack.Examples/blob/master/src/RedisStackOverflow/RedisStackOverflow.ServiceInterface/IRepository.cs#L180   我对使用PIPELINE的担心是   我相信它将阻止所有其他   客户在服务命令时。 这不是一个真正的问题,我不会考虑Redis在这里的工作方式,假设它在Pipeline不会阻止其他客户端命令处理的情况下最有效地做到这一点。从概念上讲,您可以认为redis-server按FIFO顺序处理每个命令(无论是否流水线)(即,不浪费时间等待/读取整个流水线)。 您正在描述的是更接近MULTI / EXEC(即Redis事务)的东西,在该操作中,Redis服务器读取EXEC(即EOF事务)后立即完成所有操作。这也不是问题,redis-server仍然不浪费任何时间等待接收您的整个事务,它只是将部分命令集排队在一个临时队列中,直到接收到最终的EXEC,然后立即将其全部处理。 通过这种方式,redis在收到每个命令后立即处理每个命令,从而实现原子性。由于没有其他线程,所以没有线程上下文切换,没有锁和多线程问题。它基本上是通过真正快速地处理每个命令来实现并发。 因此,在这种情况下,我将使用流水线技术,因为它总是一个胜利,更多的是,您流水线的命令越多(因为您减少了阻塞读取次数)。     
单个操作确实会阻塞,但这并不重要,因为它们不应该长时间运行。听起来您正在检索的信息超出了您真正需要的信息-当您只需要500个时,HGETALL将返回100,000个项目。 尽管有可能完全使用散列是过早优化的一种情况,但是发送500个HGET操作可能会起作用(假设集合同时存储了散列和密钥)-使用常规密钥和MGET可能会更好。     
我认为您误解了流水线操作。发送所有命令时,它不会阻塞。它要做的只是缓冲命令,然后在最后一次全部执行它们,因此它们就像是一个命令一样被执行。决不会发生阻塞。 Redis
multi
/
exec
也是如此。与阻止/锁定Redis最接近的事情是使用
watch
进行乐观锁定,如果自调用
watch
以来已写入redis密钥,则将导致
exec
失败。 与在流水线块中调用
hget
500次相比,仅调用
hmget(\'hash-key\',*keys)
效率更高,其中
keys
是您要查找的500个哈希键的数组。这将导致对redis的单个调用,这与流水线操作相同,但是执行起来应该更快,因为您不会在ruby中循环。     

要回复问题请先登录注册