以下是Redis面试中常见的考点,按不同模块分类:
基础知识
-
Redis的优缺点:优点包括高性能、丰富的数据类型、支持持久化、支持事务、高可用和分布式支持等;缺点有数据集大小受限于物理内存、持久化可能影响性能、单线程模型限制、数据安全和隐私问题等。
-
支持的数据类型:String、List、Set、Hash、Zset(有序集合)、HyperLogLogs、Bitmaps、Geospatial 和 Stream。
-
对象机制:Redis使用
redisObject
封装数据对象,不同的数据类型可以由不同的底层数据结构实现,例如集合类型可以用字典或整数集合实现。 -
单线程模型:Redis使用单线程模型处理命令,避免了多线程的上下文切换和竞争条件,同时通过多路复用技术可以同时处理多个客户端的连接请求。
数据结构与使用场景
-
数据结构的底层实现:例如ZSet使用跳跃表(SkipList)+哈希表实现,支持O(logN)复杂度的范围查询和O(1)的单点查询。
-
数据结构的应用场景:String用于缓存、计数器等;List用于消息队列、最新消息排行;Hash用于存储对象;Set用于标签系统、共同好友;ZSet用于排行榜、延迟队列;Bitmap用于用户签到、活跃统计;HyperLogLog用于UV统计等。
持久化与高可用
-
持久化机制:包括RDB(快照)和AOF(写操作日志)两种方式,各有优缺点。
-
高可用方案:主从复制、哨兵模式、Redis Cluster等。
-
持久化与高可用的结合:例如在高可用架构中,通过AOF每秒刷盘和RDB每小时备份来确保数据安全。
性能优化
-
内存优化:合理设置键的过期时间,清理无用数据;使用合适的数据结构,避免存储大对象;调整内存使用策略,设置
maxmemory-policy
。 -
网络优化:使用Pipeline减少网络开销。
-
内存碎片处理:当内存碎片率超过一定阈值时,可通过重启节点、配置优化(如开启
activedefrag
)、存储优化等方式处理。
分布式特性
-
分布式锁:使用
SETNX
和EXPIRE
命令实现分布式锁,或通过Redisson等库简化实现。 -
缓存一致性问题:包括缓存雪崩、缓存穿透和缓存击穿的解决方案。
-
集群的扩缩容:Redis Cluster的扩容和缩容流程。
监控与运维
-
监控指标:使用Redis自带的
INFO
命令或工具如Prometheus和Grafana监控Redis性能,包括客户端连接数、内存使用情况、命中率、持久化状态等。 -
运维操作:例如AOF重写期间内存暴涨的解决方案。
其他
-
事务机制:通过
MULTI
、EXEC
、DISCARD
和WATCH
支持事务操作,事务具有原子性,但不支持回滚。 -
Redis 6.0的新特性:如引入多线程机制及其对性能的影响。
内存数据库
常见数据结构
string
hash
list
set
sorted set
设置过期时间,定期删除(随机抽取)+惰性删除(查到删除)
内存淘汰机制 6种:
从已设置过期时间的数据集里面最少使用,将要过期,任意
键空间 最近最少使用,任意
新写入报错
持久化
快照:通过创建快照来获得存储在内存里面的数据在某个时间点上的副本。指定多少个key发生变化创建快照。
只追加文件:开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。
事务
Redis 通过 MULTI、EXEC、WATCH 等命令来实现事务(transaction)功能。
缓存雪崩
缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。
事前:尽量保证整个 redis 集群的高可用性,发现机器宕机尽快补上。选择合适的内存淘汰策略。
事中:本地ehcache缓存 + hystrix限流&降级,避免MySQL崩掉。
事后:利用 redis 持久化机制保存的数据尽快恢复缓存
缓存穿透
黑客故意请求不存在的数据,所有请求落在数据库,崩掉。
布隆过滤器,将所有可能存在的数据哈 希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
另外也有一个更为简单粗暴的方法(我们采用的就是这种),如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存。
并发竞争key
所谓 Redis 的并发竞争 Key 的问题也就是多个系统同时对一个 key 进行操作,但是最后执行的顺序和我们期望的顺 序不同,这样也就导致了结果的不同!
分布式锁,zookeeper和redis
缓存数据库双写一致性
读请求和写请求串行化,串到一个内存队列里去。