Redis是一种高性能的键值数据库,也是一个开源的、基于内存的数据结构服务,同时还支持多种数据结构。Redis集群能够提供高可用性、扩展性以及容错性。在Redis集群中,增加或减少节点都是需要进行动态调整的,下面就介绍如何实现Redis Cluster的动态扩容。
首先,需要构建基于Redis的集群,可以参考Redis官方文档构建Redis Cluster。大概步骤如下:
Redis Cluster动态扩容有两种方式,一种是手动方式,另一种是自动方式。首先我们介绍手动方式。
手动扩容Redis Cluster,需要遵循以下步骤:
具体来说,添加新的节点需要遵循以下步骤:
redis-cli -c -h 10.0.0.1 -p 6379
;cluster meet <ip> <port>
,将新的节点加入到集群中,比如cluster meet 10.0.0.2 6379
,其中10.0.0.2是新节点的IP地址,6379是新节点的端口号;cluster addslots <startslot> <endslot>
,为新的节点指定插槽数。一般情况下,默认会把所有插槽分给已有的节点,这时用该命令把有些插槽转移到新节点。手动添加新节点比较繁琐,可以用脚本自动化添加,可以参考如下脚本:
#!/usr/bin/env bash
# New Node IP
node_ip=10.0.0.2
# New Node Port
node_port=6379
# Existing Cluster nodes, ':' separated
cluster_nodes="10.0.0.1:6379 10.0.0.3:6379 10.0.0.4:6379"
slots_each_node=$(echo "16384/$(echo $cluster_nodes | wc -w)" | bc)
slots_total=0
echo "SLOTS/EACH_NODE="$slots_each_node
for i in $cluster_nodes; do
slots_total=$(echo "$slots_total+$slots_each_node" | bc)
echo "Adding node to $i"
creation_res=$(redis-cli -h $i cluster meet ${node_ip} ${node_port})
echo "$creation_res"
if [[ $creation_res == *"Node already added"* ]]; then
echo "Node already added... moving to next."
continue
fi
node_id=$(echo "$creation_res" | grep "^[0-9A-Fa-f]\{40\}$")
echo "New node ID: ${node_id}"
redis-cli -h $i cluster addslots $(seq $(($slots_total-$slots_each_node+1)) $(($slots_total))) > /dev/null
done
echo "New node added!"
上面脚本会自动化添加新节点,确保了新节点的端口与已存在的端口相同,可以根据需要修改相应的参数,例如IP和端口号。
添加完新节点后,为了确保新节点已经正常运行,并与集群同步,可以执行如下命令来检查:
redis-cli -h <new_node_ip> -p <new_node_port> cluster nodes
该命令会输出所有节点的状态,确保新节点已经与其他节点联通。
以下是两个示例,演示如何手动和自动添加新的节点。
假设现在已有一个集群,有3个master和3个slave总共6个节点。
在节点192.168.0.5
上下载并解压Redis;
下载Redis配置文件,修改6379
端口为7001
,其他保持不变;
启动新的节点:redis-server /usr/local/redis/redis.conf
使用redis-cli -h ${任意一节点ip} -p ${任意一节点port} cluster meet 192.168.0.5 7001
命令加入已有的集群。
使用redis-cli -h ${任意一节点ip} -p ${任意一节点port} cluster addslots [start_slot] [end_slot]
命令为新节点分配槽位,具体start_slot和end_slot值需要根据已有节点的负载情况来确定。
使用redis-cli -h 192.168.0.5 -p 7001 cluster nodes
查看所有节点状态,确保新节点状态正常。
上述示例中的所有操作也可以通过脚本实现,比如下面脚本:
#!/usr/bin/env bash
# 获取 master 节点IP和端口,存入 masters 列表
masters=`redis-cli -h ${OLD_REDIS_HOST} -p ${OLD_REDIS_PORT} --cluster nodes | grep 'master' | cut -d' ' -f2`
masters_old=`redis-cli -h ${OLD_REDIS_HOST} -p ${OLD_REDIS_PORT} --cluster nodes | grep 'master'`
# 计算出每个节点应分配的槽位数量
num_nodes=`echo $masters | wc -w`
num_slots=16384
slots=$((num_slots / num_nodes))
slots_remainder=$((num_slots % num_nodes))
# 生成变量,存储新节点的IP和端口
node_ip=${NEW_REDIS_HOST}
node_port=${NEW_REDIS_PORT}
# 修改新节点配置,准备启动
wget -O /tmp/default.conf https://hellogary.github.io/redis-cluster/
sed -i -e "s/7777/${node_port}/${g;s/192.168.1.123/${node_ip}/g" /tmp/default.conf
# 启动新节点
/usr/local/redis-5.0.5/bin/redis-server /tmp/default.conf
# 等待新节点正常运行
sleep 10
# 将新节点加入到集群中,为其分配槽位,命令中的 masters_old 和 slots 分别是之前获取的节点信息和槽位数量
echo "yes" | redis-cli -h ${NEW_REDIS_HOST} -p ${NEW_REDIS_PORT} --cluster create ${masters_old} ${node_ip}:${node_port} --cluster-replicas 1 --cluster-slots ${slots}
exit 0
该脚本将会自动分配槽位,以及自动加入新节点,非常方便。
本文链接:http://task.lmcjl.com/news/16271.html