集群简介:

Redis 集群是一个可以在多个 Redis 节点之间进行数据共享的设施(installation)。

Redis 集群不支持那些需要同时处理多个键的 Redis 命令, 因为执行这些命令需要在多个 Redis 节点之间移动数据, 并且在高负载的情况下, 这些命令将降低 Redis 集群的性能, 并导致不可预测的行为。

Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。

Redis 集群提供了以下两个好处:

将数据自动切分(split)到多个节点的能力。

当集群中的一部分节点失效或者无法进行通讯时, 仍然可以继续处理命令请求的能力。

redis集群数据共享:

Redis 集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现: 一个 Redis 集群包含 16384 个哈希槽(hash slot), 数据库中的每个键都属于这 16384 个哈希槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。

集群中的每个节点负责处理一部分哈希槽。 举个例子, 一个集群可以有三个哈希槽, 其中:

节点 A 负责处理 0 号至 5500 号哈希槽。

节点 B 负责处理 5501 号至 11000 号哈希槽。

节点 C 负责处理 11001 号至 16384 号哈希槽。

这种将哈希槽分布到不同节点的做法使得用户可以很容易地向集群中添加或者删除节点。 比如说:

如果用户将新节点 D 添加到集群中, 那么集群只需要将节点 A 、B 、 C 中的某些槽移动到节点 D 就可以了。

与此类似, 如果用户要从集群中移除节点 A , 那么集群只需要将节点 A 中的所有哈希槽移动到节点 B 和节点 C , 然后再移除空白(不包含任何哈希槽)的节点 A 就可以了。

因为将一个哈希槽从一个节点移动到另一个节点不会造成节点阻塞, 所以无论是添加新节点还是移除已存在节点, 又或者改变某个节点包含的哈希槽数量, 都不会造成集群下线。

redis集群中的主从复制:

为了使得集群在一部分节点下线或者无法与集群的大多数(majority)节点进行通讯的情况下, 仍然可以正常运作, Redis 集群对节点使用了主从复制功能: 集群中的每个节点都有 1 个至 N 个复制品(replica), 其中一个复制品为主节点(master), 而其余的 N-1 个复制品为从节点(slave)。

在之前列举的节点 A 、B 、C 的例子中, 如果节点 B 下线了, 那么集群将无法正常运行, 因为集群找不到节点来处理 5501 号至 11000 号的哈希槽。

另一方面, 假如在创建集群的时候(或者至少在节点 B 下线之前), 我们为主节点 B 添加了从节点 B1 , 那么当主节点 B 下线的时候, 集群就会将 B1 设置为新的主节点, 并让它代替下线的主节点 B , 继续处理 5501 号至 11000 号的哈希槽, 这样集群就不会因为主节点 B 的下线而无法正常运作了。

不过如果节点 B 和 B1 都下线的话, Redis 集群还是会停止运作。

redis集群的数据一致性:

Redis 集群不保证数据的强一致性(strong consistency): 在特定条件下, Redis 集群可能会丢失已经被执行过的写命令。

使用异步复制(asynchronous replication)是 Redis 集群可能会丢失写命令的其中一个原因。 考虑以下这个写命令的例子:

客户端向主节点 B 发送一条写命令。

主节点 B 执行写命令,并向客户端返回命令回复。

主节点 B 将刚刚执行的写命令复制给它的从节点 B1 、 B2 和 B3 。

如你所见, 主节点对命令的复制工作发生在返回命令回复之后, 因为如果每次处理命令请求都需要等待复制操作完成的话, 那么主节点处理命令请求的速度将极大地降低 —— 我们必须在性能和一致性之间做出权衡。

Redis 集群另外一种可能会丢失命令的情况是, 集群出现网络分裂(network partition), 并且一个客户端与至少包括一个主节点在内的少数(minority)实例被孤立。

举个例子, 假设集群包含 A 、 B 、 C 、 A1 、 B1 、 C1 六个节点, 其中 A 、B 、C 为主节点, 而 A1 、B1 、C1 分别为三个主节点的从节点, 另外还有一个客户端 Z1 。

