Redis面试题

Redis面试题

安装步骤:
1、下载redis安装包,放到Linux的/opt文件夹下
2、解压、使用make命令编译文件(报错可百度查看这里
3、然后到/usr/local/bin目录下可以看到redis的相关文件,启动命令:redis-server /opt/redis-3.2.9/myredis/redis.conf(即指定要使用的redis配置文件)
4、使用redis-cli -p 6379命令即可开始操作redis
5、使用SHUTDOWN命令退出控制台,然后exit

1、redis的数据类型
  • key的常用命令

    keys *:查看所有的key

    exists key:判断某个key是否存在

    move key db:移动某个key到指定的库(切换库:select 1/2/3/4/……)

    expire key 秒钟:为给定的key设置过期时间

    ttl key:查看还有多少秒过期,-1表示永不过期,-2表示已过期

    type key:查看key的类型

  • string(字符串,key-value模式)

    1、可以包含任何数据类型,包括图片和序列化对象

    2、value最大支持512MB

    3、常用的命令

    set/get/del/append/strlen

    incr key:key的值+1

    decr:key的值-1

    incrby key 2:key的值每次+2

    decrby key 2:key的值每次-2

    getrange key 0 3:获取key的下标为0-3的值

    setrange key 0 xxx:设置key的值,从key的0位开始

    setex key 秒值:设置key的过期时间

    setnx key value:只有当key不存在时才设置key为value

    mset k1 v1 k2 v2 k3 v3:同时设置多个值

    mget k1 k2 k3:同时获取多个值

  • list(列表)

    1、底层实现是链表

    2、常用的命令

    lpush list01 1 2 3 4 5:创建list01的同时赋值为12345

    lrange list01:0 -1:获取list01的所有值

    lpop list01:从list的左边取一个值

  • set(集合)

    1、无序集合,通过HashTable实现

    2、常用命令

    sadd set01 1 1 2 2 3 3:创建set01并赋值给1 2 3。相同的过滤掉

    smembers set01:列出set01的值

    scard set01:获取集合里面的元素个数

    srandmembers set01 3;从set01中随机选出3个数

  • zset(有序集合)

  • hash (类似于java中的Map<String,<K,V>>)

    1、KV模式不变,但是V是一个键值对

    hset user id 11:设置初始值

    hget user id:获取user的id

    hmset customer id 11 name li4 age 22:设置初始值

    hmget customer id name age:获取customer的id、name、age

    hexists customer id:查看id在customer中是否存在

2、redis的持久化
  • RDB(Redis DataBase)

    1、是什么?

    在指定的时间间隔内将内存中的数据集快照写入磁盘,恢复时将快照文件读到内存

    2、怎么实现的?

    redis会单独创建一个子进程(fork)来进行持久化,会先将数据写入到一个临时 文件中,待持久化过程结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程不进行任何IO操作,这就保证了极高的性能

    3、命令

    save

    save 120 10:如果两分钟以内修改了十次就执行RDB操作

    4、如何恢复?

    保存位置在config/dir下面,恢复时将备份文件(dump.rdb)移动到redis的安装目录并启动服务即可

    5、优势和劣势

    优势:适合大规模数据的数据恢复、对数据完整性要求不高

    劣势:如果redis意外down掉的话,就会丢失最后一次快照后的所有修改、

  • AOF(Append Only File)

    1、是什么?

    以日志的形式记录每个写操作,将 redis执行过的所有写操作记录下来,只许追加文件,但不可改写文件,redis启动之初会读取该文件重新执行以恢复数据。

    2、如何使用?

    配置文件中修改配置:appendonly yes

    保存的文件:appendfilename “appendonly.aof”

    3、记录频率

    appendsync Everysec:出厂默认推荐,每秒钟记录爱一次,如果一秒内宕机会有数据丢失

    4、Rewrite机制

    是什么?

    AOF采用文件追加的方式,文件会越来越大,为避免出现这种情况,新增了重写机制,当AOF文件的大小超过设定的阈值时,redis就会启动AOF文件的压缩,只保留可以恢复数据的最小指令集。

    重写原理?

    触发机制?

    redis会记录上次重写时AOF的大小,配置默认是当AOF的文件大小是上次rewrite后的一倍且文件大于64MB时

    5、优势和劣势

    优势:可以调整同步的频率、保证数据的完整性

    劣势:AOF的文件要大于RDB文件,恢复速度慢于RDB

  • redis的事务

    1、是什么?

    可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序串行执行而不会被其他命令插入。

    2、能干嘛?

    一个队列中,一次性、顺序性、排他性地执行一系列命令

    3、常用命令

    DISCARD:取消事务,放弃执行事务块内的所有命令

    EXEC:执行所有事务块内的命令

    MULTI:标记一个事务块的开始

    UNWATCH:取消对所有key的监视

    WATCH key:监视一个或多个key,如果在执行事务前这个key被其他名命令改动,那么事务将被打断

    4、常见的情况

    ①正常执行
    在这里插入图片描述

    ②放弃事务
    在这里插入图片描述

    ③全体连坐(有一个错误的命令会导致后面所有的命令失效)
    在这里插入图片描述

    注意:这里出错的命令直接不能通过,没有加入事务的队列中去

    ④冤有头债有主(只有出错的命令不生效)
    在这里插入图片描述

    注意:这里出错的命令能够通过,加入事务的队列中去,但是提交事务之后会报错

    ⑤WATCH监控

    通过WATCH命令在事务执行前监控多个key,倘若在 WATCH之后有任何key的值发生了变化,EXEX命令执行的事务都将被放弃,同时返回错误信息以通知调用者事务执行失败

    ⑥事务的三个阶段

    开启:以MULTI开启一个事务

    入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面

    执行:由EXEC命令触发事务

    ⑦三特性

    单独的隔离操作:事务的所有命令都会序列化,按顺序执行,并且在执行过程中不会被打断

    没有隔离级别的概念:队列中的命令没有提交之前都不会被实际地运行

    不保证原子性:redis中如果有一条命令执行失败,其后的命令 仍然会被执行,没有回滚

3、发布订阅机制
4、主从复制机制
  • 是什么

    主机数据更新后根据配置和策略,自动同步到备份机器的master/slaver机制,Master以写为主,Slave以读为主

  • 能干嘛

    读写分离

    容灾恢复

  • 怎么用

    步骤一:配置从库不配置主库

    步骤二:从库配置 SLAVEOF 主库IP 主库端口号

    例如:SLAVEOF 127.0.0.1 6379 表示备份本机的redis

    步骤三:修改配置文件和细节操作

    1、拷贝多个redis.conf文件

    2、开启daemonize yes

    3、修改PID文件名字

    4、指定端口

    5、修改logfile文件名字

    6、修改dupm.rdb名字

    步骤四:常用三招

    1、一主二仆

    一个主机一般配备两个备机,使用命令SLAVEOF 127.0.0.1 6379开启备份,开启之前的数据在备机上同样可以取到。备机不能设置值。主机宕机之后备机依然是备机,状态更新为down,当主机恢复之后,配置依旧。备机宕机之后,在宕机之间主机产生的数据,备机不存备份,当备机恢复之后角色会变成主机,除非将当前备机配置进主机的配置文件中。

    2、薪火相传

    上一个Slave可以是下一个Slave的master,Slave同样可以接收其他的Slave的连接和同步请求,那么该Slave作为了链条中的下一个master,可以有效减轻下一个master的写压力。如果中途变更转向,会清除之前的数据,重新建立拷贝最新的。

    3、反客为主

    主机宕机之后,其中的一台备机执行SLAVEOF NO ONE命令转换为主机,对数据的操作同样可以被另外一台主机感知。当宕机的主机恢复之后,其备机就不复存在了。

  • 哨兵模式

    1、是什么

    反客为主的自动版,能够监控主机是否故障,如果故障了根据投票数重新选择新的主机

    2、怎么用

    增加配置文件sentinel.conf,文件内容写

    sentinel monitor 被监控数据库名字(就是主机,名字自己起) IP 端口 1

    代表的含义:监控主机,如果主机挂了会根据票数多少重新选择新的主机,当原来的主机恢复之后,会变成新主机的备机。

5、热点数据

当Redis的使用内存超过设置的最大内存时,会触发Redis的key淘汰机制确保缓存数据都是热点数据,一般的剔除策略有 FIFO 淘汰最早数据、LRU 剔除最近最少使用、和 LFU 剔除最近使用频率最低的数据几种策略。

  • noeviction :不删除策略。当达到最大内存限制时,如果需要使用更多内存,则直接返回错误信息(redis默认淘汰策略

  • allkeys-lru:在所有key中优先删除最近最少使用(less recently used,LRU)的key。

  • allkeys-random:在所有key中随机删除一部分key。

  • volatile-lru: 在设置了超时时间(expire)的key中优先删除最近最少使用的key

  • volatile-random:在设置了超时时间的key中随机删除一部分key

  • volatile-ttl: 在设置了超时时间的key中优先删除剩余时间(time to live,TTL)的key

6、内存穿透和雪崩
  • 内存穿透:缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。

    解决办法:最简单粗暴的方法如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们就把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

  • 内存击穿:缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。

    解决办法:最简单粗暴的方法是设置热点数据永不过期

  • 缓存雪崩:如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有的查询都落在数据库上,造成了缓存雪崩。

    解决办法:设置数据的过期时间为随机,避免同一时间大量数据过期现象的发生

7、Redis为什么是单线程的?

因为Redis是基于内存的操作,单线程去操作内存效率就是最高的,因为多线程就是CPU模拟出来多个线程的情况,这种情况会有一个上下文切换的代价。Redis用单个CPU绑定一块内存的区域,然后针对这块内存的操作都是在一个CPU上完成的,所以他就是单线程处理这个事。CPU不是Redis的瓶颈,Redis的瓶颈最有可能是内存或者带宽,既然单线程容易实现,而且CPU又不会成为瓶颈,所以就采用单线程的方案了。

8、Redis为什么这么快?
  • 完全基于内存的操作
  • 数据结构简单,Redis中的数据结构是专门设计的,对数据的操作也简单
  • 采用单线程,避免了不必要的上下文切换和竞争条件
  • 使用多路I/O复用模型,非阻塞IO
9、缓存更新方式

缓存的数据在数据源发生变更时需要对缓存进行更新,数据源可能是 DB,也可能是远程服务。更新的方式可以是主动更新。数据源是 DB 时,可以在更新完 DB 后就直接更新缓存。

当数据源不是 DB 而是其他远程服务,可能无法及时主动感知数据变更,这种情况下一般会选择对缓存数据设置失效期,也就是数据不一致的最大容忍时间。

10、数据不一致

缓存不一致产生的原因一般是主动更新失败,例如更新 DB 后,更新 Redis 因为网络原因请求超时;或者是异步更新失败导致。

解决的办法是,如果服务对耗时不是特别敏感可以增加重试;如果服务对耗时敏感可以通过异步补偿任务来处理失败的更新,或者短期的数据不一致不会影响业务,那么只要下次更新时可以成功,能保证最终一致性就可以。

参考:
https://github.com/AobingJava/JavaFamily

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值