redis-cluster实践

今年的计划之一,给自己的云服务器搭建redis集群,现在有2台服务器,一台阿里云的一台腾讯云的

注意的是:必须要3个以后的主节点,否则在创建集群时会失败,我们在后续会实践到。

所以,我们假设现在有3个节点已经组成了集群,分别是:A, B, C 三个节点,它们可以是一台机器上的三个端口,也可以是三台不同的服务器。
腾讯云的配置好一点,所以腾讯云配置2个节点,阿里云配置一个节点.
0.原理

0.1背景介绍

从redis3.0.0开始,redis官方就发布了redis-cluster.

redis cluster是去中心化,去中间件的,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。

那么redis 是如何合理分配这些节点和数据的呢?

Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽 (hash slot)的方式来分配的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384。

注意的是:必须要3个以后的主节点,否则在创建集群时会失败,我们在后续会实践到。

所以,我们假设现在有3个节点已经组成了集群,分别是:A, B, C 三个节点,它们可以是一台机器上的三个端口,也可以是三台不同的服务器。那么,采用哈希槽 (hash slot)的方式来分配16384个slot 的话,它们三个节点分别承担的slot 区间是:

节点A覆盖0-5460;
节点B覆盖5461-10922;
节点C覆盖10923-16383.

那么,现在我想设置一个key ,比如叫test:

set test seal

按照redis cluster的哈希槽算法:CRC16(‘my_name’)%16384 = 2412。 那么就会把这个key 的存储分配到 A 上了。

同样,当我连接(A,B,C)任何一个节点想获取my_name这个key时,也会这样的算法,然后内部跳转到B节点上获取数据。

这种哈希槽的分配方式有好也有坏,好处就是很清晰,比如我想新增一个节点D,redis cluster的这种做法是从各个节点的前面各拿取一部分slot到D上,我会在接下来的实践中实验。大致就会变成这样:

节点A覆盖1365-5460
节点B覆盖6827-10922
节点C覆盖12288-16383
节点D覆盖0-1364,5461-6826,10923-12287

同样删除一个节点也是类似,移动完成后就可以删除这个节点了。

0.2redis-cluster主从模式

redis cluster 为了保证数据的高可用性,加入了主从模式,一个主节点对应一个或多个从节点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当这个主节点挂掉后,就会有这个从节点选取一个来充当主节点,从而保证集群不会挂掉。

上面那个例子里, 集群有ABC三个主节点, 如果这3个节点都没有加入从节点,如果B挂掉了,我们就无法访问整个集群了。A和C的slot也无法访问。

所以我们在集群建立的时候,一定要为每个主节点都添加了从节点, 比如像这样, 集群包含主节点A、B、C, 以及从节点A1、B1、C1, 那么即使B挂掉系统也可以继续正确工作。

B1节点替代了B节点,所以Redis集群将会选择B1节点作为新的主节点,集群将会继续正确地提供服务。 当B重新开启后,它就会变成B1的从节点。

不过需要注意,如果节点B和B1同时挂了,Redis集群就无法继续正确地提供服务了。

1.环境

# cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core) 

2台服务器统一版本

2.注意事项

安裝 GCC 编译工具 不然会有编译不过的问题

# yum install -y gcc g++ gcc-c++ make

创建集群需要使用redis自带的集群命令行工具redis-trib,就在redis的src目录里,我们只需要执行src目录的redis-trib.rb文件即可,该文件是ruby文件,通过向实例发送命令来创建新集群,因此,我们需要先安装ruby,命令如下:

# yum install ruby ruby-devel rubygems rpm-build

其实我这里遇到个坑,后面再说

3.集群搭建

3.1.下载并安装redis

# wget http://download.redis.io/releases/redis-4.0.1.tar.gz
# tar xzf redis-4.0.1.tar.gz
# cd redis-4.0.1
# make

这里没啥好说的,按顺序执行就行了

3.2.创建节点

我这里是双机集群,腾讯云4个节点,阿里云2个节点,下面先创建腾讯云的

在redis解压目录下,创建redis-cluster目录,根据你自己设计的端口分配计划,分别为每个端口创建一个文件夹,存储redis.conf文件

