Redis常见面试题总结

Redis是什么?

Redis(Remote Dictionary Server)是一个使用 C 语言编写的,高性能非关系型的键值对数据库。与传统数据库不同的是,Redis 的数据是存在内存中的,所以读写速度非常快,被广泛应用于缓存方向。Redis可以将数据写入磁盘中,保证了数据的安全不丢失,而且Redis的操作是原子性的。

Redis优缺点?

优点

  1. 基于内存操作,内存读写速度快。
  2. 支持多种数据类型,包括String、Hash、List、Set、ZSet等。
  3. 支持持久化。Redis支持RDB和AOF两种持久化机制,持久化功能可以有效地避免数据丢失问题。
  4. 支持事务。Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。
  5. 支持主从复制。主节点会自动将数据同步到从节点,可以进行读写分离。
  6. Redis命令的处理是单线程的。Redis6.0引入了多线程,需要注意的是,多线程用于处理网络数据的读写和协议解析,Redis命令执行还是单线程的。

arcstack大约 48 分钟缓存Redis
Redis简介

简介

Redis是一个高性能的key-value数据库。Redis对数据的操作都是原子性的。

优缺点

优点:

  1. 基于内存操作,内存读写速度快。
  2. Redis是单线程的,避免线程切换开销及多线程的竞争问题。单线程是指在处理网络请求(一个或多个redis客户端连接)的时候只有一个线程来处理,redis运行时不止有一个线程,数据持久化或者向slave同步aof时会另起线程。
  3. 支持多种数据类型,包括String、Hash、List、Set、ZSet等
  4. 支持持久化。Redis支持RDB和AOF两种持久化机制,持久化功能有效地避免数据丢失问题。
  5. redis 采用IO多路复用技术。多路指的是多个socket连接,复用指的是复用一个线程。redis使用单线程来轮询描述符,将数据库的开、关、读、写都转换成了事件。多路复用主要有三种技术:select,poll,epoll。epoll是最新的也是目前最好的多路复用技术。

arcstack大约 3 分钟缓存Redis
Redis LUA脚本

LUA脚本

Redis 通过 LUA 脚本创建具有原子性的命令: 当lua脚本命令正在运行的时候,不会有其他脚本或 Redis 命令被执行,实现组合命令的原子操作。

在Redis中执行Lua脚本有两种方法:eval和evalsha。

eval 命令使用内置的 Lua 解释器,对 Lua 脚本进行求值。

//第一个参数是lua脚本,第二个参数是键名参数个数,剩下的是键名参数和附加参数
> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"

arcstack大约 2 分钟缓存Redis
Redis删除策略

删除策略

  1. 被动删除。在访问key时,如果发现key已经过期,那么会将key删除。

  2. 主动删除。定时清理key,每次清理会依次遍历所有DB,从db随机取出20个key,如果过期就删除,如果其中有5个key过期,那么就继续对这个db进行清理,否则开始清理下一个db。

  3. 内存不够时清理。Redis有最大内存的限制,通过maxmemory参数可以设置最大内存,当使用的内存超过了设置的最大内存,就要进行内存释放, 在进行内存释放的时候,会按照配置的淘汰策略清理内存,淘汰策略一般有6种,Redis4.0版本后又增加了2种,主要由分为三类:

    • 第一类 不处理 noeviction。发现内存不够时,不删除key,执行写入命令时直接返回错误信息。(默认的配置)

    • 第二类 从所有结果集中的key中挑选,进行淘汰

      • allkeys-random 就是从所有的key中随机挑选key,进行淘汰
      • allkeys-lru 就是从所有的key中挑选最近最少使用的数据淘汰
      • allkeys-lfu 就是从所有的key中挑选使用频率最低的key,进行淘汰。(这是Redis 4.0版本后新增的策略)
    • 第三类 从设置了过期时间的key中挑选,进行淘汰

      这种就是从设置了expires过期时间的结果集中选出一部分key淘汰,挑选的算法有:

      • volatile-random 从设置了过期时间的结果集中随机挑选key删除。
      • volatile-lru 从设置了过期时间的结果集中挑选最近最少使用的数据淘汰
      • volatile-ttl 从设置了过期时间的结果集中挑选可存活时间最短的key开始删除(也就是从哪些快要过期的key中先删除)
      • volatile-lfu 从过期时间的结果集中选择使用频率最低的key开始删除(这是Redis 4.0版本后新增的策略)

arcstack大约 2 分钟缓存Redis
Redis其他知识点

其他

客户端

Redis 客户端与服务端之间的通信协议是在TCP协议之上构建的。

Redis Monitor 命令用于实时打印出 Redis 服务器接收到的命令,调试用。

redis 127.0.0.1:6379> MONITOR 
OK
1410855382.370791 [0 127.0.0.1:60581] "info"
1410855404.062722 [0 127.0.0.1:60581] "get" "a"

arcstack大约 4 分钟缓存Redis
Redis数据类型

数据类型

Redis支持五种数据类型:

  • string(字符串)
  • hash(哈希)
  • list(列表)
  • set(集合)
  • zset(sorted set)

字符串类型

字符串类型的值可以是字符串、数字或者二进制,但值最大不能超过512MB。

常用命令:set, get, incr, incrby, desr, keys, append, strlen

  • 赋值和取值
SET name tyson
GET name

arcstack大约 8 分钟缓存Redis
Redis数据结构

数据结构

动态字符串

SDS(simple dynamic string,SDS),简单动态字符串,其定义如下:

struct sdshdr {

    // 记录 buf 数组中已使用字节的数量
    // 等于 SDS 所保存字符串的长度
    int len;

    // 记录 buf 数组中未使用字节的数量
    int free;

    // 字节数组,用于保存字符串
    char buf[];

};

arcstack大约 4 分钟缓存Redis
Redis底层实现

string

字符串对象的编码可以是 int 、 raw 或者 embstr 。

  1. 如果一个字符串对象保存的是整数值, 并且这个整数值可以用 long 类型来表示, 那么会将编码设置为 int 。
  2. 如果字符串对象保存的是一个字符串值, 并且这个字符串值的长度大于 39 字节, 那么字符串对象将使用一个简单动态字符串(SDS)来保存这个字符串值, 并将对象的编码设置为 raw 。
  3. 如果字符串对象保存的是一个字符串值, 并且这个字符串值的长度小于等于 39 字节, 那么字符串对象将使用 embstr 编码的方式来保存这个字符串值。

arcstack大约 4 分钟缓存Redis
Redis排序

排序

LPUSH myList 4 8 2 3 6
SORT myList DESC
LPUSH letters f l d n c
SORT letters ALPHA

arcstack小于 1 分钟缓存Redis
Redis事务

事务

事务的原理是将一个事务范围内的若干命令发送给Redis,然后再让Redis依次执行这些命令。

事务的生命周期:

  1. 使用MULTI开启一个事务

  2. 在开启事务的时候,每次操作的命令将会被插入到一个队列中,同时这个命令并不会被真的执行

  3. EXEC命令进行提交事务

DISCARD:放弃事务,即该事务内的所有命令都将取消

一个事务范围内某个命令出错不会影响其他命令的执行,不保证原子性:


arcstack大约 1 分钟缓存Redis
2