Redis面试复习

1.认识Redis

  • 工作模型:单线程架构和IO多路复用来实现高性能的内存数据库服务
  • 原因:a)单线程简化数据结构和算法的实现;b)避免线程切换和线程竞争的开销
  • 应用场景:缓存/排行系统/统计器应用/社交网络/消息队列/热数据

2.数据类型

2-1.字符串类型

  • 命令相关:使用mget可以减少网络次数,提高开发效率(字符串不能超过512MB)
  • 内部编码:根据当前值的类型和长度决定使用哪种编码

    • int:8bytes长整型
    • embstr:小于等于39bytes的字符串
    • raw:大于39bytes的字符串
  • 底层数据结构:数组
  • 应用场景:缓存功能/计数/共享Seesion/限速

2-2.哈希类型

  • 命令相关:键值本身又是一个键值对结构; set key field
  • 内部编码:

    • ziplist压缩列表;满足哈希类型元素个数小于hash-max-ziplist-entries和所有值小于hash-max-ziplist-value
    • hashtable哈希表:当无法满足ziplist的条件时,会使用hashtable作为哈希的内部实现
  • 底层数据结构:数组(hashkey) + 链表(field)
  • 应用场景:关系数据表记录

2-3.列表类型

  • 命令相关:可以根据索引查询修改,阻塞删除,头尾添加;根据不同的命令可以实现队列/栈等操作
  • 内部编码:

    • ziplist压缩列表;满足哈希类型元素个数小于hash-max-ziplist-entries和所有值小于hash-max-ziplist-value
    • linkedlist链表:当无法满足ziplist的条件时,会使用linkedlist作为列表的内部实现
  • 底层数据结构:双向链表
  • 应用场景:消息队列/文章列表

2-4.集合

  • 命令相关:一个集合中可以存放多个元素
  • 内部编码:

    • intset整数集合:当集合中的元素个数小于set-max-intset-entries配置
    • hashtable哈希表;当集合类型无法满足intset条件
  • 底层数据结构:hash
  • 应用场景:标签功能

2-5.有序集合

  • 命令相关:一个集合中可以存放多个拥有分数的元素,用于排序
  • 内部编码:

    • ziplist压缩列表:当集合中的元素个数小于set-max-ziplist-entries配置
    • skiplist跳跃表;当集合类型无法满足ziplist条件时
  • 底层数据结构:hash + 跳跃表
  • 应用场景:排行系统

3.小功能

3-1.慢查询

  • 配置方式:a)配置文件;b)动态配置(rewrite持久化到本地配置文件中)
  • 获取慢查询日志:slowlog show get [n];采用队列存储,先进先出形式
  • 日志属性:日志标识,发生时间,命令耗时,执行命令和参数
  • 最佳实践:max-len > 1000 & slower-than 1ms

3-2.Pipeline

  • 场景:将一组命令封装,通过一次RTT传输;能够减少网络延迟和性能瓶颈
  • Redis的批量命令与Pipeline区别:

    • 原子性:批量命令是原子性的
    • 命令格式:批量命令一次对应多个Key
    • 实现机制:Pipeline需要客户端支持
  • 最佳实践:可以将大Pipeline拆分成多个小Pipeline来完成

3-3.事务和Lua

  • 事务:原子性,保证数据一致性
  • 相关命令:multi开始事务,exec事务提交,discard停止事务;watch确保事务中的key没有被其他客户端修改
  • 事务错误: a)语法错误:Redis事务忽略; b)运行错误:事务提交后执行报错
  • 不支持回滚:保持Redis的简单快捷;关于语法错误而失败应该在开发过程中被发现
  • Lua脚本:Redis脚本语言

    • Lua脚本在Redis中是原子执行的,执行过程中不插入其他命令
    • Lua脚本定制命令并可以常驻内存中,实现复用的效果
    • Lua脚本可以将多条命令一次性打包,减少网络开销

3-4.Bitmaps和Hyperloglog

  • Bitmaps:一个以位为单位的数组,数组中的每个单元只能存储0和1,数组的下标称之为偏移量
  • 设置:setbit key offset value
  • 运算:bitop [and(交集) | or(并集) | not(非) | xor(异或)] destkey [keys...]
  • 应用场景:大用户量时统计活跃数,能有效减少内存
  • Hyperloglog:一种基数算法,实际数据类型为字符串类型,利用极小的内存空间完成独立总数的统计(不需要单条记录)

3-5.发布和订阅

发布者客户端向指定的频道(channel)发布消 息,订阅该频道的每个客户端都可以收到该消息

  • 相关命令:publish发布,subscrible订阅
  • 注意点:a)客户端在执行订阅命令之后进入订阅状态;b)新开启的订阅客户端,无法接受到该频道之前的消息,因为Redis不会对发布的消息进行持久化
  • 使用场景:聊天室/公告牌/消息解耦/视频管理系统