假设集群中发生网络分裂, 那么集群可能会分裂为两方, 大多数(majority)的一方包含节点 A 、C 、A1 、B1 和 C1 , 而少数(minority)的一方则包含节点 B 和客户端 Z1 。

在网络分裂期间, 主节点 B 仍然会接受 Z1 发送的写命令:

如果网络分裂出现的时间很短, 那么集群会继续正常运行;

但是, 如果网络分裂出现的时间足够长, 使得大多数一方将从节点 B1 设置为新的主节点, 并使用 B1 来代替原来的主节点 B , 那么 Z1 发送给主节点 B 的写命令将丢失。

注意, 在网络分裂出现期间, 客户端 Z1 可以向主节点 B 发送写命令的最大时间是有限制的, 这一时间限制称为节点超时时间(node timeout), 是 Redis 集群的一个重要的配置选项:

对于大多数一方来说, 如果一个主节点未能在节点超时时间所设定的时限内重新联系上集群, 那么集群会将这个主节点视为下线, 并使用从节点来代替这个主节点继续工作。

对于少数一方, 如果一个主节点未能在节点超时时间所设定的时限内重新联系上集群, 那么它将停止处理写命令, 并向客户端报告错误。

下面开始集群的搭建和管理:首先介绍一下我们的实验环境

测试环境两台:

server1:172.16.16.34server2:172.16.16.35redis版本:redis3.2

搭建环境:redis集群,server1有7001,7002,7003三主,server2有7001,7002,7003三从,总共六个节点。这样做是为了保证redis的集群的高可用。redis的复制也是采用异步复制的方式。

1,安装redis

cd /home/maxiangqian

tar xzf redis-3.2.8.tar.gz

cd redis-3.2.8yum install gcc

make

2:创建redis目录文件夹

在server1和server2上都创建相应的文件夹:

mkdir /home/redis7001/data

mkdir-p /home/redis7001/data /home/redis7001/log /home/redis7001/tmp

mkdir-p /home/redis7002/data /home/redis7002/log /home/redis7002/tmp

mkdir-p /home/redis7003/data /home/redis7003/log /home/redis7003/tmp

3:为server1和server2的三个节点分别配置配置文件

以一个配置文件为例:

port 7001timeout300daemonize yes

pidfile"/home/redis7001/tmp/redis_7001.pid"loglevel notice

logfile"/home/redis7001/log/redis_7001.log"databases16save900 1save300 10save60 10000stop-writes-on-bgsave-error yes

rdbcompression yes

rdbchecksum yes

dbfilename"dump.rdb"dir"/home/redis7001/data"slave-serve-stale-data yes

#slave-read-only yes # yes开启从库只读

repl-diskless-sync no

repl-diskless-sync-delay 5repl-disable-tcp-nodelay no

slave-priority 100appendonly yes

#appendfilename"appendonly.aof"appendfsync everysec

no-appendfsync-on-rewrite no

auto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mb

lua-time-limit 5000slowlog-log-slower-than 10000slowlog-max-len 128latency-monitor-threshold 0requirepass"maxiangqianredis"masterauth"maxiangqianredis"#cluster

cluster-enabled yes

cluster-config-file /home/redis7001/nodes7001.conf

cluster-node-timeout 5000

上面是redis7001的配置文件内容

然后启动7001的redis:

redis-server /home/redis7001/redis7001.conf

我们看一下启动日志:

1574:M 03 May 16:22:53.444 * No cluster configuration found, I'm 363ecec54c92c2548dcab016146bdb4c104e5e84

每个实例都会为自己生成一个唯一的ID,用来识别集群中的唯一身份。

然后使用同样的方法启动其余五个实例

server1 7001server17002server17003server27001server27002server27003

OK,现在已经有六个已经启动的redis实例了。我们下一步开始做集群

4:开始创建集群

redis-trib.rb create --replicas 1 10.103.16.34:7001 10.103.16.34:7002 10.103.16.34:7003 10.103.16.35:7001 10.103.16.35:7002 10.103.16.35:7003

执行报错:

/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- redis (LoadError)

from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'from /home/maxiangqian/redis-3.2.8/src/redis-trib.rb:25

我们需要安装以下几个包:

yum -y install zlib ruby rubygems

gem install redis

然后重新启动创建集群的操作:

[root@localhost redis7003]# redis-trib.rb create --replicas 1 10.103.16.34:7001 10.103.16.34:7002 10.103.16.34:7003 10.103.16.35:7001 10.103.16.35:7002 10.103.16.35:7003

>>>Creating cluster

[ERR] Sorry, can't connect to node 10.103.16.34:7001

又报错了我擦。

网上各种搜资料咨询,最好还是发现不是什么版本问题,是因为我的配置文件里加了以下两行配置:

requirepass "maxiangqianredis"masterauth"maxiangqianredis"

群集是不支持认证的,把这两行注释掉就好了,然后我们在执行创建群集的命令:

[root@localhost redis7003]# redis-trib.rb create --replicas 1 10.103.16.34:7001 10.103.16.34:7002 10.103.16.34:7003 10.103.16.35:7001 10.103.16.35:7002 10.103.16.35:7003

>>>Creating cluster>>> Performing hash slots allocation on 6nodes...

Using3masters:10.103.16.35:7001

10.103.16.34:7001

10.103.16.35:7002Adding replica10.103.16.34:7002 to 10.103.16.35:7001Adding replica10.103.16.35:7003 to 10.103.16.34:7001Adding replica10.103.16.34:7003 to 10.103.16.35:7002M: 363ecec54c92c2548dcab016146bdb4c104e5e8410.103.16.34:7001slots:5461-10922 (5462slots) master

S: 93a0e8d405959480fcbd310a5d15a92346c69d4310.103.16.34:7002replicates d015a22abc57c021f568973f4f1c03c7a5c7b772

S: 78f77749f9f9a5f0d7c99427e0311912a3fa04e710.103.16.34:7003replicates 89147e5837e378b69233dd2b8290267975719bc4

M: d015a22abc57c021f568973f4f1c03c7a5c7b77210.103.16.35:7001slots:0-5460 (5461slots) master

M: 89147e5837e378b69233dd2b8290267975719bc410.103.16.35:7002slots:10923-16383 (5461slots) master

S: ce9d635236567ccde4c864f78863fa0a4b26f25a10.103.16.35:7003replicates 363ecec54c92c2548dcab016146bdb4c104e5e84

Can Iset the above configuration? (type 'yes' to accept):

OK,已经提示成功了,我们直接选择yes就好了。

>>>Nodes configuration updated>>>Assign a different config epoch to each node>>>Sending CLUSTER MEET messages to join the cluster

Waitingforthe cluster to join..>>> Performing Cluster Check (using node 10.103.16.34:7001)

M: 363ecec54c92c2548dcab016146bdb4c104e5e8410.103.16.34:7001slots:5461-10922 (5462slots) master1additional replica(s)

S: 78f77749f9f9a5f0d7c99427e0311912a3fa04e710.103.16.34:7003slots: (0slots) slave

replicates 89147e5837e378b69233dd2b8290267975719bc4

M: d015a22abc57c021f568973f4f1c03c7a5c7b77210.103.16.35:7001slots:0-5460 (5461slots) master1additional replica(s)

M: 89147e5837e378b69233dd2b8290267975719bc410.103.16.35:7002slots:10923-16383 (5461slots) master1additional replica(s)

S: ce9d635236567ccde4c864f78863fa0a4b26f25a10.103.16.35:7003slots: (0slots) slave

replicates 363ecec54c92c2548dcab016146bdb4c104e5e84

S: 93a0e8d405959480fcbd310a5d15a92346c69d4310.103.16.34:7002slots: (0slots) slave

replicates d015a22abc57c021f568973f4f1c03c7a5c7b772

[OK] All nodes agree about slots configuration.>>> Check foropen slots...>>>Check slots coverage...

[OK] All16384 slots covered.

这样群集就设置成功了。

查看一下集群的状态,测试一下:

在10.103.16.34:7001创建name测试字符串,然后验证

