Redis 日常使用场景总结

本篇文章来主要是想介绍下我们工作中使用redis的一些场景,先从最常用的开始说。
1. 用作缓存
比如:我们将一个比较复杂的查询结果直接缓存起来,下次同样条件的查询就可以直接从内存中取数据,这个时候我们常常使用的是string 这种数据类型。当然使用string 类型保存完整的数据不利于对其中单个字段的修改,如果要求对单个字段的修改可以使用hash这个数据类型,hash适合存储对象。
2. 队列
redis 提供了一种数据类型叫list,底层是quicklist(双向链表+ziplist)来实现的,利用这个list 数据类型可以轻松的实现一个队列。那队列有啥作用呢?
(1) 比如秒杀的场景可以使用队列来保存库存信息,防止超卖。
(2) 异步操作,比如用户在下完单后,系统会自动给用户发一条短信,那么这个发短信的信息可以先放到队列里面去,用户下完单后就直接返回成功而不是等到短信发完了再返回下单成功
(3) 流量削峰的作用,对于一些抢购的场景,可以将请求转入队列,队列的一端接受消息,另一端平滑的输出消息。
说起队列笔者在这里还想补充一些,就是延迟队列这个,比如一个业务场景就是用户下完单后,需要隔几秒钟给用户发一条短信,那么这个时候就可以使用到延迟队列,对于redis的延迟队列一般使用zset有序集合还实现,然后其中一个线程/进程来读取有序集合的第一个元素,不过使用redis做延迟队列也会存在一定的问题,比如没有确认机制,就比较难保证可靠性那些。
3 位图(二进制字符串)
位图的一些使用场景:
(1)用户是否签到
(2)用户在线状态
(3) 各种状态值
由于是直接操作位的,使得占用的空间比较小;另外还可以使用bitcount 来统计数据。
4. Redis 分布式锁
在单进程的系统中,当遇到并发情况下,会出现一些数据异常的问题,但是如果这些数据是需要保证唯一性的话,那我们就希望在同一时刻,只能有一个线程在执行这块代码,通常我们一般都是通过简单的加锁或同步来实现并解决这个问题。
但是以上都是单进程多线程的情况,如果出现多进程多线程,显然会出现问题。因为多线程之间是可以共享内存的,但是多进程之间是不行的,所以这个时候需要用到分布式锁。
当然分布式锁其实还有另外两种实现方案:
(1) 基于数据库实现分布式锁(这种笔者认为不太合适,会比较慢)
(2)基于zookeeper的分布式锁(尽管不知道原理是啥,但是最起码知道有这个东东)
php + redis 实现分布式锁
5. Redis 缓存雪崩,穿透
我们使用redis 做缓存,可能会存在缓存雪崩的情况, 在说怎么解决缓存雪崩之前,先说下啥是缓存雪崩,缓存雪崩就是短时间内大量的缓存失效,使得请求全部走向了数据库,解决方法有以下几种:
(1) 缓存过期时间加上一个随机值
(2)使用redis 分布式锁,防止大量请求全部到数据库
(3)缓存不过期,数据程序员在后台写脚本去刷新
(4) 限流
再来说下啥是缓存穿透: 就是用户请求数据库里面没有的数据,这个时候缓存肯定不会命中,就会直接到数据库里面取数据,然而数据库里面也没有,如果这种请求很多的话,就会给数据库造成一定的压力,
那笔者想到的解决方案就是,当查到没有这个数据的时候也缓存一下说明没有这个数据,说到这里笔者想起了布隆过滤器,这个东西就是如果得知一个key不存在那么就肯定不存在,得知一个key 存在的话就是可能存在,具体原理这里就不说了。
有啥不对的地方欢迎小伙伴们指出,看到会及时回复。

你可能感兴趣的:(Redis 日常使用场景总结)