一、setbit是什么?
setbit是Redis提供的bitmap数据类型中的一条命令。bitmap数据类型用于表示二进制的位图,每一位表示0或1,可以用于记录某个元素是否出现过、某个用户是否在线等场景。
setbit命令用于设置指定位的值,可以设置为0或1。该命令有三个参数,分别是键名、偏移量、值。比如SETBIT mykey 7 1表示将mykey键的第7位设置为1。
SETBIT mykey 7 1
二、setbit的使用场景
bitmap数据类型虽然基于比特,但是可以当做一个整数类型来处理,因为其每个比特都只有0和1两种值。因此,虽然比特个数有限,但是可以存下大量的信息。
setbit命令可以用于以下场景:
1.在线用户统计:可以使用bitmap数据类型记录某个用户是否在线。为了便于统计在线用户数,可以使用bitcount命令统计比特位为1的个数。
SETBIT online_user 1001 1 # 代表用户1001在线 SETBIT online_user 2002 1 # 代表用户2002在线 SETBIT online_user 3003 1 # 代表用户3003在线 # 统计在线用户数 BITCOUNT online_user
2.物品去重:可以使用bitmap数据类型实现去重,简单有效。在需要去重的场合,利用setbit命令,将每个元素的状态用各自的比特位表示,比如用第i位表示元素i是否已存在。当一个元素需要插入时,先利用getbit命令确认元素是否存在(检查第i位的值),如果第i位的值为1,证明元素已经存在,直接返回;如果第i位的值为0,证明元素不存在,调用setbit命令将第i位的值设置为1。
# 插入元素 SETBIT existed_items 12345 1 # 判断元素是否存在 GETBIT existed_items 12345
三、setbit的性能分析
setbit命令实现了对指定位的原子性操作,是原子性最强的Redis命令之一,非常适合于高并发的场景。比如很多广告系统都采用bitmap数据类型进行去重,并将bitmap数据存储在Redis中,利用setbit命令插入新的广告ID,避免了传统的关系型数据库在高并发场景下的不稳定性。
同时,因为bitmap数据类型只有0、1两种取值,相较于字符串类型,可以大大降低内存消耗。另外,setbit命令只操作一个比特位,因此其执行时间非常短,对Redis性能影响不大。
四、setbit的使用技巧
1.利用位运算实现多个状态的存储:因为每个比特位只有0和1两种取值,可以利用相应位运算的结果来存储多个状态。比如利用与运算(&)可以判断指定的一组比特是否都为1,利用或运算(|)可以将指定的一组比特置为1。
# 利用与运算判断多个位是否为1 SETBIT mykey 3 1 # 将第3位设置为1 SETBIT mykey 7 1 # 将第7位设置为1 GET mykey # 输出结果为 00001001 # 判断第3、7位是否为1 GETBIT mykey 3 # 返回1 GETBIT mykey 7 # 返回1 GETBIT mykey 5 # 返回0 # 利用或运算设置多个位为1 SETBIT mykey 3 1 SETBIT mykey 7 1 SETBIT mykey 5 1 GET mykey # 输出结果为 00011001
2.使用psetex命令设置位的过期时间:虽然bitmap数据类型不支持设置过期时间,但是可以将setbit命令与psetex命令结合使用,来实现有限时间内使用bitmap数据类型临时存储信息的功能。比如可以利用bitmap数据类型记录某个广告ID的展示次数,同时使用psetex命令设置过期时间,避免了资源浪费。
# 设置某个广告ID的展示次数为10次 SETBIT AD_VIEW 12345 1 # 设置过期时间为1个小时 PSETEX AD_VIEW 3600000 "EXPIRED"
五、setbit的代码示例
# 设置第7位为1 SETBIT mykey 7 1 # 获取第7位的值 GETBIT mykey 7 # 判断多个比特是否为1 SETBIT mykey 3 1 SETBIT mykey 7 1 GET mykey # 结果为00001001 GETBIT mykey 3 # 返回1 GETBIT mykey 5 # 返回0 # 将多个位都设置为1 SETBIT mykey 3 1 SETBIT mykey 7 1 SETBIT mykey 5 1 GET mykey # 结果为00011001 # 利用psetex命令设置过期时间 SETBIT AD_VIEW 12345 1 # 设置过期时间为1个小时 PSETEX AD_VIEW 3600000 "EXPIRED"