redis4.0.14集群搭建

redis集群搭建

搭建集群工作需要以下三个步骤:

1)准备节点。

2)节点握手。

3)分配槽。

redis版本:4.0.14

准备节点

下载安装包

mkdir -p /opt/server
cd /opt/server
wget http://download.redis.io/releases/redis-4.0.14.tar.gz
tar -xvf redis-4.0.14.tar.gz


编译安装

cd redis-4.0.14
yum -y install tcl
make PREFIX=/opt/server/redis install

测试编译结果

cd src
make test

看到如下结果说明测试成功

\o/ All tests passed without errors!

Cleanup: may take some time... OK

创建相关目录

cd /opt/server/redis
mkdir {conf,data,log,script}

Redis集群一般由多个节点组成,节点数量至少为6个才能保证组成完整 高可用的集群。每个节点需要开启配置cluster-enabled yes,让Redis运行在集 群模式下。把6个节点配置统一放在 conf目录下,集群相关配置如下:

#节点端口 
port 6379

bind 172.16.10.212 127.0.0.1

# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
daemonize yes

# pid文件位置
pidfile /var/run/redis_6379.pid

# 日志文件位置
logfile "/opt/server/redis/log/redis-6379.log"

# 指定生成的快照文件名
dbfilename dump-6379.rdb

# 工作目录
# 例如上面的 dbfilename 只指定了文件名,
# 但是它会写入到这个目录下。这个配置项一定是个目录,而不能是文件名。
dir /opt/server/redis/data/

# 最大使用内存, 设置为物理内存的80%左右,例如物理内存8G,则设置为6GB
maxmemory 6GB

#当Redis所用内存达到maxmemory上限时会触发相应的溢出控制策略。
#根据LRU算法删除设置了超时属性(expire)的键,直到腾出足够空间为止。如果没有可删除的键对象,回退到noeviction策略。
maxmemory-policy volatile-lru

#开启RDB-AOF混合持久化
aof-use-rdb-preamble yes

#开启AOF持久化
appendonly yes

# The name of the append only file (default: "appendonly.aof")
appendfilename "appendonly-6379.aof"

#每秒持久化
appendfsync everysec

#指定是否在后台aof文件rewrite期间调用fsync,默认为no,表示要调用fsync(无论后台是否有子进程在刷盘)。Redis在后台写RDB文件或重写afo文件期间会存在大量磁盘IO,此时,在某些linux系统中,调用fsync可能会阻塞。
no-appendfsync-on-rewrite yes

# 对执行时间大于多少微秒(microsecond,1秒 = 1,000,000 微秒)的命令进行记录,默认10000微秒,即10毫秒。
slowlog-log-slower-than 10000

# slowlog 最多能保存多少条日志,当发现redis性能下降的时候可以查看下是哪些命令导致的
slowlog-max-len 512


# 开启集群模式 
cluster-enabled yes
# 节点超时时间,单位毫秒 
cluster-node-timeout 10000

#当cluster-require-full-coverage为no时,
#表示当负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群仍然可用;
#当cluster-require-full-coverage为yes时,
#表示当负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群不可用
cluster-require-full-coverage no

# 集群内部配置文件 
cluster-config-file /opt/server/redis/conf/nodes-6379.conf

# 将一些危险的命令rename-command
rename-command FLUSHALL "FLUSHALL_CUSTOM"
rename-command FLUSHDB  "FLUSHDB_CUSTOM"
rename-command CONFIG   "CONFIG_CUSTOM"
rename-command KEYS     "KEYS_CUSTOM"

注意:以上为需要修改或添加的配置,其他默认配置保持不变。

其他配置和单机模式一致即可,配置文件命名规则redis-{port}.conf,准备好配置后启动所有节点,命令如下:

./bin/redis-server conf/redis-6379.conf 

./bin/redis-server conf/redis-6380.conf 

./bin/redis-server conf/redis-6381.conf 

./bin/redis-server conf/redis-6382.conf 

./bin/redis-server conf/redis-6383.conf 

./bin/redis-server conf/redis-6384.conf

检查节点日志是否正确,日志内容如下:

cat log/redis-6379.log 

15444:C 16 Dec 14:59:08.042 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
15444:C 16 Dec 14:59:08.042 # Redis version=4.0.14, bits=64, commit=00000000, modified=0, pid=15444, just started
15444:C 16 Dec 14:59:08.042 # Configuration loaded
15445:M 16 Dec 14:59:08.043 * No cluster configuration found, I'm f40a6ee42b86b2b31fe9a492f3cefb603f3650da

6379节点启动成功,第一次启动时如果没有集群配置文件,它会自动创建一份,文件名称采用cluster-config-file参数项控制,建议采用node{port}.conf格式定义,通过使用端口号区分不同节点,防止同一机器下多个 节点彼此覆盖,造成集群信息异常。如果启动时存在集群配置文件,节点会 使用配置文件内容初始化集群信息。

