基础原理

Redis的一些常见面试题总结

2019-05-20  本文已影响24人  要记录的Ivan

1. Redis为什么这么快?

  1. 完全基于内存,绝大部分请求是纯粹的内存操作,执行效率非常高。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);

  2. 数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;

  3. 采用单线程(该单线程指的是处理网络请求的线程),避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

  4. 使用多路I/O复用模型,非阻塞IO;

2. Redis中常用数据类型

查看详细

3. 从海量Key里查询出某一固定前缀的Key

留意细节:

使用keys指令来扫出指定模式的key列表,

使用keys对线上的业务的影响:

KEYS pattern:查找所有符合给定模式pattern的key

缺点:

这时可以使用SCAN指令:

SCAN cursor [MATCH pattern] [COUNT count]

>scan 0 match k1* count 10

4. 如何通过Redis实现分布式锁

分布式锁需要解决的问题:

如何实现:

SETNX(Set if not exsist) key value:如果key不存在,则创建并赋值。因为SETNX有上述功能,并且操作都是原子的,因此在初期的时候可以用来实现分布式锁。

使用EXPIRE key seconds来解决SETNX长期有效的问题:

RedisService redisService = SpringUtils.getBean(RedisService.class);
long status = redisService.setnx(key,"1");

if(status == 1){
    redisService.expire(key,expire);
    //执行独占资源逻辑
    doOcuppiedWork();
}

从Redis 2.1.6 以后,原子操作set:

SET key value [EX seconds] [PX milliseconds] [NX|XX]

> set lock 123 ex 10 nx
OK
> set lock 122 ex 10 nx
(nil)

代码实现例如:

RedisService redisService = SpringUtils.getBean(RedisService.class);
String result = redisService.set(lockKey,requestId,SET_IF_NOT_EXIST,
                                 SET_WITH_WITH_EXPIRE_TIME,expireTime);
if("OK".equals(result)){
    //执行独占资源逻辑
    doOcuppiedWork();
}

大量key同时过期的注意事项:

集中过期,由于清楚大量key很耗时,会出现短暂的卡顿现象。

解决方法:在设置key的过期时间的时候,给每个key加上一个随机值。

5. 如何使用Redis做异步队列

使用List作为队列,RPUSH生产消息,LPOP消费消息。

BLPOP key [key ...] timeout:阻塞直到队列有消息就能够返回或超时

pub/sub:主题发布-订阅模式

6. Redis如何做持久化

Redis有三种持久化的方式:

  1. RDB(快照)持久化:保存某个时间点的全量数据快照;

缺点:

redis.conf文件中:

save 900 1 #900秒之内如果有1条写入指令就触发一次快照
save 300 10
save 60 10000
​

stop-writes-on-bgsave-error yes #表示备份进程出错的时候,主进程就停止接收新的写入操作,是为了保护持久化数据的一致性
​
rdbcompression no #RDB的压缩设置为no,因为压缩会占用更多的CPU资源

手动触发:

自动触发:

BGSAVE原理:

Copy-on-write:

如果有多个调用者同时要求相同资源(如内存或磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本给该调用者,而其他调用者所见到的最初的资源仍然保持不变。

  1. AOF(Append-Only-File)持久化:保持写状态

日志重写解决AOF文件大小不断增大的问题,原理如下:

对于上图有几个关键点:

RDB和AOF文件共存情况下的恢复流程

RDB和AOF的优缺点:

类别 优点 缺点
RDB 全量数据快照,文件小,恢复快 无法保存最近一次快照之后的数据,会丢失这部分的数据
AOF 可读性高,适合保存增量数据,数据不易丢失 文件体积大,恢复时间长
  1. RDB-AOF混合持久化方式

在Redis 4.0之后推出了混合持久化方式,而且作为默认的配置方式。先以RDB方式从管道写全量数据再使用AOF方式从管道追加。AOF文件先半段是RDB形式的全量数据,后半段是Redis命令形式的增量数据。

7. 使用Pineline的好处

Redis的同步机制:

主从同步原理

全同步过程:

全同步完成后,后续所有写操作都是在Master上进行,读操作都是在Salve上进行。

增量同步过程:

主从模式的弊端在于不具有高可用性,当Master挂掉以后,Redis将不能对外提供写入操作。

Redis Sentinel(Redis哨兵)

解决主从同步Master宕机后的主从切换问题:

留言协议Gossip

在杂乱无章中寻求一致

8. Redis的集群原理

如何从海量数据里快速找到所需?

一致性哈希算法:对2^32取模,将哈希值空间组织成虚拟的圆环

将数据key使用相同的函数Hash计算出哈希值,具体可以选择服务器的ip或主机名作为关键字进行hash,这样就能确定每个服务器在Hash环上的位置。接下来,对数据使用同样的方法进行Hash去定位访问到的服务器,沿环顺时针行走第一台遇到的服务器就是存储的目标服务器。

综上所述,一致性哈希算法对于节点的增减都只需要定位环空间中的一小部分数据,具有较好的容错性和扩展性。

缺点:服务节点较少的时候,Hash环的数据倾斜问题

解决方法:引入虚拟节点,即对每个服务器节点计算多个hash,计算结果的位置都放置一个节点称为虚拟节点。具体做法,例如在服务器ip或主机名后添加后缀名。

参考资料

https://coding.imooc.com/class/303.html

上一篇 下一篇

猜你喜欢

热点阅读