redis 集群搭建详细过程

2017-01-06 07:57:15来源:CSDN作者:honglicu123人点击

准备工作

在 github 上下载 redis 源码,编译

./configuremake

LZ 下载的 redis 版本是 3.0.7
编译成功后,在源码的根目录下的 src 目录中,会生成对应的可执行文件

redis-server redis 服务器启动程序redis-cli redis客户端程序redis-trib.rb 这是一个ruby程序,可以用于创建集群、检查、删除节点等redis-sentinel 哨兵程序,能够监控redis HA和主备主机

创建集群

在 redis 官网也介绍了集群的搭建方法 [https://redis.io/topics/cluster-tutorial]

LZ 共使用了四个虚拟机,用于创建集群,每天虚拟机三个节点,分别是一个 RHEL,三个Ubuntu Server 16.04,IP地址分别如下:

192.168.192.166,以下简称166192.168.192.132,以下简称132192.168.192.133,以下简称133192.168.192.134,以下简称134

创建节点

在 166 主机创建 config/clusters/ 目录,再在这个目录下创建 7001, 7002 和 7003 三个目录,分别以目录名称作为端口号(前提是你的机器上这些端口号没有被占用, netstat -pnl 查看端口号)

创建一个通用配置文件 redis-common.conf

daemonize yestcp-backlog 511timeout 0tcp-keepalive 0loglevel debug  #开放最大日志级别,能够通过日志信息查看更多细节database 16slave-serve-stale-data yes #redis在复制的时候也可访问#slave 只读slave-read-only yesrepl-disable-tcp-nodelay yesslave-priority 100#打开 aofappendonly yesappendfsync everysec #在不清楚的这个配置的情况,redis 推荐设置这个参数为 everysecno-appendfsync-on-rewrite yes #关闭aof rewite的时候对新的写操作进行 fsyncauto-aof-rewrite-min-size 64mblua-time 5000#打开redis集群cluster-enabled yes#节点互联超时时的阀值cluster-node-timeout 15000cluster-migration-barrier 1#slow logslowlog-log-slower-than 10000slowlog-max-len 128notify-keyspace-events ""  hash-max-ziplist-entries 512  hash-max-ziplist-value 64  list-max-ziplist-entries 512  list-max-ziplist-value 64  set-max-intset-entries 512  zset-max-ziplist-entries 128  zset-max-ziplist-value 64  activerehashing yes  client-output-buffer-limit normal 0 0 0  client-output-buffer-limit slave 256mb 64mb 60  client-output-buffer-limit pubsub 32mb 8mb 60  hz 10  aof-rewrite-incremental-fsync yes

再根据不同的节点,为每一个节点创建一个特殊的配置文件,比如 redis-7001.conf,并通过 include 包含通用配置

include redis-common.confport 7001bind 192.168.192.166logfile "" #日志文件保存路径+日志文件名,建议方便的话,可以保存在对应的节点目录下dir "" #rdb, aof ,nodes.conf 文件的保存路径appendfilename "appendonly-7001.aof"cluster-config-file "nodes-7001.conf" #这个配置文件是由redis自动创建的,里面记录的集群节点的一些信息,比如master 节点,slave 节点的IP,端口号以及状态(是否failed)maxmemory 100mmaxmemory-policy allkeys-lru #内存耗尽时的淘汰策略#remove any keys according to the LRU algorithmauto-aof-rewrite-percentage 100

为每一个虚拟机创建好三个节点之后,就开始启用节点

启动节点

166主机

redis-server redis-7001.confredis-server redis-7002.confredis-server redis-7003.conf

132主机

redis-server redis-7004.confredis-server redis-7005.confredis-server redis-7006.conf

133主机

redis-server redis-7007.confredis-server redis-7008.confredis-server redis-7009.conf

134主机

redis-server redis-7010.confredis-server redis-7011.confredis-server redis-7012.conf

节点启动后,查看日志信息,观察是否均启动成功

创建集群

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

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

Redis 集群会把数据存在一个 master 节点,然后在这个 master 和其对应的salve 之间进行数据同步。当读取数据时,也根据一致性哈希算法到对应的 master 节点获取数据。只有当一个master 挂掉之后,才会启动一个对应的 salve 节点,充当 master 。

需要注意的是:必须要3个或以上的主节点,否则在创建集群时会失败,并且当存活的主节点数小于总节点数的一半时,整个集群就无法提供服务了。

当所有的节点都创建好后,在 src 目录中有一个文件 redis-trib.rb(前面介绍了这个文件),用这个工具创建集群。

Usage: redis-trib <command> <options> <arguments ...>  set-timeout     host:port milliseconds  del-node        host:port node_id  reshard         host:port                  --from <arg>                  --pipeline <arg>                  --yes                  --timeout <arg>                  --slots <arg>                  --to <arg>  create          host1:port1 ... hostN:portN                  --replicas <arg>  help            (show this help)  info            host:port  check           host:port  call            host:port command arg arg .. arg  add-node        new_host:new_port existing_host:existing_port                  --master-id <arg>                  --slave  rebalance       host:port                  --weight <arg>                  --threshold <arg>                  --pipeline <arg>                  --auto-weights                  --simulate                  --timeout <arg>                  --use-empty-masters  fix             host:port                  --timeout <arg>  import          host:port                  --replace                  --from <arg>                  --copyFor check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.

上面是这个工具的用法,该文件是使用 ruby 编写的,首先在你的环境中需要安装 ruby
RHEL 中安装

yum install ruby

Ubuntu 中安装

sudo apt-get install ruby

LZ因为环境比较无语,主机无法连接网络,所以都是使用的本地仓库的形式,具体如何创建网络仓库,可以去找找资料,这里不多说,Ubuntu 创建本地仓库比较简单,就是挂在一个镜像,然后使用 apt-cdrom,在 source.list 文件中就会增加一个源,指向的就是挂在的镜像目录。

安装好 ruby 之后,执行 redis-trib.rb 文件可能仍会报错

`require`: no such file to load -- rubygems (LoadError)`require`: no such file to load -- redis (LoadError)

这个是因为你的环境中没有安装 rubygems 和 ruby redis (在没网的环境中,手动下载依赖包简直就是噩梦)

下载 rubygems: [https://rubygems.org/page/download]
ruby redis: [https://rubygems.org/gems/redis],这是一个ruby 的redis 客户端

下载好 rubygems 后,执行

ruby setup.rb --help

能够查看详细的细节,安装执行 gem

ruby setup.rb

安装完成之后,即可安装 ruby redis 客户端了

gem install -l redis-3.2.1.gem

OK,环境配置好后,开始创建集群

./redis-trib.rb create replicas 2 192.168.192.166:7001 192.168.192.166:7002 192.168.192.166:7003 192.168.192.132:7004 192.168.192.132:7005 192.168.192.132:7006 192.168.192.133:7007 192.168.192.133:7008 192.168.192.133:7009 192.168.192.134:7010 192.168.192.134:7011 192.168.192.134:7012

创建12个节点,4个 master 节点,每一个 master 节点有 2 个 slave 节点。

如下图所示表示成功
这里写图片描述
这里写图片描述

集群操作

1. 查看节点信息

使用 redis-trib.rb info IP:PORT

./redis-trib.rb info  192.168.192.166:7001

这里写图片描述

2. 检查集群状态

使用 redis-trib.rb check IP:PORT

这里写图片描述

3. 停止其中一个master,再启动,观察变化

当前集群运行状态是 OK 的

cluster_state:okcluster_slots_assigned:16384cluster_slots_ok:16384cluster_slots_pfail:0cluster_slots_fail:0cluster_known_nodes:12cluster_size:4cluster_current_epoch:17cluster_my_epoch:1cluster_stats_messages_sent:43924cluster_stats_messages_received:11595

一共12个节点,有4个master节点,在 7001 的节点下,查看 node-7001.conf 这个文件(这个文件是 redis 自动生成的)

这里写图片描述

这个文件记录了集群中所有相关的能够到达的节点的信息,包括master的状态(是否是failed)

我们来看一下,每一个master节点都有哪些slave,info replication 能够清晰的查看slave 或者 master 的信息

master: 192.168.192.166 7003ip:192.168.192.133,port:7007ip:192.168.192.134,port:7012master: 192.168.192.166 7002ip:192.168.192.132,port:7005master: 192.168.192.132 7004ip:192.168.192.132,port:7006ip:192.168.192.133,port:7009master: 192.168.192.166 7001ip:192.168.192.133,port:7008ip:192.168.192.134,port:7011

这是当前我们的集群分布,上面的是 master,下面的两个是该 master 的两个 slave

现在我们来关闭其中一个 master,7004

redis-cli -h 192.168.192.132 -p 7004shutdown

关闭之后再来查看 node-7001.conf 这个文件信息,此时发现,有一个 master 显示的是 failed

这里写图片描述

当 master failed 的时候,redis 会从它的从服务器中选一个作为新的 master,然后另一个从服务器将作为新的 master 的 slave,再来看集群分布

master: 192.168.192.132 7006ip:192.168.192.133,port:7009master: 192.168.192.166 7003ip:192.168.192.133,port:7007ip:192.168.192.134,port:7012master: 192.168.192.166 7002ip:192.168.192.132,port:7005master: 192.168.192.166 7001ip:192.168.192.133,port:7008ip:192.168.192.134,port:7011

在没有停止 7004 之前,7004 作为 master,7006 和 7009 作为它的 slave,在将 7004 停止之后,7006 成为了新的 master,并且 7009 变成了它的 slave,当我们再次重新启动 7004 时,redis 不会重新把它作为 master,它将作为新的 master 7006 的一个 slave

4. 集群失败

redis 集群必须要有三个或以上的 master 节点,否则集群将创建失败,目前集群的状态时 ok,如果我们关闭 166 和 132 主机,查看集群状态为 fail

这里写图片描述

5. 添加新的 master 节点

在 132 主机上创建 8000 节点,在 133 主机上创建 8001 节点 (配置文件与其他节点的相同,只需要修改一下相应的文件保存路径即可)

启动节点

redis-server redis-8001.confredis-server redis-8000.conf

添加节点

./redis-trib.rb add-node 192.168.192.132:8000 192.168.192.133:7004

出现如下错误

[ERR] Node 192.168.192.132:8000 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

这个节点之前添加了一次,没有添加成功,导致节点非空,添加失败,解决办法:
1) 登陆数据库,将数据进行删除 flushdb
2) 将节点下的集群配置文件删除,即 node-8000.conf,redis 自动生成的文件
3) 删除节点下的 aof , rdb 文件等本地备份文件

