Redis在高并发环境下的场景面试题

1. 如何记录上亿个用户的签到情况?

解释: 这个问题的突出是数据量大,并发高(如果好多用户同时进行签到),所以这里可以使用Redis进行解决
统计大数据量用户的签到情况可以使用redis来实现。
在redis中,有一个bitmap的数据类型可以统计0或者1的比特位(当然只能是0和1),bitmap本质是一个str类型,由于str类型支持最大为512mb,所以bitmap最大可以存储42亿多个比特位。
对于这种签到的场景,我想到两种方法,一种是利用日期作为bitmap的key,需要将用户的id进行映射到bitmap的比特位上,所以需要保证用户id是唯一的。
但是这种情况对于单个用户不是很友好,如果需要查这个用户的签到情况需要遍历多个bitmap进行查询。
还有一种方法是利用用户id作为bitmap的key,用1-30作为一个月的签到,或者用1-365作为一年的签到。
但是这种方法对于记录每天有多少用户签到了,需要遍历所有用户进行统计。

BitMap的实现原理

Redis 的 Bitmap(位图)本质上是基于字符串(String)类型实现的一种底层二进制位操作机制。
其核心原理在于:Redis 将一个 String 值视为由连续字节组成的二进制序列,每个字节包含 8 个 bit,每个 bit 可独立设为 0 或 1。
用户通过偏移量(offset)直接访问和修改特定位置的 bit,而无需操作整个字符串。
例如,执行 SETBIT key 100 1 会将 key 对应字符串中第 100 位(从 0 开始计数)设为 1,若原字符串长度不足,Redis 会自动扩容并用零填充。
这种设计利用了内存对齐与紧凑存储的优势,极大提升了空间效率——1 亿用户的每日活跃状态仅需约 12.5 MB 内存。
此外,Redis 提供 BITCOUNT(统计 1 的数量)、BITOP(执行位级逻辑运算)等命令,使 Bitmap 不仅能高效存储布尔状态,还能支持集合运算、交并差等复杂分析。
因此,Bitmap 在签到系统、实时去重、用户行为统计等场景中被广泛应用,兼具高性能与低开销的特点。

2. 给你一个亿的redis key,如何统计用户双方共同的好友?

这个问题首先想到的解决方法就是利用redis的set集合进行交集判断,但是在实际中,在一亿个数据中查找两个数据的交集也不是特别快。
所以可以以下几个方法进行计算:

  • 采用数据库分表分库的异步操作去查找
  • 采用neo4j技术,neo4j是专门查找数据库中两个数据的关系图的技术
  • 使用大数据工具:HBase+Hadoop的离线计算来查找

3. redis如何实现上亿用户实时积分榜?

对于这个问题,可以使用redis的zset进行实时排序,但是对于这种大数据量的实时排序单使用zset还是太慢了。
1 亿用户 ≈ 每条记录约 3050 字节(含 member 字符串),总内存可能达 35 GB 甚至更高。查询全量排名(如查某用户全局 rank)为 O(N),是不推荐的。
但 Top-K 查询(如前 1000)依然高效,因为 Redis 使用跳表,无需遍历全部。
所以可以采用zset分桶分治(分片)的方法来进行实时积分排行。其核心思想是将海量用户按某种规则(如用户 ID 哈希取模)分散到多个 ZSET 中,
例如 rank:0、rank:1 等,从而降低单个有序集合的规模,缓解内存和操作压力。
然而,这种分片方式仅适用于局部排行榜(如分区内的排名),无法高效支持全局 Top-K 查询,因为需合并所有分片结果,计算开销大。
因此,分片虽能提升单节点性能,却不适合需要精确全局排序的实时积分总榜场景,实际应用中常结合热数据缓存、异步更新或混合存储策略来平衡性能与功能需求。
这里其实也可以(如1-1000为一桶,1001-2000为一桶….)最后进行排序就可以。

Zset的实现原理

Redis 的 ZSET(Sorted Set,有序集合)是一种复合数据结构,其核心原理结合了 跳跃表(Skip List) 和 哈希表(Hash Table)。
每个成员(member)唯一,关联一个浮点数分数(score),ZSET 按 score 升序自动排序。哈希表用于 O(1) 时间内快速判断成员是否存在及获取其 score;
跳跃表则维护成员的有序链表结构,支持高效的范围查询、插入和删除,平均时间复杂度为 O(log N)。
例如,ZADD 通过哈希表检查 member 是否存在,再在跳表中定位插入位置;ZRANGE 则直接遍历跳表的有序节点。
这种双结构设计使 ZSET 在保证排序能力的同时,兼顾了成员查找与范围操作的性能。正因如此,ZSET 被广泛用于实时排行榜、带权重的任务队列等场景。
虽然内存开销略高于普通集合,但其在亿级数据下仍能高效支持 Top-K 查询(如前 100 名),是 Redis 实现高性能实时排序的核心数据结构。

4. 秒杀系统如何实现?

重点:流量激增,库存有限,单数和库存保持一致
所以,根据程序设计层级进行设计:

  • 页面层:将秒杀页面(秒杀商品图片,信息等)从动态渲染变为静态渲染,其目的是减轻后端的QPS并发量(动态渲染需要请求后端接口)
  • 转发层:合理使用Nginx进行负载均衡,Nginx一般一个都是3-5w,所以需要建立Nginx的集群
  • 网关层:合理利用GetWay进行服务降级,认证 + 熔断 + 流控等
  • 服务层:合理使用redis进行热点数据的预热,Lua 保证原子性,还可以使用MQ进行异步生成订单、通知等非核心链路,以达到削峰填谷的目的
  • 数据库层:要保证数据库的一致性