Redis基本原理!

Redis协议

RESP,它是一种简单的文本协议,用于在客户端和服务器之间操作和传输数据。

RESP协议描述了不同类型的数据结构,并且定义了请求和响应之间如何以这些数据结构进行交互。

RESP 非常简单且人类可读,这使得 Redis 能够易于使用和调试。

同时,RESP 也允许客户端和服务器以高效和低延迟的方式发送和接收数据。

单线程模式

Redis的网络IO和键值对读写是由一个线程来完成的。

Redis在处理客户端的请求时包括获取(读)、解析、执行、内容返回(写)等都由一个顺序串行的主线程处理。

由于Redis在处理命令的时候是单线程作业的,所以会有一个Socket队列。

  • 每一个到达的服务端命令来了之后都不会马上被执行,而是进入队列,然后被线程的事件分发器逐个执行。

image

Redis的其他功能,比如持久化、异步删除、集群数据同步等等,其实是由额外的线程执行的。

Redis工作线程是单线程的,但是在4.0之后,对于整个Redis服务来说,还是多线程运作的。

Redis为什么那么快?

基于内存实现:

Redis 将数据存储在内存中,读写操作不会受到磁盘的 IO 速度限制,所以Redis的读写速度会非常的快。

CPU 不是 Redis 的瓶颈,Redis 的瓶颈是机器内存的大小或者网络带宽

使用I/O多路复用模型:

Redis 线程不会阻塞在某一个特定的客户端请求处理上。

  • 可以同时和多个客户端连接并处理请求,从而提升了并发性。

采用单线程模型:

Redis 的网络 IO 以及键值对指令读写是由一个线程来执行的。

  • 对于 Redis 的持久化、集群数据同步、异步删除等都是其他线程执行。

单线程 避免了 线程切换竞态 产生的消耗,对于服务端开发来说,锁和线程切换 通常是性能杀手。

高效的数据结构:

为了追求速度,不同数据类型使用不同的数据结构速度才得以提升。

Redis是如何保证高可用的?

主从复制

  • 每个节点都有多个副本,一个主节点搭配多个从节点。
  • 主节点负责读写,从节点只负责读。
  • 主节点的数据实时异步复制到从节点。

自动故障转移(Failover)

  • 当主节点宕机时,从节点通过心跳检测发现主节点故障。
  • 从节点会发起投票选举一个新主节点。
  • 选举成功后,从节点自动提升为主节点,继续提供服务。

集群节点通信机制

  • 集群内节点通过 Gossip 协议交换状态信息,感知节点健康状况。
  • 节点之间定期发送心跳消息,快速发现节点失效。

数据分片与槽(Slot)机制

  • Redis集群将数据分为16384个槽,每个节点负责一部分槽。
  • 当节点故障时,仅受影响槽的数据不可用,而不是整个集群不可用,其他槽数据正常服务。

客户端智能路由

  • Redis集群客户端可感知节点拓扑结构,自动路由请求至正确的节点。
  • 当节点发生变化时,客户端能快速感知并调整请求路由。

通过以上机制,Redis集群能够在节点发生故障时,快速恢复并保持高可用状态。

CPU多核对Redis性能的影响

在 CPU 多核场景下,Redis 实例被频繁调度到不同 CPU 核上运行的话,那么,对 Redis 实例的请求处理时间影响就大了。

因为每调度一次,一些请求就会受到运行时信息、指令和数据重新加载过程的影响。

  • 这就会导致某些请求的延迟明显高于其他请求。

要避免Redis总在不同CPU核上来回调度执行,可将Redis实例和CPU核绑定。

  • 这样Redis实例会固定运行在一个CPU核上。