Redis:哪些你还不知道的热门应用场景

Redis:哪些你还不知道的热门应用场景

Redis是一个高性能的键值存储数据库,它具有许多应用场景。

本篇文章将介绍一下redis的哪些热门应用场景,并介绍一下这些场景怎么实现它。

graph LR A(redis的应用场景) ---> B(缓存) A(redis的应用场景) ---> C(排行榜) A(redis的应用场景) ---> D(计数器应用) A(redis的应用场景) ---> E(共享Session) A(redis的应用场景) ---> F(分布式锁) A(redis的应用场景) ---> G(社交网络) A(redis的应用场景) ---> H(消息队列) A(redis的应用场景) ---> I(位操作) style B fill:#FFC0CB,stroke:#FFC0CB,stroke-width:2px style C fill:#FFA07A,stroke:#FFA07A,stroke-width:2px style D fill:#FFFFE0,stroke:#FFFFE0,stroke-width:2px style E fill:#98FB98,stroke:#98FB98,stroke-width:2px style F fill:#ADD8E6,stroke:#ADD8E6,stroke-width:2px style G fill:#00FFFF,stroke:#00FFFF,stroke-width:2px style H fill:#E6E6FA,stroke:#E6E6FA,stroke-width:2px style I fill:#D3D3D3,stroke:#D3D3D3,stroke-width:2px

一、缓存

我们一提到 redis,自然而然就想到缓存,国内外中大型网站都离不开缓存。

合理利用缓存,比如缓存热点数据,不仅可以提升网站访问速度,还可以降低数据库 DB 压力。

并且,Redis 相比于 memcached,还提供了丰富数据结构,并且提供 RDB 和 AOF 等持久化机制,强得一批。

1、使用 Redis 做缓存的查询步骤

  1. 检查缓存中是否存在所需数据:在进行数据库或其他开销较高的操作之前,首先检查 Redis 缓存中是否存在所需数据。你可以使用 Redis 的 GET 命令或者相应的客户端库函数来查询缓存。

  2. 查询命中:如果缓存中存在所需数据,即查询命中,可以直接从缓存中获取数据,避免了昂贵的数据库或其他操作。你可以将获取到的数据返回给应用程序进行处理。

  3. 查询未命中:如果缓存中不存在所需数据,即查询未命中,你需要从数据库或其他来源获取数据,并将其存储在 Redis 缓存中,以供后续查询使用。在这种情况下,你可以执行以下步骤:

    a. 发起数据查询:根据业务需求,通过数据库查询或其他方式获取所需数据。

    b. 将数据存储到 Redis 缓存中:使用 Redis 的 SET 命令或相应的客户端库函数,将查询到的数据存储在 Redis 缓存中。你可以选择设置合适的过期时间,以确保缓存数据在一定时间后自动失效。

    c. 返回数据给应用程序:将从数据库获取的数据返回给应用程序进行处理。

  4. 处理缓存失效:当缓存中的数据过期或被删除时,你需要处理缓存失效的情况。在查询缓存之前,你可以先检查数据库中是否存在数据,如果不存在,则不进行缓存查询,从而避免对数据库造成压力。

2、使用 Redis 做缓存的查询流程图

sequenceDiagram participant 应用程序 participant Redis缓存 participant 数据库 应用程序->>Redis缓存: 查询数据 Redis缓存->>应用程序: (缓存命中)返回缓存数据 应用程序->>Redis缓存: 查询数据 Redis缓存-->>应用程序: 缓存未命中 应用程序->>数据库: 发起数据查询 数据库-->>应用程序: 返回查询结果 应用程序->>Redis缓存: 存储数据到缓存 Redis缓存-->>应用程序: 数据存储成功 应用程序-->>应用程序: 处理数据

二、排行榜

当今互联网应用,有各种各样排行榜,如电商网站月度销量排行榜、社交APP 礼物排行榜、小程序投票排行榜等等。

Redis 提供zset数据类型能够实现这些复杂排行榜。

比如,用户每天上传视频,获得点赞排行榜可以这样设计

  1. 用户 Jay 上传一个视频,获得 6 个赞,可以酱紫:

    zadd user:ranking:2021-03-03 Jay 3

  2. 过了一段时间,再获得一个赞,可以这样:

    zincrby user:ranking:2021-03-03 Jay 1

  3. 如果某个用户 John 作弊,需要删除该用户:

    zrem user:ranking:2021-03-03 John

  4. 展示获取赞数最多的 3 个用户

    zrevrangebyrank user:ranking:2021-03-03 0 2

三、计数器应用

各大网站、APP 应用经常需要计数器功能,如短视频播放数、电商网站浏览数。

这些播放数、浏览数一般要求实时,每一次播放和浏览都要做加1操作,如果并发量很大对于传统关系型数据性能是一种挑战。

Redis 天然支持计数功能而且计数性能也非常好,可以说是计数器系统重要选择,在 Redis 中实现计数器可以使用 Redis 提供的 INCR 和 DECR 命令或相应的客户端库函数。

