likes
comments
collection
share

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

作者站长头像
站长
· 阅读数 30

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

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

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

redis的应用场景
缓存
排行榜
计数器应用
共享Session
分布式锁
社交网络
消息队列
位操作

一、缓存

我们一提到 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 做缓存的查询流程图

应用程序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。

SET counter_key 0

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

INCR counter_key

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

INCRBY counter_key 5

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

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

DECR counter_key

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

DECRBY counter_key 3

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

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

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 数据作为值进行存储。
SET session_id session_data
  • 使用哈希存储:使用 Redis 的哈希命令,如 HSET,将 Session ID 作为哈希的字段(field),用户的 Session 数据作为哈希的值(value)进行存储。
HSET session_key field value

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

EXPIRE session_key seconds

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

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

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

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

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

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

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

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

用户应用程序Redis身份验证或访问应用程序生成唯一的 Session ID存储 Session 数据(字符串或哈希)设置 Session 过期时间返回响应,包含 Session ID发送后续请求,提供 Session ID根据 Session ID 获取 Session 数据(字符串或哈希)返回存储的 Session 数据返回响应更新 Session 数据更新存储的 Session 数据(字符串或哈希)数据更新成功注销或过期删除存储的 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来实现分布式锁的泳道图如下

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

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

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

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

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

六、社交网络

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

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

七、消息队列

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

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

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

八、位操作

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

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

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

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

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