驽马十驾 驽马十驾

驽马十驾,功在不舍

目录
Redis集群方案
/  

Redis集群方案

Redis集群方案

Redis简介

Redis特点

Redis是一个开源的高性能的key-value存储系统。具有以下特点:

  1. 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  2. 丰富的数据类型 – Redis支持二进制案例的 String, List, Hash, Set 及 Sorted Set 数据类型操作。
  3. 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
  4. 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性
  5. Redis支持数据的备份,即master-slave模式的数据备份。
  6. Redis支持数据的持久化,能够在一定层度上保证数据不丢失。

Redis常见误区

  1. Redis代理传统数据库。
  2. Redis是多线程的。
  3. 一台服务器部署一个Redis实例。

Redis高性能的原因

  1. 存储:数据存储在内存中。
  2. 通信:通过多路复用进行IO优化。
  3. 单线程:通过单线程运行,避免了多线程下上下文切换导致的时间耗费。

Redis集群高可用方案

Redis集群高可用方案可以分为如下几类

  • 传统的Replication方案,即Master-Slave-Sentinel。
  • 客户端分片,客户端自己通过Key分片,服务端通过多组Redis高可用进行组合。
  • 代理分片,服务端通过多组Redis高可用进行组合。
  • Redis3.0官方带来的Redis Cluster集群方案。

下面将分别介绍这些方案。

Replication方案:Master-Slave-Sentinel

通过一主多从的方案实现Redis的高可用,其核心架构为1个Master多个Slave再加多个Sentinel。

示意图如下所示:
image.png

  1. Master负责Redis集群对外的的写和读操作。
  2. Slave为Master的副本,其数据来源于Master的同步,客户端可以从此处进行信息读取,减轻Master服务器压力。
  3. Sentinel是哨兵,主要作用是监控Master和Slave的存活情况,当Master宕机后将Slave提升为Master,并发布事件通知。

该方案的优点是:

  1. 历史最悠久的Redis高可用方案,大部分的Redis集群都是建立在该方案的基础上的。
  2. 经过最大量的实践,可靠性得到了充足的验证。
  3. 运维方式比较简单,不需要引入第三方中间件。

该方案有什么缺点了?

  1. Redis的容量上限受制于Master所在服务器的内存上限。
  2. Redis的计算能力受限于Master所在服务器的CPU资源上限。

为了弥补上述缺点,在Redis Cluster方案出来之前,开源者们提出了数据分片的概念来解决此问题。

Redis数据分片

数据分片是指将数据的主键通过Hash算法将其路由到不同的Redis Group中。其中每一个Redis Group的容量只有传统Replication的一部分,将压力分摊到每个Redis Group中,其服务端部署图如下所示:

image.png

该方案简述如下:

  1. 每一个Redis Group 只负责一部分缓存,分配了传统方式Master的内存压力和CPU压力。
  2. 每一个Redis Group可以由Master+Slave+Sentinel 组成,保证高可用。

该方案的优点:

  1. 内存压力由之前的单台服务器转嫁到了多台服务器,多台服务器可以承担更大的存储要求。
  2. 将Redis的计算压力进行了分摊,充分利用了多台主机的CPU资源。

那么如何实现该方案了?

客户端分片

客户端分片是客户端在进行Redis操作的时候,在本地就对Key进行hash处理来获取具体对哪台服务器进行操作。

该方法比较简单,只需要在进行操作前,对Key进行Hash处理,然后直接操作对应的Redis服务端即可。

该方式的缺点也是比较明显:

  1. 如果后端Redis的实例发生变换的时候,就有可能找不到缓存,需要重新从数据库读取并缓存。
  2. 无法支持涉及多键的操作:例如对Set 1和Set 2 求交集的时候,如果其不在一个Redis中,那么就无法直接操作。

代理分片

