Redis:哪些你还不知道的热门应用场景
Redis是一个高性能的键值存储数据库,它具有许多应用场景。
本篇文章将介绍一下redis的哪些热门应用场景,并介绍一下这些场景怎么实现它。
一、缓存
我们一提到 redis,自然而然就想到缓存,国内外中大型网站都离不开缓存。
合理利用缓存,比如缓存热点数据,不仅可以提升网站访问速度,还可以降低数据库 DB 压力。
并且,Redis 相比于 memcached,还提供了丰富数据结构,并且提供 RDB 和 AOF 等持久化机制,强得一批。
1、使用 Redis 做缓存的查询步骤
-
检查缓存中是否存在所需数据:在进行数据库或其他开销较高的操作之前,首先检查 Redis 缓存中是否存在所需数据。你可以使用 Redis 的 GET 命令或者相应的客户端库函数来查询缓存。
-
查询命中:如果缓存中存在所需数据,即查询命中,可以直接从缓存中获取数据,避免了昂贵的数据库或其他操作。你可以将获取到的数据返回给应用程序进行处理。
-
查询未命中:如果缓存中不存在所需数据,即查询未命中,你需要从数据库或其他来源获取数据,并将其存储在 Redis 缓存中,以供后续查询使用。在这种情况下,你可以执行以下步骤:
a. 发起数据查询:根据业务需求,通过数据库查询或其他方式获取所需数据。
b. 将数据存储到 Redis 缓存中:使用 Redis 的 SET 命令或相应的客户端库函数,将查询到的数据存储在 Redis 缓存中。你可以选择设置合适的过期时间,以确保缓存数据在一定时间后自动失效。
c. 返回数据给应用程序:将从数据库获取的数据返回给应用程序进行处理。
-
处理缓存失效:当缓存中的数据过期或被删除时,你需要处理缓存失效的情况。在查询缓存之前,你可以先检查数据库中是否存在数据,如果不存在,则不进行缓存查询,从而避免对数据库造成压力。
2、使用 Redis 做缓存的查询流程图
二、排行榜
当今互联网应用,有各种各样排行榜,如电商网站月度销量排行榜、社交APP 礼物排行榜、小程序投票排行榜等等。
Redis 提供zset数据类型能够实现这些复杂排行榜。
比如,用户每天上传视频,获得点赞排行榜可以这样设计:
-
用户 Jay 上传一个视频,获得 6 个赞,可以酱紫:
zadd user:ranking:2021-03-03 Jay 3
-
过了一段时间,再获得一个赞,可以这样:
zincrby user:ranking:2021-03-03 Jay 1
-
如果某个用户 John 作弊,需要删除该用户:
zrem user:ranking:2021-03-03 John
-
展示获取赞数最多的 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 的流程图
五、分布式锁
几乎每个互联网公司中都使用了分布式部署,分布式服务下,就会遇到对同一个资源并发访问技术难题,如秒杀、下单减库存等场景。
用 synchronize 或者reentrantlock 本地锁肯定是不行。如果是并发量不大话,使用数据库悲观锁、乐观锁来实现没啥问题。但是在并发量高场合中,利用数据库锁来控制资源并发访问,会影响数据库性能。
实际上,可以用 Redis setnx 来实现分布式锁。
1、使用SETNX来实现分布式锁的一般流程
1、客户端获取一个唯一的标识符,可以使用UUID或者其他生成唯一标识符的方法。
2、客户端调用Redis的SETNX命令,将该唯一标识符作为锁的键名(key)设置到Redis中,并设置一个适当的过期时间,以防止锁被永久占用。
-
如果SETNX返回1,表示客户端成功获取到了锁,可以执行临界区代码。
-
如果SETNX返回0,表示锁已经被其他客户端占用,客户端无法获取到锁,需要等待或进行其他处理。
3、客户端在临界区执行业务逻辑。
4、临界区代码执行完毕后,客户端调用Redis的DEL命令删除锁,释放资源。
2、使用SETNX来实现分布式锁的泳道图如下
这是一个简单的分布式锁实现流程,但需要注意以下几点:
在设置锁的过期时间时,应根据业务需求合理设置,避免锁过早释放或过长占用。
在删除锁时,应使用原子操作,例如使用Redis的DEL命令,以确保释放锁的同时不会被其他客户端获取。
分布式锁需要考虑异常情况下的处理,例如客户端执行代码异常或崩溃时,需要确保锁最终能够被释放。
六、社交网络
赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等是社交网站必备功能,由于社交网站访问量通常比较大,而且传统关系型数据不太适保存这种类型数据。
Redis 提供数据结构可以相对比较容易地实现这些功能。
七、消息队列
消息队列是大型网站必用中间件,如 ActiveMQ、RabbitMQ、Kafka 等流行消息队列中间件,主要用于业务解耦、流量削峰及异步处理实时性低业务。
Redis 提供了发布/订阅及阻塞队列功能,能实现一个简单消息队列系统。
另外,==这个不能和专业消息中间件相比==;这里不多做赘述。
八、位操作
用于数据量上亿场景下,例如几亿用户系统签到,去重登录次数统计,某用户是否在线状态等等。
腾讯 10 亿用户,要几个毫秒内查询到某个用户是否在线,能怎么做?
千万别说给每个用户立一个 key,然后挨个记(你可以算一下需要内存会很恐怖,而且这种类似需求很多。这里要用到位操作------使用 setbit、getbit、bitcount 命令。
原理是:redis 内构一个足够长数组,每个数组元素只能是 0 和 1 两个值,然后这个数组下标 index 用来表示用户id(必须是数字哈),那么很显然,这个几亿长大数组就能通过下标和元素值(0 和 1)来构一个记忆系统。
建议:==要使用这个位操作建议去了解一下布隆过滤器和布谷鸟过滤器==;这里不多做赘述。