暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

巧用redis位图存储亿级数据与访问

小白懂编程 2017-06-17
99

PS:向公众号发送关键字可以搜索文章哦!


业务背景

现有一个业务需求,需要从一批很大的用户活跃数据(2亿+)中判断用户是否是活跃用户。由于此数据是基于用户的各种行为日志清洗才能得到,数据部门不能提供实时接口,只能提供包含用户及是否活跃的指定格式的文本由业务方使用。

存在的挑战

  1. 海量数据如何尽可能用小的空间存储

  2. 如何能快速获取指定的数据

  3. 如何能快速的写入到目标存储

解决思路

  1. 由于我的业务中只需要根据某个用户id查询是否是活跃用户,不存在复杂的查询条件,所以用redis很合适。

  2. 如此大的数据如果用普通的键值对一一存储所以用户的活跃数据,即使每个key/value占用的内存很小,但数亿个key/value所花费的内存也每个节点随便都需要数G,业务中有很多类似的需求,都用这种方式的话,存储是个很大的问题。

这里使用redis的位操作来处理。
redis中所有数据都是二进制形式存储的。redis支持一个setbit和getbit操作,它支持在某个key的value上直接对某个二进制位操作,每个二进制位都只有0和1两种状态,正好可以表示用户是否活跃两种状态。

比如redis中键a的value数据的二进制码是
0110 0110 0001
它总共有12位,在redis的位操作中,二进制中的第几位称为offset。

我们可以这样将这个数据的第10个二进制位为1:
setbit a 10 1

这样,原来的数据就变成了
0110 0110 0101

这是所谓的位图。

那么我们考虑在redis中放一个key,它的value很大很大,大到它的二级制位数大于最大的用户id,redis中单个key的最大值是512M,可以达到40多亿bit,足够很多业务的需要了,我们以用户id作为offset,该offset的值作为是否活跃的值即可达到我们的目的。这样只需要一个key就能解决对所有数据的查询问题。假设我们的id最大值是1亿,那么我们需要一亿个bit就行了,相当于只需要1亿/(8*1024*1024)=11.9M内存。这里大家了解下二进制就能理解。


具体操作:

写入一个key,值是一亿个bit,足够容纳你的数据中最大offset就行,假如这个key的名称是a。


然后写入数据
//用户id123456是活跃用户
setbit a 123456 1
//用户id234567不是活跃用户
setbit a 234567 0

getbit a 123456

这样完美解决了存储和访问的问题!

  1. 接下来还要解决数据写入问题,这么多数据要怎样快速写入呢?使用redis官方提供的方式,将数据转成redis协议格式,使用redis-cli提供的pipe模式写入。
    一个命令的例子:

    *4$6setbit
    $9is_active
    $3123$11
    复制

    上面*4表示这个命令总共有四个参数:
    $数据表示下面的参数的字节数量,一个参数对应一个$
    以换行结尾,注意,换行必须是\r\n,linux中需要转换。
    得到redis协议格式的文本后,使用redis-clie执行。

cat data.txt|redis-cli --pipe




@不迷失|知识改善生活

微信公众号:java技术


专注技术研究与视频教学,分享有价值的技术与经验,关注程序员的发展!

技术博客:http://bumishi.cn

技术交流群:245130488

@不迷失教学视频


腾讯课堂:http://bumishi.ke.qq.com


百度课堂:http://chuanke.com/s3377987.html






 


推荐阅读


 

不迷失admin-manage:基于springboot的通用后台管理系统

不迷失博客V1.0正式发布了

Java软件工程师培训系列课程--Java入门第一课

Java软件工程师培训系列课程--Java入门第二课

Java软件工程师培训系列课程--Java入门第三课

Java软件工程师培训系列课程--Java入门第四课

Java软件工程师培训系列课程--Java入门第五课

Java软件工程师培训系列课程--Java入门第六课

Java软件工程师培训系列课程--Java入门第七课

Java软件工程师培训系列课程--Java入门第八课

Java软件工程师培训系列课程--Java入门第九课

Java软件工程师培训系列课程--Java入门第十课

Java软件工程师培训系列课程--Java入门第十一课

Java软件工程师培训系列课程--Java入门第十二课

Java软件工程师培训系列课程--Java入门第十三课

Java软件工程师培训系列课程--Java入门第十四课

Java软件工程师培训系列课程--Java入门第十五课

Java软件工程师培训系列课程--Java入门第十六课

Java自学系列课程17--接口




文章转载自小白懂编程,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论