代理分片技术有2款重要的开源产品,一款是Twitter的Twemproxy,一款是Codis。

  • Twemproxy已经停止维护了,但是因为其功能很简单,所以目前仍然能够满足基本使用。
  • Codis可以看做是Twemproxy的一个超集,不仅实现了Twemproxy的所有功能,再引入Codis其他组件的情况下,还能实现Redis服务器动态增减、监控等其他附加功能。

设计架构图如下所示:

image-20181107162718180

  1. 每一个redis group 都应该是一个高可用的Redis集群,其架构设计同Replication,如下所示

image-20181107162839072

  1. 代理节点因为不应该是单点,所以通过Keepalived来实现高可用。

image-20181107162941051

  1. 客户端只需要连接Keepavlied暴露的虚拟IP即可。

该架构的优点是:

  1. 客户端无侵入,因为Proxy实现了Redis的协议,所以之前怎么操作Redis,现在也如何操作,无需客户端代码变更。
  2. 通过代理的方式引入了数据分片的技术,提高了服务器的资源利用。

其缺点也很明显:

  1. 因为走了一层代理,多了一层请求转发和响应转发,随意性能会有一定损耗,其该损耗随着数据增大而近乎几何倍增大。
  2. 服务端Redis服务器增加受到限制。其中TwemProxy完全不支持Redis服务器增加后的自动重新分配,Codis需要使用其维护的Codis Redis Server才能够实现该功能,这样也限制了自身Redis Server的升级,同时因为非官方维护,也存在一定风险。
  3. 引入了其他中间件,增加了运维难度:单个代理存在单点问题,所以需要类似Keepalived的方式来实现高可用。
  4. 同客户端分片一样,不支持多键操作,比如交集和并集。

服务端分片:Redis 3.0 Cluster

Redis 3.0发布后,官方终于发布了自己的服务端分片技术Redis Cluster,这是一种去中心化的设计。

其核心原理是在多个Redis实例上平均分配0-16384个槽(slot),每一个Redis实例有部分Slot。然后通过主键进行Hash处理,将结果缓存到对应的slot所在的服务器中,其算法为:hash_slot = crc16(key) mod 16383

下面通过一个简单的例子进行说明:假如有3个Redis的实例,第一个Redis实例有0-5461个slot,第二个实例有5462-10922,第三个实例有10923-16383。有一个Key经过hash取模后得到的slot为3456,那么便会将对应的数据存放在第一个服务器中。

其架构图如下所示:

image-20181107165409219

  1. 节点之间通过Ping-Pong机制进行存活判定,当半数以上的实例来判定某一个Redis实例宕机,那么该实例宕机
  2. 因为需要半数确认,所以在做高可用,需要部署3个Master实例,并且每一个Master实例都加一个Slave。该方案最起码需要3主3从共6个Redis实例。
  3. 在Master宕机后,Slave会被自动提升为Master,不需要额外通过Sentinel,客户端只要有1个Master节点可以通信就可以保证服务正常运行。

该架构优点为:

  1. 客户端使用简单。
  2. 动态增减Redis实例的时候,服务端可以很方便的进行重新分片,客户端无感知。
  3. 每一个节点都可以对外提供服务,可以通过ASK 转向/MOVED 转向机制进行请求的转发。
  4. 相比Codis运维简单,不需要引入第三方中间件。

总结

从部署和运维方式来看,由易到难是如下顺序:

Replication ≈ 客户端分片< 简单代理 ≈ 服务端分片(Cluster)< 中间代理并支持Redis的重新分配

从客户端代码实现复杂度来讲:

Replication ≈ 服务端分片(Cluster) ≈ 简单代理 < 客户端分片 ≈ 中间代理并支持Redis的重新分配

综上所述

  1. 如果仅仅只需要进行缓存,且该缓存的预期量级单机都能支持的,那么通过Replication进行高可用即可。
  2. 其他的选型可以根据上述罗列的分类进行选型。
骐骥一跃,不能十步。驽马十驾,功在不舍。