1、Redis 各种数据类型的基本用法
String 普通字符串
Hash 类似于map
list 有序集合 还可以用作队列
set 无序集合,有去重效果
sorted set 有序去重集合
HyperLogLog 用于去重统计
2、各种使用场景
1、热点数据缓存
比如分布式 session,热点查询数据的缓存。这个就比较简单了,查询数据时先从 redis 里查询,如果查到了直接返回,如果没有查到再从数据库查询,把查询结果缓存到 redis,然后再返回结果
注意点:
缓存的雪崩
当大量的 key 在同一时间过期时,大量的请求都直接访问到数据库,这时数据库可能扛不住压力崩溃,导致服务不可用。
所以尽量避免将大量的 key 设置一个相同的过期时间
缓存的穿透
缓存穿透指的是,请求一个数据库中不存在的记录时,先从缓存中取,取不到,就会访问数据库,结果数据库也查不到记录,所以这时也不会将结果放入缓存,下次请求还会去访问数据库。
这种情况我们可以把空结果缓存到 reids 中
这位大佬讲的很清晰
2、分布式锁
redis 有个命令:setnx key value 当值不存在时就设置值,后面还可以为这个key 设置一个过期时间(需要事务)
因为 redis 是单线程的,同时又有上面这个命令,而且它还是个内存数据库,读写速度快,所以很适合用作分布式锁
可以将一下代码在一个事务中执行 EVAL script numkeys key [key ...] arg [arg ...]
if (redis.call('exists', KEYS[1]) == 0)
then redis.call('hset', KEYS[1], ARGV[2], 1);
redis.call('pexpire', KEYS[1], ARGV[1]);
return nil;
end;
if (redis.call('hexists', KEYS[1], ARGV[2]) == 1)
then redis.call('hincrby', KEYS[1], ARGV[2], 1);
redis.call('pexpire', KEYS[1], ARGV[1]);
return nil;
end;
return redis.call('pttl', KEYS[1]);
用 hash 类型存制定的 key(即分布式锁的键),value 为 1,然后设置一个过期时间,
如果要设置的 key 已存在就把 value + 1,从这里可知,这是一个可重入锁
3、list类型实现消息队列
生产者 lpush 在左边加入消息
消费者 rpop 从右边消费消息
客户端需要轮询去消息。如果没有消息客户端会死循环,这样太消耗CPU,最好是每次 sleep(100) 一下
4、布隆过滤器 可以进行去重
5、HyperLogLog 可以用于统计用户点击量
比如每有一个用户访问了某个接口我们可以把接口地址作为 key 用户的 id 作为 value,它可以自动去重记录总数量,不会保存用户的 id,所以占用空间较小,这也是为什么不用 set 来实现的原因。
6、幂等校验
比如有些接口不能重复提交,我们可以把接口名称和参数存入 redis,设置个过期时间。再收到相同的请求时,先查一下 redis 里是否存在,如果存在表示重复提交,拦截请求