Redis技术总结 — 基础篇

Redis简介

Redis是一种基于键值对的NoSQL数据库,redis的值支持string,hash,list,set,zset,Bitmaps,HyperLogLog,GEO等。Redis常作为分布式系统架构中的缓存,也可做简单的消息队列服务。

效率高的原因

  • 数据存放在内存中
  • C语言编写
  • 单线程架构:1.基于epoll的I/O多路复用技术非阻塞I/O(类似于java NIO) 2.单线程避免了线程切换和竞态产生的消耗。

单机部署架构图

redis单机部署架构图如下面所示,部署一个master节点和多个slave节点。我们来整理一下客户端写入数据到redis的整个过程。

  • 客户端通过RESP(redis序列化协议基于TCP协议)连接redis服务器
  • 多个客户端连接redis服务器后,redis服务器端基于epoll的I/O多路复用技术,监听epoll的连接,读写,关闭事件
  • client执行redis写入命令,命令进入每个客户端专用的输入缓冲区
  • 命令从输入缓冲区进入事件执行队列排队等待执行
  • redis执行命令
  • 命令执行结果保存在每个客户端专用的输出缓冲区等待返回结果给客户端
  • 客户端处理执行结果

总结一下整个流程:client连接redis -> client发送命令 -> redis输入缓冲区 -> redis执行队列 -> 执行命令 -> 输出缓冲区 -> client处理执行结果

Redis技术总结 — 基础篇_第1张图片

 

键命令和过期策略

遍历键

  1. 全量遍历键,如果redis包含大量的键,可能会造成redis阻塞(redis执行命令的线程只有一条)。
  2. scan渐进式遍历,多次遍历,一次遍历一部分的键,如果遍历过程中有增加,删除,修改键,可能造成遍历出来的键丢失,重复,不正确等。

键过期策略

  1. 惰性删除,当客户端读取到键时,如果发现键过期,删除键 并返回null。
  2. 定时任务删除,定时任务每秒允许10次(可配置)。每隔一段时间执行一次删除过期键的操作,并通过限制删除操作执行时长和频率来减少操作对cpu时间的影响。

常用功能

  • 慢查询日志,找到执行慢的命令
  • Pipeline,比批量命令更加好用,节约网络通信的时间
  • 事务,单机模式下可执行
  • lua脚本,自己组装命令成脚本,一起原子执行
  • 客户端连接池,复用连接提高效率减少开销

持久化

RDB

RDB持久化是把当前的数据生成数据快照保存到硬盘上的过程。

手动触发:

  • save命令,阻塞当前redis服务器,直到RDB过程完成为止
  • bgsave命令,redis执行fork操作创建子进程,持久化过程由子进程负责。fork期间redis服务器阻塞很短的时间

自动触发:

  • 使用了save相关配置,‘save m n’,m秒内数据集存在n次修改
  • 从节点执行全量复制操作
  • debug reload命令重新加载redis
  • shutdown命令,如果没有开启AOF持久化

优缺点:

  • 压缩的二进制文件,加载速度快
  • 无法做到实时持久化

AOF

以独立日志的方式记录每次命令,重启时重新执行命令来恢复数据。

流程如下:

  • 所有命令(redis序列化协议格式)会追加到AOF缓冲区中。
  • AOF缓冲区同步到硬盘。
  • AOF重写压缩文件体积。可以压缩的原因是,1.进程内超时的数据不写入。2.去掉无效的命令,只保留最终的写入命令。 3.合并命令。
  • 重新加载。服务器重启时优先加载AOF,AOF无法加载成功时,加载RDB。

AOF缓冲区同步硬盘策略:

  • always,命令写入AOF缓冲区后,执行fsync(强制同步, 阻塞直到写入硬盘为止)操作同步到AOF硬盘文件。
  • no,命令写入AOF缓冲区后,执行write(先写入系统缓冲区,系统缓冲区写满或者达到特定的事件周期后,操作系统帮忙写入硬盘),后操作系统帮忙写入硬盘(一般30秒左右后会持久化到硬盘)。
  • everysec,命令写入AOF缓冲区后,执行write操作。专门线程每秒调用一次fsync命令写入命令道AOF硬盘文件。

复制

redis为了解决单点问题通常会将数据复制到多个副本部署到其他机器上。

复制过程:

  • 从节点保存主节点信息
  • 从节点与主节点建立socket网络连接
  • 从节点发送ping请求进行首次通信
  • 主节点验证权限
  • 复制数据
  • 持续复制,保证主从数据一致性

复制知识点:

  • 复制分为全量复制和部分复制。
  • 主从节点保存复制偏移量记录复制的位置。
  • 复制积压缓冲区保存最近复制的命令用于复制命令丢失的数据补救。
  • 全量复制主节点把RDB文件发送给从节点,部分复制主节点发送命令给从节点执行。

阻塞场景:

  • API或数据结构使用不合理,复杂度为O(n)的操作,存储过大的对象。
  • 持久化阻塞,fork创建子进程阻塞,AOF刷盘阻塞,主命令执行进程和AOF刷盘执行的fsync命令都会往硬盘上写入数据,如当硬盘压力过大时,主线程发现距离上一次fsync成功时间超过2秒,主线程为了保证数据的安全性会阻塞直到fsync完成为止。
  • 单机效率达到上限,CPU饱和,需要使用集群模式来分担压力。
  • CPU竞争,内存交换,网络问题等外在因素也会导致redis阻塞。

内存溢出控制策略

当redis所用内存达到maxmemory上限时会触发内存溢出控制策略,6种策略如下:

  • volatile-lru -> 根据LRU算法生成的过期时间来删除。
  • allkeys-lru -> 根据LRU算法删除任何key。
  • volatile-random -> 根据过期设置来随机删除key。
  • allkeys->random -> 无差别随机删。
  • volatile-ttl -> 根据最近过期时间来删除(辅以TTL)
  • noeviction -> 谁也不删,直接在写操作时返回错误。

 

 

你可能感兴趣的:(开源技术总结,开源技术总结)