1、使用 Redis 实现计数器步骤

1、初始化计数器:如果计数器不存在,需要进行初始化。可以使用 SET 命令将计数器的初始值设置为0。

shell 复制代码
SET counter_key 0

2、增加计数:使用 INCR 命令将计数器的值增加指定的增量。

shell 复制代码
INCR counter_key

// 如果要增加的增量不是1,可以在 `INCR` 命令中指定增量值。

INCRBY counter_key 5

// 上述命令将计数器的值增加5。

3、减少计数:使用 DECR 命令将计数器的值减少指定的减量。

shell 复制代码
DECR counter_key

// 如果要减少的减量不是1,可以在 `DECR` 命令中指定减量值。

DECRBY counter_key 3

// 上述命令将计数器的值减少3。

4、获取计数器的值:使用 GET 命令获取计数器的当前值。

shell 复制代码
GET counter_key

// 上述命令将返回计数器的当前值。

四、共享Session

如果一个分布式 Web 服务将用户 Session 信息保存在各自服务器,用户刷新一次可能就需要重新登录了,这样显然有问题。

实际上,可以使用 Redis将用户 Session 进行集中管理,每次用户更新或者查询登录信息都直接从Redis 中集中获取。

1、使用 Redis 实现共享 Session 的步骤

1、配置 Redis:确保 Redis 服务器已正确配置,并且应用程序能够连接到 Redis。

2、创建 Session ID:当用户进行身份验证或访问您的应用程序时,为每个用户生成一个唯一的 Session ID。您可以使用随机生成的字符串或其他唯一标识符作为 Session ID。

3、存储 Session 数据:将用户的 Session 数据存储在 Redis 中。可以使用 Redis 的数据结构之一来存储 Session 数据,如字符串(String)或哈希(Hash)。将 Session ID 作为键,将用户的 Session 数据作为值进行存储。

  • 使用字符串存储:使用 SET 命令将 Session ID 作为键,用户的 Session 数据作为值进行存储。
redis 复制代码
SET session_id session_data
  • 使用哈希存储:使用 Redis 的哈希命令,如 HSET,将 Session ID 作为哈希的字段(field),用户的 Session 数据作为哈希的值(value)进行存储。
redis 复制代码
HSET session_key field value

4、设置 Session 过期时间:为了控制 Session 的生命周期,可以设置 Session 的过期时间,确保存储在 Redis 中的 Session 在一定时间后自动过期。您可以使用 Redis 的过期命令,如 EXPIRE 或 PEXPIRE,为存储的 Session 设置过期时间。

redis 复制代码
EXPIRE session_key seconds

// 该命令将在指定的秒数后自动使 Session 过期。

5、根据 Session ID 获取 Session 数据:当用户发送后续请求时,通过提供的 Session ID,从 Redis 中检索相应用户的 Session 数据。

  • 使用字符串存储:使用 GET 命令根据 Session ID 获取存储的 Session 数据。
redis 复制代码
GET session_id
  • 使用哈希存储:使用 Redis 的哈希命令,如 HGET,根据 Session ID 和字段名获取存储的 Session 数据。
redis 复制代码
HGET session_key field

6、更新 Session 数据:如果用户的 Session 数据发生变化,可以通过更新存储在 Redis 中的 Session 数据来保持同步。

  • 使用字符串存储:使用 SET 命令更新存储的 Session 数据。
redis 复制代码
SET session_id new_session_data
  • 使用哈希存储:使用 Redis 的哈希命令,如 HSET,更新存储的 Session 数据。
redis 复制代码
HSET session_key field new_value

7、删除 Session 数据:当用户注销或过期时,应从 Redis 中删除相应的 Session 数据。

  • 使用字符串存储:使用 Redis 的删除命令,如 DEL,根据 Session ID 删除存储的 Session 数据。
redis 复制代码
DEL session_id
  • 使用哈希存储:使用 Redis 的哈希命令,如 HDEL,根据 Session ID 和字段名删除存储的 Session 数据。
redis 复制代码
HDEL session_key field

2、使用 Redis 实现共享 Session 的流程图

sequenceDiagram participant 用户 participant 应用程序 participant Redis 用户->>应用程序: 身份验证或访问应用程序 应用程序->>应用程序: 生成唯一的 Session ID 应用程序->>Redis: 存储 Session 数据(字符串或哈希) 应用程序->>Redis: 设置 Session 过期时间 应用程序-->>用户: 返回响应,包含 Session ID 用户->>应用程序: 发送后续请求,提供 Session ID 应用程序->>Redis: 根据 Session ID 获取 Session 数据(字符串或哈希) Redis-->>应用程序: 返回存储的 Session 数据 应用程序-->>用户: 返回响应 用户->>应用程序: 更新 Session 数据 应用程序->>Redis: 更新存储的 Session 数据(字符串或哈希) Redis-->>应用程序: 数据更新成功 用户->>应用程序: 注销或过期 应用程序->>Redis: 删除存储的 Session 数据(字符串或哈希) Redis-->>应用程序: 数据删除成功

