Redis 可以应用于很多场景,这里列举几个经典的应用场景。
缓存是 Redis 最常见的应用场景。
Redis 有多种数据类型,以及丰富的操作命令,并且有着高性能、高可用的特性,非常适合用于分布式缓存。
缓存应用的基本原理,请参考 缓存基本原理 第四 ~ 第六节内容。
Redis 除了 5 种基本数据类型外,还支持 BitMap 和 BloomFilter(即布隆过滤器,可以通过 Redis Module 支持)。
BitMap 和 BloomFilter 都可以用于解决缓存穿透问题。要点在于:过滤一些不可能存在的数据。
什么是缓存穿透,可以参考:缓存基本原理
小数据量可以用 BitMap,大数据量可以用布隆过滤器。
使用 Redis 作为分布式锁,基本要点如下:
- 互斥性 - 使用
setnx
抢占锁。 - 避免永远不释放锁 - 使用
expire
加一个过期时间,避免一直不释放锁,导致阻塞。 - 原子性 - setnx 和 expire 必须合并为一个原子指令,避免 setnx 后,机器崩溃,没来得及设置 expire,从而导致锁永不释放。
更多分布式锁的实现方式及细节,请参考:分布式锁基本原理
根据 Redis 的特性,在实际应用中,存在一些应用小技巧。
使用 keys
指令可以扫出指定模式的 key 列表。
如果这个 redis 正在给线上的业务提供服务,那使用 keys
指令会有什么问题?
首先,Redis 是单线程的。keys
指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。
这个时候可以使用 scan
指令,scan
指令可以无阻塞的提取出指定模式的 key 列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用 keys
指令长。
不过,增量式迭代命令也不是没有缺点的: 举个例子, 使用 SMEMBERS
命令可以返回集合键当前包含的所有元素, 但是对于 SCAN
这类增量式迭代命令来说, 因为在对键进行增量式迭代的过程中, 键可能会被修改, 所以增量式迭代命令只能对被返回的元素提供有限的保证 。