Redis学习笔记(三)

这一篇博客主要是学习redis的复制以及阻塞相关知识,在分布式系统中为了解决单点问题,通常会把数据复制多个副本到其他机器,满足故障恢复以及负载均衡等需求,redis也是如此,复制功能是redis高可用的基础。
redis是单线程架构,所有的读写操作都是在主线程中完成,当redis用于高并发时,如果出现阻塞,对于应用都是不好的,所以阻塞是redis是重点知识。

复制

我们将从redis复制的使用方式,可支持的复制方式以及复制原理这几个方面来说明redis复制。
使用方式
参与复制的redis实例划分为主节点和从节点,默认情况下, redis都是主节点,每个从节点只能有一个从节点,而主节点可以同时具有多个从节点,复制的数据六都是单向的,只能从主节点复制到从节点,复制方式有下面三种:

  1. 在配置文件中加入slaveof{masterHost}{masterPort}
  2. 在redis-server启动命令后键入 --slaveof{masterHost}{masterPort}
  3. 直接使用命令slaveof{masterHost}{masterPort}

主从节点复制成功后可以使用info replication命令查看复制相关状态
当我们需要断开复制的时候,使用slaveof no one来断开复制关系,断开后从节点晋升为主节点,同时也可以使用slaveof命令来实现把当前从节点的主节点切换到另一个主节点的操作,操作的流程是先断开与旧主节点的复制关系,与新节点建立复制关系,删除从节点当前所有的数据,对新主节点进行复制操作。
拓扑
redis的复制托盘结构可以支持单层或者多层复制关系,根据拓扑复杂性可以分为下main三种:一主一从,一主多从,树状主从。
首先我们来看最简单的一主一从结构,用于主节点出现宕机的时候从节点提供故障转移支持,党应用写命令并发量较高并且需要持久化的时候,可以只在从节点上开启AOF(持久化)这样既可以保证数据安全性同时也避免了持久化对主节点的性能干扰。
对于一主多从结构来说,使得应用端可以利用多个从节点实现读写分离,对于读占比比较大的场景,可以将读命令发送到从节点来减轻压力,多个从节点会导致主节点写命令的多次发送从而过度消耗网络带宽,同时加重了主节点的负载影响服务器稳定性。
还有一种树状主从结构,,使得从节点不但可以复制主节点的数据,同时可以作为其他从节点的主节点继续向下层复制,通过引入复制中间层,可以有效降低主节点负载和需要传送给从节点的数据量。
原理
在从节点执行slaveof命令后,复制过程便开始运作,大致可以分为下面六个过程:

  1. 保存主节点信息
  2. 主从建立socket连接
  3. 发送ping命令
  4. 权限验证
  5. 同步数据集
  6. 命令持续复制

阻塞

发生阻塞的内部原因可能有不合理的使用API或数据结构,CPU饱和或者持久化阻塞等,外在原因可能有CPU竞争,内存交换,网络问题等。
内在原因
通常redis知行命令速度非常快,但也存在例外,比如一个包含上万个原色的哈希使用hgetall操作,由于数据量大并且算法复杂度是o(n)这个就是对于API或者数据结构使用不合理。
除此之外还可能是CPU饱和,单线程的redis处理命令的时候只能使用一个cpu,而cpu饱和是说单核cpu的使用率接近100%,使用top命令可以识别出进程的cpu使用率,cpu饱和是非常危险的,将导致redis无法处理更多的命令,严重影响吞吐量和应用方的稳定性。
内部原因还包含持久化阻塞问题,杜宇开启了持久化功能的redis节点,需要排查是否是持久化导致的问题,持久化引起的主线程阻塞操作主要有fork阻塞,AOF刷盘等,fork阻塞发生在RDB与AOF重写的时候,redis主线程调用fork操作产生共享内存的子进程,由子进程完成持久化文件的重写工作。如果fork操作本身耗时过长,必然会导致主线程的阻塞。
外在原因
排查reids自身原因引起的阻塞原因后,如果还没有定位问题,需要排查是否是外部原因引起,可能的原因由cpu竞争,内存交换以及网络问题。
cpu竞争问题可能是进程竞争,redis是典型的cpu密集型应用,如果其他家including过度消耗cpu的时候,将会对redis吞吐量进行影响。
redis保存高性能的一个前提就是所有数据存在内存中,如果操作系统吧redis使用的部分内存换出到硬盘,由于内存与硬盘读写速度差了几个量级,会导致发生交换后的redis性能下降。

你可能感兴趣的:(系统编程)