Redis-核心概念
wenking 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 主从复制支持 主从同步
和 从从同步
两种。
原理:
- 保存主节点信息(ip和port)
- 从节点尝试和主节点建立socket链接
- 从节点发送ping命令
- 从节点提供密码进行权限认证
- 主节点发送数据到从节点同步数据集
- 命令持续复制
问题:
- 主节点故障,需要手动将从节点晋升为主节点,需要人工干预。
- 写能力和存储能力受单机影响
# 哨兵模式
哨兵节点: 哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的 Redis 节点,不存储数据,对数据节点进行监控。 数据节点: 主节点和从节点都是数据节点;
监控:
- 每隔10秒,每个Sentinel节点会向主节点和从节点发送info命令获取最新的拓扑结构
- 每隔2秒,每个Sentinel节点会向Redis数据节点的__sentinel__:hello 频道上发送该Sentinel节点对于主节点的判断以及当前Sentinel节点的信息
- 每隔1秒,每个Sentinel节点会向主节点、从节点、其余Sentinel节点发送一条ping命令做一次心跳检测,来确认这些节点当前是否可达
功能:
- 监控主节点和从节点工作情况
- 主节点不工作,哨兵将会把其中一个从节点升级为主节点,让其他从节点复制该选举的主节点
- 客户端连接哨兵获取主节点地址
- 故障转移结果发送给客户端
流程:
- 每个Sentinel节点对其他节点(主、从、其他Sentinel)发送ping,如果节点响应超时,会被该Sentinel标记为主观下线
- 当主观下线的节点是主节点,Sentinel会询问其他Sentinel节点对该主节点判断,当超过半数被Sentinel标记为主观下线,Sentinel将标记该节点为客观下线
- Sentinel领导选举,选出一个Leader做故障转移(Raft)。
- 从其他节点中选取一个从节点,让其成为主节点,并向其他从节点发送服从新主节点命令,将原先主节点标记为从节点,并持续关注状态,恢复正常后去复制新的主节点
主节点选取原则: 网络响应状态好、复制偏移最高或优先级配置
# 集群
功能:数据分片、数据冗余、故障恢复、负载均衡。
# 集群分片方案
- 节点取余:hash(key) % N(节点编号) 问题: 当节点数量变化时,如扩容或收缩节点,数据节点映射关 系需要重新计算,会导致数据的重新迁移。
- 一致性哈希: 问题: 加入和删除节点会影响哈希环(顺时针下一个)节点(减少/增加相邻节点数据量),缓存在圆环上分配不均,导致部分节点压力过大。
- 虚拟槽:CRC16(key)% 16383;集群启动时每个节点都将分配一定量的槽数,增加/删除节点都将重新分配槽(回收其他节点槽/分配该节点槽给其他节点)