Redis基础
1.Redis有那些数据结构
字符串、字典Hash、列表List、集和Set、有序集和SortedSet。
….加分项
BitMap、Geo、HyperLogLog、
应用场景补充
字符串:常规的key-value缓存应用。常用计数器:微博数,粉丝数
hash: 存储部分变更数据,如用户信息等。
list: 可以构建消息队列
set: 交集、并集、差集,去重,找共同的爱好……
sortedset: 通过score对元素进行优先排序,带权重的消息队列
2.大量key同一时间过期
如果大量的key在同一时间过期,那么到过期的时间点Redis会发生卡顿现象,严重的话会造成缓存雪崩,解决方法是在设置失效时间时加上一个随机值。
3.Redis分布式锁
分布式锁是为了解决多进程之间的同步,redis可以实现分布式锁。可以用setnx原子操作来获得锁(),抢到之后用expire给锁添加过期时间。
1 | setnx k v |
追问:如果setnx获取锁成功,但线程执行expire之前崩溃,会如何,怎样解决?
此时,这个锁将一直被持有,无法释放。可以用同时具有setnx和expire的原子指令***解决:
1 | set k v nx[key必须不存在] [ex t 秒级]/[px t 毫秒级] |
4.如何在Redis中查询大量的具有固定前缀的key
可以利用keys指令查询,但该指令会一次性查找全部符合条件的key,会造成卡顿(Redis是单线程的):
1 | keys [pattern] |
因为keys指令需要全部遍历,数据量很大的话,需要一定的执行时间。由于Redis是单线程,所以其他服务会暂停,直到keys指令结束。为避免此情况发生,可以使用scan指令,scan指令可以无阻塞的取出指定模式的key列表(每次执行会找到若干个符合条件的key),但会出现重复,所以客户端需要去重:
1 | scan cursor[0代表从头开始] [MATCH pattern] [COUNT num] |
由于scan不是一次性遍历(增量式迭代),所以在全部扫描完成时可能有些key会发生变化。
5.Redis异步队列
Redis可以实现异步队列,一般用List实现,rpush生产消息,lpop消费消息。当lpop没有消息可消费时,需要sleep一会儿重试。
除了sleep还可以使用blpop指令,在没有消息时,他会阻塞住直到消息到来。
一次生产,多次消费如何实现?
可以使用pub/sub主题订阅模式,可以实现1:N的消息队列
pub/sub有何问题
在消费者下线情况下,生产的消息会丢失,可以使用RabbitMQ。
如何实现延时队列
可以使用有序集和sortedset,将时间作为score,消息内容作为key,调用zadd来生产消息,消费者通过zrangebyscore指令获取N秒前的消息.
6.Redis持久化
Redis持久化有两种方式:RDB镜像全量持久化、AOF增量持久化。
RDB:
Redis每隔一段时间可以将所有数据备份到磁盘,Redis会fork一个子线程进行RDB操作,子线程创建后,父子线程共享数据段,父线程将继续提供服务,写脏的页面数据会和子线程分开(cow, copy on write)。cow数据未发生变化时,父子线程共享数据,一旦发生变化,子线程才会分配空间存储数据。
自动触发:配置文件中,可以配置经过多少次save就触发;
手动触发:通过bgsave命令,会fork一个子进程。
AOF:
将Redis执行的指令记录到磁盘,sync属性可以支持每条指令都写到磁盘,但代价较高。可以设置每秒sync,这样最多会丢失1s的数据。
AOF日志会随着时间不断变大,可以通过AOF重写解决。首先读取数据库中所有键值的状态,使用一条命令替代前面多条操作语句。使用bgrewriteaof命令进行重写,重写时会fork一个子进程进行重写,主进程将重写期间的命令放到重写缓冲区中,待重写完成将其添加到AOF文件中。
RDB无法实时持久化,AOF文件较大(AOF重写解决)。
7.Pipline是什么
普通的请求中,每次请求都对应一次IO操作等待(往返时延),而Pipline会将所有请求转化为一次IO操作(一次往返)。使用前提是指令之间没有因果相关性。
8.Redis的同步机制
Redis同步机制有两种:主从同步
主从同步:
- 从服务器向主服务器发送sync命令
- 主服务器收到sync命令,开始执行bgsave命令生成RDB文件,并用缓存开始记录此后执行的所有写命令
- 主服务器bgsave完成之后,向从服务器发送RDB文件,继续在缓存中记录写命令
- 从服务器收到RDB文件,丢弃所有旧数据,载入RDB
- 主服务器向从服务器发送缓存中的命令
- 从服务器载入RDB后开始接收命令请求,执行来自主服务器中的缓存命令
通过以上操作,全量同步完成,以后主服务器向从服务器发送所有的写操作进行增量同步。
9.Redis集群
Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。
Redis Cluster着眼于扩展性,在单个Redis内存不足时,使用Cluster进行分片存储。
10.Redis为什么快
数据放在内存中,而且其存储数据类似HashMap,所以速度很快
单线程,没有线程上下文切换开销
多路IO复用,可以一个线程监听多路IO
研究表明,redis的瓶颈在网络时延
11.Redis与memcached区别
- memcached只支持字符串,redis支持更丰富的数据类型
- redis支持数据持久化
- redis支持数据备份,即master-slave
12.redis数据过期回收
定期回收
没过一段时间去抽查一部分数据是否过期,过期就删除。
惰性删除
使用key时,先判断是否过期,过期则删除。
原文作者: NTJD
原文链接: http://yoursite.com/2020/08/13/Redis基础/
版权声明: 转载请注明出处(必须保留作者署名及链接)