刷题:OK
-
第8题:redis数据淘汰机制? 当Redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。 1.volatile-lru:从已设置过期的数据集中挑选最近最少使用的淘汰。 2.volatile-ttr:从已设置过期的数据集中挑选将要过期的数据淘汰。 3.volatile-random:从已设置过期的数据集中任意挑选数据淘汰。 4.allkeys-lru:从数据集中挑选最近最少使用的数据淘汰。 5.allkeys-random:从数据集中任意挑选数据淘汰。 6.noenviction:禁止淘汰数据。 redis淘汰数据时还会同步到aof。
-
第9题:Redis集群的成熟方案。RedisCluster sentinel,cluster,主从。Codis
4.redis的5种对象和8种数据结构?14-70 、 每种对象结构由对应编码的数据结构组成。8种数据编码以及8种底层结构。 1-int/存储long类型的整数 2-embstr/embstr编码的简单动态字符串 3-raw/简单动态字符串SDS 4-ziplist/压缩列表 5-linkedisk/双端链表 6-hashtable/HT/字典 7-intset/整数集合 8-skiplist/字典+跳跃表 对象结构共有5个属性: type:该对象什么类型。 encoding:该对象使用的底层数据结构 ptr:指向底层数据结构的指针 refcount:引用计数,用于内存回收和对象共享 lru:对象最后一次被访问的时间。空转时长:当前时间-lru时间。
第二题:Redis缓存雪崩,缓存穿透如何解决? 什么事redis缓存雪崩?数据未加载,或者缓存大面积失效,导致大量请求打到数据库导致数据库CPU和内存负载过高,甚至宕机。 预防缓存雪崩:1redis集群高可用性方案:Redis sentinel,Redis Cluster。2.缓存降级,利用本地缓存ehcache,对服务的限流,隔离,降级。3.Redis备份/主从 4.快速预热。5.不存在的数据设置默认值。 4.提前演练, 什么是缓存穿透?Redis缓存和Mysql不存在的数据,每次请求都到数据库查询,造成缓存穿透。
第6题:Redis集群,Cluster,Sentinel,读写分离的区别? Cluster:将集群分为16838个哈希槽,比如5个节点:第一个节点为0~3276号哈希槽,依此类推。增加节点时5个节点分别分槽给新的第6个节点;删除第五个节点时将节点哈希槽分配给其他节点,最终删除空哈希槽的节点。 Sentinel:一个Sentinel发送心跳监控其他Sentinel进程和Redis主从,主观下线和客观下线/一半以上。 读写分离:Redis主从模式。
第17题:Redis如何解决key冲突。 redis集群的业务隔离,良好的key命名规则:业务名称,系统名称,模块名称,关键词等。
Redis哨兵、集群的设计原理和区别?/sentinel,cluster sentinel和Cluster。 cluster:1万6千多个哈希槽。 sentinel:每秒发送心跳给集群中的主从redis服务器,当主服务器宕机后,从服务器转为主服务器。
Redis有哪些数据结构?底层的编码有哪些?有序链表采用了哪些不同的编码?14-70
-
Redis失效key清理策略: 1。立即清理:创建回调事件,key过期立即删除。缺点:消耗CPU。 2。惰性清理:读写过期key时清理。缺点:浪费内存。 3。定期清理:每隔一段时间清理失效key,是立即清理与惰性清理的折中方案。 redis惰性清理与定期清理配合使用。 redis.conf中 hz 默认值10。每秒执行10次后台任务。
-
redis的哨兵机制,sentinel。 监控:sentinel监控所有主redis,从redis,其他sentinel。 提醒:redis故障时,通过API通知。 故障转移:当主redis故障时,失效主redis的从redis升级为主redis。 主观下线:有一半以上的sentinel认为主redis故障。客观下线:一个sentinel认为主redis故障。 每个sentinel以每秒一次向其他主从redis,sentinel发送ping命令。
-
redis的并发竞争问题时什么?如何解决?redis事务的CAS方案? 什么是redis并发竞争:多个redis客户端同时设置key引起的并发问题。 解决redis并发竞争key:分布式锁,redis,mysql,Zookeeper。 消息队列:并行读写进行串型化。 redis事务命令:EXE,MULTI,WATCH,DISCARD. WATCH命令提供CAS,被WATCH监控的key改动过,执行EXEC时返回失败。客户端要在循环里判断失败重试。
-
redis队列使用场景。 List用在排行榜等。
-
列举一个redis客户端的并发模型。 Jedis,redisson,lettuce。 Jedis:对Redis进行并发访问时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,由于客户端连接混乱造成。有2种解决方法:Jedis对Redis连接进行池化,同时读写采用synchronized加锁。服务器角度,利用setnx实现锁。如某客户端要获得一个名字list的锁,客户端使用下面的命令进行获取。 Jedis使用阻塞的I/O,不支持异步。Jedis客户端实例不是线程安全的,需要通过连接池来使用Jedis。 Redisson:使用非阻塞的I/O和基于Netty框架的事件驱动,是异步的。Redisson的API是线程安全的,可以操作单个Redisson连接来完成各种操作。 lettuce:基于Netty框架的事件驱动,Lettuce的API是线程安全的。支持集群,Sentinel,管道和编码器。
第8题:Redis有哪些集群模式,各自的区别? Cluster:将集群分为16838个哈希槽,比如5个节点:第一个节点为0~3276号哈希槽,依此类推。增加节点时5个节点分别分槽给新的第6个节点;删除第五个节点时将节点哈希槽分配给其他节点,最终删除空哈希槽的节点。 Sentinel:一个Sentinel发送心跳监控其他Sentinel进程和Redis主从,主观下线和客观下线/一半以上。 读写分离:Redis主从模式。
-
第15题.AOF如何缩减自身文件大小。 Aof文件重写机制。fork出一条新进程来遍历进程内存中的数据,每条记录对应一条set语句,写到临时文件中,然后再替换到旧的日志文件(类似rdb的操作方式)。默认触发是当aof文件大小是上次重写后大小的一倍且文件大于64M时触发。
-
第16题.AOF缩减自身文件大小的时候,数据库来了新的操作怎么办? 新的操作写入旧的AOF文件,瘦身完成后新的操作写入瘦身后的AOF文件。
-
25.分布式下redis如何保证线程安全。 Redis单线程单进程,将并发访问改为串型访问。
-
33.如何搭建redis集群。 1.twemproxy 2.codis,目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在 节点数量改变情况下,旧节点数据可恢复到新hash节点。 3.Redis cluster3.0自带的集,特点在于他的分布式算法不是一致性hash,而是hash槽的概念,以及自身支持节点设置从节点。 4.redis sentinel:sentinel进程发送每秒ping检测给主从Redis以及其他sentinel进程。如果主Redis宕机升级对应Slave-Redis为主Redis。客观下线:一半以上sentinel进程投票下线,主观下线:一台sentinel认为宕机。
-
34.redis如何主从同步。 Redis主从同步的过程:slave会建立和master的连接,发送sync命令。master启动一个后台进程,将数据库快照保存到文件中.同时master主进程会开始收集新的写命令并缓存起来。当后台进程完成写文件后,master就将快照文件发送给slave,slave将文件保存到磁盘上,然后加载到内存将数据库快照恢复到slave上。slave完成快照文件的恢复后,master就会把缓存的命令都转发给slave,slave更新内存数据库。后续master收到的写命令都会通过开始建立的连接发送给slave。
-
37.redis持久化方式及区别。 1。RDB:指定的时间间隔对内存数据进行快照存储。默认开启RDB。内存中的数据快照到磁盘。dump.rdb。fork子进程,父进程的数据复制到子进程的内存,然后由子进程写入到临时文件,这个临时文件替换上次的快照文件,子进程退出内存释放。缺点:内存消耗加倍。 2.AOF:记录每次写操作。RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储。 Fork新进程遍历进程内存数据,写到临时文件,然后替换旧的日志文件。 可以同时开启两种持久化,优先载入AOF文件,AOF文件保存的数据比RDB完整.
-
LRU算法,slab分配,如何减少内存碎片。 内存碎片原因:分配的内存比实际使用的内存大。 内存碎片率:操作系统分配给redis的内存/redis使用分配器分配的内存,大于1表示有内存碎片,1~1.5之间正常,小于1表示有使用虚拟内存即硬盘,大于1.5内存碎片过多。 解决内存碎片:redis4.0开始支持内存碎片整理功能。重启redis服务器 LRU算法:最近最少使用。
-
如何解决缓存单机热点? redis热点key引发的问题:1Redis单机的查询压力大,2redis热点key失效时对底层数据库冲击大。 解决:1.互斥锁:线程锁或者分布式锁来控制对访问数据库和设置缓存值的并发数。 2.value内置过期时间,内置过期时间小于key的实际过期时间,检测到过内置过期时间提前更新key。 3.redis层面永不过期,异步脚本重构缓存。4.对于单机redis查询压力大时再次散列到不同redis服务器。客户端或者nginx实现。
Redis设计与实现
对象与编码类型: 1.使用对象来表示数据库中的键和值,键对象(字符串对象),值对象(字符串对象,列表对象,集合对象,哈希对象,有序集合对象)。 2.对象redisObject的属性:type对象类型(5种),encoding编码(对象的编码8种),ptr指针(数据结构的指针),refcount引用计数。 3.8种编码: long型整数:int embstr编码的简单动态字符串:embstr 简单动态字符串:raw 压缩列表:ziplist 双端链表:linkedlist 字典:hashtable 整数集合:intset 跳跃表+字典:skiplist 4.对象的编码: 字符串对象:int + raw + embstr。raw简单动态字符串,embstr编码的简单动态字符串。 小于32字节-embstr:操作一次内存,内存为连续的内存空间,embstr为只读,修改embstr后变成raw编码。存10086会转成int型,修改后变成“10086”的raw编码。 大于32字节-raw简单动态字符串,操作两次内存,不连续的内存空间。 列表对象:ziplist + linkedlist。压缩列表+双端列表。 ziplist:所有元素长度小于64字节,并且,元素个数小于512个。 不满足ziplist条件转为linkedlist编码。 集合对象:intset + hashtable intset:所有对象是整数值,并且,元素数量不超过512个。 不满足,intset编码转为hashtable编码。 哈希对象:ziplist + hashtable,压缩列表+字典。 ziplist:键值长度小于64字节,并且,键值对小于512个。 不满足,ziplist编码转为hashtable。 有序集合对象:ziplist,hashtable+skiplist,压缩列表,字典+跳跃表。 ziplist:小于64字节,并且,元素个数小于128个。 不满足,转为字典hashtable+跳跃表skiptable。 hashtable:无序,O(1),skiplist:有序,O(logN)。 跳跃表,skiplist: 查找平均O(logN),最坏O(N) 效率可以与平衡树媲美。 【表头节点】 header:表头节点 tail:表尾节点 level:层数最大节点的层数 length:节点数量/表头不算 【节点】 level[]:L1…Ln:指向其他节点的指针,1-32的高度/数组,幂次定律:越大的数出现次数越小。 level[].forward:前进指针,指向其他节点 level[].span:跨度,与当前节点的距离 BW:后退指针,向表头遍历,只能回腿前一个节点。 score:分值,分值从小到大排序 obj:成员对象
持久化:rdb和aof
复制:master & Slave
Sentinel: sentinel实际上是特殊模式下的Redis服务器:事务 ,Lua脚本,aof,rdb等命令不使用。 Sentinel进程每秒向其他主从服务器/sentinel发送PING命令,判断实例是否在线。 主观下线,客观下线/半数以上sentinel。 选举领头sentinel,对故障主服务器执行故障转移操作。(Raft算法) Cluster:
- 命令:CLUSTER MEET
- 节点A向节点B进行握手:节点A向节点B发送MEET消息,节点B返回PONG消息,节点A返回PING消息。
- 之后,节点A通过Gossip协议广播集群中其他节点,让其他节点与节点B进行握手。
- 集群Cluster分为18384个哈希槽。
- 属于哪个哈希槽:CRC16(KEY)& 16383
- 集群节点只能处理0号数据库
- Redis集群中节点分为主节点和从节点,主节点处理槽,从节点复制某个主节点。
- 故障检测:集群中每个节点向其他节点发送PING消息--判断是否在线,不返回PONG消息—疑似下线。
- 确认下线:半数以上处理槽的主节点判断下线。
- 选举新的主节点:N/2+1票,半数以上,基于Raft算法。 发布/订阅
事务 MULTI,命令。。。,EXEC。事务执行 WATCH,MULTI,命令。。。,EXEC。 WATCH:乐观锁,在EXEC命令执行前是否有key被修改,修改则拒绝执行。 Redis事务不支持回滚, Redis事务,遵循ACID特性,持久性在某些情况下满足。
Lua脚本 Lua脚本:原子地执行多个Redis命令。 Redis使用伪客户端执行Lua脚本/包含Redis命令。
1.Redis key请求过热/热点问题。 2.Redis key集群中不均匀分布的问题。