这几天一直在研究redis怎么搭建高可用集群,阅读了redis官网,也看了很多博客,但是每个博客都有或多或少的坑。先把遇到的坑罗列一下:
① :创建集群出现:Waiting for the clusterto join.....
② :执行gem install redis命令 " 出现 " ERROR: Error installing redis redis requires Rubyversion >= 2.2.2.
③ :创建集群时,报Sorry, can't connect tonode错误
虽然就这三个问题,但是这每个问题的背后都要解决很多问题。那么下面就开始redis集群的搭建吧!
搭建环境:两台虚拟机模拟6个节点,一台机器3个节点,创建出3 master、3 salve 环境。
第一台虚拟机ip:192.168.2.4,第二台192.168.2.5,
然后分别在两天虚拟机上安装redis
① :wget http://download.redis.io/releases/redis-4.0.8.tar.gz
② :tar -zxvf redis-34.0.8.tar.gz-C /usr/local
③ :切换到 /usr/local/redis-4.0.8 目录下 cd /usr/local/ redis-4.0.8
④ :执行make && make install命令,如果不能编译,说明要安装gcc环境,执行
yum install gcc
⑤ :至此,redis已经安装成功,验证方式: cd /usr/local/bin,执行redis-server /usr/local/redis-4.0.8/redis.conf,此时你会看到redis启动,使用ps -ef | grep -i redis命令,可以看到redis进程,再执行redis-cli,可以进入redis客户端,此时在客户端敲ping命令,会得到pong,至此说明redis单机版已经安装并启动成功。
准备开始搭建集群:
⑥ :再切换到redis解压的下的src目录下将redis-trib.rb复制到 /usr/local/bin 目录下。cd/usr/local/redsi-4.0.8; cp redis-trib.rb/usr/local/bin/
⑦ :现在分别在两台虚拟机上创建3个节点,在ip为192.168.2.4机器上,在/usr/local/redis-4.0.8下创建redis_cluster目录,mkdir redis_cluster,redis_cluster目录下,创建名为7000、7001、7002的目录,并将redis.conf 拷贝到这三个目录中,命令如下:
cpredis.conf redis_cluster/7000
cpredis.conf redis_cluster/7001
cpredis.conf redis_cluster/7002
另一台机器也一样,先创建redis_cluster,在redis_cluster目录下,创建名为7003、7004、7005的目录,通用将redis.conf 拷贝到这三个目录。
⑧ :分别修改这六个配置文件(注:修改时一定要细心),修改内容如下:
port 7000 | 端口7000,7001,7002,7003,7004,7005 |
bind 本机ip | 默认ip为127.0.0.1 需要改为其他节点机器可访问的ip 否则创建集群时无法访问对应的端口,无法创建集群 |
daemonize yes | redis后台运行 |
pidfile /var/run/redis_7000.pid | pidfile文件对应7000,7001,7002,7003, 7004,7005 |
cluster-enabled yes | 开启集群 |
cluster-config-file nodes_7000.conf | 集群的配置 配置文件首次启动自动生成 7000,7001,7002 |
cluster-node-timeout 15000 | 请求超时 默认15秒,可自行设置 |
appendonly yes | aof日志开启 有需要就开启,它会每次写操作都记录一条日志 |
⑨ :启动各个节点。第一台机器上执行:(注:cd/usr/local/bin,现切到bin目录下)
redis-server /usr/local/redis-4.0.8/redis_cluster/7000/redis.conf
redis-server /usr/local/redis-4.0.8/redis_cluster/7001/redis.conf
redis-server /usr/local/redis-4.0.8/redis_cluster/7002/redis.conf
另外一台机器上执行
redis-server /usr/local/redis-4.0.8/redis_cluster/7003/redis.conf
redis-server /usr/local/redis-4.0.8/redis_cluster/7004/redis.conf
redis-server /usr/local/redis-4.0.8/redis_cluster/7005/redis.conf
⑩ :检查 redis 启动情况,分别在两台机器上执行ps -ef | grep redis,可以看到如下图,则说明每个节点都启动成功。
⑪ :创建集群,Redis 官方提供了 redis-trib.rb 这个工具,就在解压目录的 src 目录中,第三步中已将它复制到 /usr/local/bin 目录中,可以直接在命令行中使用了。由于redis-trib.rb依赖ruby,所以在使用该命令前,先在两台机器上安装ruby(注:ruby安装版本大于2.2.0,不然会遇到上面的第二个坑,这里我尝试了各种安装方法,但最终我选择了官网提供的RVM工具,Ruby中文官网)。
⑫ :安装ruby环境,第一步执行:yum install gcc-c++,第二步:gpg --keyserverhkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E37D2BAF1CF37B13E2069D6956105BD0E739499BDB 第三步:curl -sSLhttps://get.rvm.io | bash -s stable (注:此过程需要比较久的时间,请耐心等待) 第四步:source /etc/profile.d/rvm.sh 第五步:得到ruby版本列表:rvm list known 第六步:安装ruby
执行rvm install 2.4.1第七步:验证ruby安装是否成功,执行ruby -v //查看验证下已经安装的版本
⑬ :执行gem install redis
⑭ :分别在两个虚拟机上执行如下命令:
ip为192.168.2.4的:
firewall-cmd --zone=public--add-port=7000-7002/tcp –permanent
firewall-cmd --zone=public--add-port=17000-17002/tcp –permanent
ip为192.168.2.5的:
firewall-cmd --zone=public--add-port=7003-7005/tcp –permanent
firewall-cmd --zone=public--add-port=17003-17005/tcp –permanent
(注:必须开集群总线端口,集群总线端口=端口号+10000,例:7000的集群总线端口是17000。这个集群总线端口不开放,集群的时候外部服务器的节点添加不进来,不然就会出现上面第一个坑)
⑮ :执行redis-trib.rb create --replicas 1 192.168.2.4:7000 192.168.2.4:7001 192.168.2.4:7002 192.168.2.5:7003 192.168.2.5:7004 192.168.2.5:7005
⑯ :集群验证:在第一台机器上连接集群的7002端口的节点,在另外一台连接7005节点,连接方式为redis-cli -h 192.168.2.4 -c -p7002, redis-cli -h 192.168.2.5 -c -p 7005
进入7003:执行cluster info获取集群信息:
或者在7002执行 set name wpf,在7005执行get name,此时7005得到wpf, 说明集群运作正常,至此整个集群就搭建完成了。
⑰ :上面提到的第三个坑解决办法:进入/usr/local/bin目录下删除掉nodes-7000.conf,nodes-7001.conf,nodes-7002.conf,nodes-7003.conf,nodes-7004.conf,nodes-7005.conf,appendonly.aof这样就OK了
简单说一下原理
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个或以上的主节点,否则在创建集群时会失败,并且当存活的主节点数小于总节点数的一半时,整个集群就无法提供服务了。
列出集群中的所有主节点 redis-cli -p 7000 cluster nodes | grep master
获取集群上的所有的节点信息cluster nodes
添加集群节点 redis-trib.rb add-node 192.168.2.4:7006<已经存在的节点的IP和端口>
添加一个从节点 redis-trib.rb add-node --slave192.168.2.4:7006 <已经存在的节点的IP和端口>
移除一个节点 redis-trib del-node 127.0.0.1:7000`<node-id>`