上篇文章刚刚介绍完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的代码
- git clone https://github.com/twitter/twemproxy.git
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-cli -p 22121 连接成功后如图,即可对redis进行操作
三、通过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配置的注释放开,并按下图进行配置
6、根据5中的注意,所以我们现在需要去修改哨兵的配置文件,将其监控的master名称由默认的mymaster改为shard001,又因为我们需要哨兵监控两个主从集群,所以需要再加一个shard002的master配置,命令如下:
vi 26379.conf 、 vi 26380.conf 、 vi 26381.conf
修改完的配置文件如下图
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
- 启动成功如下图:
10、用redis客户端测试
虽然上面搭建废了九牛二虎之力,但是对客户端而言只需关注predixy对外暴露的服务连接即可:
- redis-cli -p 7617
连接成功后就可以操作redis了,predixy会自动分发到不同的redis集群中去;设置如图:
- 然后连接36379可以发现,k1和设置了tag的key都分发到此了,如图:
- 再连接46379,发现k2被分发到46379了