目录
标题:使用 Redis 记录用户连续登录天数的方法及代码分享
在本文中,我们将探讨如何使用 Redis 记录用户连续登录天数的问题。这是一个在面试中可能会遇到的场景题,同时也在实际的购物 APP 和游戏中经常出现。当用户连续签到达到一定天数时,可以获得奖励,因此准确记录用户的连续登录天数非常重要。
一、为什么不适合放在数据库中
如果将用户连续登录的数据放在数据库中,需要有一张表单独记录每一个用户在哪一天进行了签到。当用户量非常多时,这个表的数据会成倍增长,给数据库带来巨大的压力。因此,放在 MySQL 数据库中是不合适的。
二、Redis 的 bitmap 介绍
我们可以利用 Redis 提供的 bitmap(位图)来实现用户连续登录天数的记录。Bitmap 实际上是由一个一个的 bit 的二进制位所组成的数组,每一个位只能存 0 和 1。凡是这种二值统计,都可以用 bitmap 来实现,比如是否登录、是否签到、是否点赞等涉及到海量数据的场景。因为它所占的内存很小,并且统计速度也非常快。
Redis 的 bitmap 是由 string 类型所实现的,string 类型最大可以存储 512 兆。经过计算,512 兆最多可以存储 42 亿多个 bit 的位,所以哪怕有几亿个用户需要统计他们的连续签到,bitmap 也是可以存储得下的,并且所占的内存也是可以承受的。
三、存储方式及统计方法
(一)以每天维度存储
- 存储方式:
- 假如要统计 30 天的所有用户的连续登录,就需要存储 30 个 bitmap。以日期作为 bitmap 的 key,将用户的 id 映射到 bitmap 的偏移位。前提是用户 id 是唯一的数字,比如 id 为五的用户登录了,就可以把他的 bit 位存储为 1。第二天再给他存储一个 bitmap,到对应的用户的 id 登录了,同样存储为 1,以此类推。
- 统计方法:
- 以最后一个日期(当天)为起点,往前面的日期去推算。凡是碰到 1,就给用户的登录次数加 1;碰到 0,则不再给这个用户进行统计。这样就可以统计对应用户的连续登录次数。
- 适用场景:
- 这种方式统计每一天的所有用户效率比较高,但统计单个用户不太方便,需要循环每一个日期的 key。比较适用于用户量比较多的情况。
- 注意事项:
- 不建议统计超过 30 天的日期,一般游戏或签到也只统计 30 天。可以将当前 key 的过期时间设置为 30 天,超过 30 天自动过期,这样可以有效利用 Redis 的内存。
(二)以用户维度存储
作者准备了以用户维度来进行存储并且统计的代码,大家需要的话,可以在评论区扣 666 来进行获取查看。
以下是用 Java 语言实现以日期维度存储和统计用户连续登录天数的示例代码,使用了 Jedis 库来连接 Redis:
import redis.clients.jedis.Jedis;
public class RedisUserLoginDays {
public static void main(String[] args) {
// 连接 Redis
Jedis jedis = new Jedis("localhost", 6379);
// 假设用户 id 为 5,当前日期为 '20240926'
int userId = 5;
String today = "20240926";
// 将用户登录状态存储到当天的 bitmap 中
jedis.setbit(today, userId, true);
// 统计连续登录天数(假设今天是第 5 天,前四天用户都有登录)
int days = 0;
for (int i = 1; i < 5; i++) {
String prevDay = "202409" + (26 - i);
if (jedis.getbit(prevDay, userId)) {
days++;
} else {
break;
}
}
System.out.println("用户连续登录天数:" + (days + 1));
// 关闭连接
jedis.close();
}
}
对于以用户维度存储和统计的代码,可以根据上述思路进行类似的 Java 实现,具体的实现方式可以根据实际需求进行调整和扩展。
标签:存储,登录,天数,Redis,用户,bitmap,统计 From: https://blog.csdn.net/m0_57836225/article/details/142578323