redis 五种基本数据类型
- String
- List
- Hash
- Set
- SortedSet
redis 从海量数据里查询某一固定前缀的 key:
keys pattern:查找所有符合给定模式 pattern 的 key。
keys一次性返回所有的key
键的数量过大会使服务卡顿
scan cursor [MATCH pattern] [COUNT count]
(scan 每次执行都只返回少量元素)
scan 是基于游标的迭代器,需要基于上一次的游标,延续之前的迭代过程
以0为游标开始一次新的迭代,知道命令返回游标 0 完成一次遍历
不保证每次执行都返回指定数量的元素,支持模糊查询
一次返回的数量不可控,只能是大概率符合 count 参数
例:scan 0 match k1* count 10 (cursor 并不一定是递增的,因此获取到的key有可能重复)
redis 如何实现分布式锁
分布式锁是控制分布式系统或不同系统之间,共同访问共享资源的一种锁的实现
如果同一个系统或不同系统的主机之间共享了某个资源时往往需要互斥来防止彼此干扰,进而保证一致性
分布式锁需要解决的问题:
- 互斥性 任一时刻只能有一个客户端获取锁,不能同时有两个客户端获取到锁
- 安全性 锁只能被持有该锁的客户端删除,不能由其他客户端删除
- 死锁 获取锁的客户端因为某些原因而宕机而未能释放锁,其他客户端再也不能获取到锁而导致了死锁,此时需要有机制来避免这个问题的发生
- 容错 某一些节点宕机时,客户端依然能获取到锁和释放锁
如何实现?
SETNX key value : 如果key不存在则创建并赋值 (set if not exists)
时间复杂度 O(1) ,设置成功返回1,设置失败返回 0 , 不持之expire参数
如何解决 SETNX 长期有效问题?
EXPIRE key seconds 设置key 的生存时间,key 过期会被自动删除
缺点:原子性得不到满足
推荐方式:
SET key value [EX seconds] [PX milliseconds] [NX|XX]
EX seconds :设置 key 的过期时间为 second 秒
PX milliseconds : 设置键的过期时间为 millisecond 毫秒
NX:只在键不存在时,才对键进行设置操作
XX:只在键已存在时,才对键进行设置操作
大量key同时过期的注意事项
集中过期,由于清除大量的 key 很耗时,会出现短暂的卡顿现象
解决方法:在设置过期时间时,给key加上随机值
如何实现异步队列?
使用list作为队列,rpush产生队列,lpop消费消息
缺点:没有等待队列里有值就直接消费
弥补:可以通过在应用层引入 sleep 机制去调用 lpop 重试
BLPOP key [key…] timeout :在没有消息时阻塞直到队列有消息或超时
缺点:只能供一个消费者消费
推荐:pub/sub 主题订阅者模式
发送者(pub)发送消息,订阅者(sub) 接收消息
订阅者可以订阅任意数量的频道
subscribe mytpoic (订阅)
publish mytpoic “hello" (发布)
缺点:消息的发布是无状态的,无法保证可达