再次添加节点

>>> Check for open slots...>>> Check slots coverage...[OK] All 16384 slots covered.>>> Send CLUSTER MEET to node 192.168.192.132:8000 to make it join the cluster.[OK] New node added correctly.

节点添加成功。查看集群的状态发现节点数成了13个

cluster_state:okcluster_slots_assigned:16384cluster_slots_ok:16384cluster_slots_pfail:0cluster_slots_fail:0cluster_known_nodes:13cluster_size:4cluster_current_epoch:24cluster_my_epoch:0cluster_stats_messages_sent:284cluster_stats_messages_received:284

当前集群的分布如下所示

master: 192.168.192.132 7005ip:192.168.192.134,port:7010ip:192.168.192.166,port:7002master: 192.168.192.132 7006ip:192.168.192.133,port:7009ip:192.168.192.132,port:7004master: 192.168.192.166 7003ip:192.168.192.134,port:7012ip:192.168.192.133,port:7007master: 192.168.192.132 8000master: 192.168.192.166 7001ip:192.168.192.133,port:7008ip:192.168.192.134,port:7011

新添加的 8000 端口是 master 节点,它不包含任何数据,因为没有包含任何的 slot。新添加的都为主节点,当集群需要将某个节点升级为新的主节点时,这个节点不会被选中。