3.2.1.

# mkdir /redis-4.0.1/redis-cluster
# cd /redis-4.0.1/redis-cluster
# mkdir 6379 6479 6579 6679

3.2.2.将redis.conf文件copy到每个端口目录里,并修改配置如下:

#端口6379,6479
port 6479

#默认ip为127.0.0.1,需要改为其他节点机器可访问的ip,否则创建集群时无法访问对应的端口,无
法创建集群
#bind 127.0.0.1
bind 0.0.0.0#远程连接需要将ip改为0.0.0.0

#redis后台运行
daemonize yes

#pidfile文件对应6379
pidfile /var/run/redis_6479.pid

#开启集群,把注释#去掉
cluster-enabled yes

#集群的配置,配置文件首次启动自动生成 6379,6479
cluster-config-file nodes_6479.conf

#请求超时,默认15秒,可自行设置 
cluster-node-timeout 10100

#aof日志开启,有需要就开启,它会每次写操作都记录一条日志
appendonly yes

3.2.3.启动redis

# src/redis-server redis-cluster/6379/redis.conf

3.2.4.检查启动状态

# ps -ef | grep redis           //redis是否启动成功
# netstat -tnlp | grep redis    //监听redis端口

4.启动集群

4.1.

在任意一台机执行以下命令:

src/redis-trib.rb create --replicas 1 127.0.0.1:6379 127.0.0.1:6479 127.0.0.1:6579 127.0.0.1:6679 远程ip:6379 远程ip:6479

出现错误提示:


因为没装好ruby和redis的连接,我们只要执行一个命令就可以了:

# gem install redis

这时候前面说的坑就出现了


查了查资料,CentOS7 yum库中ruby的版本支持到 2.0.0,可gem 安装redis需要最低是2.2.2,自己编译的ruby源码,再执行还是报错…我们需要采用rvm来更新ruby:

gpg2 --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
curl -L get.rvm.io | bash -s stable

find / -name rvm -print

source /usr/local/rvm/scripts/rvm
rvm install 2.3.3
rvm use 2.3.3            #使用一个ruby版本
rvm use 2.3.3 --default  #设置默认版本
rvm remove 2.0.0         #卸载centos7.0默认的2.0.0版本
gem install redis        #回到我们的坑里

ok,坑填好了,我们继续启动集群

src/redis-trib.rb create --replicas 1 127.0.0.1:6379 127.0.0.1:6479 127.0.0.1:6579 127.0.0.1:6679 远程ip:6379 远程ip:6479

yes,回车...然后就卡在这里了...有空再写吧

为什么会这样的?第一反应google it...原因:
redis集群不仅需要开通redis客户端连接的端口,而且需要开通集群总线端口
集群总线端口为redis客户端连接的端口 + 10000
前面我已经把防火墙关闭了,因为2台都是我自己玩的服务器,关了也没关系,如果是正式的服务器千万不要学我...
# systemctl stop firewalld.service
我分别把阿里云和腾讯云服务器的安全组设置好,然后继续执行上面的启动集群命令...

这个是小问题...google一下有很多解决方法

1)停止redis服务

pkill redis
2)把redis目录下的node_xxx(端口).conf删了

3)重启所有服务

继续执行...还是不行,继续waiting for the cluster join...其实是我输入命令错了,我用了本地ip127.0.0.1去启动集群,另外一台机子连不上...

把命令的地址改一下

src/redis-trib.rb create --replicas 1 外网地址1:6379 外网地址1:6479 外网地址1:6579 外网地址1:6679 外网地址2:6379 外网地址2:6479

5.测试集群

可以通过以下命令检查集群

src/redis-trib.rb check ip:端口

5.1.插入测试,由于我忽略了-h参数,默认连接本机地址,-c为集群连接参数

src/redis-cli -c -p 6379


如上图,set test命令我之前已经在另一台机执行了,get test命令的结果重定向到了另外一个slot,接下来的的del,和set还是在这台机6379这端口的节点上,证明集群正常可用

待续...



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值