[root@mxqmongodb2 sa]# redis-cli -c -p 7001

127.0.0.1:7001> getname-> Redirected to slot [5798] located at 10.103.16.34:7001

"txt"

10.103.16.34:7001>exit

[root@mxqmongodb2 sa]# redis-cli -c -p 7002

127.0.0.1:7002> getname-> Redirected to slot [5798] located at 10.103.16.34:7001

"txt"

10.103.16.34:7001>exit

[root@mxqmongodb2 sa]# redis-cli -c -p 7003

127.0.0.1:7003> getname-> Redirected to slot [5798] located at 10.103.16.34:7001

"txt"

5:我们接下来查看一下集群的基本信息:

[root@localhost redis7003]# redis-cli -p 7001cluster nodes

78f77749f9f9a5f0d7c99427e0311912a3fa04e710.103.16.34:7003 slave 89147e5837e378b69233dd2b8290267975719bc4 0 1493879665448 5connected

d015a22abc57c021f568973f4f1c03c7a5c7b77210.103.16.35:7001 master - 0 1493879663946 4 connected 0-546089147e5837e378b69233dd2b8290267975719bc410.103.16.35:7002 master - 0 1493879664948 5 connected 10923-16383ce9d635236567ccde4c864f78863fa0a4b26f25a10.103.16.35:7003 slave 363ecec54c92c2548dcab016146bdb4c104e5e84 0 1493879665949 6connected

93a0e8d405959480fcbd310a5d15a92346c69d4310.103.16.34:7002 slave d015a22abc57c021f568973f4f1c03c7a5c7b772 0 1493879664446 4connected

363ecec54c92c2548dcab016146bdb4c104e5e8410.103.16.34:7001 myself,master - 0 0 1 connected 5461-10922

可以看到现在的集群有六个节点,三个主节点和三个从节点。而且每个主节点都会记录自己分配的哈希槽,从中我们可以看到

103.16.35:7001 master - 0 1493879663946 4 connected 0-5460

10.103.16.34:7001 myself,master - 0 0 1 connected 5461-10922

10.103.16.35:7002 master - 0 1493879664948 5 connected 10923-16383

当然我们也可以对这些节点的哈希槽进行重新的分配,我们现在打算将103.16.35:7001的前100个哈希槽移动到10.103.16.34:7001

[root@localhost redis7003]# redis-trib.rb reshard 10.103.16.34:7001

然后会提示我输入数值以及从哪里迁移到哪里:

How many slots do you want to move (from 1 to 16384)? 100Whatis the receiving node ID?363ecec54c92c2548dcab016146bdb4c104e5e84

Please enter all the source node IDs.

Type'all' to use all the nodes as source nodes forthe hash slots.

Type'done'once you entered all the source nodes IDs.

Source node #1:d015a22abc57c021f568973f4f1c03c7a5c7b772

Source node #2:done

执行完以后就可以进行迁移了,迁移完以后我们再打印出来节点信息看一下:

[root@localhost redis7003]# redis-cli -p 7001cluster nodes

78f77749f9f9a5f0d7c99427e0311912a3fa04e710.103.16.34:7003 slave 89147e5837e378b69233dd2b8290267975719bc4 0 1493881167965 5connected

d015a22abc57c021f568973f4f1c03c7a5c7b77210.103.16.35:7001 master - 0 1493881166460 4 connected 101-546089147e5837e378b69233dd2b8290267975719bc410.103.16.35:7002 master - 0 1493881166962 5 connected 10923-16383ce9d635236567ccde4c864f78863fa0a4b26f25a10.103.16.35:7003 slave 363ecec54c92c2548dcab016146bdb4c104e5e84 0 1493881167465 7connected

93a0e8d405959480fcbd310a5d15a92346c69d4310.103.16.34:7002 slave d015a22abc57c021f568973f4f1c03c7a5c7b772 0 1493881167965 4connected

363ecec54c92c2548dcab016146bdb4c104e5e8410.103.16.34:7001 myself,master - 0 0 7 connected 0-100 5461-10922