集群模式的Redis除了原有的配置文件之外又加了一份集群配置文件。 当集群内节点信息发生变化,如添加节点、节点下线、故障转移等。节点会 自动保存集群状态到配置文件中。需要注意的是,Redis自动维护集群配置 文件,不要手动修改,防止节点重启时产生集群信息错乱。

在节点6380执行cluster nodes命令获取集群节点状 态:

127.0.0.1:6380>cluster nodes 
0745daa759e5ae1bf2f1d5ec4a911f9761d2ce63 127.0.0.1:6380 myself,master - 0 0 0 connected

每个节点目前只能识别出自己的节点信息。我们启动6个节点,但每个 节点彼此并不知道对方的存在,下面通过节点握手让6个节点彼此建立联系 从而组成一个集群。

节点握手

节点握手是指一批运行在集群模式下的节点通过Gossip协议彼此通信, 达到感知对方的过程。节点握手是集群彼此通信的第一步,由客户端发起命 令:cluster meet{ip}{port}

127.0.0.1:6379> cluster meet 127.0.0.1 6380
OK
127.0.0.1:6379> cluster meet 127.0.0.1 6381
OK
127.0.0.1:6379> cluster meet 127.0.0.1 6382
OK
127.0.0.1:6379> cluster meet 127.0.0.1 6383
OK
127.0.0.1:6379> cluster meet 127.0.0.1 6384
OK

对节点6379和6380分别执行cluster nodes命令,可以看到它们彼此已经感知到对方的存在。

127.0.0.1:6379> cluster nodes 
f40a6ee42b86b2b31fe9a492f3cefb603f3650da 127.0.0.1:6379 myself,master - 0 0 0 connected 0745daa759e5ae1bf2f1d5ec4a911f9761d2ce63 127.0.0.1:6380 master - 0 1468073534265 1 connected

127.0.0.1:6380> cluster nodes 
f40a6ee42b86b2b31fe9a492f3cefb603f3650da 127.0.0.1:6379 master - 0 1468073571641 0 connected 0745daa759e5ae1bf2f1d5ec4a911f9761d2ce63 127.0.0.1:6380 myself,master - 0 0 1 connected

节点建立握手之后集群还不能正常工作,这时集群处于下线状态

通过cluster info命令可以获取集群当前状态:

127.0.0.1:6379> cluster info 
cluster_state:fail 
cluster_slots_assigned:0 
cluster_slots_ok:0 
cluster_slots_pfail:0 
cluster_slots_fail:0 
cluster_known_nodes:6 
cluster_size:0 ...

从输出内容可以看到,被分配的槽(cluster_slots_assigned)是0,由于 目前所有的槽没有分配到节点,因此集群无法完成槽到节点的映射。只有当 16384个槽全部分配给节点后,集群才进入在线状态。

分配槽

Redis集群把所有的数据映射到16384个槽中。每个key会映射为一个固 定的槽,只有当节点分配了槽,才能响应和这些槽关联的键命令。通过 cluster addslots命令为节点分配槽。这里利用bash特性批量设置槽(slots), 命令如下:

/opt/server/redis/bin/redis-cli -h 127.0.0.1 -p 6379 cluster addslots {0..5461} 
/opt/server/redis/bin/redis-cli -h 127.0.0.1 -p 6380 cluster addslots {5462..10922} 
/opt/server/redis/bin/redis-cli -h 127.0.0.1 -p 6381 cluster addslots {10923..16383}

把16384个slot平均分配给6379、6380、6381三个节点。执行cluster info 查看集群状态,如下所示:

127.0.0.1:6379> cluster info 
cluster_state:ok 
cluster_slots_assigned:16384 
cluster_slots_ok:16384 
cluster_slots_pfail:0 
cluster_slots_fail:0 
cluster_known_nodes:6 
cluster_size:3 
cluster_current_epoch:5 
cluster_my_epoch:0 
cluster_stats_messages_sent:4874 
cluster_stats_messages_received:4726

当前集群状态是OK,集群进入在线状态。所有的槽都已经分配给节点,执行cluster nodes命令可以看到节点和槽的分配关系:

127.0.0.1:6379> cluster nodes
c36da792cc2533c4883aed4e943a69c83cd12e6e 172.16.10.212:6384@16384  master 0 1576205497759 5 connected
2b32e0aad58439d4d90b6c1b370477ef2be51a92 172.16.10.212:6383@16383 master 0 1576205498000 4 connected
3424c5eefd0b348885dd7d7df50f8bd6e4d67327 172.16.10.212:6381@16381 master - 0 1576205498761 2 connected 10923-16383
0745daa759e5ae1bf2f1d5ec4a911f9761d2ce63 172.16.10.212:6380@16380 master - 0 1576205496000 1 connected 5462-10922
f52d5410226fffaa778212bfd2fa49de8ba56c62 172.16.10.212:6382@16382 master 0 1576205497000 3 connected
f40a6ee42b86b2b31fe9a492f3cefb603f3650da 172.16.10.212:6379@16379 myself,master - 0 1576205497000 3 connected 0-5461

