上篇文章刚刚介绍完redis的主从复制集群,但主从复制集群主要是为了解决redis集群的单点故障问题,通过整合哨兵能实现集群的高可用;但是却无法解决数据容量以及单节点的压力问题,所以本文继续介绍redis的分片集群;分片集群即将不同的数据分发到不同的redis实例(或者主从集群),每个redis实例没有关联,这样当数据量过大时就做到了数据的分治,如果某个实例故障也不至于丢失所有的数据;下面我会首先解决分片集群的常用实现方案,然后介绍如何搭建Twitter和predixy两种代理实现的redis集群,正常情况,按照我的步骤做完就能够搭建一套可以的redis集群了;下面开始

一、分片集群的解决方案

这里我们不单一讨论redis,我们从分片集群的根本出发,分片即将数据分发到不同的后端服务上去,那么显然我们可以从客户端和服务端这两个方面下手;

1、客户端实现

(1)、通过业务分类

  • 可以根据业务分类,由客户端控制,将不同业务线的数据打到不同的实例

(2)、hash+取模(modula)

  • 思路:通过对key进行hash+取模然后根据结果打到不同的实例上;模几取决于redis集群的实例数量;
  • 缺点:模数是固定的,如果集群拓展时需要调整,且拓展前的数据就不好取到了;

(3)、通过随机数选择redis实例(random)

  • 思路:数据到达时随机往集群中的某个实例扔数据,这样存数据是容易了但是取数据难
  • 使用场景:这种情况适用于实现消息队列,往不同的redis里仍相同key的不同数据,客户端消费集群中的每个实例后就能获取到完整数据

(4)、一致性哈希环(ketama)

  • 思路:维护一个虚拟的环形结构,该环有N个点组成;将redis集群中的所有实例通过一致性哈希算法计算后映射到该哈希环上,作为环中唯一的物理节点,如果集群有三个实例,那么环中就会有三个物理节点;当数据进来时,对key做哈希运算最终也要落到这个哈希环上,然后找出离自己最近的物理节点,再将数据打到该节点上即可
  • 缺点:
    • 由于每个实例参与计算的信息不一样,并不总能保证集群的各节点在环上是均匀分布的,所以为了解决数据倾斜的问题,可以将每个实例多映射几份一起参与计算,这样散在环上的节点变多了,也就一定程度上解决了数据倾斜的问题
    • 当有新的实例上线时,会丢失一定长度数据;可以通过改变寻找实例的逻辑解决,当key打到环上时,我们不再是找离它最近的一个节点,而是找离他最近的两个节点取数据

2、服务端实现(redis cluster)

(1)、基本概念介绍(概念摘自redis官网)

  • Redis集群是一个提供在多个Redis间节点间共享数据的程序集,能够自动分发数据到不同实例;其并没有使用一致性哈希算法,而是引入了哈希槽的概念;Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:
    • 节点 A 包含 0 到 5500号哈希槽.
    • 节点 B 包含5501 到 11000 号哈希槽.
    • 节点 C 包含11001 到 16384号哈希槽.

(2)、redis的集群搭建

  • 这里的搭建很简单,按照中文官网的步骤往下走就行了,这里就不一一介绍了,需要搭建的可以移步http://redis.cn/topics/cluster-tutorial.html

