redis集群搭建及原理
一、前言
集群技术
集群技术分为三类 ,高可用集群,负载均衡集群和科学集群。 redis3.0版本后提供redis cluster使用的是高可用集群的方式。
高可用集群(HA):节点主次形式,节点间数据共享,发送故障时能够快速恢复,次节点顶替主节点。
负载均衡集群:数据不共享,通过负载均衡器来分配流量。负载均衡扩展了网络设备和服务器带宽,增加吞吐量,加强网络数据处理能。
科学集群:并行计算的集群。并行计算又包括时间并行(单个cpu多个单元并行执行)和空间(多个cpu并发执行)并行。
当然集群类别的划分是一个相对的概念,不是绝对的。
CAP原则
consistency(一致性):在分布式环境下,数据在多个副本之间能否保证一致的特性。
availability(可用性):对于用户的每一个操作总是能在有限时间内返回结果。
partition tolerance(分区容错性):分布式系统在遇到任何网络分区故障的时候,仍然需要对面满足一致性和可用性服务,除非是整个网络环境发生故障。
但我们总是无法同时满足这三个需求
二、Redis集群简单介绍
redis集群去中心化结构,去除了中间件,集群中任意节点平等,多个redis节点共享数据,每个节点都保存了集群状态。并且提供了一定的可用性(处理故障的能力)。redis集群符合上述的高可用集群思想
Redis 集群的优势:
- 自动分割数据到不同的节点上。
- 整个集群的部分节点失败或者不可达的情况下能够继续处理命令。
Redis集群属于CAP原则中ap模型
思想:去中心化
结构:redis集群 = 分布式数据 + 主从复制
数据分片
Redis 集群没有使用一致性hash算法, 而是引入了 哈希槽的概念.两者都是通过算法将数据写入不同redis节点,实现分布式存储。
Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:
- 节点 A 包含 0 到 5500号哈希槽.
- 节点 B 包含5501 到 11000 号哈希槽.
- 节点 C 包含11001 到 16384号哈希槽.
这种结构很容易添加或者删除节点. 比如如果我想新添加个节点D, 我需要从节点 A, B, C中得部分槽到D上. 如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可. 由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态.
redis集群实现了分布式存储,类似数据库中分库分表的思想,保证了redis的可用性
主从复制
为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制品.
在我们例子中具有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少5501-11000这个范围的槽而不可用.
然而如果在集群创建的时候(或者过一段时间)我们为每个节点添加一个从节点A1,B1,C1,那么整个集群便有三个master节点和三个slave节点组成,这样在节点B失败后,集群便会选举B1为新的主节点继续服务,整个集群便不会因为槽找不到而不可用了
不过当B和B1 都失败后,集群是不可用的.
通过主从复制保证了redis集群的可用性,redis从节点不提供读写
一般性一致性保证
主从复制引起的一致性问题
Redis集群并不能保证数据的强一致性。但单Redis实例可以保证CP模型。
原因:1.Redis使用了异步复制
写操作过程:客户端向主节点B写入一条命令,主节点B向客户端回复命令状态,主节点将写操作复制给他得从节点 B1, B2 和 B3。因为如果每次请求都要等复制完成,主节点的请求速度将极大的降低,所以我们必须在性能和一致性上作出选择。
所有我们无法保证主节点A向客户端返回数据到主节点A复制数据到从节点A1期间不会发生系统异常。一旦发生,便可能引起数据不一致。
2.Redis集群出现了网络分区(网络中断)
客户端向主节点A发出写命令, da主节当出现网络故障,且时间较长,为了包装系统的可用性,从节点A1被选为主节点,此次客户端写入节点A的数据被丢失。
三、搭建实例
启动redis
redis集群至少需要三个主节点。这里使用三主三从
1.新建文件夹 7000~7002(主节点) 7003~7005(从节点)
cd /usr/local/src/redis-4.0.10
mkdir 7000 7001 7002 7003 7004 7005
2.在7000~7005中各创建一个redis.conf配置文件,并将端口改成和文件名相同的号码
基本配置
#端口
port 7000
#开启集群
cluster-enabled yes
#集群每个节点配置,自动生成
cluster-config-file nodes-7000.conf
cluster-node-timeout 15000
appendonly yes
appendfilename "appendonly-7000.aof"
其他配置
#守护进程后天运行
daemonize yes
#不绑定ip
#bind 127.0.0.1
#关闭保护模式
protected-mode no
3.启动redis实例
切换到7000文件,启动redis
cd 7000
../src/redis-server ./redis.conf
同理启动7001~7005
4.修改防火墙端口限制(测试环境下,linux可先关闭防火墙)
使用 ps -ef | grep redis 命令查看redis运行情况
搭建集群
1.Redis 集群的主从复制模型
2.搭建ruby环境
使用yum install ruby 安装的ruby版本比较老,我们使用rvm方式安装
1)安装rvm 参考rvm
$ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
$ \curl -sSL https://get.rvm.io | bash -s stable
按照提示运行命令 source /etc/profile.d/rvm.sh ,rvm安装成功(界面没有提示表示成功)
2)列出已知ruby版本
rvm list known
3)安装ruby
rvm install 2.5.1 (等待漫长的下载,编译过程,完成以后,Ruby, Ruby Gems 就安装好了。)
4)替换ruby的使用源
$ gem source -r https://rubygems.org/
$ gem source -a https://gems.ruby-china.org
$ gem source -l
*5)安装Rails(ruby web框架)
$ gem install rails
3.使用ruby脚本构建
1.安装redis-4.0.1.gem ,原因:redis-trib.rb脚本依赖redis.gem
$ gem install redis
2.使用ruby脚本文件(redis-trib.rb)构建集群
切换到redis下src目录
./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
注意事项: redis在部署到远程linux服务器上时,这里的127.0.0.1 需要进行替换成对外ip地址。才能使得jedis客户端(如redisson)进行远程访问连接
如果显示如下,说明现在创建的结点包括了旧集群的结点信息,需要删除之前的节点信息(appendonly.aof,dump.rdb,nodes-conf),重新启动实例并运行ruby脚本
3.部署成功显示如下
显示 ALL 16384 slots covered 表示集群中的 16384 个槽都有至少一个主节点在处理, 集群运作正常
4.使用Shell脚本启动关闭redis集群
对于redis集群的部署我们使用shell脚本来简化操作
#!/bin/bash
path=/usr/local/src/redis-4.0.10
echo -e "Plead input:
1 start redis
2 stop redis
3 create redis cluster
4 connect redis
"
read aNum
case $aNum in
1)
cd $path/src
./redis-server ../7000/redis.conf
./redis-server ../7001/redis.conf
./redis-server ../7002/redis.conf
./redis-server ../7003/redis.conf
./redis-server ../7004/redis.conf
./redis-server ../7005/redis.conf
;;
2)
cd $path/src
./redis-cli -p 7000 shutdown
./redis-cli -p 7000 shutdown
./redis-cli -p 7000 shutdown
./redis-cli -p 7000 shutdown
./redis-cli -p 7000 shutdown
./redis-cli -p 7000 shutdown
;;
3)
cd $path/src
./redis-trib.rb create --replicas 1 192.168.56.128:7000 192.168.56.128:7001 192.168.56.128:7002 192.168.56.128:7003 192.168.56.128:7004 192.168.56.128:7005
;;
4)
cd $path/src
./redis-cli -c -p 7000
*)
echo "请输入正确的数字"
;;
esac
5.删除redis集群
关闭redis集群服务,并删除生成的appendonly.aof,dump.rdb,nodes-conf文件信息
四、测试
cluster info 或者 cluster nodes 查看集群节点状态