Ubuntu 16.04下Redis Cluster集群搭建(官方原始方案)

前提:先安装好Redis,参考:http://www.cnblogs.com/EasonJim/p/7599941.htmlhtml

说明:Redis Cluster集群模式能够作到动态增长节点和下线节点,使用起来很是的方便。node

下面教程主要是经过官方提供的文档进行搭建测试:mysql

https://redis.io/topics/cluster-tutorialredis

http://www.redis.cn/topics/cluster-tutorial.html算法

http://ifeve.com/redis-cluster-tutorial/sql

http://ifeve.com/redis-cluster-spec/(翻译自官方高级使用教程)数据库

上面中文教程均可以在官方提供的文档中找到。vim

原理应该以下图所示:ruby

注意:如下的搭建教程比较简单,基于伪集群的模式,若是是生产环境能够每台机部署一个实例。操做基本一致。bash

这篇教程是Redis集群的简要介绍,而非讲解分布式系统的复杂概念。它主要从一个使用者的角度介绍如何搭建、测试和使用Redis集群,至于Redis集群的详细设计将在“Redis集群规范”中进行描述。

本教程以redis使用者的角度,用简单易懂的方式介绍Redis集群的可用性和一致性。

注意: 本教程要求Redis3.0或以上的版本。

若是你打算部署Redis集群,你能够读一些关于集群的详细设计,固然,这不是必须的。由这篇教程入门,先大概使用一下Redis的集群,而后再读Redis集群的详细设计,也是不错的选择。

Redis集群 101

Redis集群在启动的时候就自动在多个节点间分好片。同时提供了分片之间的可用性:当一部分redis节点故障或网络中断,集群也能继续工做。可是,当大面积的节点故障或网络中断(好比大部分的主节点都不可用了),集群就不能使用。

因此,从实用性的角度,Redis集群提供如下功能:

  • 自动把数据切分到多个Redis节点中
  • 当一部分节点挂了或不可达,集群依然能继续工做

Redis集群的TCP端口

Redis集群中的每一个节点都须要创建2个TCP链接,监听这2个端口:一个端口称之为“客户端端口”,用于接受客户端指令,与客户端交互,好比6379;另外一个端口称之为“集群总线端口”,是在客户端端口号上加10000,好比16379,用于节点之间经过二进制协议通信。各节点经过集群总线检测宕机节点、更新配置、故障转移验证等。客户端只能使用客户端端口,不能使用集群总线端口。请确保你的防火墙容许打开这两个端口,不然Redis集群无法工做。客户端端口和集群总线端口之间的差值是固定的,集群总线端口比客户端端口高10000。

注意,关于集群的2个端口:

  • 客户端端口(通常是6379)须要对全部客户端和集群节点开放,由于集群节点须要经过该端口转移数据。
  • 集群总线端口(通常是16379)只需对集群中的全部节点开放

这2个端口必须打开,不然集群无法正常工做。

集群节点之间经过集群总线端口交互数据,使用的协议不一样于客户端的协议,是二进制协议,这能够减小带宽和处理时间。

Redis集群数据的分片

Redis集群不是使用一致性哈希,而是使用哈希槽。整个Redis集群有16384个哈希槽,决定一个key应该分配到那个槽的算法是:计算该key的CRC16结果再模16834。

集群中的每一个节点负责一部分哈希槽,好比集群中有3个节点,则:

  • 节点A存储的哈希槽范围是:0 – 5500
  • 节点B存储的哈希槽范围是:5501 – 11000
  • 节点C存储的哈希槽范围是:11001 – 16384

这样的分布方式方便节点的添加和删除。好比,须要新增一个节点D,只须要把A、B、C中的部分哈希槽数据移到D节点。一样,若是但愿在集群中删除A节点,只须要把A节点的哈希槽的数据移到B和C节点,当A节点的数据所有被移走后,A节点就能够彻底从集群中删除。

由于把哈希槽从一个节点移到另外一个节点是不须要停机的,因此,增长或删除节点,或更改节点上的哈希槽,也是不须要停机的。

