redis cluster搭建
简介:
redis cluster集群为redis官方给出的一种可高可用集群方案,与哨兵模式不同,Redis cluster实现高可用自动切换以外,通过切片服务动态添加服务器以横向扩展集群的内存容量
1、所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
2、节点的fail是通过集群中超过半数的节点检测失效时才生效。
3、客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
4、redis-cluster把所有的物理节点映射到[0-16383]slot上(不一定是平均分配),cluster 负责维护node<->slot<->value。
5、Redis集群预分好16384个桶,当需要在 Redis 集群中放置一个 key-value 时,根据 CRC16(key) mod 16384的值,决定将一个key放到哪个桶中。
主要思路:
Redis本身可以通过不同端口部署于同一台机器上,本次搭建需要使用keepalived,所以准备了6台虚拟机使用相同端口(3主3备),备机虽然不能写入数据,但由于Redis集群的内部跳转机制,VIP也可以飘在从节点上,写入数据时自动跳转到主节点。由于服务器较多可以考虑使用ansible、pssh等批量工具处理。
搭建过程:
准备基础系统
注 : 系统使用centos7.4 最小化安装 额外安装了perl gcc等常用工具包
一 .安装软件(所有节点):
[[email protected] ~]# tar -zxvf redis-4.0.7.tar.gz
[[email protected] ~]# cd redis-4.0.7
[[email protected] ~]# make && make install
[[email protected] ~]# yum install -y tcl
#安装tcl包,make test需要该包支持(可选)
[[email protected] ~]# make test
#检查安装是否完全(可选)
[[email protected] ~]#mv redis-4.0.7 /usr/local
二 .修改Redis配置文件redis.conf(所有节点):
[[email protected] ~]# sed -i 's/bind 127.0.0.1/# bind 127.0.0.1/g' redis.conf
说明:注释掉bind,因为我们要使用keepalived,所以不绑定本地地址,通过VIP连接集群
[[email protected] ~]# sed -i 's/protected-mode yes/protected-mode no/g' redis.conf
说明: 需要从外部通过VIP连接Redis数据库,故此处需要取消保护模式
[[email protected] ~]# echo "net.core.somaxconn = 10240">>/etc/sysctl.d/99-sysctl.conf
[[email protected] ~]# echo "net.ipv4.tcp_max_syn_backlog = 20480">>/etc/sysctl.d/99-sysctl.conf
[[email protected] ~]# sed -i 's/tcp-backlog 511/tcp-backlog 10240/g' redis.conf
说明: 调整系统somaxconn完全连接数的值为10240,调整系统tcp_max_syn_backlog半连接队列值为20480,最后调整Redis配置文件的tcp-backlog值为10240,该值取决于somaxconn值大小,如果配置大于somaxconn值,将按系统somaxconn值处理,故此处设置等值。可以根据主机性能同步扩大上述值
[[email protected] ~]# sed -i 's/tcp-keepalive 300/tcp-keepalive 120/g' redis.conf
说明: 修改tcp保持链接时间为120秒,此值视具体情况而定
[[email protected] ~]# sed -i 's/daemonize no/daemonize yes/g' redis.conf
说明 :让Redis以守护进程方式启动
[[email protected] ~]# sed -i 's/logfile ""/logfile \/var\/log\/redis_6379.log/g' redis.conf
说明:设置Redis输入日志路径
[[email protected] ~]# sed -i 's/databases 16/databases 1/g' redis.conf
说明:Redis单机默认支持16个数据库,但是Redis Cluster只支持1个
[[email protected] ~]# sed -i 's/dbfilename dump.rdb/dbfilename dump_6379.rdb/g' redis.conf
注:本次配置未修改RDB持久化相关配置,未开启AOF持久化属性,可视情况修改停用rdbchecksum等功能以提供更好的性能。
[[email protected] ~]# sed -i 's/# maxmemory <bytes>/maxmemory 12884901888/g' redis.conf
说明:设置Redis使用的最大内存,如果Redis作为缓存服务器,对于数据没有严格完整性要求的情况下应该设置其能使用的最大内存,并且设置相关数据淘汰算法,防止内存耗尽服务器崩溃,这里设置服务器总内存的3/4,为12GB,注意单位换算,Redis使用字节为基本单位
[[email protected] ~]# sed -i 's/# maxmemory-policy noeviction/maxmemory-policy allkeys-lru/g' redis.conf
说明:数据淘汰策略为maxmemory-policy allkeys-lru,如果要求数据完整性可以使用默认策略maxmemory-policy noeviction在内存达到上限后,不删除任何键,但是返回错误
[[email protected] ~]# sed -i 's/# maxmemory-samples 5/maxmemory-samples 5/g' redis.conf
[[email protected] ~]# sed -i 's/# cluster-enabled yes/cluster-enabled yes/g' redis.conf
说明:开启Redis Cluster集群服务
[[email protected] ~]# sed -i 's/# cluster-config-file nodes-6379.conf/cluster-config-file nodes-6379.conf/g' redis.conf
说明:指定集群配置文件,该配置文件在集群创建时自动生成,无需人为干预
[[email protected] ~]# sed -i 's/# cluster-node-timeout 15000/cluster-node-timeout 10000/g' redis.conf
说明:设置集群节点最大超时时间为10秒
[[email protected] ~]# sed -i 's/# cluster-require-full-coverage yes/cluster-require-full-coverage yes/g' redis.conf
说明:作为缓存服务器时可以修改cluster-require-full-coverage值为no, 当slot的覆盖不完全时(如其中一个主节点宕机,从节点未能切换为主节点时),集群仍然可以接受请求。如果对数据完整性有要求时使用默认值yes,当slot的覆盖不完全时,集群将停止工作
三 .启动Redis服务(所有节点)
[[email protected] ~]# redis-server redis.conf
四 .安装Ruby(所有节点)
由于RedisCluster脚本使用Ruby编写,所以需要Ruby支持,本次使用ruby-2.4.2
[[email protected] ~]# tar -zxvf ruby-2.4.2.tar.gz
[[email protected] ~]# cd ruby-2.4.2
[[email protected] ~]# ./configure
[[email protected] ~]# make && make install
[[email protected] ~]# ruby -v
#检查ruby安装是否正常
五 .安装Ruby包管理器rubygems(所有节点)
下载地址: https://rubygems.org/pages/download
[[email protected] ~]# unzip rubygems-2.7.6.zip
[[email protected] ~]# cd rubygems-2.7.6
[[email protected] ~]# ruby setup.rb
注 :Ruby与rubygems也可以通过yum安装 yum install -y ruby rubygems
六 .使用Ruby包管理器安装redis-gem包(所有节点)
下载地址为:https://rubygems.org/gems/redis/versions,本次使用redis-4.0.1.gem
[[email protected] ~]# gem install -l redis-4.0.1.gem
七 .拷贝集群脚本至/usr/local/bin并创建集群(任一节点)
[[email protected] ~]# cp /usr/local/redis-4.0.7/src/redis-trib.rb /usr/local/bin/redis-trib
[[email protected] ~]# redis-trib create --replicas 1 IP1:6379 IP2:6379 IP3:6379 IP4:6379 IP5:6379 IP6:6379
说明:--replicas 1表示每台主机配置一台从机
在出现主机列表详细信息后,输入yes完成集群创建
[[email protected] ~]# redis-cli -c -p 6379 -h xx.xx.xx.xx
#通过客户端连接至集群任意节点
xx.xx.xx.xx:6379>cluster info
#查看集群状态
八 .集群创建密码(所有节点)
[[email protected] ~]# redis-cli -c -h xx.xx.xxx.xxx -p 6379 config set masterauth redistest
[[email protected] ~]# redis-cli -c -h xx.xx.xxx.xxx -p 6379 config set requirepass redistest
[[email protected] ~]# redis-cli -c -h xx.xx.xxx.xxx -p 6379 -a redistest config rewrite
masterauth "redistest"
requirepass "redistest"
设置Redis开机自动启动(所有节点)
redis已经做好了自动启动脚本,稍加修改即可完成
[[email protected] ~]# cp /usr/local/redis-4.0.7/utils/redis_init_script /etc/init.d/redis
[[email protected] ~]# vi /etc/init.d/redis
修改后文件配置如下,标红为新增或修改项:
#!/bin/sh
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem.
# chkconfig: 2345 90 10
# description: redis
REDISPORT=6379
EXEC=/usr/local/bin/redis-server
CLIEXEC=/usr/local/bin/redis-cli
PIDFILE=/var/run/redis_${REDISPORT}.pid
CONF="/usr/local/redis-4.0.7/redis.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
保存文件即可
[[email protected] ~]# chkconfig redis on
配置keepalived通过VIP对外进行服务 (所有节点)
在所有节点上安装keepalived
[[email protected] ~]# yum install -y keepalived
[[email protected] ~]# systemctl enable keepalived
编辑keepalived.conf
[[email protected] ~]# vi /etc/keepalived/keepalived.conf
内容如下,注意每台主机修改不同的 router_id:
! Configuration File for keepalived
global_defs {
router_id rediscluster1
}
vrrp_script chk_rediscluster {
script "/etc/keepalived/check_all.sh"
interval 5
}
vrrp_instance rediscluster {
state BACKUP
interface eth0
virtual_router_id 151
priority 100
nopreempt
advert_int 2
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
xx.xx.xx.xx/24 dev eth0
}
track_script {
chk_rediscluster
}
}
编辑check_all.sh脚本:
#!/bin/bash
#check redis status
redis-cli -c -p 6379 -h 127.0.0.1 -a redistest cluster nodes
if [ $? != 0 ]
then
killall keepalived
fi
#check gateway status
ping xx.xx.xx.xx -c 2
if [ $? != 0 ]
then
killall keepalived
fi
每台主机启动keepalived
[[email protected] ~]# systemctl start keepalived
通过VIP访问集群,测试集群是否正常
至此整个集群搭建完成
Redis集群常用维护命令
//集群命令
CLUSTER INFO 打印集群的信息
CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。
//节点命令
CLUSTER MEET <ip> <port> 将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
CLUSTER FORGET <node_id> 从集群中移除 node_id 指定的节点。
CLUSTER REPLICATE <node_id> 将当前节点设置为 node_id 指定的节点的从节点。
CLUSTER SAVECONFIG 将节点的配置文件保存到硬盘里面。
CLUSTER ADDSLOTS <slot> [slot ...] 将一个或多个槽(slot)指派(assign)给当前节点。
CLUSTER DELSLOTS <slot> [slot ...] 移除一个或多个槽对当前节点的指派。
CLUSTER FLUSHSLOTS 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
CLUSTER SETSLOT <slot> NODE <node_id> 将槽 slot 指派给 node_id 指定的节点。
CLUSTER SETSLOT <slot> MIGRATING <node_id> 将本节点的槽 slot 迁移到 node_id 指定的节点中。
CLUSTER SETSLOT <slot> IMPORTING <node_id> 从 node_id 指定的节点中导入槽 slot 到本节点。
CLUSTER SETSLOT <slot> STABLE 取消对槽 slot 的导入(import)或者迁移(migrate)。
//键命令
CLUSTER KEYSLOT <key> 计算键 key 应该被放置在哪个槽上。
CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的键值对数量。
CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 个 slot 槽中的键。
//新增命令
CLUSTER SLAVES node-id 返回一个master节点的slaves 列表