当前位置: 首页 > 科技观察

不懂Redis,面试的时候很担心,Redis面试题(含答案)如何一次性解决?

时间:2023-03-12 12:01:12 科技观察

Redis是一个非常流行的非关系型数据库。它有多受欢迎?只要是互联网公司,都会用。Redis相关的问题可以说是面试必问的问题。下面,我就个人作为面试官的经历总结几个必须掌握的知识点。简介:Redis是一个开源的非关系型数据库,用ANSIC语言编写,遵守BSD协议,支持网络,可以是基于内存或持久化日志,Key-Value数据库,提供多种语言的API。传统数据库遵循ACID规则。而Nosql(NotOnlySQL的缩写,是区别于传统关系型数据库的数据库管理系统的总称)一般是分布式的,分布式一般遵循CAP定理。String:格式:setkeyvalue字符串类型是二进制安全的。这意味着redis的字符串可以包含任何数据。比如jpg图片或者序列化的对象。字符串类型是Redis最基本的数据类型,一个key最多可以存储512MB。哈希格式:hmsetnamekey1value1key2value2Redis哈希是一组键值对(key=>value)。Redishash是string类型字段和值的映射表,hash特别适合存储对象。List(列表)Redis列表只是一个字符串列表,按插入顺序排序。可以在列表的头部(左)或尾部(右)添加一个元素格式:lpushnamevalue在key对应的列表头部添加一个字符串元素格式:rpushnamevalue在尾部添加一个字符串元素key对应的列表的格式:lremnameindexkey对应删除列表中与value相同的count个元素类型。集合是通过哈希表实现的,所以增删改查的复杂度都是O(1)。zset(sortedset:有序集合)格式:zaddnamescorevalueRediszset和set一样,也是string类型元素的集合,不允许有重复的成员。不同之处在于每个元素都将与一个双精度类型的分数相关联。Redis使用分数将集合的成员从小到大排序。zset的成员是唯一的,但是分数(score)可以重复。什么是Redis持久化?Redis有哪几种持久化方式?优缺点都有什么?持久化就是将内存中的数据写入磁盘,防止服务宕机时内存数据丢失。Redis提供了两种持久化方式:RDB(默认)和AOFRDB:rdb是RedisDataBase函数的缩写核心函数rdbSave(生成RDB文件)和rdbLoad(从文件加载内存)两个函数AOF:Aof是Append-onlyfile的缩写flushAppendOnlyFile函数每当执行服务器(计时)任务或功能时都会调用。该函数执行以下两个任务:WRITE:根据条件将aof_buf中的缓存写入AOF文件SAVE:根据条件,调用fsync或fdatasync函数将AOF文件保存到磁盘。存储结构:内容为redis通信协议(RESP)格式的命令文本存储。比较:aof文件比rdb文件更新更频繁,首选aof恢复数据。Aof比rdb更安全,也更大。rdb比aof有更好的性能。如果两者都配置了优先加载AOF,你刚刚在上面提到了redis通信协议(RESP)。你能解释一下RESP是什么吗?有什么特点?(可以看到很多面试其实都是连环炮,面试官其实就是在等你回答这一点,如果你回答了对你的评价,还会加一分。)RESP是redis客户端和服务端之前的一次通信协议;RESP特点:实现简单,分析速度快,可读性好ForSimpleStrings回复的第一个字节是“+”ReplyForErrors回复的第一个字节是“-”ForIntegers回复的第一个字节是“:”Integer对于批量字符串,回复的第一个字节是“$”字符串对于数组,回复的第一个字节是“*”数组Redis有哪些架构模式?说说他们各自的特点。单机版特点:简单问题:1.内存容量有限2.处理能力有限3.不能高可用。主从复制Redis的复制功能允许用户基于一台Redis服务器创建任意数量的服务器副本。被复制的服务器是主服务器(master),复制创建的服务器副本是从服务器(slave)。只要主从服务器之间的网络连接正常,主从服务器就会有相同的数据,主服务器会一直把自己发生的数据更新同步到从服务器,从而保证数据的一致性主从服务器的配置是一样的。特点:master/slave角色master/slave数据相同减少master从库中读取压力问题:不能保证高可用不解决master写压力SentinelRedisSentinel是一个分布式系统,监控redismaster-从服务器和主服务器离线时自动故障转移。其中三个特点:监控(Monitoring):Sentinel会不断地检查你的主服务器和从服务器是否正常工作。通知:当被监控的Redis服务器出现问题时,Sentinel可以通过API向管理员或其他应用发送通知。自动故障转移(Automaticfailover):当主服务器无法正常工作时,Sentinel会启动自动故障转移操作。特点:保证高可用,监控每个节点自动故障转移缺点:主从模式,切换需要时间数据丢失不能解决master写的压力集群(proxy类型):Twemproxy是Twitter开源的快速/轻量级代理,用于redis和memcache服务器;Twemproxy是一个快速的单线程代理,支持MemcachedASCII协议和redis协议。特点:多种哈希算法:MD5、CRC16、CRC32、CRC32a、hsieh、murmur、Jenkins支持故障节点自动删除后端分片分片逻辑对业务透明,业务端读写方式一致与单个Redis一起运行缺点:新增proxy需要保持高可用。故障转移逻辑需要自己实现,不支持故障自动转移。扩展性差,扩缩容需要集群人工干预(直连型):redis-cluster集群从redis3.0以后的版本开始支持,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都连接到所有其他节点。特点:去中心化架构(不存在影响性能瓶颈的节点),缺少代理层。数据按照槽位存储分布在多个节点之间,节点间数据共享可以动态调整数据分布。可扩展性,线性扩展到1000个节点,可以动态添加或删除节点。高可用,当部分节点不可用时,集群仍然可用。通过添加Slave作为备份数据副本,实现故障时的自动故障转移,节点之间通过gossip协议交换状态信息,并使用投票机制完成从Slave到Master的角色提升。缺点:资源隔离性差,容易相互影响。数据是异步复制的,不保证数据的强一致性。什么是一致性哈希算法?什么是哈希槽?这两个问题太长了。在网上找到两篇不错的文章www.cnblogs.com/lpfuture/p/...blog.csdn.net/z1573262158...Redis常用命令?keyspattern是指匹配所有以bit开头的keys。检查Exists键是否存在。将key对应的值设置为字符串类型的值。setnx将key对应的值设置为字符串类型的值。如果key已经存在,则返回0,nx表示不存在。删除一个key,第一次返回1,第二次删除返回0Expire设置过期时间(以秒为单位)TTL检查还剩多少时间Setex将key对应的值设置为字符串类型的值,并指定该键值对应的有效期。mset一次设置多个key的值,成功返回ok,表示设置了所有值,失败返回0,表示没有设置值。getset设置key的值并返回key的旧值。mget一次获取多个key的值,如果对应的key不存在则返回nil。Incr添加键的值并返回新值。请注意,如果incr是一个不是int的值,则会返回错误。如果incr是一个不存在的key,则将key设置为1。incrby类似于incr,增加一个指定的值。当key不存在时,设置key并认为原值为0。decrpairkeydecrby同decr,如果decr中没有key则减去指定的值。Append将值附加到指定键的字符串值,并返回新字符串值的长度。Strlen取指定键值的长度。persistCancel过期时间Select选择数据库Randomkey返回一个随机keyRenameRenameType返回数据类型你用过Redis分布式锁吗,是怎么实现的?先用setnx去竞争锁,然后用expire给锁加一个过期时间,防止锁忘记释放。如果在setnx之后执行expire之前进程意外崩溃或者需要重启维护怎么办?set命令的参数非常复杂,所以应该可以把setnx和expire同时合并成一个命令!你用过Redis作为异步队列吗?你是怎么用的?缺点是什么?一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,需要sleep一会再试。缺点:当消费者下线时,生产的消息会丢失,必须使用rabbitmq等专业的消息队列。能否一次生产多次消费?使用pub/sub主题订阅者模式,可以实现1:N的消息队列。什么是缓存穿透?如何避免?什么是缓存雪崩?如何避免?缓存穿透一般的缓存系统是根据key来缓存query的。如果没有对应的值,就去后台系统(比如DB)去查找。一些恶意请求会故意查询不存在的key,大量的请求会给后端系统带来很大的压力。这称为缓存穿透。如何避免?1:即使查询结果为空也缓存,将缓存时间设置短一些,或者插入key对应的数据后清空缓存。2:过滤一定不能存在的key。可以把所有可能的key放到一个大的Bitmap中,查询的时候通过bitmap进行过滤。缓存雪崩当缓存服务器重启或一定时间内大量缓存失效时,失效时会给后端系统带来很大的压力。导致系统崩溃。如何避免?1:缓存过期后,通过加锁或队列控制读数据库和写缓存的线程数。例如,只允许一个线程查询某个key的数据和写cache,其他线程等待。2:做二级缓存,A1为原始缓存,A2为副本缓存,当A1失效时,可以访问A2,A1的缓存过期时间设置为短期,A2设置为长期3:不同的key,设置不同的过期时间,这样缓存失效的时间点尽量统一