Redis-核心概念

7/11/2024 redis

# redis早期使用单线程模型已经6.0后选择多选程模型原因

  • 早期使用单线程原因:redis基于内存的操作,对内存和网络I/O读写要求比较高,对CPU计算要求不高。
  • 6.0后选择多线程原因:通常说redis是单线程原因在于redis执行命令是按接受顺序执行,此处多线程是指redis执行I/O操作使用多线程提高网络读写效率。

redis服务端架构采用reactive模型,主线程收到命令后会将其拆分多读、写事件,采用多线程方式处理这些读写事件可以加速网络I/O。

# 缓存一致性解决方案

读缓存:读缓存,读缓存失败则读数据库,然后缓存读数据库数据。 写缓存:更新数据库,然后删除缓存。

CacheAside 方案为常规缓存一致方案,但仍然存在缓存不一致情况。如果对一致性要求比较高,需要额外操作。

缓存和数据库不一致原因:

  • 缓存key删除失败【比如某时刻缓存失效、读key不存在,读数据库,写更新数据库并删缓存(删除失败,缓存不存在),读写缓存】
  • 并发导致写入脏数据

解决方案:

  • 消息队列保证key被删除:把删除失败的key放入消息队列中,然后拉取消息重试删除。
  • canal订阅binlog + 消息队列重试

# 高可用

功能: 数据冗余、故障恢复、负载均衡。

# 主从复制

Redis 主从复制支持 主从同步从从同步 两种。

原理:

  1. 保存主节点信息(ip和port)
  2. 从节点尝试和主节点建立socket链接
  3. 从节点发送ping命令
  4. 从节点提供密码进行权限认证
  5. 主节点发送数据到从节点同步数据集
  6. 命令持续复制

问题:

  • 主节点故障,需要手动将从节点晋升为主节点,需要人工干预。
  • 写能力和存储能力受单机影响

# 哨兵模式

哨兵节点: 哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的 Redis 节点,不存储数据,对数据节点进行监控。 数据节点: 主节点和从节点都是数据节点;

监控:

  1. 每隔10秒,每个Sentinel节点会向主节点和从节点发送info命令获取最新的拓扑结构
  2. 每隔2秒,每个Sentinel节点会向Redis数据节点的__sentinel__:hello 频道上发送该Sentinel节点对于主节点的判断以及当前Sentinel节点的信息
  3. 每隔1秒,每个Sentinel节点会向主节点、从节点、其余Sentinel节点发送一条ping命令做一次心跳检测,来确认这些节点当前是否可达

功能:

  1. 监控主节点和从节点工作情况
  2. 主节点不工作,哨兵将会把其中一个从节点升级为主节点,让其他从节点复制该选举的主节点
  3. 客户端连接哨兵获取主节点地址
  4. 故障转移结果发送给客户端

流程:

  1. 每个Sentinel节点对其他节点(主、从、其他Sentinel)发送ping,如果节点响应超时,会被该Sentinel标记为主观下线
  2. 当主观下线的节点是主节点,Sentinel会询问其他Sentinel节点对该主节点判断,当超过半数被Sentinel标记为主观下线,Sentinel将标记该节点为客观下线
  3. Sentinel领导选举,选出一个Leader做故障转移(Raft)。
  4. 从其他节点中选取一个从节点,让其成为主节点,并向其他从节点发送服从新主节点命令,将原先主节点标记为从节点,并持续关注状态,恢复正常后去复制新的主节点

主节点选取原则: 网络响应状态好、复制偏移最高或优先级配置

# 集群

功能:数据分片、数据冗余、故障恢复、负载均衡。

# 集群分片方案

  • 节点取余:hash(key) % N(节点编号) 问题: 当节点数量变化时,如扩容或收缩节点,数据节点映射关 系需要重新计算,会导致数据的重新迁移。
  • 一致性哈希: 问题: 加入和删除节点会影响哈希环(顺时针下一个)节点(减少/增加相邻节点数据量),缓存在圆环上分配不均,导致部分节点压力过大。
  • 虚拟槽:CRC16(key)% 16383;集群启动时每个节点都将分配一定量的槽数,增加/删除节点都将重新分配槽(回收其他节点槽/分配该节点槽给其他节点)