集群原理
redis cluster在设计的时候,就考虑到了去中心化,去中间件,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。
Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽 (hash slot)的方式来分配的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384。所以我们在测试的时候看到set 和 get 的时候,直接跳转到了7000端口的节点。
Redis 集群会把数据存在一个 master 节点,然后在这个 master 和其对应的salve 之间进行数据同步。当读取数据时,也根据一致性哈希算法到对应的 master 节点获取数据。只有当一个master 挂掉之后,才会启动一个对应的 salve 节点,充当 master 。
需要注意的是:必须要3个或以上的主节点,否则在创建集群时会失败,并且当存活的主节点数小于总节点数的一半时,整个集群就无法提供服务了。
环境
硬件:两台linux电脑
软件:ruby、ruby-devel、rubygems、rpm-build
说明
这里我两台电脑的ip分别是10.185.162.108、10.185.162.114
集群的服务端口是7001~7006
下载
常见redis有:原生redis、ApsaraCache redis官方文档:redis文档、ApsaraCache文档 其他运行环境:ruby、zlib、openssl
编译安装
解压
我们如果下载的是原生redis,默认文件后缀是.tar.gz格式的,那么我们用tar命令来解压文件
tar -zxvf redis-4.0.6.tar.gz
如果我们下载的是ApsaraCache,默认文件后缀是.zip格式的,我们可用unzip来解压
unzip ApsaraCache-master.zip
注意:由于这是一个redis集群,所以我们把多个节点的配置和程序放在一个共同的目录下,便于管理,由于我安装的是ApsaraCache(飞天缓存);所以我就创建了目录ApsaraCache_cluster,并把刚解压的文件移动到这个目录下并且重新命名redis_cluster
mv ApsaraCache-master redis_cluster
mkdir ApsaraCache_cluster
mv redis_cluster ApsaraCache_cluster/
编译
cd ApsaraCache_cluster/redis_cluster
make
make install
这里算是安装完了redis,如果是单机版,那么我们可以启动redis了,如果是集群,那么请参考我们的部署
src/redis-server redis.conf
部署
因为我们要创建3主3从共计6个节点的redis,所以我们把配置和redis运行文件分开,这里我用两台电脑(这里我用ip1、ip2来表示两台电脑的ip地址)来实现redis集群,由于两台电脑的配置是类似的,所以这里我只给出一台电脑的配置,另一台请参照这个配置,只需要修改少数地方即可。我们可以使用7001~7006共计6个数字来表示分别对应的端口,7001~7003是ip1的三个redis,7004-7006是ip2的三个端口,ip2的配置请参照ip1的配置来修改
cd ..
mkdir 7001 7002 7003
cp redis_cluster/redis.conf 7001/
cp redis_cluster/redis.conf 7002/
cp redis_cluster/redis.conf 7003/
分别修改这三个配置文件,修改如下内容:
port 7001 //端口7001,7002,7003
bind 本机ip //这里要配置本机ip,不是配置127.0.0.1
daemonize yes //redis后台运行
pidfile /var/run/redis_7001.pid //pidfile文件对应7000,7001,7002
cluster-enabled yes //开启集群 把注释#去掉
cluster-config-file nodes_7001.conf //集群的配置 配置文件首次启动自动生成 7000,7001,7002
cluster-node-timeout 15000 //请求超时 默认15秒,可自行设置
appendonly yes //aof日志开启 有需要就开启,它会每次写操作都记录一条日志
接着在另一台电脑上进行上面的下载、编译、部署三个操作,只需要把目录改成7004、7005、7006,然后把三个配置文件按照规则一并修改了即可
启动各节点
第一台机器上执行
redis_cluster/src/redis-server redis_cluster/7001/redis.conf
redis_cluster/src/redis-server redis_cluster/7002/redis.conf
redis_cluster/src/redis-server redis_cluster/7003/redis.conf
另外一台机器上执行
redis_cluster/src/redis-server redis_cluster/7004/redis.conf
redis_cluster/src/redis-server redis_cluster/7005/redis.conf
redis_cluster/src/redis-server redis_cluster/7006/redis.conf
检查redis启动情况
这里只演示一台机器,另一台机器命令一样
查看redis进程情况
ps -ef | grep redis
root 2001 1 0 13:02 ? 00:00:06 redis_cluster/src/redis-server 127.0.0.1:7001 [cluster]
root 2003 1 0 13:02 ? 00:00:06 redis_cluster/src/redis-server 127.0.0.1:7002 [cluster]
root 2011 1 0 13:02 ? 00:00:06 redis_cluster/src/redis-server 127.0.0.1:7003 [cluster]
查看redis端口情况
netstat -lntp | grep redis
tcp 0 0 127.0.0.1:17002 0.0.0.0:* LISTEN 2003/redis_cluster/
tcp 0 0 127.0.0.1:17003 0.0.0.0:* LISTEN 2011/redis_cluster/
tcp 0 0 127.0.0.1:7001 0.0.0.0:* LISTEN 2001/redis_cluster/
tcp 0 0 127.0.0.1:7002 0.0.0.0:* LISTEN 2003/redis_cluster/
tcp 0 0 127.0.0.1:7003 0.0.0.0:* LISTEN 2011/redis_cluster/
tcp 0 0 127.0.0.1:17001 0.0.0.0:* LISTEN 2001/redis_cluster/
创建集群
Redis 官方提供了 redis-trib.rb 这个工具,就在解压目录的 src 目录中,可以直接在命令行中使用了。使用下面这个命令即可完成集群部署,当提示我们输入时,我们输入yes
即可
/home/hyxt/ApsaraCache_cluster/redis_cluster/src/redis-trib.rb create --replicas 1 10.185.162.108:7001 10.185.162.108:7002 10.185.162.108:7003 10.185.162.114:7004 10.185.162.114:7005 10.185.162.114:7006
由于我对linux不太熟悉,这里我只查看了iptables是没有启用,忽略了systemctl防火墙了,后面我打开了systemctl就可以访问了,添加systemctl的方法请自行搜索查找(开放7001-7006和17001-17006),7001-7006是我们的服务端口,17001-17006是我们的集群通信端口
注意:由于这个集群命令是ruby环境,所以我们需要提前安装好ruby,如果没有ruby环境,那么我们可以用yum安装一下
yum -y install ruby ruby-devel rubygems rpm-build
gem install redis
这里我使用yum安装的是1.8.7版本的ruby,导致版本太低,无法运行,然后我去ruby官网下载了ruby-2.4.3,但是这个编译始终不行,然后我又去淘宝镜像下载了ruby-2.3.0并编译成功了,然后就成功安装好了ruby
然后我用gem安装redis插件是失败,这里安装失败是因为外网镜像比较慢,导致我们下载失败,所以我们需要更换成淘宝镜像
gem sources --remove https://rubygems.org/ //删除ruby官方镜像
gem sources -a https://ruby.taobao.org/ //添加ruby淘宝镜像
gem sources -l //查看镜像列表
这里我们运行./redis-trib.rb
命令启动集群时,如果出现如下的错
>>> Creating cluster
[ERR] Node 10.185.162.108:7001 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
1、将需要新增的节点下aof、rdb等本地备份文件删除;
2、同时将新Node的集群配置文件删除,即:删除你redis.conf里面cluster-config-file所在的文件;
3、再次添加新节点如果还是报错,则登录新Node,./redis-cli–h x –p对数据库进行flushdb
.在使用redis-trib.rb create --replicas 1 xxx来创建集群,在运行到下面的时候一直等待
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join.................................
这里一直等待join.
原因是在配置文件中的参数bind 写的有问题,
原来是bind 127.0.0.1 192.168.1.1
后来修改为bind 10.185.162.108 127.0.0.1,这个ip地址换成我们服务器的ip地址
即将实际IP写在回环ip之前即可解决.
安全配置
注意事项
1.如果是使用redis-trib.rb工具构建集群,集群构建完成前不要配置密码,集群构建完毕再通过config set + config rewrite命令逐个机器设置密码
如果对集群设置密码,那么requirepass和masterauth都需要设置,否则发生主从切换时,就会遇到授权问题,可以模拟并观察日志
各个节点的密码都必须一致,否则Redirected就会失败,这里我们将密码设置成abc,如果当前节点作为从节点是,我们使用masterauth认证,如果当前节点作为主节点,我们是用requirepass认证,这里我们将两个节点设置成一样的密码
config set masterauth abc
config set requirepass abc
config rewrite
如果原来没有设置密码,那么我们使用config rewrite
则会出错,因为我们设置密码后立即生效了,我们没验证时不允许其他操作
2.修改Redis默认端口,将默认的6379端口修改为其他端口
3.设置密码访问认证,可通过修改redis.conf配置文件中的"requirepass" 设置复杂密码
4禁止Redis服务对公网开放,可通过修改redis.conf配置文件中的"#bind 127.0.0.1" ,去掉前面的"#"即可,然后将127.0.0.1换成本机地址即可
集群验证
在第一台机器上连接集群的7002端口的节点,在另外一台连接7005节点,连接方式为
redis-cli -h 192.168.31.245 -c -p 7002 //加参数 -C 可连接到集群,因为上面 redis.conf 将 bind 改为了ip地址,所以 -h 参数不可以省略。`
在7005节点执行命令
set hello world
然后在另外一台7002端口,查看 key 为 hello 的内容
get hello
如果得到
world
说明集群运作正常
如果有提示CLUSTERDOWN The cluster is down
,这个往往是由于主node移除了,但是并没有移除node上面的slot,从而导致了slot总数没有达到16384,其实也就是slots分布不正确。所以在删除节点的时候一定要注意删除的是否是Master主节点
官方是推荐使用redis-trib.rb fix 来修复集群…. …. 通过cluster nodes看到7001这个节点被干掉了… 那么
./redis-trib.rb fix 10.185.162.108:7001
修复完成后再用check命令检查下是否正确
./redis-trib.rb check 10.185.162.108:7000
只要输入任意集群中节点即可,会自动检查所有相关节点。可以查看相应的输出看下是否是每个Master都有了slots,如果分布不均匀那可以使用下面的方式重新分配slot:
./redis-trib.rb reshard 10.185.162.108:7001
常见问题
linux控制台下不会修改配置
1. 请参考vi命令
服务器没通外网导致无法在线安装ruby和ruby相关软件:
1. ruby官网下载所需要的ruby环境和gem相关环境
2. 使用光盘安装ruby和gem环境
3. 联系网管开通外网服务,使用yum在线安装ruby和gem
服务器未开放7001-7006导致无法连接redis
联系网管开通7001-7006服务端口
服务器未开放17001-17006导致集群无法通信,一直提示try...
联系网管开通17001-17006端口
安装了ruby ruby-devel rubygems rpm-build提示找不到zlib、openssl
换成2.3.0就解决了这个问题
gem install redis提示ERROR: Could not find a valid gem 'redis' (>= 0) in any repository
将地址换成国内淘宝的镜像即可
gem sources --remove https://rubygems.org/
gem sources -a https://ruby.taobao.org/
gem sources -l
参考资料
- http://www.runoob.com/ruby/ruby-installation-unix.html
- http://chinacheng.iteye.com/blog/1480145
- http://bbs.qcloud.com/thread-30706-1-1.html