redis面试题

#、redis穿透问题

  • 缓存穿透:key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。
  • 缓存击穿:key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。
  • 缓存雪崩:当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。

#、高并发下redis缓存穿透问题解决方案

使用双重检测锁

public List<UsersDO> getAllUserWithNoPage(){
        try{
            //序列化器,将key的值设置为字符串
            RedisSerializer redisSerializer=new StringRedisSerializer();
            redisTemplate.setKeySerializer(redisSerializer);
            //查缓存
            List<UsersDO> list=(List<UsersDO>)redisTemplate.opsForValue().get("allUsers");
 
            if(null==list){
                //双重检测 锁
                synchronized (this) {
 
                    List<UsersDO> list1 = (List<UsersDO>) redisTemplate.opsForValue().get("allUsers");
                    if (null == list1) {
 
                        UsersQuery query=new UsersQuery();
                        list=usersDOMapper.selectByExample(query);
                        redisTemplate.opsForValue().set("allUsers", list);
 
                        System.out.println("从数据库中取数据");
                    }
                    else{
                        System.out.println("从缓存中取数据");
                    }
                }
            }
            else{
                System.out.println("从缓存中取数据");
            }
            return list;
        }
        catch (Exception e) {
            logger.error("UserService.getAllUserWithNoPage error",e);
        }
        return null;
    }

#、redis集群模式主要有以下几种方式:

  • 主从复制(Master-Slave Replication)

工作原理:Slave从节点服务启动并连接到Master之后,它将主动发送一个SYNC命令。Master服务主节点收到同步命令后将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,Master将传送整个数据库文件到Slave,以完成一次完全同步。而Slave从节点服务在接收到数据库文件数据之后将其存盘并加载到内存中。此后,Master主节点继续将所有已经收集到的修改命令,和新的修改命令依次传送给Slaves,Slave将在本次执行这些数据修改命令,从而达到最终的数据同步。如果Master和Slave之间的链接出现断连现象,Slave可以自动重连Master,但是在连接成功之后,一次完全同步将被自动执行。

配置
修改从节点的配置文件:slaveof masterip masterport
如果设置了密码,就要设置:masterauth master-password

优缺点
优点:同一个Master可以同步多个Slaves。
Slave同样可以接受其它Slaves的连接和同步请求,这样可以有效的分载Master的同步压力。因此我们可以将Redis的Replication架构视为图结构。
Master Server是以非阻塞的方式为Slaves提供服务。所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求。
Slave Server同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据
为了分载Master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务仍然必须由Master来完成。即便如此,系统的伸缩性还是得到了很大的提高。
Master可以将数据保存操作交给Slaves完成,从而避免了在Master中要有独立的进程来完成此操作。
支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。

缺点:Redis不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。
主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
Redis的主从复制采用全量复制,复制过程中主机会fork出一个子进程对内存做一份快照,并将子进程的内存快照保存为文件发送给从机,这一过程需要确保主机有足够多的空余内存。若快照文件较大,对集群的服务能力会产生较大的影响,而且复制过程是在从机新加入集群或者从机和主机网络断开重连时都会进行,也就是网络波动都会造成主机和从机间的一次全量的数据复制,这对实际的系统运营造成了不小的麻烦。
Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。
其实redis的主从模式很简单,在实际的生产环境中是很少使用的,我也不建议在实际的生产环境中使用主从模式来提供系统的高可用性,之所以不建议使用都是由它的缺点造成的,在数据量非常大的情况,或者对系统的高可用性要求很高的情况下,主从模式也是不稳定的。

  • 哨兵模式

Sentinel(哨兵)进程是用于监控redis集群中Master主服务器工作的状态,在Master主服务器发生故障的时候,可以实现Master和Slave服务器的切换,保证系统的高可用。无论是主从模式,还是哨兵模式,这两个模式都有一个问题,不能水平扩容,并且这两个模式的高可用特性都会受到Master主节点内存的限制。

