当前位置: 首页 > article >正文

Redis的15种常用场景

1. 缓存

Redis最常见的用途是作为缓存,用于加速应用程序的响应速度。

频繁访问的数据放在内存中,可以减少对后端数据库的访问压力。如热点数据缓存(明星出轨),对象缓存、全页缓存、可以提升热点数据的访问速度。

SET user:1001 "{name: 'Alice', age: 30}" EX 3600  #设置1小时过期时间

2.分布式锁

日常开发中,我们经常会使用Redis做为分布式锁。可以在分布式系统中协调多节点对共享资源的访问,确保操作的原子性

用redisson写了个分布式锁模板:

   public <T> T executeWithLock(String lockKey, long timeout, Callable<T> action) {
        RLock lock = redissonClient.getLock(lockKey);
        boolean isLock = false;

        try {
            // 尝试获取锁,最大等待时间1秒,锁自动释放时间为timeout秒
            isLock = lock.tryLock(1, timeout, TimeUnit.SECONDS);
            if (isLock) {
                try {
                    // 执行传入的操作并返回结果
                    return action.call();
                } finally {
                    // 检查是否持有锁再释放
                    if (lock.isHeldByCurrentThread()) {
                        lock.unlock();
                    }
                }
            } else {
                System.out.println("未能获取锁,稍后重试");
                return null; // 或者抛出异常
            }
        } catch (InterruptedException e) {
            // 处理异常,恢复线程中断状态
            Thread.currentThread().interrupt();
            System.out.println("获取锁时被中断");
            return null; // 或者抛出异常
        } catch (Exception e) {
            // 处理其他异常
            System.out.println("执行操作时发生异常: " + e.getMessage());
            return null; // 或者抛出异常
        }
    }

3. 排行榜

redis 经常用来做排行榜,比如游戏积分实时排名、直播送礼排名等等。

可以基于Sorted Set来实现:

实时排名更新:

ZADD game_leaderboard 1000 "player_1"  # 插入分数
ZINCRBY game_leaderboard 50 "player_1" # 增加分数
ZREVRANGE game_leaderboard 0 9 WITHSCORES  # 获取Top10

4. 计数器

redis 也经常应用作为计数器,如文章的阅读量、微博点赞数等等。

# 用户 1001 点赞文章 123
SADD article:123:likes 1001

# 获取文章 123 的点赞数
SCARD article:123:likes

# 检查用户 1001 是否点赞了文章 123
SISMEMBER article:123:likes 1001

# 用户 1001 取消点赞文章 123
SREM article:123:likes 1001

5. 消息队列

Redis 可以作为消息队列使用,特别是使用其 List 数据结构以及相关的阻塞操作(BLPOP 和 BRPOP)。这些操作使得 Redis 成为一种简单、高效的消息队列解决方案,广泛用于消息传递、任务队列等场景。

假设你有一个队列 task_queue

生产者(Producer)向队列中添加任务:

bash
LPUSH task_queue "task1"
LPUSH task_queue "task2"

消费者(Consumer)从队列中取出任务,设置超时为 5 秒:

bash
BLPOP task_queue 5

6.会话管理

Redis 非常适合用作 会话管理,尤其是在分布式应用中。

  • 分布式会话:解决多服务器间 Session 共享问题。

  • 快速失效:通过 EXPIRE 实现自动会话清理。

HSET session:abBitmapc123 user_id 1001 last_active 1690000000
EXPIRE session:abc123 1800  # 30分钟过期

7. Bitmap 记录签到

Redis Bitmap是一种非常适合用于签到系统的数据结构。它通过位图(bit array)存储和操作数据,可以高效地处理大量的签到操作,特别适合于需要频繁更新并查询某个用户是否已签到的场景。

假设每个用户的签到状态通过 位图(Bitmap) 记录,每个用户对应一个唯一的 ID,通过设置和查询位来确定该用户是否签到。

设置用户 101 已签到
SETBIT sign_in_bitmap 101 1

比如查询用户 ID 为 101 的签到状态
GETBIT sign_in_bitmap 101

统计总共有多少用户已签到
BITCOUNT sign_in_bitmap

8. 地理位置服务

Redis 可以作为地理位置服务(Geolocation Service)的存储和查询引擎。Redis 提供了 GEO 数据结构,专门用于存储和查询地理位置信息。

比如类似场景:

用户打开 App,查找当前位置附近的餐厅或商店。

# 添加餐厅地理位置
GEOADD restaurants 13.361389 38.115556 "餐厅A"
GEOADD restaurants 15.087269 37.502669 "餐厅B"
GEOADD restaurants 9.191383 45.464211 "餐厅C"

# 用户当前位置:经纬度 (14, 37)
# 查找附近 100 公里内的餐厅
GEORADIUS restaurants 14 37 100 km
# 返回:餐厅A 餐厅B

9. 限流

