今年遇到的PHP面试题--Redis
Redis
Redis有哪些常用数据类型
怎么用Redis统计上亿访问量的日活跃用户
Bitmap
HyperLogLog
两者区别
Redis怎么实现分布式锁
set key value [EX seconds] [PX milliseconds] [NX|XX]
EX seconds:设置失效时长,单位秒
PX milliseconds:设置失效时长,单位毫秒
NX:key不存在时设置value,成功返回OK,失败返回(nil)
XX:key存在时设置value,成功返回OK,失败返回(nil)
Redis Cluster集群获取key对应的value的流程
redis cluster模式采用了无中心节点的方式来实现,每个主节点都会与其它主节点保持连接。节点间通过gossip协议交换彼此的信息,同时每个主节点又有一个或多个从节点。
客户端连接集群时,直接与redis集群的每个主节点连接,根据hash算法取模将key存储在不同的哈希槽上。
在集群中采用数据分片的方式,将redis集群分为16384个哈希槽。
每个节点会保存一份数据分布表,节点会将自己的slot信息发送给其他节点,节点间不停的传递数据分布表。
Redis Cluster集群中某个节点故障了该怎么获取数据
Redis Cluster集群怎么扩容
Redis主从数据库怎么同步数据
全量同步
当从节点启动时,会向主节点发送SYNC命令。
主节点接收到SYNC命令后,开始在后台执行保存快照的命令生成RDB文件,并使用缓冲区记录此后执行的所有写命令。
主节点快照完成后,将快照文件和所有缓存命令发送给集群内的从节点,并在发送期间继续记录被执行的写命令。
主节点快照发送完毕后开始向从节点发送缓冲区中的写命令。
从节点载入快照文件后,开始接收命令请求,执行接收到的主节点缓冲区的写命令。
增量同步
Redis的数据持久化有哪些方式
RDB
手动触发:save、bgsave命令
自动触发:在Redis的配置文件中配置触发条件
RDB文件是一个紧凑的二进制压缩文件,是Redis在某个时间点的全部数据快照。所以使用RDB恢复数据的速度远远比AOF的快,非常适合备份、全量复制、灾难恢复等场景。
每次进行bgsave操作都要执行fork操作创建子经常,属于重量级操作,频繁执行成本过高,所以无法做到实时持久化,或者秒级持久化。
AOF
手动触发:使用bgrewriteaof命令。
自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage配置确定自动触发的时机。
命令追加(append):所有写命令都会被追加到AOF缓存区(aof_buf)中。
文件同步(sync):根据不同策略将AOF缓存区同步到AOF文件中。
文件重写(rewrite):定期对AOF文件进行重写,以达到压缩的目的。
数据加载(load):当需要恢复数据时,重新执行AOF文件中的命令。
always:每次写入缓存区都要同步到AOF文件中,硬盘的操作比较慢,限制了Redis高并发,不建议配置。
no:每次写入缓存区后不进行同步,同步到AOF文件的操作由操作系统负责,每次同步AOF文件的周期不可控,而且增大了每次同步的硬盘的数据量。
eversec:每次写入缓存区后,由专门的线程每秒钟同步一次,做到了兼顾性能和数据安全。是建议的同步策略,也是默认的策略。
持久化的速度快,因为每次都只是追加,rdb每次都全量持久化。
数据相对更可靠,丢失少,因可以配置每秒持久化、每个命令执行完就持久化
灾难性恢复的时候过慢,因为aof每次都只追加原命令,导致aof文件过大,但是后面会rewrite,但是相对于rdb也是慢的。
会对主进程对外提供请求的效率造成影响,接收请求、处理请求、写aof文件这三步是串行原子执行的。而非异步多线程执行的。Redis单线程!
Redis过期键回收策略
定期删除
惰性删除
定期删除
惰性删除
Redis内存淘汰策略
淘汰策略
noeviction:当内存使用超过配置的时候会返回错误,不会驱逐任何键
allkeys-lru:加入键的时候,如果过限,首先通过LRU算法驱逐最久没有使用的键
volatile-lru:加入键的时候如果过限,首先从设置了过期时间的键集合中驱逐最久没有使用的键
allkeys-random:加入键的时候如果过限,从所有key随机删除
volatile-random:加入键的时候如果过限,从过期键的集合中随机驱逐
volatile-ttl:从配置了过期时间的键中驱逐马上就要过期的键
volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键
allkeys-lfu:从所有键中驱逐使用频率最少的键
LRU算法
LRU
算法需要一个双向链表来记录数据的最近被访问顺序,但是出于节省内存的考虑,Redis
的LRU
算法并非完整的实现。Redis
并不会选择最久未被访问的键进行回收,相反它会尝试运行一个近似LRU
的算法,通过对少量键进行取样,然后回收其中的最久未被访问的键。通过调整每次回收时的采样数量maxmemory-samples
,可以实现调整算法的精度