为新节点分配 slot

redis-trib.rb rehashed 192.168.192.132:8000

按照提示操作

#选择要迁移的 slot 数量How many slots do you want to move (from 1 to 16384)? 500What is the receiving node ID? 81e71239d85d4112e87c5fe00d513f879c980118#all 表示从所有的 master 重新分配Please enter all the source node IDs.  Type 'all' to use all the nodes as source nodes for the hash slots.  Type 'done' once you entered all the source nodes IDs.Source node #1:allReady to move 500 slots.  Source nodes:    M: 030197fec21c3192c0f8938ad276f8c8062c6410 192.168.192.166:7001   slots:0-4095 (4096 slots) master   2 additional replica(s)    M: c6e30b67bc201f4f48bdf5fe9d88209505e2f0d9 192.168.192.132:7005   slots:4096-8191 (4096 slots) master   2 additional replica(s)    M: 70d2ed1edd1035972927a7c8415ca9d0c941d21d 192.168.192.166:7003   slots:8192-12287 (4096 slots) master   2 additional replica(s)    M: c63aac7105f9601915e65ef0d3ff45b0b3f0a7ec 192.168.192.132:7006   slots:12288-16383 (4096 slots) master   2 additional replica(s)    M: 1a260ae8c08a9ee1b4d856e0fcf190c271590cf0 192.168.192.133:8001   slots: (0 slots) master   0 additional replica(s)  Destination node:    M: 81e71239d85d4112e87c5fe00d513f879c980118 192.168.192.132:8000   slots: (0 slots) master   0 additional replica(s)  Resharding plan:    Moving slot 0 from 030197fec21c3192c0f8938ad276f8c8062c6410    ......Do you want to proceed with the proposed reshard plan (yes/no)? yes    Moving slot 0 from 192.168.192.166:7001 to 192.168.192.132:8000:     ......

