redis使⽤场景之位操作(⼤数据处理)
在学习redis的过程了,看到了redis还能⽤于⼤数据处理,具体场景如下:
腾讯10亿⽤户,要⼏个毫秒内查询到某个⽤户是否在线,你能怎么做?千万别说给每个⽤户建⽴⼀个key,然后挨个记(你可以算⼀下需要的内存会很恐怖,⽽且这种类似的需求很多,腾讯光这个得多花多少钱。。)
原理是:
redis内构建⼀个⾜够长的数组,每个数组元素只能是0和1两个值,然后这个数组的下标index⽤来表⽰我们上⾯例⼦⾥⾯的⽤户id(必须是数字哈),那么很显然,这个⼏亿长的⼤数组就能通过下标和元素值(0和1)来构建⼀个记忆系统,就能实现上述场景。⽤到的命令是:tbit、getbit、bitcount 先来说说tbit、getbit、bitcount这三个指令的⽤法:
在学习这⼏个命令之前,我们得先了解下redis中字符串的存储⽅式,redis中的字符串都是以⼆进制的⽅式进⾏存储的,⽐如说我执⾏如下命令:
我们知道 'a' 的ASCII码是 97。转换为⼆进制是:01100001。我们BIT相关命令都是对这个⼆进制数据进⾏操作
GETBIT
GETBIT命令可以返回key对应的value在offt(偏移)处的bit值,以上⽂提到的kk为例,a对应的⼆进制数据是01100001,所以当offt为0时,对应的bit值为0;offt为1时,对应的bit值为1;offt为2时,对应的bit值为1;offt为3时,对应的bit值为0,依此类推….,如下:
通过上述结果,可以看到offt从0到7,就是01100001,也就是说offt是从左往右计数的,也就是从⾼位往低位。当超过位数时,结果是0
BITCOUNT
BITCOUNT可以⽤来统计这个⼆进制数据中1的个数,如下:
官⽹上有⼀个⾮常有意思的案例:⽤户上线次数统计。节选部分原⽂如下:
SETBIT
我们通过SETBIT 命令将 andy中的 'a' 变成 'b' 应该怎么变呢?
也就是将 01100001 变成 01100010 (b的ASCII码是98),这个很简单啦,也就是将'a'中的offt 6从0变成1,将offt 7 从1变成0。如下图:
⼤家可能也发现了,每次SETBIT完毕之后,有⼀个(integer) 0或者(integer)1的返回值,这个是在你进⾏SETBIT 之前,该offt位的⽐特值。
另外使⽤ BITPOS 指令可以⽤来获取⼆进制位串中第⼀个1或者0的位置,如下: