1.Redis分布式部署方案
1)客户端分区
由客户端程序决定key写分配和写入的redis node,但是需要客户端自己处理写入分配、高可用管理和故障转移等
2)代理方案
基于第三方软件实现redis proxy,客户端先连接代理层,由代理层实现key的写入分配,对客户端来说是比较简单,
但是对于集群,管理节点增减相对比较麻烦,而且代理本身也是单点和性能瓶颈
单机的redis写入性能受限于:单机的内存大小、并发数量、网卡速率等因素
redis官方在redis3.0版本之后推出了无中心架构的redis cluster机制,在无中心的redis集群中,其每个节点保存
当前节点数据和整个集群状态,每个节点都和其他所有节点连接
#特点如下:
1.所有Redis节点使用PING机制互联
2.集群中某个节点的失效是:整个集群中超过半数的节点监测都失效才算真正的失效
3.客户端不需要proxy即可直接连接redis,应用程序需要写全部的redis服务器IP
4.redis cluster把所有的redis node映射到0-16383个槽位(slot)上,读写需要到指定的redis node上进行操作
,因此有多少个reids node相当于redis并发扩展了多少倍。
5.Redis cluster预先分配16384个槽位(slot),当需要在redis集群中写入一个key value的时候,会使CRC16(key)mod 16384
之后的值,决定将key写入值哪一个槽位,从而决定写入哪一个Redis节点上,从而有效解决单机瓶颈
1.2.基本架构
1.3.主从架构
2.部署
2.1部署前提
1.每个redis node节点,采用相同的硬件配置、相同的密码
requirepass 123456
masterauth 123456 #设置masterauth,否则主从无法建立;手动设置:CONFIG SET masterauth 123456
2.每个节点必须开启的参数
cluster enabled yes #必须开启集群状态,开启后redis进程会有cluster显示
cluster config file nodes 6380.conf #此文件有redis cluster集群自动创建和维护,不需要任何手动操作
3.所有redis服务器必须没有任何数据
4.先启动为单机redis且没有任何key value
ip地址 | 端口 | 说明 |
192.168.47.54 | 6379 | master |
192.168.47.54 | 6380 | slave |
192.168.47.55 | 6379 | master |
192.168.47.55 | 6380 | slave |
192.168.47.56 | 6379 | master |
192.168.47.56 | 6380 | slave |
192.168.47.57 | 6379 | 作为后期新加入集群节点-master |
192.168.47.57 | 6380 | 作为后期新加入集群节点-slave |
2.2redis-trib.rb安装--这儿就作为参考吧,在ubuntu中redis-trib.rb都废弃了
Redis3和4版本
需要使用到集群管理工具redis-trib.rb
这个工具是redis官方推出的,管理redis集群的工具,集成在redis的源码src目录下
是基于redis提供的集群命令,封装成简单、便捷、实用的操作工具
redis-trib.rb是redis作者用ruby开发完成的
centos系统yum安装的ruby存在版本较低问题,所以需要编译安装
#编译安装,安装到一台主机即可
root@ubuntu:~# wget https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.5.tar.gz
root@ubuntu:~# tar xf ruby-2.5.5.tar.gz
root@ubuntu:~# cd ruby-2.5.5
root@ubuntu:~/ruby-2.5.5# ./configure
root@ubuntu:~/ruby-2.5.5# apt-get install make
root@ubuntu:~/ruby-2.5.5# make -j 2 && make install
root@ubuntu:~/ruby-2.5.5# ruby -v
ruby 2.5.5p157 (2019-03-15 revision 67260) [x86_64-linux]
root@ubuntu:~/ruby-2.5.5# apt-get install rubygems
root@ubuntu:~/ruby-2.5.5/ext/openssl# gem install redis
Fetching: redis-4.6.0.gem (100%)
Successfully installed redis-4.6.0
Parsing documentation for redis-4.6.0
Installing ri documentation for redis-4.6.0
Done installing documentation for redis after 0 seconds
1 gem installed #安装成功
2.2.2.提示错误1
root@ubuntu:~/ruby-2.5.5# gem install redis
ERROR: Loading command: install (LoadError)
cannot load such file -- zlib
ERROR: While executing gem ... (NoMethodError)
undefined method `invoke_with_build_args' for nil:NilClass
这是缺少zlib依赖,需要安装zlib库
解决办法
root@ubuntu:~/ruby-2.5.5/ext/zlib# cd /root/ruby-2.5.5/ext/zlib
root@ubuntu:~/ruby-2.5.5/ext/zlib# ruby extconf.rb
checking for deflateReset() in -lz... no
checking for deflateReset() in -llibz... no
checking for deflateReset() in -lzlib1... no
checking for deflateReset() in -lzlib... no
checking for deflateReset() in -lzdll... no
checking for deflateReset() in -lzlibwapi... no #这种情况表示失败,检测环境
1:gcc
2:zlib-devel
在ubuntu软件源里zlib和zlib-devel叫做zlib1g zlib1g.dev
sudo apt-get install zlib1g
sudo apt-get install zlib1g.dev #如果是centos系统,yum install zlib-devel
#成功了
root@ubuntu:~/ruby-2.5.5/ext/zlib# ruby extconf.rb
checking for deflateReset() in -lz... yes
checking for zlib.h... yes
checking for crc32_combine() in zlib.h... yes
checking for adler32_combine() in zlib.h... yes
checking for z_crc_t in zlib.h... yes
creating Makefile
#提示如下错误
root@ubuntu:~/ruby-2.5.5/ext/zlib# make
make: *** No rule to make target '/include/ruby.h', needed by 'zlib.o'. Stop.
遇到此问题是因为前一步自动配置的文件[Makefile]路径错误,
将Makefile文件中的$(top_srcdir)/include/ruby.h修改为$(hdrdir)/ruby.h即可
#成功
root@ubuntu:~/ruby-2.5.5/ext/zlib# make
compiling zlib.c
linking shared-object zlib.so
root@ubuntu:~/ruby-2.5.5/ext/zlib# make install
/usr/bin/install -c -m 0755 zlib.so /usr/local/lib/ruby/site_ruby/2.5.0/x86_64-linux
2.2.3.提示错误2
root@ubuntu:~/ruby-2.5.5/ext/zlib# gem install redis
ERROR: While executing gem ... (Gem::Exception)
Unable to require openssl, install OpenSSL and rebuild Ruby (preferred) or use non-HTTPS sources
#缺少openssl库的错误
解决办法
#安装包
RedHat、centos:yum install openssl-devel
ubuntu:sudo apt-get install openssl && sudo apt-get install libssl-dev
root@ubuntu:~/ruby-2.5.5/ext/openssl# ruby extconf.rb
root@ubuntu:~/ruby-2.5.5/ext/openssl# vim Makefile
:%s@$(top_srcdir)/include/ruby.h@$(hdrdir)/ruby.h@ #所有的$(top_srcdir)/include/ruby.h修改为$(hdrdir)/ruby.h
root@ubuntu:~/ruby-2.5.5/ext/openssl# make
root@ubuntu:~/ruby-2.5.5/ext/openssl# make install
/usr/bin/install -c -m 0755 openssl.so /usr/local/lib/ruby/site_ruby/2.5.0/x86_64-linux
installing default openssl libraries
2.2.4.验证
root@ubuntu:/data/redis-5.0.3/src# ln -s /data/redis-5.0.3/src/redis-trib.rb /usr/bin/
root@ubuntu:/data/redis-5.0.3/src# redis-trib.rb
-------------------------------------------------------------
WARNING: redis-trib.rb is not longer available!
You should use redis-cli instead.
All commands and features belonging to redis-trib.rb have been moved
to redis-cli.
In order to use them you should call redis-cli with the --cluster
option followed by the subcommand name, arguments and options.
Use the following syntax:
redis-cli --cluster SUBCOMMAND [ARGUMENTS] [OPTIONS]
Example:
redis-cli --cluster info 127.0.0.1:7000
To get help about all subcommands, type:
redis-cli --cluster help
2.2.5.redis-trib.rb命令
[root@s1-ruby-2.5.4]# redis-trib.rb
Usage: redis
trib <command> <options> <arguments ...>
create host1: port1 ... hostN:portN #创建集群
--replicas <arg> #指定master的副本数量
check host:port #检查集群信息
info host:port #查看集群主机信息
fix host:port #修复集群
--timeout <arg>
reshard host:port #在线热迁移集群指定主机的slots数据
--from <arg>
--to <arg>
--slots <arg>
--yes
--timeout <arg>
--pipeline <arg>
rebalance host:port #平衡集群中各主机的slot数量
--weight <arg>
--auto weights
--use empty masters
--timeout <arg>
--simulate
--pipeline <arg>
--threshold <arg>
add-node new_host:new_port existing_host:existing_port #添加主机到集群
--slave
--master id <arg>
del-node host:port node_id #删除主机
set-timeout host:port milliseconds #设置节点的超时时间
call host:port command arg arg .. arg #在集群上的所有节点上执行命令
import host:port #导入外部redis服务器的数据到当前集群
--from <arg>
--copy
--replace
help (show this help)
2.3.创建集群
vim /usr/local/lib/ruby/gems/2.5.0/gems/redis-4.6.0/lib/redis/client.rb
#修改redis登录密码,没搞懂这个在哪里修改,这里我没有修改它
#集群创建
Redis3/4版本---会提示用redis-cli创建,所以我还是用的下面redis-cli创建的集群
[root@s1 ~]# redis-trib.rb create --replicas 1 \
192.168.47.54:6379 192.168.47.55:6379 192.168.47.56:6379 \
192.168.47.54:6380 192.168.47.55:6380 192.168.47.56:6380
#Redis5版本
/usr/local/6379/redis/bin/redis-cli -a 123456 --cluster create \
192.168.47.54:6379 192.168.47.55:6379 192.168.47.56:6379 \
192.168.47.54:6380 192.168.47.55:6380 192.168.47.56:6380 --cluster-replicas 1
2.3.2.查看
生成的集群架构图
2.3.3.集群状态
2.3.4.写入key验证
在56主机写入
127.0.0.1:6379> set key1 value1
(error) MOVED 9189 192.168.47.55:6379
提示要去55主机写,在55主机写入成功
127.0.0.1:6379> set key1 value1
OK
2.3.5.集群状态监测
root@ubuntu:~# redis-trib.rb check 192.168.47.54:6379
----------------------------------------------------------------
WARNING: redis-trib.rb is not longer available!
You should use redis-cli instead.
All commands and features belonging to redis-trib.rb have been moved
to redis-cli.
In order to use them you should call redis-cli with the --cluster
option followed by the subcommand name, arguments and options.
Use the following syntax:
redis-cli --cluster SUBCOMMAND [ARGUMENTS] [OPTIONS]
Example:
redis-cli --cluster check 192.168.47.54:6379
To get help about all subcommands, type:
redis-cli --cluster help
----------------------------------------------------------------
3.redis集群节点维护
#动态添加节点
增加redis node节点,需要与之前的redis node版本相同,配置一致
3.1添加节点
检查没有问题,加入节点有问题,emo..
redis-cli --cluster check 127.0.0.1:6379 -a 123456
#Redis5添加方式
#这里add-node任意写一个节点都可以
root@ubuntu:~# redis-cli -a 123456 --cluster add-node 192.168.47.54:6379 192.168.47.57:6379
---------------------------------------------------------------------------------------------
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Adding node 192.168.47.54:6379 to cluster 192.168.47.57:6379
>>> Performing Cluster Check (using node 192.168.47.57:6379)
M: ae0577b87fdc9408581ae6e70d15bb907906e65f 192.168.47.57:6379
slots: (0 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[ERR] Not all 16384 slots are covered by nodes.
##emo了,结果写反了,反手给自己一巴掌
redis-cli -a 123456 --cluster add-node 192.168.47.57:6379 192.168.47.54:6379
redis-cli -a 123456 --cluster add-node 192.168.47.57:6380 192.168.47.54:6379
前面的为新增加的主机ip和端口,后面为集群中某个节点的ip和端口
这里加入集群都是作为master的,后续需要给某个master指定slave,比如后面我会把192.168.47.57:6380
指定为192.168.47.57:6379的slave
注意,注意啦,分配槽位是不能有数据存在的
#分配槽位
使用命令对新加的主机重新分配槽位
redis-cli -a 123456 --cluster reshard 192.168.47.57:6379
因为选的是all,这里重新分配槽位是自动从每个Redis node上移动一些槽位到新的master上
为新的master指定slave节点
登录到192.168.47.57:6380 执行下面命令
CLUSTER REPLICATE ae0577b87fdc9408581ae6e70d15bb907906e65f #命令格式为cluster replicate MASTERID
192.168.47.57:6379查看MASTERID
3.2删除节点
添加节点的时候先添加node节点到集群,然后分配槽位,删除节点的操作与添加节点的操作正好相反;
先将被删除的redis node上的槽位迁移到集群中的其他redis node 节点上,然后再将其删除。
如果一个redis node节点上的槽位没有完全迁移,删除该node 的时候会提示数据无法删除
注意,注意啦....被迁移Redis 服务器必须保证没有数据
这里模拟删除192.168.47.55主机
redis-cli -a 123456 --cluster reshard 192.168.47.55:6379 #槽位迁移
虽然槽位已经迁移完成,但是服务器IP信息还在集群当中,因此还需要将IP信息从集群删除
redis-cli -a 123456 --cluster del-node IP:Port ID
#删除node
redis-cli -a 123456 --cluster del-node 192.168.47.55:6379 222d8e2811d9d9b51a886b3227c033af2aca8234
redis-cli -a 123456 --cluster del-node 192.168.47.55:6380 24bc0650b0dd40fb415b906aceb18a8acd694d3b
重新分配slave
redis slave 节点一定不能和master在一个服务器,必须为跨主机交叉备份模式,避免主机故障后主备全部挂掉
移除55主机后,原本55主机的从,分配到了57主机的master上去了,现在将57主机上的从分配到54主机,让54主机保持有一个salve
CLUSTER REPLICATE a598e168888c86d813601f4de41a2996e9902dca
3.3模拟master宕机
这里模拟master宕机,用56主机,56的从是54主机的6380;关闭56的master(即6379对应的redis),查看54的从是否能变为master
65主机写入数据测试
root@ubuntu:~# redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> set key1 value1
(error) MOVED 9189 192.168.47.57:6379
127.0.0.1:6379> set key2 value1
(error) MOVED 4998 192.168.47.54:6379
127.0.0.1:6379> set key3 value1
(error) MOVED 935 192.168.47.57:6379
127.0.0.1:6379> set key4 value1
OK
#54主机,slave验证
root@ubuntu:~# redis-cli -p 6380 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6380>
127.0.0.1:6380> keys *
1) "key4"
#停止56的master
systemctl stop redis-6379.service
查看54已经变为了master
重新启动56的6379,直接指向了54的新提升的master
3.4导入现有redis数据
导入数据需要redis cluster不能与被导入的数据有重复的key名称否则导入不成功或中断
案例:
公司将redis cluster部署完成之后,需要将之前的数据导入redis cluster集群,但是由于redis cluster使用
的分片保存key的机制,因此使用传统的AOF文件或RDB快照无法满足需求,因此需要使用集群数据导入命令
导入数据之前需要关闭各redis服务器的密码,包括集群中的各Node和源redis server ,避免认证带来的环境不一致
从而无法导入,可以加参数--cluster-replace 强制替换redis cluster 已有的key
redis-cli -h 192.168.47.54 -p 6379 -a 123456
config set requirepass ""
将源redis server 的数据直接导入redis cluster
redis-cli --cluster import 集群服务器ip:port --cluster-from 外部redis node-ip:port --cluster-copy --cluster replace
#导入集群
redis-cli --cluster import 192.168.47.54:6379 \
--cluster-from 192.168.47.55:6379 --cluster-copy --cluster-replace
外部redis数据
导入集群
查看数据
排错参考:https://blog.csdn.net/pf1234321/article/details/781126