我们可以很清楚的看到已经迁移成功了。

6:我们来测试一下集群的故障转移功能

首先我们要看一下集群的主节点信息:

[root@localhost redis7003]# redis-cli -p 7001 cluster nodes |grep master

d015a22abc57c021f568973f4f1c03c7a5c7b77210.103.16.35:7001 master - 0 1493883826713 4 connected 101-546089147e5837e378b69233dd2b8290267975719bc410.103.16.35:7002 master - 0 1493883827213 5 connected 10923-16383363ecec54c92c2548dcab016146bdb4c104e5e8410.103.16.34:7001 myself,master - 0 0 7 connected 0-100 5461-10922

我们现在要使10.103.16.35:7001这个主节点断掉,然后重启看一下基本信息

[root@mxqmongodb2 sa]# /home/maxiangqian/redis-3.2.8/src/redis-cli -p 7001

127.0.0.1:7001>SHUTDOWN

not connected>exit

[root@mxqmongodb2 sa]# redis-server /home/redis7001/redis7001.conf

然后再打印一下集群信息看一下:

[root@localhost redis7003]# redis-cli -p 7001cluster nodes

78f77749f9f9a5f0d7c99427e0311912a3fa04e710.103.16.34:7003 slave 89147e5837e378b69233dd2b8290267975719bc4 0 1493884247801 5connected

d015a22abc57c021f568973f4f1c03c7a5c7b77210.103.16.35:7001 slave 93a0e8d405959480fcbd310a5d15a92346c69d43 0 1493884247300 8connected

89147e5837e378b69233dd2b8290267975719bc410.103.16.35:7002 master - 0 1493884246798 5 connected 10923-16383ce9d635236567ccde4c864f78863fa0a4b26f25a10.103.16.35:7003 slave 363ecec54c92c2548dcab016146bdb4c104e5e84 0 1493884246298 7connected

93a0e8d405959480fcbd310a5d15a92346c69d4310.103.16.34:7002 master - 0 1493884248301 8 connected 101-5460363ecec54c92c2548dcab016146bdb4c104e5e8410.103.16.34:7001 myself,master - 0 0 7 connected 0-100 5461-10922

通过信息我们可以很明显的看到了10.103.16.35:7001这个主节点已经变成了从节点,而本身他的从节点也上升为主节点了。

但是我们需要注意的是在故障转移的时间段内,一些10.103.16.35:7001的写操作是会丢失的。直到他的从库提升为主库为止,这是redis为了保证数据一致性而采取的措施。

7:集群的节点管理:

我们先看一下怎么添加节点,添加节点分为两类(主节点或者从节点)

主节点:

./redis-trib.rb add-node 10.103.16.34:7004 10.103.16.34:7001

这样我们就把10.103.16.34:7004添加为集群的新的主节点,不过我们要注意的是,这时候他仅仅是一个没有哈希槽的主节点,并不会存储任何数据。

我们可以使用 redis-trib 程序, 将集群中的某些哈希桶移动到新节点里面, 新节点就会成为真正的主节点了。

从节点:

./redis-trib.rb add-node 10.103.16.34:7004 10.103.16.34:7001redis10.103.16.34::7004> cluster replicate 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e

将新节点指定为ID为3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e的从节点。

接下来我们看一下怎么移除某个节点,语法格式如下:

./redis-trib del-node 127.0.0.1:7000 ``

但是我们要注意一点,移除主节点的时候必须保证主节点是空的,也就是事先将要移除的主节点的哈希槽给转移到其他的主节点上。

