美文网首页实用
巧用redis位图存储亿级数据与访问

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

作者: 不迷失 | 来源:发表于2017-06-16 20:08 被阅读2743次

业务背景

现有一个业务需求,需要从一批很大的用户活跃数据(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

如果key不存在,也会自动创建。

当然,如果某个位还不存在,redis也会自动填充。

可以通过getbit获取某个二进制位的值

getbit a 10 //获取键a的值上第10位的值(0或1两种状态)

这是所谓的位图。

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

//用户id123456是活跃用户
setbit a 123456 1
//用户id234567不是活跃用户
setbit a 234567 0

getbit a 123456

具体操作:

循环所有id列表,id作为offset,通过setbit写入该id是否活跃。

查询时,调用getbit a 123456即可

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

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

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

cat data.txt|redis-cli  --pipe

@不迷失|知识改善生活

微信公众号:不迷失Java技术

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

不迷失Java技术问答交流

@不迷失Java自学教学视频

不迷失java自学专栏.jpg qqketang_qrcode
腾讯课堂:http://bumishi.ke.qq.com baiduketang_qrcode
百度课堂:http://chuanke.com/s3377987.html

技术交流群:245130488

相关文章

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

    业务背景 现有一个业务需求,需要从一批很大的用户活跃数据(2亿+)中判断用户是否是活跃用户。由于此数据是基于用户的...

  • Android数据存储与访问

    Android数据存储与访问 Android数据存储与访问方式中的一个——文件存储与读写,当然除了这种方式外,我们...

  • Redis 服务器其他细节

    Redis优点: 少量数据存储,高速读写访问。通过数据全部in-momery 的方式来保证高速访问,同时提供数据落...

  • mysql与redis

    硬盘与内存 硬盘放置主体数据用于持久化存储,而内存则是当前运行的那部分数据;CPU访问内存而不是硬盘 redis出...

  • javascript设计模式——数据访问对象

    数据访问对象模式: 抽象和封装对数据源的访问与存储,DAO通过对数据源链接的管理方便对数据的访问与存储 代码实现:...

  • 【Redis缓存】- Redis数据结构、基本命令操作、持久化

    一、Redis 数据结构 要想使用 Redis 进行数据存储,首先需要了解 Redis 的数据结构,redis存储...

  • redis简介与安装

    redis使用场景: 1、登录会话存储:存储在redis中,与memcached相比,数据不会丢失。 2、排行版/...

  • Redis初识

    欢迎访问本人博客:http://wangnan.tech redis是一个速度非常快的非关系数据库,他可以存储键与...

  • 干货 | Redis 内存使用优化与存储

    干货 | Redis 内存使用优化与存储 Redis 常用数据类型 Redis 最为常用的数据类型主要有以下五种:...

  • Redis(02)-空间节约工具

    位图 Redis除了之前介绍的5中数据类型之外,我们还可以使用另一种数据结构,位图位图不是一个真实的数据类型,而是...

网友评论

    本文标题:巧用redis位图存储亿级数据与访问

    本文链接:https://www.haomeiwen.com/subject/sbumqxtx.html