1、 Redis支持的数据类型?
(1) String(字符串)
二进制安全,最大能存储512M
(2) Hash(字典)
键值对集合,如编程语言中的Map类型
(3) List(列表)
链表(双向链表),增删快
(4) Set(集合)
哈希表实现,元素不重复
(5) Sorted Set(有序集合)
将Set中的元素增加一个score元素,按照score有序排列
2、 Redis持久化
(1) RDB(Redis DataBase)
RDB机制通过把某个时刻的所有数据生成一个快照来保存,有一种触发机制来实现这个过程,分别为save、bgsave、自动化
- save: 该命令会阻塞当前Redis服务器,执行save命令期间,redis不能处理其他命令,直到RDB过程完成为止。这种方式不可取。
- bgsave: 执行该命令时,Redis会在后台异步进行快照操作,快照同时可以响应客户端请求。基本上Redis内部所有的RDB操作都是采用bgsave命令。
- 自动化: 自动触发是由我们的配置文件来完成的。
(2) AOF(Append Only File)
AOF的工作机制很简单,redis会将每一个收到的写命令都通过write函数追加到文件中。通俗理解就是日志记录。AOF有三种触发机制。
- always: 每次修改同步always,同步持久化,每次发生数据更新会立刻记录到磁盘,性能差但是数据完整性好。
- everysec: 每秒同步everysec,异步操作,如果一秒内宕机,有数据丢失。
- no: 从不同步。
3、 Redis架构模式
(1)单机版
- 内存容量有限
- 内存容量有限
- 无法高可用
(2)主从复制
redis的复制功能允许用户根据一个redis服务器来创建任意多个该服务器的复制品,其中被复制的服务器为主服务器(master),而通过复制创建出来的为从服务器(slave)
- 降低master读压力
- 无法保证高可用
- 没有解决master写的压力
(3)哨兵模式
Redis sentinel是一个分布式系统中监控redis主从服务器,并在主服务器下线时自动进行故障转移。其中三个特性有:
- 监控(Monitoring):Sentinel会不断检查你的主服务器和从服务器是否运作正常。
- 提醒(Notification):当被监控某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知。
- 自动故障迁移(Automatic failover):当一个主服务器不能正常工作时,Sentinel会开始一次自动故障迁移操作。
(4)集群
- proxy型
- 直连型
4、Redis分布式锁
5、Redis异步队列
6、缓存穿透?缓存雪崩?
(1)缓存穿透
查询一个一定不存在的数据。由于缓存不命中,并且出于容错考虑,如果从数据库查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库查询,失去了缓存的意义。
- 解决方案:由于请求的参数不合法(每次请求不存在的参数),我们可以使用布隆过滤器拦截,不合法的数据就过滤掉,不让它请求到数据库。
(2)缓存雪崩
缓存数据设置的过期时间是相同的,并且恰好这部分数据全部删光了。这就会导致在这段时间内,这些缓存同时失效,全部请求到数据库中。
- 解决方案1:在缓存的过期时间加上一个随机值,大幅度减少同一时间过期。
- 解决方案2:主从架构+sentinel(哨兵),尽量避免Redis挂掉的情况发生。
7、Redis常用命令
-
keys * 取出所有key
-
exists name 查看是否有name这个key
-
del name 删除key name
-
expire confirm 100 设置confirm这个key100秒过期
-
ttl confirm 获取confirm这个key的有效时长
-
persist confirm 移除confirm这个key的过期时间
-
type key 返回key的数据类型
8、Redis单线程怎么支撑高并发?
redis使用多路复用技术,可以处理并发的连接。非阻塞IO内部实现采用epoll,采用epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时间。
9、Redis内存淘汰策略
(1)volatile-lru
从设置过期时间的数据集中挑选出最近最少使用的数据淘汰。没有设置过期时间的key不会被淘汰,这样就可以增加内存空间的同时保证需要持久化的数据不会丢失。
(2)volatile-ttl
从设置过期时间的数据集中挑选将要过期的数据淘汰,ttl值越大越优先被淘汰。
(3)volatile-random
从已设置过期时间的数据集中任意选择数据淘汰。当内存达到限制无法写入非过期时间的数据集时,可以通过该淘汰策略在主键空间中随机移除某个key。
(4)allkeys-lru
从数据集中挑选最近最少使用的数据淘汰,该策略要淘汰的key面向的时全体key集合,而非过期的key集合。
(5)allkeys-random
从数据集中任意选择数据淘汰。
(6)no-enviction
禁止驱逐数据,也就是当内存不足以容纳新入数据时,新写入操作就会报错,请求可以继续进行,线上任务也不能持续进行,采用no-enviction策略可以保证数据不被丢失,这也是系统默认的一种淘汰策略。
10、Redis并发竞争问题怎么解决?
redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争,但在业务客户端对Redis进行并发访问时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题都是由于客户端连接混乱造成的。解决方法有:
- 客户端加锁(synchronized)
- 乐观锁(redis的命令watch) :当执行多键值事务操作时,Redis不仅要求这些键值需要落在同一个Redis实例上,还要求落在同一个slot上,所以redis的事务比较鸡肋。不过可以想办法遵循redis内部的分片算法把设计到的所有key分到同一个slot
- redis的setnx实现内置的锁:要设置超时时间,防止抢占到锁的客户端因失败、崩溃或其他原因没有办法释放锁而造成死锁。
整理自部分面经及网上内容,侵删