二、通过Twitter的twemproxy代理搭建redis集群

  • 1、mkdir twemproxy在/root目录创建一个twemproxy用来存放twemproxy的源码

  • 2、安装git yum install git

  • 3、克隆twemproxy的代码

  • 4、进入源码目录,cd twemproxy

  • 5、安装automake和libtool

    • yum install automake libtool -y
  • 6、安装configure,执行autoreconf -fvi

  • 7、执行 ./configure

  • 8、执行make编译源码,编译完正常会有可执行程序出现

  • 9、进入源码的/scripts目录,将配置文件拷贝至/etc/init.d/twemproxy目录

    • cp nutcracker.init /etc/init.d/twemproxy
  • 10、进入init.d文件, 执行chmod +x twemproxy给twemproxy赋权

  • 11、创建配置文件所在的目录

    • mkdir /etc/nutcracker
  • 12、进入源码安装目录的conf目录,将conf目录下的配置文件拷贝到11步创建的文件夹下

    • cd ~/soft/twemproxy/twemproxy/conf
    • cp ./* /etc/nutcracker/
  • 13、进入源码安装目录的src目录,将编译完的可执行程序复制到/usr/bin目录下,这样在系统任意位置都可以运行nutcracker

    • cd ~/soft/twemproxy/twemproxy/src/
    • cp nutcracker /usr/bin
  • 14、进入nutcracker目录,修改配置文件

    • cd /etc/nutcracker/
    • cp nutcracker.yml nutcracker.yml.bak 稳妥起见,先备份
    • vi nutcracker.yml 编辑配置文件
  • 15、启动两个redis实例

    • redis-server ~/testRedis/6379.conf
    • redis-server ~/testRedis/6380.conf
  • 16、启动nutcracker

    • service twemproxy start
  • 17、启动redis客户端连接nutcracker对外暴露的端口

    • redis-cli -p 22121 连接成功后如图,即可对redis进行操作
      redis集群之分片集群的原理和常用代理环境部署-LMLPHP

三、通过predixy搭建redis集群

  • 1、在~/soft目录创建predixy目录并且进入,用于下载源码;
    • mkdir predixy
    • cd predixy
  • 2、下载源码包
  • 3、解压
    • tar xf predixy-1.0.5-bin-amd64-linux.tar.gz
  • 4、进入conf目录,编辑predixy.conf文件
    • vi predixy.conf
    • 将bind 127.0.0.1:7617的注释放开
    • 将Include try.conf注释,将Include sentinel.conf放开
  • 5、编辑sentinel.conf 文件
    • vi sentinel.conf
    • 将SentinelServerPool配置的注释放开,并按下图进行配置
      redis集群之分片集群的原理和常用代理环境部署-LMLPHP
  • 6、根据5中的注意,所以我们现在需要去修改哨兵的配置文件,将其监控的master名称由默认的mymaster改为shard001,又因为我们需要哨兵监控两个主从集群,所以需要再加一个shard002的master配置,命令如下:

    • vi 26379.conf 、 vi 26380.conf 、 vi 26381.conf

    • 修改完的配置文件如下图
      redis集群之分片集群的原理和常用代理环境部署-LMLPHP

  • 7、启动哨兵集群

    • redis-server ./26379.conf --sentinel
    • redis-server ./26380.conf --sentinel
    • redis-server ./26381.conf --sentinel
  • 8、任意位置创建文件夹test,在里面创建36379、80和46379、80的目录

    • 进入36379目录执行 redis-server --port 36379

    • 进入36380目录执行 redis-server --port 36380 --replicaof 127.0.0.1 36379追随36379

      这样一个主从集群就搭建起来了,46379和80与上面一致,只需更改对应端口即可,我这里就不再赘述了

  • 9、进入predixy安装的bin目录启动predixy

    • cd soft/predixy/predixy-1.0.5/bin
    • ./predixy ../conf/predixy.conf
    • 启动成功如下图:
      redis集群之分片集群的原理和常用代理环境部署-LMLPHP
  • 10、用redis客户端测试

    虽然上面搭建废了九牛二虎之力,但是对客户端而言只需关注predixy对外暴露的服务连接即可:

    • redis-cli -p 7617

    连接成功后就可以操作redis了,predixy会自动分发到不同的redis集群中去;设置如图:
    redis集群之分片集群的原理和常用代理环境部署-LMLPHP

    • 然后连接36379可以发现,k1和设置了tag的key都分发到此了,如图:
      redis集群之分片集群的原理和常用代理环境部署-LMLPHP
    • 再连接46379,发现k2被分发到46379了
      redis集群之分片集群的原理和常用代理环境部署-LMLPHP
12-01 10:07