6. 添加新的 slave 节点

节点添加与上面添加 master 的前面步骤相同
1. 创建节点目录和节点配置文件,启动节点
2. redis-trib.rb add-node new-ip:new-port exist_ip:exist_port
3. 这样,添加上的节点为 master 节点,然后使用 redis-cli 连接,输入命令

cluster replicate node-id

即添加成功,node-id 可以通过查看命令 CLUSTER NODES查看,也可以直接查看节点的 node.conf 文件

NOTE:在线添加 slave 节点时,需要 dump 整个 master 进程,并传递到 slave,再由 slave 加载 rdb 文件到内存, rdb 传输过程中可能无法提供服务,整个过程需要消耗大量的I/O。

7. 删除 master 节点

删除节点之前,需要使用 reshard 移除该 master 的全部 slot,然后才能删除节点,接收 slot 的节点必须是 master 节点

./redis-trib.rb reshard 192.168.192.134:8003How many slots do you want to move (from 1 to 16384)? 500What is the receiving node ID? c6023463d9f33e4c5ca72fdc85eb4c7d95b258a5*** The specified node is not known or not a master, please retry.What is the receiving node ID? 1a260ae8c08a9ee1b4d856e0fcf190c271590cf0Please enter all the source node IDs.  Type 'all' to use all the nodes as source nodes for the hash slots.  Type 'done' once you entered all the source nodes IDs.Source node #1:81e71239d85d4112e87c5fe00d513f879c980118Source node #2:doneReady to move 500 slots.  Source nodes:    M: 81e71239d85d4112e87c5fe00d513f879c980118 192.168.192.132:8000   slots:0-124,4096-4220,8192-8316,12288-12412 (500 slots) master   1 additional replica(s)  Destination node:    M: 1a260ae8c08a9ee1b4d856e0fcf190c271590cf0 192.168.192.133:8001   slots: (0 slots) master   0 additional replica(s)  Resharding plan:    Moving slot 0 from 81e71239d85d4112e87c5fe00d513f879c980118    ......

移除所有的 slot 之后,删除空 master 节点

redis-trib.rb del-node 192.168.192.132:8000 '81e71239d85d4112e87c5fe00d513f879c980118'

8. 删除 slave 节点

#redis-trib.rb del-node ip:port 'node-id'

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台