【Redis】-【应用篇】Redis我使用过的那些场景

session 共享

在 web 开发中,http 是无状态的协议,而为了保持会话状态,就需要维护一个列表,列表的数据格式为 key:value。

http 通过携带 key 进行访问,后台通过 key 获取 value 值,来确定此次 http 请求会话。

早期 该列表的维护保存在应用内存 session 中。在多机冗余部署的时候,会出现 session 共享的问题。业界有很多种解决方案,如 tomcat 配置 session 共享等。

使用 Redis 进行 session 集中管理是比目前较常用的一种方式。使用方式也很简单,使用 redis 中的 string 数据结构,就能够完成。

总结:通过集中存储 用户session 数据到Redis 中,所有需要进行认证的接口,都从该Redis 中获取 session 数据,进行认证判定。

简单日活统计

背景

待过的一家创业公司,给出的需求:简单的统计平台用户活跃数据(单位/天)。

需求分析
  • 1、首先用户每日登陆过至少一次,代表今日活跃。
  • 2、关键数据结构:时间、用户日活数据

设想一:使用Mysql 。

思路:每个用户,每日一条数据

存在问题:

  • 1、随着用户剧增,数据量也会疯狂增加。
  • 2、mysql 直接买的阿里云的,增加容量需要加钱
  • 3、数据量增加,统计sql 也会开始变慢,响应延迟开始变高。

设想一结论:从长远来看,不可取。

设想二:使用Mysql。

思路:所有用户每日只存一条数据。

分析:

  • 1、数据结构中需要指定一个字段用来存储所有用户的日活数据。
  • 2、通过二进制的格式存储,0代表今日未上线过,1代表今日已上线。
  • 3、通过计算用户主键对应的唯一数字作为偏移量,数据库中用户主键为数字自增,能够直接作为偏移量。

假设表结构如下

dateTime datetime ‘时间’
content varchar(m) ‘日活’

content 格式如下 0000010101 -> 表示:当前 dateTime 日期中,有3个人活跃。

不过很明显有个致命的问题,一个用户需要一个站位,1个varchar 站位1个字节,多少个用户多少个字节,且 varchar 最多 65532 个字节,明显不行。

假设表结构如下
dateTime datetime ‘时间’
content bigint(m) ‘日活’

如果通过数值,然后转换2二进制。如:id = 1 00 00 的用户进入活跃为1,则二进制位在1万位,对应的数字为 2^10000 ,超出想象

设想二结论:思路可以,通过Mysql 实现不靠谱。

设想三:使用文件存储。

思路:与设想二同,使用二进制格式存储。

分析:

  • 1、在Linux 系统中,1000 个用户的偏移大约 1k
    -rw-r–r--. 1 root root 1020 5月 12 22:31 20190515

    1 0000 个用户大约 10k ,可以得出 100 万用户大约 1M左右。

    从数据的存储上来说能够实现。但是存在一个问题,就是统计计算复杂,加上io操作的损耗,同样不可取。

设想三结论:对比设想二,数据存储得到了解决,但是统计变得复杂,不可取。

设想四:使用 Redis 作为存储介质。

思路:与设想二同,采取二进制存储结构。

分析:

  • 首先,Redis 中的数据结构 bitmap 就是直接使用的二进制存储结构进行存储。
  • 其次,Redis 中提供了 bitCount ,bitop 命令 能够进行统计。
  • Redis 针对二进制的操作,提供了设值 和计算的方法。简化了很多步骤,但是Redis 是否就适合,此时的应用场景?

我们通过 Redis 中 bitmap 操作的相关说明进行分析。

设值:SETBIT key offset value

官方介绍

When setting the last possible bit (offset equal to 232 -1) and the string value stored at key does not yet hold a string value, or holds a small string value, Redis needs to allocate all intermediate memory which can block the server for some time。

setbit 进行设值的时候,空间是动态分配的。也就是说,日活存量随着用户增加,占用的内存随着增加,无需一次性进行空间分配。这个棒棒哒。

