面试问题
Redis优点
1、(支持多种数据类型)支持多种数据结构,如 string(字符串)、 list(双向链表)、dict(hash表)、set(集合)、zset(排序set)、hyperloglog(基数估算)(Memcached只支持key/velue格式)
2、(支持持久化)支持持久化操作,可以进行aof及rdb数据持久化到磁盘,从而进行数据备份或数据恢复等操作,较好的防止数据丢失的手段。
3、(支持主从复制)支持通过Replication进行数据复制,通过master-slave机制,可以实时进行数据的同步复制,支持多级复制和增量复制,master-slave机制是Redis进行HA的重要手段。(不能持久化)
4、(单线程)单线程请求,利用队列技术将并发访问变为串行访问,并发情况下不需要考虑数据一致性问题。
5、(做消息中间件)支持pub/sub消息订阅机制,可以用来进行消息订阅与通知。
6、(支持简单的事务)支持简单的事务需求,但业界使用场景很少,并不成熟。
Redis的局限性
1、(单线程)Redis只能使用单线程,性能受限于CPU性能,故单实例CPU最高才可能达到5-6wQPS每秒(取决于数据结构,数据大小以及服务器硬件性能,日常环境中QPS高峰大约在1-2w左右)。(Memcached单实例吞吐量极高")
2、(事务)支持简单的事务需求,但业界使用场景很少,并不成熟,既是优点也是缺点。
3、(string类型)Redis在string类型上会消耗较多内存,可以使用dict(hash表)压缩存储以降低内存耗用。
4 . Memcached和Redis都是Key-Value类型,不适合在不同数据集之间建立关系,也不适合进行查询搜索。比如redis的keys pattern这种匹配操作,对redis的性能是灾难。
Redis 常见的性能问题都有哪些?如何解决?
1.Master写内存快照
save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。 Master最好不要做任何持久化工作
2.Master AOF持久化
如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。
3.Master调用BGREWRITEAOF重写AOF文件
AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。
4.Redis主从复制的性能问题
为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内
- 主从复制不要用图状结构,用单向链表结构更为稳定
即:Master <- Slave1 <- Slave2 <- Slave3…
这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。
缓存击穿,穿透,雪崩
- 缓存穿透
当缓存与数据库中都不存在该数据时,由于当数据库查询不到数据就不会写入缓存,这个时候如果用户不断的恶意发起请求,就会导致这个不存在的数据每次请求都会查询DB,请求量大的情况下,就会导致DB压力过大,直接挂掉。
- 解决方案:
1、当查询返回一个空数据时,直接将这个空数据存到缓存中,过期时间不宜设置过长,建议不超过5分钟
2、采用布隆过滤器:将所有可能存在数据,分别通过多个哈希函数生成多个哈希值,然后将这些哈希值存到一个足够大的bitmap中,此时一个一定不存在的数据就会被这个bitmap拦截,从而减少了数据库的查询压力。
- 击穿
某一个数据缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,严重情况下会直接挂掉。
- 解决方案:
1、添加互斥锁:
ReentrantLock公平锁
根据key值加锁,这样线程之间会不影响,不会因为某一个线程获取了锁,其它线程就处于等待时间,也就是线程A从数据库取key1的数据并不妨碍线程B取key2的数据
2、设置热点数据永不过期(物理上的不过期、“逻辑上”的不过期(缓存到期动态构建缓存))
- 雪崩
缓存中大批量的数据都到了过期时间,从而导致查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同,缓存击穿是指某一条数据到了过期时间,大量的并发请求都来查询这一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库
- 解决方案:
1、设置热点数据永不过期
2、缓存数据的过期时间设置随机,可以在原有的过期时间上加上一个随机值,比如1-3min,防止同一时间大量缓存数据集体失效,导致数据库压力过大。
3、如果是分布式部署缓存数据库,可将热点数据分别存放到不同的缓存数据库中,避免某一点由于压力过大而down掉。
redis单线程为什么这么快
删除key会阻塞redis吗
理论上会的。如果删除的string类型特别大,可能会导致删除很慢。删除其他类型例如list,key的个数也决定了删除的效率。
Redis主从、哨兵、集群架构优缺点比较
主从:优:相对简单,成本低。缺:主节点挂了需要有运维人员进行重启或者升级从节点为主节点,人员成本高
哨兵:优:能自动检测主节点是否挂了,并能选举新的主节点,自动化更强。缺:主从切换过程会进行主从复制,会进行大量io操作可能造成性能阻塞问题。主节点挂了之后,哨兵监听时会有一段时间等待,服务不可用。
集群:优:支撑扩展,容灾额能力更强。缺:成本更高,对
Redis集群数据hash分片算法是怎么回事
CRC(16):redis集群中计算每个主节点可以存放那些槽位的数据(共16384),计算那些数据需要存放在那哥主节点中
Redis执行命令竟然有死循环阻塞Bug
redis主节点在删除key时会判断是否已经过期,如果已经过期就会去寻找其他key。但是从节点不会主动删除可以、而是需要主节点通知需要删除时再能删除。所以删除命令在从节点删除时如果大量key失效,那就会不断寻找其他key,这样就静茹一个死循环。(randomkey命令是在数据库中随机返回一个key)
一次线上事故,Redis主从切换导致了缓存雪崩
主节点和从节点机器时间不一致,主节点认为key没有过期,但是从节点认为key过期。主节点挂了之后从节点成为为主节点,删除大量的key。
edis持久化RDB、AOF、混合持久化是怎么回事(补充)
RDB:写时复制技术
AOF:追加的方式写命令
同时开启两种持久化机制,在需要持久化时,先进行RDB持久化,之后的命令会写到主线程和aof缓冲区,rdb完成后,会将rfb文件放在aof文件开头,剩下的命令继续写道剩下的文件中。保持性能的同时也保证了数据的完整性。
Redis主从复制风暴是怎么回事
主节点有很多从节点,从节点重启时会向主节点同步数据,主节点需要同时向从节点发送rdb文件导致主节点压力过大。
Redis集群支持批量操作命令吗
如果这些数据都是在同一个节点上时可以的,如果不是正常情况下时不能的。但是可以在存数据的时候加上一个同一个key的属性。
Lua脚本能在Redis集群里执行吗
lua操i做的key需要落到同一个节点上,操作步骤和上一题一样,需要使用hashtag方式进行。
Redlock如何解决Redis主从切换分布式锁丢失问题
其中一个解决方案RedLock*(不推荐使用),可以使用redisson实现分布式锁。
大厂线上大规模商品缓存数据冷热分离实战
有些不是热点数据但是一直存在redis中造成内存浪费,可以解决缓存穿透和缓存击穿问题,设置过期时间。或者将一部分数据放在内存多级缓存不走redis。
大促压力暴增导致分布式锁串行争用问题优化实战
使用分布式锁可能会导致所有线程串行执行操作,这时候可以使用redisson的读写锁方式对于写操作使用的写锁(悲观锁),对于读操作使用读锁(乐观锁)会提升性能。