最近整理一份关于Redis常见面试题的,也会根据自己的经验, 标注一些出现的概率,最高5颗★出现的概率最高。比如这样:
Redis 最适合的场景, 可以简单的说说吗?
出现概率: ★★★★
一、Redis基础知识
二、数据结构
三、事务
四、Redis数据持久化
五、Redis集群
六、Redis淘汰策略
七、Redis分布式锁
八、Redis缓存问题
九、运维和部署
一般来讲在面试当中, 关于Redis相关的面试题频率出现比较高的几个关键词是适合哪些场景、数据结构、hash实现原理和如何扩容、如何做持久化、关系型数据库和非关系数据库对比等等。 把这几个点问完基本也差不多10~20分钟了(一般一轮面试1小时左右), 基本这些可以让面试官对你的Redis知识有一定的了解了。也可以在线看我的博客
也欢迎关注我的公众号: 漫步coding
。 一起交流, 在coding的世界里漫步, 回复: redis
, 免费获取最新Redis面试题(含答案)。
希望这篇文章可以帮助大家, 也希望大家都能找到的好工作。
出现概率: ★★★★
Redis是一个非关系性数据库, 开源的、使用C语言编写、支持网络、可基于内存亦可持久化的日志型、key-value(键值对)数据库,是目前分布式架构中不可或缺的一环。
Redis服务器程序是单进程模型,也就是在一台服务器上可以同时启动多个Redis进程,而Redis的实际处理速度则完全依靠于主进程的的执行效率。若在服务器上只运行一个Redis进程,当多个客户端同时访问时,服务器的处理能力会有一定程度的下降,若在同一台服务器上开启多个Redis进程,Redis在提高并发处理能力的同时会给服务器的CPU造成很大压力。也就是说,在实际生产环境中,需要根据实际的需求来决定开启多少个Redis进程。若对高并发要求更高一些,可能会考虑在同一台服务器上开启多个进程。若CPU资源比较紧张,采用单进程即可。
Redis优点:
1)、性能极高, 读写性能优异,从内存当中进行IO读写速度快。
2)、支持数据的持久化(支持AOF和RDB两种持久化方式),对数据的更新采用Copy-on-write技术(写拷贝),可以异步的保存在磁盘上
由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁 盘上,当redis重启后,可以从磁盘中恢复数据。
redis提供两种方式进行持久化,一种是RDB持久化:指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
还有一种是AOF持久化:以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
3)、支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。
4)、数据结构丰富:除了支持string类型的value外还支持string、hash、set、sortedset、list等数据结构。
5)、原子性:多个操作通过MULTI和EXEC指令支持事务
Redis缺点:
1)、主从同步,如果主机宕机,宕机前有一部分数据没有同步到从机,会导致数据不一致。
2)、主从同步,数据同步会有延迟。
3)、读写分离,主机写的负载量太大,也会导致主机的宕机
4)、数据库容量受到物理内存的限制,不能用作海量数据的高性能读写
出现概率: ★★★★
1、会话缓存(Session Cache)最常用的一种使用Redis的情景是会话缓存(session cache), Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。
2、排行榜/计数器
Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。
3、发布/订阅
Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统!
4、缓存热数据
可以缓存一些高频读, 低频写的内容, 比如app首页一些设置等。
5、利用BitMap统计用户签到、统计活跃用户、用户在线状态等
Redis从2.2.0版本开始新增了setbit,getbit,bitcount等几个bitmap相关命令。虽然是新命令,但是并没有新增新的数据类型,因为setbit等命令只不过是在set上的扩展。
可以利用BitMap统计用户签到、统计活跃用户、用户在线状态
6、限速,接口访问频率限制:比如发送短信验证码的接口,通常为了防止别人恶意频刷,会限制用户每分钟获取验证码的频率,例如一分钟不能超过 5 次。
假设用于数据量上亿的场景下,例如几亿用户系统的签到,去重登录次数统计,某用户是否在线状态等等。腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,能怎么做?
千万别说给每个用户建立一个key,然后挨个记(你可以算一下需要的内存会很恐怖,而且这种类似的需求很多。这里要用到位操作——使用setbit、getbit、bitcount命令。原理是:
redis内构建一个足够长的数组,每个数组元素只能是0和1两个值,然后这个数组的下标index用来表示用户id(必须是数字哈),那么很显然,这个几亿长的大数组就能通过下标和元素值(0和1)来构建一个记忆系统。
Redis key name 约定
$dayKey = 'login:'.\date('Ymd',\time());
Redis 数据结构
key | sign:20220405 | sign:20220405 | sign:20220405 … |
---|---|---|---|
offset (UserId) | 1000 | 1001 | 1002 |
value | 0 | 1 | 1 |
status | 未签到 | 已签到 | 已签到 |
使用经验
127.0.0.1:6379> setbit 'login-20220405' 2 1 127.0.0.1:6379> setbit 'login-20220405' 100 1 (integer) 1 127.0.0.1:6379> setbit 'login-20220405' 200000000 1 (integer) 1 127.0.0.1:6379> setbit 'login-20220405' 4290000000 1 (integer) 1 127.0.0.1:6379> setbit 'login-20220405' 4300000000 1 (error) ERR bit offset is not an integer or out of range 127.0.0.1:6379> getbit 'login-20220405' 100 (integer) 1 127.0.0.1:6379> getbit 'login-20220405' 101 (integer) 0 127.0.0.1:6379>
这里需要注意的是Redis中字符串限制最大为512MB,所以位图中最大可以设置2^32个不同的位(42.9亿个)。图位的最小单位是比特(bit),每个bit的值只能是0或1。 同时注意setbit时的偏移量,当偏移量很大时,可能会有较大耗时。 位图不是绝对的好,有时可能更浪费空间。
出现概率: ★★★
如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:
1 、数据支持类型 Memcache 对数据类型支持相对简单。Redis 有复杂的数据类型。Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
2 、Redis支持数据的备份,即master-slave模式的数据备份。
3 、存储方式 Memecache 把数据全部存在内存之中, 断电后会挂掉, 数据不能超过内存大小。Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
Redis中字符串限制最大为512MB
出现概率: ★★★
读取请求QPS(Queries Per Second)压力较大的服务, 可以采用Redis读写分离,可以提供高可用、高性能、灵活的读写分离服务,满足热点数据集中及高并发读取的业务需求,最大化地节约运维成本。
读写分离版采取链式复制架构,可以通过扩展只读实例个数使整体实例性能呈线性增长,同时基于源码层面对Redis复制流程的定制优化,可以最大程度地提升线性复制的系统稳定性,充分利用每一个只读节点的物理资源。
由于数据同步至只读节点存在一定延迟,且采用链式复制,只读节点数越多,靠近链路末端的只读节点数据延迟越大,因此选用此架构时,业务需要能接受一定程度的脏数据。如果对数据一致性要求较高,推荐选用集群架构。
出现概率: ★★★★
Redis 官方站提出了一种权威的基于 Redis 实现分布式锁的方式名叫Redlock,此种方式比原先的单节点的方法更安全。它可以保证以下特性:
安全特性:互斥访问,即永远只有一个client能拿到锁
避免死锁:最终 client 都可能拿到锁,不会出现死锁的情况,即使原本锁住某资源的 client crash 了或者出现了网络分区
容错性:只要大部分 Redis 节点存活就可以正常提供服务