目录
一、redis是什么
(1)redis 基于内存的非关系型数据库,读写速度非常快,可以用作数据库缓存、消息中间件;
(2)是一种Nosql数据库,性能优秀;
(3)支持字符串、hash、list、set、zset数据类型;
(4)支持数据可持久化,可将内存中的数据保存到磁盘中,主从复制、哨兵。
二、redis缓存怎么使用
(1)直接通过RedisTemplate(2)使用Spring Cache集成redis
三、主从模式特点是什么
(1)主数据库可以进行读写操作,当读写操作导致数据变化时会自动将数据同步到从数据库中;
(2)一个master对应多个slave,但一个slave只能对应一个master;
(3)slave挂了不影响其他的slave的读和master的读和写,重启之后将从master同步过来。
四、 主从复制有哪些问题
一旦主节点宕机,从节点晋升为主节点,同时需要修改应用方的主节点地址,还需要命令从节点去复制主节点,整个过程需要人工去干预,主节点的写能力受到限制,储存能力受到单机的限制。
五、怎样解决主从复制的问题
哨兵机制
哨兵可以执行以下四个任务:
监控:不断 检查主服务器和从服务器是否正常运行;
通知:当被监控的某个redis服务器出现问题,哨兵通过脚本向管理员或其他应用程序发出通知;
自动故障转移:当主节点不能正常工作时,与失效主节点是主从关系的一个从节点升为主节点,并且将其他的从节点指向新的主节点。这样人工干预就可以免了。
六、redis的过期策略与内存淘汰机制
(1)定期删除:用一个定时器负责监视key,过期则删除,内存即使释放,但十分耗费CPU资源。【随机抽取检查】
(2)惰性删除:你在获取某个key时,redis会检查一下,如果过期了则删除。
但如果定期删除没删除key,然后你也没及时请求到key,也就是惰性删除也没生效,redis内存会越来越高。
这时就要使用内存淘汰机制:
-
noeviction:当内存使用达到阈值的时候,所有引起申请内存的命令会报错。
-
allkeys-lru:在主键空间中,优先移除最近未使用的key。
-
volatile-lru:在设置了过期时间的键空间中,优先移除最近未使用的key。
-
allkeys-random:在主键空间中,随机移除某个key。
-
volatile-random:在设置了过期时间的键空间中,随机移除某个key。
-
volatile-ttl:在设置了过期时间的键空间中,具有更早过期时间的key优先移除。
七、redis与memcache的区别
(1)存储方式memcache把数据全部存在内存中,断电后会挂掉,数据不能超过内存大下;redis有部分可以存在硬盘上,redis可以持久化其数据;
(2) memcache 数据类型是简单的字符串,redis支持更丰富的数据类型;
(3)value值大小不同,redis最大可以达到512M,memcache只有1M;
(4)redis速度比memcache快很多。
八、解释一下缓存穿透、缓存击穿和缓存雪崩
(1)缓存穿透:查询一个数据库一定不存在的数据;
解决办法:
缓存空值:访问key但未在DB查询到值,也将空值写进缓存,但可以设置较短过期时间;会储存更多的空值的键。
布隆过滤器:使用一个足够大的bitmap,对所有可能查询的参数以hash形式存储,用于存储可能访问的key,不存在的key直接被过滤;
(2)缓存击穿:一个key热点,大并发集中对这一点进行访问,当这个key失效的瞬间,持续的大并发就穿透缓存,直接请求数据库;
解决办法:
主打商品让缓存永不过期;
互斥锁:缓存失效的时候(判断拿出来的值是否为空),不是立即去loadDB,而是使用redis的互斥锁去set一个mutex key ,当操作返会成功时,在loaddb的操作并回设缓存,否则就重试整个get缓存方法。
public String get(key) {
String value = redis.get(key);
if (value == null) { //代表缓存值过期
//设置3min的超时,防止del操作失败的时候,下次缓存过期一直不能load db
if (redis.setnx(key_mutex, 1, 3 * 60) == 1) { //代表设置成功
value = db.get(key);
redis.set(key, value, expire_secs);
redis.del(key_mutex);
} else { //这个时候代表同时候的其他线程已经load db并回设到缓存了,这时候重试获取缓存值即可
sleep(50);
get(key); //重试
}
} else {
return value;
}
}
(3)缓存雪崩:某一时间段缓存集中过期,缓存层出现问题,不是所有的请求都会达到存储层,存储层调用量会暴增,造成存储层也会挂掉。
失效场景:缓存服务器挂了;高峰期缓存局部失效;热点缓存失效
解决方法:
不同的key设置不同超时时间,热门商品设置时间长点,冷门商品时间缓存时间短点;
增加互斥锁,控制数据库的请求,重建缓存;
用redis集群
九、redis为什么这么快?
(1)完全基于内存。类似于hashmap,查找和操作时间的复杂度都是O(1);
(2)数据结构简单,对数据操作也简单;
(3)采用单线程,避免不必要的上下文切换和竞争条件,也不存在多线程或者多线程导致切换消耗CPU,不用考虑锁的问题;
(4)多路IO复用:采用此技术可以让单个线程高效的处理多个连接请求。在空闲的时候会把当前线程阻塞掉,当有一个或多个I/O事件,就会从阻塞中唤醒,于是程序就会轮询一遍所有的流,并且只依次顺序处理就绪的流,避免大量无用操作。
十、redis持久化
RDB与AOF
RDB:在指定时间间隔内将内存中的数据集快照写入磁盘。redis会单独创建一个进程来进行持久化,会将数据写到一个临时文件中,待持久化过程都结束了,再将这个临时文件替换上次持久化好的文件。
dump.rdb文件,最后一次持久化的数据可能丢失;
默认设置:一分钟内改变一万次,五分钟改变十次,十五分钟改变一次就会触发备份;
如何恢复:将备份文件移动到redis安装目录并开启服务即可;
AOF:以日志的形式记录写操作,将redis执行过的所有写命令记录下来,只许追加文件不可以修改文件。
默认是以AOF文件恢复。
二者比较:
相同数据集的数据而言aof文件要远大于rdb文件,恢复速度慢于rdb;
aof运行效率慢于rdb,,每秒同步策略效率较高。
十一、哨兵故障切换过程
(1)投票(半数原则)
当任何一个哨兵发现被监控的master下线时,会通知其他的哨兵开会,投票确定该master是否下线;
(2)选举
当哨兵确定master下线后,会在所有的slaves中选举一个新节点,升级为master节点,其他slave节点转为该节点的从节点
(3)原master重新上线
当原master重新上线,自动转为当前master节点的从节点。