工作原理:Sentinel(哨兵)进程的作用
监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。
提醒(Notification):当被监控的某个Redis节点出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作,它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master;当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用现在的Master替换失效Master。Master和Slave服务器切换后,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置文件的内容都会发生相应的改变,即,Master主服务器的redis.conf配置文件中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换。
Sentinel(哨兵)进程的工作方式
每个Sentinel(哨兵)进程以每秒钟一次的频率向整个集群中的Master主服务器,Slave从服务器以及其他Sentinel(哨兵)进程发送一个 PING 命令。
如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel(哨兵)进程标记为主观下线(SDOWN)
如果一个Master主服务器被标记为主观下线(SDOWN),则正在监视这个Master主服务器的所有 Sentinel(哨兵)进程要以每秒一次的频率确认Master主服务器的确进入了主观下线状态
当有足够数量的 Sentinel(哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内确认Master主服务器进入了主观下线状态(SDOWN), 则Master主服务器会被标记为客观下线(ODOWN)
在一般情况下, 每个 Sentinel(哨兵)进程会以每 10 秒一次的频率向集群中的所有Master主服务器、Slave从服务器发送 INFO 命令。
当Master主服务器被 Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向下线的 Master主服务器的所有 Slave从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
若没有足够数量的 Sentinel(哨兵)进程同意 Master主服务器下线, Master主服务器的客观下线状态就会被移除。若 Master主服务器重新向 Sentinel(哨兵)进程发送 PING 命令返回有效回复,Master主服务器的主观下线状态就会被移除。

优缺点
优点:

哨兵集群模式是基于主从模式的,所有主从的优点,哨兵模式同样具有。
主从可以切换,故障可以转移,系统可用性更好。
哨兵模式是主从模式的升级,系统更健壮,可用性更高。

缺点:

Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。

  • Redis官方 Cluster集群模式(服务端sharding)
  • Jedis sharding集群(客户端sharding)
  • 利用中间件代理

更多参考:     https://blog.csdn.net/qq_35152037/article/details/84583573


3、redis通讯协议 (RESP)?有什么特点?

  • RESP 是redis客户端和服务端之前使用的一种通讯协议;
  • RESP 的特点:实现简单、快速解析、可读性好

RESP实际上是一个支持以下数据类型的序列化协议:简单字符串(Simple Strings),错误(Errors),整数(Integers),块字符串(Bulk Strings)和数组(Arrays)。

服务器(Server)根据命令执行的情况返回一个具体的RESP类型作为回复。有些的数据类型取决于第一个字节
1、对于简单字符串,回复的第一个字节是"+"
2、对于错误,回复的第一个字节是" - "
3、对于整数,回复的第一个字节是":"
4、对于批量字符串,回复的第一个字节是"$"
5、对于数组,回复的第一个字节是"*"
在RESP协议中,协议的不同部分始终以" "(CRLF)结尾。


2、Redis有哪几种持久化方式?

参考  https://blog.csdn.net/hguisu/article/details/90748916

两种持久化方式:RDB(默认) 和AOF 

  • RDB定时快照方式(snapshot): RDB 将数据库的快照(snapshot)以二进制的方式保存到磁盘中。
  • AOF基于语句追加文件的方式:则以协议文本的方式,将所有对数据库进行过写入的命令(及其参数)记录到 AOF 文件,以此达到记录数据库状态的目的。

正确关闭服务器:redis-cli shutdown 或者 kill,都会保证写RDB文件以及将AOF文件fsync到磁盘,不会丢失数据。 如果是粗暴的Ctrl+C,或者kill -9 就可能丢失。

RDB持久化的触发分为手动触发和自动触发两种:

1、手动触发:通过redis的save命令和bgsave命令,都可以生成RDB文件。

客户端可以通过 LASTSAVE 命令查看相关信息,判断 BGSAVE 命令是否执行成功。

2、自动触发:自动触发最常见的情况是在redis.conf配置文件中通过save m n,指定当m秒内发生n次变化时,会触发bgsave。 

AOF基于语句追加方式

AOF方式实际类似mysql的基于语句的binlog方式,即每条会使Redis内存数据发生改变的命令都会追加到一个log文件中,也就是说这个log文件就是Redis的持久化数据。

1、手动触发:使用bgrewriteaof命令:Redis主进程fork子进程来执行AOF重写,这个子进程创建新的AOF文件来存储重写结果,防止影响旧文件。因为fork采用了写时复制机制,子进程不能访问在其被创建出来之后产生的新数据。Redis使用“AOF重写缓冲区”保存这部分新数据,最后父进程将AOF重写缓冲区的数据写入新的AOF文件中然后使用新AOF文件替换老文件。

2、自动触发:和RDB一样,配置在redis.conf文件里;

优缺点比较:

  • aof文件比rdb更新频率高,优先使用aof还原数据。
  • aof比rdb更安全也更大
  • rdb性能比aof好
  • 如果两个都配了优先加载AOF

1、语法

String

  • SET name "runoob"
  • GET name

List

  • lpush runoob zhangsan
  • lrange runoob 0 10

Set         

  • sadd runoob zhangsan
  • smembers runoob

zset       

  • zadd runoob 0 zhangsan
  • ZRANGEBYSCORE runoob 0 1000

Hash

  • HMSET myhash field1 "Hello" field2 "World"
  • HGET myhash field1
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值