3-6.GEO

地理信息定位功能:支持存储地理位置信息来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能;底层实现是:zset

4.客户端

客户端通信协议:基于TCP协议定制RESP实现交互的
RESP协议优点:a)实现容易;b)解析快;c)人类可读

4-1.客户端管理

4-2.客户端常见异常

5.持久化

5-1.RDB方式

RDB持久化:把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化分为手动触发和自动触发

  • 手动触发:通过bgsave命令Redis进程执行fork操作创建子进程,由子进程负责完成
  • 自动触发:

    • save相关配置: sava m n (表示m秒内数据集存在n次修改即自动触发bgsave)
    • 从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点
    • 执行debug reload命令重新加载Redis时,也会自动触发save操作
    • 默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行bgsave
  • 执行流程:

Redis面试复习_第1张图片

  • RDB文件处理:保存和压缩并校验
  • RDB优点:

    • 代表某个时间点的数据快照,适用备份和全量复制等场景
    • 压缩的二进制文件,恢复“大数据集”效率较高
  • RDB缺点:

    • 数据的实时持久化较差并且fork()操作会带来堵塞
    • 特定的二进制文件会带来兼容性问题

5-2.AOF方式

AOF持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的,解决数据持久化的实时性

  • AOF工作流程:
  1. 命令写入以追加方式到AOF_buf
  2. AOF缓冲区根据策略同步到AOF文件
  3. 随着AOF文件变大,需要定期对AOF文件进行重写,达到压缩目的
  4. 当Redis重启时,可以加载AOF文件进行数据恢复
  • 命令写入追加到缓冲区的目的:

    • 写入的内容是文件协议格式(1.兼容性;2.可读性;3.避免二次处理开销)
    • 在性能和安全性方面做出平衡
  • 同步策略:Redis提供多种AOF缓冲区同步文件策略,由appendfsync控制

    • always:调用write操作后并调用fsync保证AOF文件写入到磁盘中
    • no:调用write操作后,AOF文件同步到磁盘交由操作系统去实现
    • everysec:调用write操作后,由专门线程去每秒调用一次fsync
  1. write操作:会触发延迟写机制,因为Linux在内核提供页缓冲区来提供磁盘IO性能;write操作在写入系统缓冲区后直接返回,同步硬盘依赖于系统调度机制
  2. fsync操作:针对单个文件操作做强制硬盘同步,fsync将阻塞直到写入硬盘完成后返回,保证了数据持久化

重写机制:把Redis进程内的数据转化为命令同步到新AOF文件的过程,这个过程会让AOF文件体积变小,从而提高恢复时的效率

  1. 进程已经超时的数据不再写入新文件
  2. 通过进程内数据直接生成,避免旧文件中的无效命令
  3. 多条命令可以合并为一个

AOF重写触发方式:
手动触发:执行bgrewriteaof命令
自动触发:同时满足以下2个条件

  1. auto-aof-rewrite-min-size:表示运行AOF重写时文件最小体积,默认为64MB
  2. auto-aof-rewrite-percentage:表示当前AOF文件空间和上一次重写后AOF文件空间的比值
  • AOF重写工作流程

Redis面试复习_第2张图片

  • Redis持久化加载流程

    1. AOF持久化开启时且存在AOF文件时,优先加载AOF文件
    2. AOF关闭或者AOF文件不存在时,加载RDB文件
    3. 加载AOF/RDB文件成功后,Redis启动成功
    4. AOF/RDB文件存在错误时,Redis启动失败
  • 关于AOF文件异常

    • 损坏的文件Redis服务会拒绝启动(可以通过redis-check-aof-fix命令修复后,进行对比并进行手工修改补全)
    • 结尾不挖完整的文件Redis服务忽略并继续启动,同时打印报警信息

AOF追加阻塞:当开启AOF持久化时,常用的同步磁盘策略是everysec,对于这种方式,Redis会使用同步条线程每秒执行fsync同步硬盘,当系统硬盘资源繁忙时,会造成Redis主线程阻塞
everysec刷盘策略过程

  1. 同步线程负责每秒调用fsync操作进行同步磁盘
  2. 主进程会去对比上次fsync同步时间,如果在2s内则通过,否则会堵塞(磁盘资源紧张)
  3. everysec策略最多可能丢失2s数据;如果系统fsync缓慢,会导致主进程堵塞
  • AOF优点:

    • 实时备份:能够到秒级
    • 以appen-only的模式写入:没有磁盘寻址开销,写入性能较高
    • 可读性强:具有更灵活的处理方式
  • AOF缺点:

    • 相同的数据集:AOF文件会比RDB文件大
    • Redis高负载情况下:RDB会拥有更好的性能保证
    • 数据恢复比价慢,不适合做全量备份

6.复制

7.阻塞

8.内存

9.集群架构

10.缓存设计

11.其他

你可能感兴趣的:(redis,面试)