我们来简单的验证一下,官方的说法是否就是正确的。

  • 记录当前 redis 数据内存空间占用。
    used_memory_human:856.30K
  • 模拟 最大 id 10 万的用户,并查看当前 Redis 数据内存空间占用
    SETBIT 20190515 100000 1
    used_memory_human:870.38K
  • 模拟 最大 id 1000 万的用户,并查看当前 Redis 数据内存空间占用
    SETBIT 20190515 100 0000 1
    used_memory_human:3.34M

验证结论:
1、SETBIT的空间分配是,动态分配的。
2、BitMap 空间占用小。
单单从 value 值来说,占用的内存空间 1000 0000 / 8 / 1024 / 1024 = 1.19M。加上key 占用的空间等。当用户达到 1000 0000,一条日活数据,也就占用大约 2.5M 的空间。
且setbit 偏移量最大为 2^32 -1 大约为 42 9496 7296(约42亿) ,value 占用内存空间最大为 512M。

统计:BITCOUNT key

官方介绍

Count the number of set bits (population counting) in a string.

统计指定bitmap 格式的key 中,二进制偏移被设置为1的数量。

也就是,(key -> value)20190515 -> 0010101010101,中1出现的次数。

我们可以通过该方法,统计某个时间点 日活数量。

BITCOUNT 能够直接进行计算,操作简便,那么其性能怎么样呢?

官方给出了,BITCOUNT 时间复杂度 :O(N)。可以理解随着偏移量增多,也就是用户量增多,计算时间会延长。那究竟时间是多长?官方举了个简单的例子进行描述。

456 字节的查询的时间花费和 GET,INCR 命令的 O(1)操作一样。
也就是 用户量 3648 几乎没什么影响。那在增加10 - 20 倍呢,经过简单测试,几乎也没什么影响。足以应对,小公司中的用户增长。

复杂统计:BITOP operation destkey key [key …]

官方介绍

The BITOP command supports four bitwise operations: AND, OR, XOR and NOT, thus the valid forms to call the command are:
BITOP AND destkey srckey1 srckey2 srckey3 … srckeyN
BITOP OR destkey srckey1 srckey2 srckey3 … srckeyN
BITOP XOR destkey srckey1 srckey2 srckey3 … srckeyN
BITOP NOT destkey srckey

BITOP 能够对多个 bitmap 进行位运算。通过位运算我们能够计算更复杂的计算。

比如:统计 20190515,20190516,20190517 这3天的日活总数。

20190515 -> 01010100000      3
20190516 -> 10000000000      1
20190517 -> 00000000111      3
----------------------------------
            11010100111      7

使用 BITOP OR DELAY_DAY_3 20190515 20190516 20190517 就能够得到 3日日活数据。

总结:使用 Redis 提供的 bitmap 数据结构,加上 BITCOUNT、BITOP 命令进行日活统计。

  • 数据存储
    日期(单位/日) : 用户ID作为偏移量 其中:0代表不活跃,1代表活跃
    如:20190515 000001010101010101
  • 数据统计:BITCOUNT
    使用BITCOUNT 计算 20190515 000001010101010101 中 1 的个数,能够得到 20190515 当天日活
  • 数据统计:BITOP
    使用 BITOP 能够计算,复杂的统计。

用户签到

背景

用户签到活动,每日一签,并计算用户周签到数,月签到数,达到标准进行奖励发放。

需要如下的数据展示,在这里插入图片描述
以及,后台的用户签到统计。

需求分析

设想一:Mysql,每个用户每天一条签到记录。

表结构:
sign_id bigint(10) 主键id
u_id bigint(10) 用户id
sign_time datetime 签到时间

从数据存储来说:1个用户,如果每天签到,一年假设 365 天,占用空间,大约:(8+8+8)* 365 = 8760 b = 0.0083 MB

从数据展示来说:针对没有签到的时间,没有记录,如果需要返回某月的,签到详细记录。没有签到的日期,需要补全,并返回日期数据到前台。

设想二:Redis 每个用户,所有的签到记录,只有1条数据。

使用 bitmap 数据格式保存数据。存入的数据格式为:用户唯一标识 : 签到记录

其中签到记录,起始时间为功能上线那天。之后根据时间天差,作为 offset 偏移量进行设值。

从数据存储来说:1个用户,如果每天签到,一年假设 365天,占用空间,大约:365 bit = 0.0000435 MB。