Redis 适合用于限流(Rate Limiting)场景。限流的目的是控制某个操作在特定时间内的访问频率,比如 API 请求、短信发送、登录尝试等。Redis 的原子操作和高效性能使其成为实现限流的理想工具。

比如使用 Redis 实现滑动窗口计数器

  • 使用 Redis 的 ZSET(有序集合)存储每次请求的时间戳。

  • 每次请求时,移除时间窗口外的旧记录,并添加新记录。

  • 统计当前时间窗口内的记录数,如果超过阈值则拒绝请求。

def sliding_window_rate_limit(user_id, limit=10, window_size=60):
    """
    滑动窗口限流函数
    :param user_id: 用户 ID
    :param limit: 时间窗口内的最大请求数
    :param window_size: 时间窗口大小(秒)
    :return: True(允许请求)或 False(拒绝请求)
    """
    key = f"rate_limit:{user_id}"
    current_time = int(time.time())
    window_start = current_time - window_size

    # 移除时间窗口外的旧记录
    redis_client.zremrangebyscore(key, 0, window_start)

    # 添加当前请求的时间戳
    redis_client.zadd(key, {current_time: current_time})

    # 统计时间窗口内的请求数
    request_count = redis_client.zcard(key)

    if request_count > limit:
        return False  # 超过阈值,拒绝请求
    return True  # 允许请求

# 测试滑动窗口限流
user_id = "user123"
for i in range(15):
    if sliding_window_rate_limit(user_id, limit=10, window_size=60):
        print(f"请求 {i + 1}:允许")
    else:
        print(f"请求 {i + 1}:拒绝")
    time.sleep(1)  # 模拟请求间隔

10. 发布订阅

实时消息广播

# 订阅频道
SUBSCRIBE news_updates

# 发布消息
PUBLISH news_updates "Breaking: Redis 7.0 released!"

11. 延迟任务(Delayed Task)

Redis 可以作为延迟任务的实现工具。

  • 基于 Sorted Set 的延迟任务。

利用 Sorted Set 的 有序性 和 范围查询 特性,将任务的执行时间作为分数(score),任务数据作为成员(member),定时轮询获取到期的任务。

-- 添加延迟任务:
ZADD delayed_tasks <timestamp> "task_data"
-- 定时轮询获取到期任务
ZRANGEBYSCORE delayed_tasks 0 <current_timestamp>

12.全局ID

在分布式系统中生成唯一ID。

基于 INCR:

INCR global_id  # 返回唯一ID

基于雪花算法:

SET global_id_snowflake 0
INCR global_id_snowflake

13. 推荐模型

基于用户行为推荐商品。

基于Sorted Set:

ZADD recommendations:user1001 0.9 "product_1" 0.8 "product_2"
ZRANGE recommendations:user1001 0 9 WITHSCORES

14. 用户关注

之前在第一个公司上班的时候,看到代码,有使用redis去维护用户关注、粉丝的关系。

SADD user:1001:followers "user2"
SADD user:1002:following "user1"

15. 用户消息时间线(Timeline)

Redis适合实现用户消息时间线(Timeline)功能.用户消息时间线通常用于展示用户动态、朋友圈、微博等场景,核心需求是按时间顺序存储和展示用户的相关消息或动态。

-- 使用 LPUSH 将新消息插入到时间线的头部:
LPUSH timeline:user1001 "New post: Hello, Redis!"

-- 使用 LRANGE 获取指定范围内的消息:
LRANGE timeline:user1001 0 9  # 获取最新的10条消息

http://www.kler.cn/a/554611.html

相关文章:

  • 嵌入式C语言之快速排序方法实现原理
  • 用LightRAG+智谱GLM-4提升政务对话精度:从知识图谱到精准问答的实战指南
  • AI前端开发:拥抱未来,规划职业新高度
  • Unix-进程
  • 深入理解WebSocket接口:如何使用C++实现行情接口
  • C++ STL中的reverse/unique/sort/lower_bound/upper_bound函数使用
  • 上海市计算机学会竞赛平台2025年1月月赛丙组音乐播放
  • 机器学习_12 逻辑回归知识点总结
  • 【精调】LLaMA-Factory 快速开始1: Meta-Llama-3.1-8B-Instruct
  • 【QT】第一个 QT程序(对象树)
  • Moonshot AI 新突破:MoBA 为大语言模型长文本处理提效论文速读
  • UEFI Spec 学习笔记---9 - Protocols — EFI Loaded Image
  • [特殊字符]边缘计算课程资料整理|从零到实战全攻略[特殊字符]
  • 【Linux】【网络】不同子网下的客户端和服务器通信
  • 爬虫FirstDay01-Request请求模块详解
  • 网易严选DevOps实践:从传统到云原生的演进
  • 如何利用ArcGIS Pro打造萤火虫风格地图
  • 二叉树层序遍历的三种情况(总结)
  • 蓝桥杯备考:递归初阶
  • Vue.js Vue 测试工具:Vue Test Utils 与 Jest