linux集群组建和管理,Redis集群搭建与管理相关推荐

  1. redis集群moved重定向与redis集群ask重定向

    1.redis集群一共有16384个虚拟slot,被均匀分配到集群里所有redis机器node上: 2.每个node之间可以互相meet操作,都知道彼此slot范围: 3.客户端向redis集群任意n ...

  2. 【Linux部署】借助Docker部署Redis集群(Docker网卡创建+6个Redis集群搭建shell脚本)

    话不多说,直接上代码- # 创建桥接 网卡 docker network create redis --subnet 172.38.0.0/16 # 查看所有 网卡 docker network ls ...

  3. 最大的Redis集群:新浪Redis集群揭秘

    前言 Tape is Dead,Disk is Tape,Flash is Disk,RAM Locality is King.       - Jim Gray Redis不是比较成熟的Memcac ...

  4. 【Linux云计算架构:第三阶段-Linux高级运维架构】第25章—— 搭建jumperserver管理王者荣耀数万台游戏服务器

    本节内容: 34.1 Jumpserver堡垒机概述-部署Jumpserver运行环境 34.2 安装Coco组件 34.3 安装Web-Terminal前端-Luna组件-配置Nginx整合各组件 ...

  5. 【linux下多实例Tomcat+Nginx+redis+mysql环境搭建】

    一.搭建环境之前最好自己先创建一个文件夹,再次文件夹下在创建文件夹来安放项目包和Tomcat等应用以及性能测试监控的文件 1.项目存放地址: mkdir export (创建一个文件),mkdir a ...

  6. LINUX安装REDIS集群

    linux安装单机版redis已经在另一篇文章说过了,下边来搞集群,环境是新浪云服务器: redis3.0以后开始支持集群. 前言:redis用什么做集群? 用一个叫redis-trib.rb的rub ...

  7. redis 集群_Redis集群管理

    阅读文本大概需要10分钟. 1.简介 Redis在生产环境中一般是通过集群的方式进行运行,Redis集群包括主从复制集群和数据分片集群两种类型. *主从复制集群提供高可用性,而数据分片集群提供负载均衡 ...

  8. Linux CentOS 7 系统安装Redis集群

    首先确定自己需要建立多少个Redis主节点,因为Redis集群需要进行选举判决,所以主节点个数必须是奇数个,也就是说集群里面最少的主节点个数就是3个.因为每个主节点至少有一个备份节点,所以面我将在一台 ...

  9. redis 集群 实操 (史上最全、5w字长文)

    文章很长,建议收藏起来慢慢读! 总目录 博客园版 为大家准备了更多的好文章!!!! 推荐:尼恩Java面试宝典(持续更新 + 史上最全 + 面试必备)具体详情,请点击此链接 尼恩Java面试宝典,34 ...

最新文章

  1. “破五唯”之后,竟然立这个!
  2. 公司网络推广为你解答蜘蛛为什么有抓取网页却没收录?
  3. 函数中{}输出格式详解(C#)
  4. ida提取hashab算法记录
  5. 检测是否是手机访问接口
  6. 怎样为wordpress主题的文章列表添加无插件分页?
  7. oracle中执行自带脚本,oracle自带脚本
  8. 华科计算机学院三好学生,他是华科“三好学生标兵”,被保研到北大、复旦、交大等3所名校!...
  9. C++ 空间配置器(allocator)
  10. httpcode状态码
  11. The following types may not be used as proxies 异常处理办法
  12. 35岁是青春的后期你最好把下面十件事做好
  13. 实验吧—Web——WP之 Forms
  14. mysql数据库攻击与防御pdf_SQL注入攻击与防御 中文PDF清晰扫描版(38.6M)
  15. 给大家推荐几本JAVA相关书籍
  16. ​力扣解法汇总2315. 统计星号
  17. 看美国无线路由器品牌用户满意度排行榜
  18. 浅谈一下线程中synchronized块、wait,notify的用法
  19. 全球最大 IPO,我们能否赚笔养老钱?
  20. Java.lang.RuntimeException: Unable to start activity

热门文章

  1. Windows Server 2016 Technical Preview 4 (x64) 简体中文版下载!
  2. 同一页面实现多个Tab选项卡功能
  3. Centos7.0系统下Rsync+sersync实现多文件数据实时增量同步
  4. RecyclerView实现滑动删除和拖拽功能
  5. Webrtc服务器搭建转
  6. ofbiz 分开默认数据库
  7. sql2012 数据库连接错误
  8. async 和 await 关键字
  9. python 多线程Thread
  10. Manjaro.常用命令/ Mnajaro安装后的配置