若是多个key都属于一个哈希槽,集群支持经过一个命令(或事务, 或lua脚本)同时操做这些key。经过“哈希标签”的概念,用户可让多个key分配到同一个哈希槽。哈希标签在集群详细文档中有描述,这里作个简单介绍:若是key含有大括号”{}”,则只有大括号中的字符串会参与哈希,好比”this{foo}”和”another{foo}”这2个key会分配到同一个哈希槽,因此能够在一个命令中同时操做他们。

Redis集群的主从模式

为了保证在部分节点故障或网络不通时集群依然能正常工做,集群使用了主从模型,每一个哈希槽有一(主节点)到N个副本(N-1个从节点)。在咱们刚才的集群例子中,有A,B,C三个节点,若是B节点故障集群就不能正常工做了,由于B节点中的哈希槽数据无法操做。可是,若是咱们给每个节点都增长一个从节点,就变成了:A,B,C三个节点是主节点,A1, B1, C1 分别是他们的从节点,当B节点宕机时,咱们的集群也能正常运做。B1节点是B节点的副本,若是B节点故障,集群会提高B1为主节点,从而让集群继续正常工做。可是,若是B和B1同时故障,集群就不能继续工做了。

Redis集群的一致性保证

Redis集群不能保证强一致性。一些已经向客户端确认写成功的操做,会在某些不肯定的状况下丢失。

产生写操做丢失的第一个缘由,是由于主从节点之间使用了异步的方式来同步数据。

一个写操做是这样一个流程:

      1)客户端向主节点B发起写的操做
      2)主节点B回应客户端写操做成功
      3)主节点B向它的从节点B1,B2,B3同步该写操做

从上面的流程能够看出来,主节点B并无等从节点B1,B2,B3写完以后再回复客户端此次操做的结果。因此,若是主节点B在通知客户端写操做成功以后,但同步给从节点以前,主节点B故障了,其中一个没有收到该写操做的从节点会晋升成主节点,该写操做就这样永远丢失了。

就像传统的数据库,在不涉及到分布式的状况下,它每秒写回磁盘。为了提升一致性,能够在写盘完成以后再回复客户端,但这样就要损失性能。这种方式就等于Redis集群使用同步复制的方式。

基本上,在性能和一致性之间,须要一个权衡。

若是真的须要,Redis集群支持同步复制的方式,经过WAIT指令来实现,这可让丢失写操做的可能性降到很低。但就算使用了同步复制的方式,Redis集群依然不是强一致性的,在某些复杂的状况下,好比从节点在与主节点失去链接以后被选为主节点,不一致性仍是会发生。

这种不一致性发生的状况是这样的,当客户端与少数的节点(至少含有一个主节点)网络联通,但他们与其余大多数节点网络不通。好比6个节点,A,B,C是主节点,A1,B1,C1分别是他们的从节点,一个客户端称之为Z1。

当网络出问题时,他们被分红2组网络,组内网络联通,但2组之间的网络不通,假设A,C,A1,B1,C1彼此之间是联通的,另外一边,B和Z1的网络是联通的。Z1能够继续往B发起写操做,B也接受Z1的写操做。当网络恢复时,若是这个时间间隔足够短,集群仍然能继续正常工做。若是时间比较长,以至B1在大多数的这边被选为主节点,那刚才Z1发给B的写操做都将丢失。

注意,Z1给B发送写操做是有一个限制的,若是时间长度达到了大多数节点那边能够选出一个新的主节点时,少数这边的全部主节点都不接受写操做。

这个时间的配置,称之为节点超时(node timeout),对集群来讲很是重要,当达到了这个节点超时的时间以后,主节点被认为已经宕机,能够用它的一个从节点来代替。一样,在节点超时时,若是主节点依然不能联系到其余主节点,它将进入错误状态,再也不接受写操做。

Redis集群参数配置

