今天来搭建一个Redis-Cluster, redis是在3.0.0版本后支持了Redis-Cluster集群, 它是Redis官方提出的解决方案, Redis-Cluster采用无中心结构, 每个节点保存数据和整个集群状态, 每个节点都和其他所有节点连接.
对于redis是什么, 以及如何搭建redis单机版本, 本文中就不介绍了.
我们为什么需要用到redis集群?
下面我们用一张图来看一下, 如何解决这样一个需求: 我需要存30G的数据到redis中, 但是一台机器只有10G不够使用, 所以我想使用redis集群来解决, 并且同时要做到高可用.
redis最少需要3个主节点, 对应每个主节点有一个副本(从节点), 所以我们最少需要6个节点. 本文将要搭建的依然是redis的伪集群, 就是在一台服务器(虚拟机)上搭建, 通过不同的端口号来区分. 其实与实际生产环境中的搭建步骤没有本质区别, 都是一样的.
了解redis集群中的存储机制 – 槽的概念(slot)
redis-cluster 把所有的物理节点映射到slot 上,cluster 负责维护.
Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样运算后得出的数肯定回事0-16383之间的一个数字. 因此这样每个key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。
例如三个节点:槽分布的值如下:
SERVER1: 0-5460
SERVER2: 5461-10922
SERVER3: 10923-16383
举个栗子:
在正式搭建之前, 先整理一下搭建Redis-Cluster集群需要哪些步骤:
准备工作:
redis的安装包
wget http://download.redis.io/releases/redis-4.0.2.tar.gz
tar -zxvf redis-4.0.2.tar.gz
linux系统 (这里使用的是centOS 6)
安装编译C语言的环境 (redis是C语言写的)
yum -y install gcc gcc-c++ libstdc++-devel tcl -y
安装ruby (们需要使用ruby脚本来实现集群搭建)
yum install ruby
yum install rubygems
搭建工作:
第一步: 上传redis的安装包到linux中, 解压缩.
mv redis-4.0.2/ redis-src
第二步: 进入redis, make 编译
cd /usr/local/redis-cluster/redis-src/
make MALLOC=libc
第三步: make install 安装6个redis实例
cd /usr/local/redis-cluster/redis-src/
make install PREFIX=/usr/local/redis-cluster/redis-1
make install PREFIX=/usr/local/redis-cluster/redis-2
make install PREFIX=/usr/local/redis-cluster/redis-3
make install PREFIX=/usr/local/redis-cluster/redis-4
make install PREFIX=/usr/local/redis-cluster/redis-5
make install PREFIX=/usr/local/redis-cluster/redis-6
第四步: 拷贝redis的配置文件redis.conf到6个实例的bin目录下
vim redis-1/bin/redis.conf
vim redis-2/bin/redis.conf
vim redis-3/bin/redis.conf
vim redis-4/bin/redis.conf
vim redis-5/bin/redis.conf
vim redis-6/bin/redis.conf
第六步: 启动6个redis实例
cd /usr/local/redis-cluster/redis-1/bin
./redis-server redis.conf
第七步: 上传用于搭建redis集群的ruby脚本
gem install redis-4.0.2.gem
然后发现出现了以下错误:
gem install redis
ERROR: Error installing redis:
redis requires Ruby version >= 2.2.2.
原来是因为我的centOSyum库中ruby的版本支持到1.8.7, 可gem 安装redis需要最低是2.2.2.
查了查资料, 解决办法有几种, 可以直接通过下面这一行命令直接下载高版本的ruby
wget https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.7.tar.gz
也可以使用rvm, 采用rvm来更新ruby. 那么rvm是什么呢? RVM是一个命令行工具, 可以提供一个便捷的多版本Ruby环境的管理和切换, 接下来我们使用rvm.
第一步: 接下来, 先安装rvm
#RVM需要通过CRUL来进行下载,那么我们要先下载CUEL
yum install curl
#使用curl安装rvm
curl -L get.rvm.io | bash -s stable
当然, 如果你网络不好, 也可以把压缩包下载下来, 然后传到linux上, 解压缩也是可以的. 下载地址:
https://codeload.github.com/rvm/rvm/tar.gz/1.29.4
第二步: 使用source读入该目录下的shell文件并执行
source /usr/local/redis-cluster/rvm-1.29.4/scripts/rvm
第三步: 查看rvm中管理的所有ruby版本
rvm list known
第四步: 选择一个版本, 安装ruby
rvm install 2.5.1
第五步: 使用ruby
rvm use 2.5.1
第六步: 查看当前ruby的版本号
ruby --version
到这里, 我们回到redis集群的搭建上来…
接下来, 我们再次安装用于搭建redis集群的ruby脚本
第八步: 安装ruby脚本
gem install redis-4.0.2.gem
第九步: 执行ruby脚本搭建redis集群
进入redis源码目录中的src目录 (有redis-trib.rb脚本) 执行下面的命令
注意: IP地址之间有空格
./redis-trib.rb create --replicas 1 192.168.179.133:7001 192.168.179.133:7002 192.168.179.133:7003 192.168.179.133:7004 192.168.179.133:7005 192.168.179.133:7006
参数
create: 创建
replicas 1: 副本数量为1
后面为6个redis实例的IP地址和端口号
这是执行返回的图, 可以看到7001,7002,7003是Master, 分别分配了对应的槽. 7004-7006是Slave分别对应上面的Master. 下方是询问我们是否同意这样配置, 这里输入yes即可.
到这里我们的Redis-Cluster就搭建完毕了, 接下来让我们测试一下吧.
第十步: 存入key-value, 进行测试
我们进入redis-1/bin下面, 使用客户端连接
./redis-cli -h 192.168.179.133 -p 7001 -c
-h 连接的IP
-p 连接的端口
-c 指的是使用集群
然后, 我们存入一个key-value
set name abc
这里我们看到, 为name的key得到的槽是5798, 所以cluster自动将该key-value分配到了7002上面.
然后我们进入7005, 看下作为7002的从节点, 是否有这个值呢?
可以看到, 通过7005也是有这个值的, 验证了redis集群的高可用性.
这里只需要在我们的xml配置文件中, 创建cluster的bean对象即可.
<bean id="redis-clusterConfiguration" class="org.springframework.data.redis.connection.redis-clusterConfiguration">
<property name="maxRedirects" value="${redis.maxRedirects}">property>
<property name="clusterNodes">
<set>
<bean class="org.springframework.data.redis.connection.redis-clusterNode">
<constructor-arg name="host" value="${redis.host1}">constructor-arg>
<constructor-arg name="port" value="${redis.port1}">constructor-arg>
bean>
<bean class="org.springframework.data.redis.connection.redis-clusterNode">
<constructor-arg name="host" value="${redis.host2}">constructor-arg>
<constructor-arg name="port" value="${redis.port2}">constructor-arg>
bean>
<bean class="org.springframework.data.redis.connection.redis-clusterNode">
<constructor-arg name="host" value="${redis.host3}">constructor-arg>
<constructor-arg name="port" value="${redis.port3}">constructor-arg>
bean>
<bean class="org.springframework.data.redis.connection.redis-clusterNode">
<constructor-arg name="host" value="${redis.host4}">constructor-arg>
<constructor-arg name="port" value="${redis.port4}">constructor-arg>
bean>
<bean class="org.springframework.data.redis.connection.redis-clusterNode">
<constructor-arg name="host" value="${redis.host5}">constructor-arg>
<constructor-arg name="port" value="${redis.port5}">constructor-arg>
bean>
<bean class="org.springframework.data.redis.connection.redis-clusterNode">
<constructor-arg name="host" value="${redis.host6}">constructor-arg>
<constructor-arg name="port" value="${redis.port6}">constructor-arg>
bean>
set>
property>
bean>
添加properties属性文件
#cluster configuration
redis.host1=192.168.179.133
redis.port1=7001
redis.host2=192.168.179.133
redis.port2=7002
redis.host3=192.168.179.133
redis.port3=7003
redis.host4=192.168.179.133
redis.port4=7004
redis.host5=192.168.179.133
redis.port5=7005
redis.host6=192.168.179.133
redis.port6=7006
好了, 到这里本文就告一段落了. 我也要起来活动活动了, 坐的久了容易的痔疮…