Redis的SETBIT、GETBIT和BITCOUNT有哪些使用场景?

3
在阅读了Can someone explain redis setbit command?http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/(在redis文档中引用),我仍然难以确定何时使用SETBITSET更好。以上来源似乎提到了使用SETBIT将事件和可数数据集以二进制形式存储的驱动因素,因为它可以极大地减少需要存储的数据量,同时仍然保持易于访问性。

将网站每日独特访问者按用户ID(通过从0偏移来识别)存储在位图100000001中——其中只有ID08的用户进行了访问——是否比仅设置时间戳:用户ID更好?请解释一下,谢谢。

非常抱歉这个问题显然是一个新手问题。

2个回答

2

比特是计算机使用的基本数据单位,Redis的BIT*命令允许您轻松操作位值。在原帖提供的示例中,使用位流主要会节省空间。

为每个登录保留一个密钥将至少需要密钥和值的大小,总计约10字节,而位流仅需要每个用户1个比特。


为了充分回答这个问题,您能否定义任何其他具体的用例,其中这种存储和操作水平将是明显的优势? - sjt003
那么这基本上是将保存的数据限制为可以用布尔值表示的数据吗? - sjt003
我们的年龄不就证明了几乎一切都可以数字化吗? :) - Itamar Haber
我在谈论数据类型——具体来说是像存储字符串、整数、布尔值、JSON文档等等。这个setbit系统强制你思考你的模式并以一种非常特定的方式建模你的数据存储,这种方式可能不适用于每个数据集。我的问题很具体,我正在寻找具体的答案,而不是像上面那样的大而无当的陈述。我只是试图让对话保持SO的主题。谢谢。 - sjt003
当然,这只是我的古怪幽默感 :) 位(bit)对于布尔类型显然是一个很明显的选择,但是你也可以轻松地存储整数(例如8位、16位...)或者任何其他格式。 - Itamar Haber

2
答案是:这取决于具体情况。在以上用例中,例如您每天有多少次登录(bitmask中有多少位是活跃的)等因素都会影响选择。如果您只有2个登录或任意用户ID,则最好只存储登录列表。但是,如果您拥有一个活跃的用户群体,并且60%的用户都是活跃的...那么使用1个比特(实际上平均比这更少,因为Redis仅将位掩码存储到达最高设置位(1)为止)比在列表中存储ID更节省内存。在列表中存储ID将导致使用例如32位(整数)来表示1位信息,这是浪费的。如果列表使用了一些带有显式指向相关节点的树概念,则可能会使用更多。由于内存相对昂贵/有限,我们希望事物也具有可扩展性,因此应该以最小的内存使用量为目标,同时仍然满足所有查询要求。因此,这是我会从情况到情况决定的事情。然而,使用位掩码允许对大型数据集进行非常快速的批处理过滤。假设您存储2个位掩码:1个是今天登录,1个是注册了通讯。通过使用位运算(处理器可以非常快地执行这些操作),您可以突然过滤出所有同时今天登录和注册了通讯的用户ID(由1的位位置表示)。因为位掩码的交集可以比两个ID有序列表的交集快至少一个数量级,所以您可以在数百万个用户上执行此操作并仍保持低于50ms。最后,使用位掩码允许进行实时分析,否则将无法进行实时分析,并且如果您预期列表中有许多项,则可以节省大量内存。请注意,这只是其中一种用途,还有许多其他用途(例如布隆过滤器)。

你知道我们如何计算 setbit 中的总数据吗?如果我使用 bitcount,它将需要 O(N) 的操作。 - Gujarat Santana

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接