咱们后面会部署一个Redis集群做为例子,在那以前,先介绍一下集群在redis.conf中的参数。

  • cluster-enabled <yes/no>: 若是配置”yes”则开启集群功能,此redis实例做为集群的一个节点,不然,它是一个普通的单一的redis实例。
  • cluster-config-file <filename>: 注意:虽然此配置的名字叫“集群配置文件”,可是此配置文件不能人工编辑,它是集群节点自动维护的文件,主要用于记录集群中有哪些节点、他们的状态以及一些持久化参数等,方便在重启时恢复这些状态。一般是在收到请求以后这个文件就会被更新。
  • cluster-node-timeout <milliseconds>: 这是集群中的节点可以失联的最大时间,超过这个时间,该节点就会被认为故障。若是主节点超过这个时间仍是不可达,则用它的从节点将启动故障迁移,升级成主节点。注意,任何一个节点在这个时间以内若是仍是没有连上大部分的主节点,则此节点将中止接收任何请求。
  • cluster-slave-validity-factor <factor>: 若是设置成0,则不管从节点与主节点失联多久,从节点都会尝试升级成主节点。若是设置成正数,则cluster-node-timeout乘以cluster-slave-validity-factor获得的时间,是从节点与主节点失联后,此从节点数据有效的最长时间,超过这个时间,从节点不会启动故障迁移。假设cluster-node-timeout=5,cluster-slave-validity-factor=10,则若是从节点跟主节点失联超过50秒,此从节点不能成为主节点。注意,若是此参数配置为非0,将可能出现因为某主节点失联却没有从节点能顶上的状况,从而致使集群不能正常工做,在这种状况下,只有等到原来的主节点从新回归到集群,集群才恢复运做。
  • cluster-migration-barrier <count>:主节点须要的最小从节点数,只有达到这个数,主节点失败时,它从节点才会进行迁移。更详细介绍能够看本教程后面关于副本迁移到部分。
  • cluster-require-full-coverage <yes/no>:在部分key所在的节点不可用时,若是此参数设置为”yes”(默认值), 则整个集群中止接受操做;若是此参数设置为”no”,则集群依然为可达节点上的key提供读操做。

建立和使用Redis集群

注意:手动部署Redis集群可以很好的了解它是如何运做的,但若是你但愿尽快的让集群运行起来,能够跳过本节和下一节,直接到”使用create-cluster脚本建立Redis集群”章节。

要建立集群,首先须要以集群模式运行的空redis实例。也就说,以普通模式启动的redis是不能做为集群的节点的,须要以集群模式启动的redis实例才能有集群节点的特性、支持集群的指令,成为集群的节点。

下面是最小的redis集群的配置文件(redis.conf):

port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

开启集群模式只需打开cluster-enabled配置项便可。每个redis实例都包含一个配置文件,默认是nodes.conf(启动时会自动生成),用于存储此节点的一些配置信息。这个配置文件由redis集群的节点自行建立和更新,不能由人手动地去修改。

一个最小的集群须要最少3个主节点。第一次测试,强烈建议你配置6个节点:3个主节点和3个从节点。

开始测试,步骤以下:先进入新的目录,以redis实例的端口为目录名,建立目录,咱们将在这些目录里运行咱们的实例。

相似这样:

mkdir cluster-test
cd cluster-test
mkdir 7000 7001 7002 7003 7004 7005

在7000-7005的每一个目录中建立配置文件redis.conf,内容就用上面的最简配置作模板,注意修改端口号,改成跟目录一致的端口。

把你的Redis服务器(用GitHub中的不稳定分支的最新的代码编译来/或者稳定代码)拷贝到cluster-test目录,而后打开6个终端页准备测试。

第一台:

在每一个终端启动一个redis实例,指令相似这样:

cd 7000
../redis-server ./redis.conf

在日志中咱们能够看到,因为没有nodes.conf文件不存在,每一个节点都给本身一个新的ID。

[82462] 26 Nov 11:56:55.329 * No cluster configuration found, I'm 97a3a64667477371c4479320d683e4c8db5858b1

这个ID将一直被此节点使用,做为此节点在整个集群中的惟一标识。节点区分其余节点也是经过此ID来标识,而非IP或端口。IP能够改,端口能够改,但此ID不能改,直到这个节点离开集群。这个ID称之为节点ID(Node ID)。

第二台:

第三台:

第四台:

第五台:

第六台:

重复第一台的操做。

建立集群

如今6个实例已经运行起来了,咱们须要给节点写一些有意义的配置来建立集群。redis集群的命令工具redis-trib可让咱们建立集群变得很是简单。redis-trib是一个用ruby写的脚本,用于给各节点发指令建立集群、检查集群状态或给集群从新分片等。redis-trib在Redis源码的src目录下,须要gem redis来运行redis-trib。