五、分布式锁

几乎每个互联网公司中都使用了分布式部署,分布式服务下,就会遇到对同一个资源并发访问技术难题,如秒杀、下单减库存等场景。

用 synchronize 或者reentrantlock 本地锁肯定是不行。如果是并发量不大话,使用数据库悲观锁、乐观锁来实现没啥问题。但是在并发量高场合中,利用数据库锁来控制资源并发访问,会影响数据库性能。

实际上,可以用 Redis setnx 来实现分布式锁。

1、使用SETNX来实现分布式锁的一般流程

1、客户端获取一个唯一的标识符,可以使用UUID或者其他生成唯一标识符的方法。

2、客户端调用Redis的SETNX命令,将该唯一标识符作为锁的键名(key)设置到Redis中,并设置一个适当的过期时间,以防止锁被永久占用。

  • 如果SETNX返回1,表示客户端成功获取到了锁,可以执行临界区代码。

  • 如果SETNX返回0,表示锁已经被其他客户端占用,客户端无法获取到锁,需要等待或进行其他处理。

3、客户端在临界区执行业务逻辑。

4、临界区代码执行完毕后,客户端调用Redis的DEL命令删除锁,释放资源。

2、使用SETNX来实现分布式锁的泳道图如下

sequenceDiagram participant Client as 客户端 participant Redis as Redis服务器 Client->>Redis: 生成唯一标识符 Client->>Redis: SETNX 锁键名(唯一标识符) alt 获取锁成功 Redis-->>Client: SETNX 返回1 Client->>Client: 执行临界区代码 Client->>Redis: DEL 锁键名 Redis-->>Client: 锁释放成功 else 锁已被占用 Redis-->>Client: SETNX 返回0 Client-->>Client: 等待或其他处理 end

这是一个简单的分布式锁实现流程,但需要注意以下几点:

  • 在设置锁的过期时间时,应根据业务需求合理设置,避免锁过早释放或过长占用。

  • 在删除锁时,应使用原子操作,例如使用Redis的DEL命令,以确保释放锁的同时不会被其他客户端获取。

  • 分布式锁需要考虑异常情况下的处理,例如客户端执行代码异常或崩溃时,需要确保锁最终能够被释放。

六、社交网络

赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等是社交网站必备功能,由于社交网站访问量通常比较大,而且传统关系型数据不太适保存这种类型数据。

Redis 提供数据结构可以相对比较容易地实现这些功能。

七、消息队列

消息队列是大型网站必用中间件,如 ActiveMQ、RabbitMQ、Kafka 等流行消息队列中间件,主要用于业务解耦、流量削峰及异步处理实时性低业务。

Redis 提供了发布/订阅及阻塞队列功能,能实现一个简单消息队列系统。

另外,==这个不能和专业消息中间件相比==;这里不多做赘述。

八、位操作

用于数据量上亿场景下,例如几亿用户系统签到,去重登录次数统计,某用户是否在线状态等等。

腾讯 10 亿用户,要几个毫秒内查询到某个用户是否在线,能怎么做?

千万别说给每个用户立一个 key,然后挨个记(你可以算一下需要内存会很恐怖,而且这种类似需求很多。这里要用到位操作------使用 setbit、getbit、bitcount 命令。

原理是:redis 内构一个足够长数组,每个数组元素只能是 0 和 1 两个值,然后这个数组下标 index 用来表示用户id(必须是数字哈),那么很显然,这个几亿长大数组就能通过下标和元素值(0 和 1)来构一个记忆系统。

建议:==要使用这个位操作建议去了解一下布隆过滤器和布谷鸟过滤器==;这里不多做赘述。

相关推荐
向前看-5 分钟前
验证码机制
前端·后端
Hacker_LaoYi34 分钟前
【渗透技术总结】SQL手工注入总结
数据库·sql
岁月变迁呀35 分钟前
Redis梳理
数据库·redis·缓存
独行soc36 分钟前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍06-基于子查询的SQL注入(Subquery-Based SQL Injection)
数据库·sql·安全·web安全·漏洞挖掘·hw
你的微笑,乱了夏天1 小时前
linux centos 7 安装 mongodb7
数据库·mongodb
工业甲酰苯胺1 小时前
分布式系统架构:服务容错
数据库·架构
超爱吃士力架2 小时前
邀请逻辑
java·linux·后端
独行soc2 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍08-基于时间延迟的SQL注入(Time-Based SQL Injection)
数据库·sql·安全·渗透测试·漏洞挖掘
White_Mountain3 小时前
在Ubuntu中配置mysql,并允许外部访问数据库
数据库·mysql·ubuntu
Code apprenticeship3 小时前
怎么利用Redis实现延时队列?
数据库·redis·缓存