从数据展示来说:需要遍历某个偏移量之间的所有值获取每个偏移量的值。

结果

选择设想二,无论从空间占用,还是数据展示统计来说,redis 都是更优的选择。

关注点

在实现的过程中,这里计算的月签到数,需要使用到 BITCOUNT 命令。

BITCOUNT 用法:BITCOUNT key 【start】 【end 】

其中 start 和 end 代表的是字节 而不是 bit 。
例如:BITCOUNT SIGN_USER_1 0 1 查询的是 SIGN_USER_! 用户,从签到功能上线起 ,前8天内的签到统计。

所以在设计,数据存储的时候我们需要如下的存储方式:

在这里插入图片描述

首先 BITCOUNT 计算 8 个bit 起,一个月最多 31 天,使用 4 个字节 32 个 byte 存储1个月的签到数据,而此时 1个用户每年的数据占用空间变为 32 * 12 = 384 bit,和之前理想化的 365 bit 相比 相差无几。

使用 Redis 提高性能,提高系统相应速度

在后台管理系统中,我们使用的是 Shiro 权限控制框架。而针对权限控制,所需要的就是当前登录用户,所拥有的权限。通常 查询一个用户拥有的权限都是相对耗时的。在用户通过后台的鉴权时,保存用户相关权限到 redis 中,当用户进行后台操作时的验权步骤中,能够较少因为验权查询数据库导致的响应时间过长。

在我们系统中,app 首页 就进行了一系列的汇总统计,如 累计订单汇总,累计交易总数汇总,累计交易金额汇总等之类的复杂汇总查询。
查询sql耗时较长,导致首页数据响应延迟高。使用 Redis 对数据进行缓存,根据可容忍的时效性进行过期控制。提高接口除第一次加载数据到缓存外的响应速度。

Redis 实现分布式锁

Redis实现分布式锁

其他

Redis 的用法除了以上这些自身用过之外,还有很多用途。比如说:

  • 数据预热。
    这个数据预热也不能说完全没用过,像上面提到的复杂sql 计算,我在项目启动的时候,已经提前进行获取当前最新的数据统计结果存入到了 Redis 中,比如说,微信公众号 accessToken 和 js票据的获取,在应用启动的时候,同样回去加载到 Redis 中。
  • 解决高并发问题
    这个就真的没用过了。想要用,也得要有场景给我啊。不过,虽然没有过,想到是有想过。网上也有很多类似的场景,比如说什么商品秒杀,高并发下的防止超卖的问题啊。

代码地址 redis 分支

<div style="text-align:center;color:red;margin:0 auto;">更多精彩内容!</div>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis-shake是一款基于Go语言开发的Redis数据迁移工具。它能够在不停机的情况下将Redis数据从一个节点迁移到另一个节点,支持集群、单机以及主从架构的数据迁移。Redis-shake具有以下特点。 1. 快速高效:Redis-shake使用并行化的方式进行数据迁移,能够充分利用多核处理器和带宽资源,提供高性能的数据迁移速度。 2. 稳定可靠:Redis-shake经过了大规模的生产环境验证,已经得到了广泛的应用。它具备重试机制,能够自动处理网络中断等异常情况,保证数据迁移的稳定性和可靠性。 3. 灵活易用:Redis-shake支持多种数据源和数据目标的组合。它可以从Redis节点迁移到另一个Redis节点,也可以将数据迁移到其他存储系统,如MySQL、MongoDB等。同时,Redis-shake提供了丰富的配置选项,可以根据需要进行灵活配置和定制。 4. 兼容支持:Redis-shake能够兼容不同版本的Redis,包括Redis 2.x和Redis 3.x等。它支持迁移过程中的数据过滤、数据分片、数据压缩等功能,可以满足不同场景下的需求。 5. 开源免费:Redis-shake是一款开源工具,遵循Apache 2.0协议。它的源代码可以在GitHub上获取,用户可以基于其代码进行定制和扩展,且使用过程中没有任何费用。 总之,Redis-shake是一款强大且灵活的Redis数据迁移工具,通过它我们可以轻松实现Redis数据的迁移和备份等操作,同时保证数据的一致性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值