gem install redis

建立集群只需输入指令:

./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

这里用的命令是create,由于咱们须要建立一个新的集群。选项”–replicas 1”表示每一个主节点须要一个从节点。其余参数就是须要加入这个集群的Redis实例的地址。

咱们建立的集群有3个主节点和3个从节点。

redis-trib会给你一些配置建议,输入yes表示接受。集群会被配置并彼此链接好,意思是各节点实例被引导彼此通话并最终造成集群。最后,若是一切顺利,会看到相似下面的信息:

[OK] All 16384 slots covered

这表示,16384个哈希槽都被主节点正常服务着。

使用create-cluster脚本建立redis集群

若是你不想像上面那样,单独的手工配置各节点的方式来建立集群,还有一个更简单的系统(固然也无法了解到集群运做的一些细节)。

在utils/create-cluster目录下,有一个名为create-cluster的bash脚本。若是须要启动一个有3个主节点和3个从节点的集群,只须要输入如下指令

#1
create-cluster start #2
create-cluster create

在步骤2,当redis-trib要你接受集群的布局时,输入”yes”。

如今你能够跟集群交互,第一个节点的起始端口默认是30001。当你完成后,中止集群用以下指令:

create-cluster stop

请查看目录下的README,它有详细的介绍如何使用此脚本。

实际操做以下:

版本:4.0.2

下载地址:https://redis.io/download

离线版本:(连接: https://pan.baidu.com/s/1bpwDtOr 密码: 4cxk)

源码编译:

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

若是不安装到指定位置,那么程序默认放在src文件夹下,

建立集群文件及文件夹:

mkdir cluster-test
cd cluster-test
mkdir 7000 7001 7002 7003 7004 7005

进入7000建立redis.conf,内容以下:

cd 7000
sudo vim redis.conf
#内容
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

进入7001建立redis.conf,内容以下:

cd 7001
sudo vim redis.conf #内容 port 7001 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes

进入7002建立redis.conf,内容以下:

cd 7002
sudo vim redis.conf #内容 port 7002 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes

进入7003建立redis.conf,内容以下:

cd 7003
sudo vim redis.conf #内容 port 7003 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes 

进入7004建立redis.conf,内容以下:

cd 7004
sudo vim redis.conf #内容 port 7004 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes

进入7005建立redis.conf,内容以下:

cd 7005
sudo vim redis.conf #内容 port 7005 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes

分别启动6台集群:

cd 7000
../redis-server ./redis.conf
cd 7001
../redis-server ./redis.conf
cd 7002
../redis-server ./redis.conf
cd 7003
../redis-server ./redis.conf
cd 7004
../redis-server ./redis.conf
cd 7005
../redis-server ./redis.conf

建立集群:

先安装ruby

sudo apt-get ruby

进入src文件夹

再经过gem安装redis

cd src
gem install redis

若是出现错误,参考:http://www.cnblogs.com/EasonJim/p/7629314.html

启动

./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

期间会提示输入yes,而后基本完成。输出的信息上有提示哪些是主节点和从节点。

 

 

参考:

http://ifeve.com/redis-cluster-tutorial/(以上内容部分转自此篇文章)

http://blog.csdn.net/fengshizty/article/details/51368004 (节点操做的测试)

http://www.redis.cn/topics/cluster-tutorial.html

http://ifeve.com/redis-cluster-spec/

http://os.51cto.com/art/201512/499551.htm

http://blog.csdn.net/robertohuang/article/details/70766809

http://blog.csdn.net/robertohuang/article/details/70768922

http://blog.csdn.net/robertohuang/article/details/70833231

http://blog.chinaunix.net/uid-28396214-id-4981572.html

http://blog.51yip.com/nosql/1725.html

http://www.cnblogs.com/wuxl360/p/5920330.html

http://blog.csdn.net/men_wen/article/details/72853078

http://blog.csdn.net/xu470438000/article/details/42971091

http://www.cnblogs.com/gomysql/p/4395504.html

相关文章
相关标签/搜索