目前还有三个节点没有使用,作为一个完整的集群,每个负责处理槽的 节点应该具有从节点,保证当它出现故障时可以自动进行故障转移。集群模 式下,Reids节点角色分为主节点和从节点。首次启动的节点和被分配槽的 节点都是主节点,从节点负责复制主节点槽信息和相关的数据。使用cluster replicate{nodeId}命令让一个节点成为从节点。其中命令执行必须在对应的 从节点上执行,nodeId是要复制主节点的节点ID,命令如下:

127.0.0.1:6382>cluster replicate f40a6ee42b86b2b31fe9a492f3cefb603f3650da
OK

127.0.0.1:6383>cluster replicate 0745daa759e5ae1bf2f1d5ec4a911f9761d2ce63
OK

127.0.0.1:6384>cluster replicate 3424c5eefd0b348885dd7d7df50f8bd6e4d67327
OK

Redis集群模式下的主从复制使用了之前介绍的Redis复制流程,依然支持全量和部分复制。

通过cluster nodes命令查看集群状态和复制关系,如下所示:

127.0.0.1:6379> cluster nodes
c36da792cc2533c4883aed4e943a69c83cd12e6e 172.16.10.212:6384@16384 slave 3424c5eefd0b348885dd7d7df50f8bd6e4d67327 0 1576205497759 5 connected
2b32e0aad58439d4d90b6c1b370477ef2be51a92 172.16.10.212:6383@16383 slave 0745daa759e5ae1bf2f1d5ec4a911f9761d2ce63 0 1576205498000 4 connected
3424c5eefd0b348885dd7d7df50f8bd6e4d67327 172.16.10.212:6381@16381 master - 0 1576205498761 2 connected 10923-16383
0745daa759e5ae1bf2f1d5ec4a911f9761d2ce63 172.16.10.212:6380@16380 master - 0 1576205496000 1 connected 5462-10922
f52d5410226fffaa778212bfd2fa49de8ba56c62 172.16.10.212:6382@16382 slave f40a6ee42b86b2b31fe9a492f3cefb603f3650da 0 1576205497000 3 connected
f40a6ee42b86b2b31fe9a492f3cefb603f3650da 172.16.10.212:6379@16379 myself,master - 0 1576205497000 3 connected 0-5461

目前为止,我们依照Redis协议手动建立一个集群。它由6个节点构成, 3个主节点负责处理槽和相关数据,3个从节点负责故障转移。

创建启动、停止脚本

cd /opt/server/redis/script/

vim redis-6379

#!/bin/sh
#chkconfig: 2345 80 90
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem.

### BEGIN INIT INFO
# Provides:     redis_6379
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description:    Redis data structure server
# Description:          Redis data structure server. See https://redis.io
### END INIT INFO

REDISPORT=6379
EXEC=/opt/server/redis/bin/redis-server
CLIEXEC=/opt/server/redis/bin/redis-cli

PIDFILE=/var/run/redis_${REDISPORT}.pid
CONF="/opt/server/redis/conf/${REDISPORT}.conf"

case "$1" in
    start)
        if [ -f $PIDFILE ]
        then
                echo "$PIDFILE exists, process is already running or crashed"
        else
                echo "Starting Redis server..."
                $EXEC $CONF
        fi
        ;;
    stop)
        if [ ! -f $PIDFILE ]
        then
                echo "$PIDFILE does not exist, process is not running"
        else
                PID=$(cat $PIDFILE)
                echo "Stopping ..."
                $CLIEXEC -p $REDISPORT shutdown
                while [ -x /proc/${PID} ]
                do
                    echo "Waiting for Redis to shutdown ..."
                    sleep 1
                done
                echo "Redis stopped"
        fi
        ;;
    *)
        echo "Please use start or stop as first argument"
        ;;
esac

分别创建redis-6379、redis-6380、redis-6381、redis-6382、redis-6383、redis-6384;修改脚本中变量REDISPORT为指定端口。

启动服务

/opt/server/redis/script/redis-6379 start
/opt/server/redis/script/redis-6380 start
/opt/server/redis/script/redis-6381 start
/opt/server/redis/script/redis-6382 start
/opt/server/redis/script/redis-6383 start
/opt/server/redis/script/redis-6384 start

停止服务

/opt/server/redis/script/redis-6379 stop
/opt/server/redis/script/redis-6380 stop
/opt/server/redis/script/redis-6381 stop
/opt/server/redis/script/redis-6382 stop
/opt/server/redis/script/redis-6383 stop
/opt/server/redis/script/redis-6384 stop

参考书籍:《Redis开发与运维》

发布了30 篇原创文章 · 获赞 7 · 访问量 3903

猜你喜欢

转载自blog.csdn.net/huchao_lingo/article/details/103522805
今日推荐