Redis-Cluster 简介
Redis 官方在 3.0 版本以后推出了 Redis-Cluster 集群版,该版本能够解决单机版 Redis 无法水平伸缩的问题,并提供去中心化、高可用的 Redis 集群服务的能力。
Redis-Custer 主要提供以下功能:
- 数据自动分片的能力
- 当集群部分节点故障或者无法与其它节点通讯的情况下,集群整体能够正常提供服务的能力
本文将主要介绍在滴滴云服务器上搭建 Redis-Cluster 的方法。
集群配置
- 1核 1G 云服务器,搭配 40G 系统盘 + 20G 数据云盘 * 3 台(此为测试使用的最小集群规模。生产环境下,建议集群整体最小核数>=集群实例数,单个 Redis 实例内存建议不超过 8G)
- 操作系统:Linux CentOS 7.4
- 建议将 Redis 持久化文件及日志文件挂载到 SSD 云盘中,以避免物理磁盘损坏的情况下 Redis 数据丢失
集群主从规划
Redis-Cluster 的每个实例支持一主多从。在生产环境下,一般给每个实例配置一主一从,并将每个主从分散到不同的主机上,这样可以最大程度避免单点故障对集群造成的影响。
以下是我们在3台主机的情况下,配置 3 主 3 从的集群规划:
- server1:7000(主)-> server2:7004(从)
- server2:7001(主)-> server3:7005(从)
- server3:7002(主)-> server1:7003(从)
下文中 server1
、server2
、server3
指代每台云主机的内网 IP。
集群安装
下载并安装 Redis 默认版本
(如需指定版本安装,可以从 Redis.io 官网下载)
sudo yum install redis -y
下载并安装 Redis 集群管理工具 Redis-trib
Redis-trib 是 Redis 官方提供的 Redis 集群管理工具,它可以提供创建集群、增加节点、数据迁移等功能。
sudo yum install redis-trib -y
优化系统参数
# 切换到root账号以修改系统配置
sudo -i
sysctl vm.overcommit_memory=1
echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
echo 511 > /proc/sys/net/core/somaxconn
echo "net.core.somaxconn = 551" >> /etc/sysctl.conf
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
# 编辑/etc/rc.local文件,增加如下内容:
vim /etc/rc.local
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi
# 将/etc/rc.local文件权限设置为可执行
chmod +x /etc/rc.local
ulimit -n 10032
# 编辑/etc/security/limits.conf文件,开大最大文件句柄限制
vim /etc/security/limits.conf
* soft nofile 10032
* hard nofile 10032
目录规划
我们将 Redis 的配置文件和数据文件放到提前挂载好的 EBS 云盘中去(云盘挂载方式请参考挂载云盘),以保障数据的高可靠性。本文中云盘挂载到 /data 目录下。
通过 mkdir
命令,分别在三台云主机上创建以下目录:
server1
└── /data/redis-cluster
├── 7000
│ ├── conf
│ ├── data
│ └── log
└── 7003
├── conf
├── data
└── log
server2
└── /data/redis-cluster
├── 7001
│ ├── conf
│ ├── data
│ └── log
└── 7004
├── conf
├── data
└── log
server3
└── /data/redis-cluster
├── 7002
│ ├── conf
│ ├── data
│ └── log
└── 7005
├── conf
├── data
└── log
制作集群配置模板
先制作一个 redis.conf 的集群模板,然后只要根据不同 IP、端口替换模板即可得到每个 Redis 实例的配置文件:
# 将redis原始配置文件cp到/data/redis-cluster下作为模板文件
sudo cp /etc/redis.conf /data/redis-cluster
# 修改模板文件,改为以下内容:
sudo vim /data/redis-cluster/redis.conf
bind REDIS_IP
port REDIS_PORT
pidfile /data/redis-cluster/REDIS_PORT/redis_REDIS_PORT.pid
logfile /data/redis-cluster/REDIS_PORT/log/redis.log
dir /data/redis-cluster/REDIS_PORT/data
cluster-config-file /data/redis-cluster/REDIS_PORT/conf/nodes-REDIS_PORT.conf
daemonize yes
# 设置redis内存上限,根据具体情况设置,建议一台云主机上的redis内存总和<物理内存-1个redis实例最大内存
maxmemory 268435456
maxmemory-policy volatile-ttl
cluster-enabled yes
cluster-node-timeout 15000
cluster-require-full-coverage no
注意:bind 一行我们强烈建议不要绑定外网 IP,只绑定内网 IP,否则会有安全风险。
生成实际配置
生成每个实例的 redis.conf 实际配置:
# 在每台机器上将模板文件cp到相应的端口目录下:
# server1:
sudo cp /data/redis-cluster/redis.conf /data/redis-cluster/7000/conf
sudo cp /data/redis-cluster/redis.conf /data/redis-cluster/7003/conf
# server2:
sudo cp /data/redis-cluster/redis.conf /data/redis-cluster/7001/conf
sudo cp /data/redis-cluster/redis.conf /data/redis-cluster/7004/conf
# server3:
sudo cp /data/redis-cluster/redis.conf /data/redis-cluster/7002/conf
sudo cp /data/redis-cluster/redis.conf /data/redis-cluster/7005/conf
将每个 Redis 实例的配置进行替换:
# server1:
sudo sed -i 's/REDIS_IP/server1/g' /data/redis-cluster/7000/conf/redis.conf
sudo sed -i 's/REDIS_PORT/7000/g' /data/redis-cluster/7000/conf/redis.conf
sudo sed -i 's/REDIS_IP/server1/g' /data/redis-cluster/7003/conf/redis.conf
sudo sed -i 's/REDIS_PORT/7003/g' /data/redis-cluster/7003/conf/redis.conf
# server2:
sudo sed -i 's/REDIS_IP/server2/g' /data/redis-cluster/7001/conf/redis.conf
sudo sed -i 's/REDIS_PORT/7001/g' /data/redis-cluster/7001/conf/redis.conf
sudo sed -i 's/REDIS_IP/server2/g' /data/redis-cluster/7004/conf/redis.conf
sudo sed -i 's/REDIS_PORT/7004/g' /data/redis-cluster/7004/conf/redis.conf
# server3:
sudo sed -i 's/REDIS_IP/server3/g' /data/redis-cluster/7002/conf/redis.conf
sudo sed -i 's/REDIS_PORT/7002/g' /data/redis-cluster/7002/conf/redis.conf
sudo sed -i 's/REDIS_IP/server3/g' /data/redis-cluster/7005/conf/redis.conf
sudo sed -i 's/REDIS_PORT/7005/g' /data/redis-cluster/7005/conf/redis.conf
集群启动
启动每个 Redis-server 实例
# server1:
sudo redis-server /data/redis-cluster/7000/conf/redis.conf
sudo redis-server /data/redis-cluster/7003/conf/redis.conf
# server2:
sudo redis-server /data/redis-cluster/7001/conf/redis.conf
sudo redis-server /data/redis-cluster/7004/conf/redis.conf
# server3:
sudo redis-server /data/redis-cluster/7002/conf/redis.conf
sudo redis-server /data/redis-cluster/7005/conf/redis.conf
建立集群
为了避免主节点和从节点分配在同一台机器上,我们需要先把主节点组成一个集群,再用不同机器的实例作为从节点挂载主节点:
# 在任意一台机器上,执行redis-trib create命令创建主节点集群
sudo redis-trib create --replicas 0 server1:7000 server2:7001 server3:7002
# 查出所有实例的node-id
sudo redis-cli -h server1 -p 7000 CLUSTER NODES |grep myself |awk '{print $2" "$1}'
sudo redis-cli -h server2 -p 7001 CLUSTER NODES |grep myself |awk '{print $2" "$1}'
sudo redis-cli -h server3 -p 7002 CLUSTER NODES |grep myself |awk '{print $2" "$1}'
# 分配从节点,保障每个从节点和主节点不在一台机器上
sudo redis-trib add-node --slave --master-id cec814c0c7182145263fd5df0c6e8802266c176a server1:7003 server1:7000
sudo redis-trib add-node --slave --master-id 2dcf06aa6df347221323df6a5de9179d826c1d7e server2:7004 server1:7000
sudo redis-trib add-node --slave --master-id 9c3b048d31eea45d4b26e6c9b299f009ebcb4318 server3:7005 server1:7000
# 检查集群状态,确认每个master节点都正确挂载了slave节点,并且slave和master不在一台机器上分配
sudo redis-trib.rb check server1:7000
# 测试读写性能
sudo redis-benchmark -h server1 -p 7000 -r 10000 -n 100000 -t set,get
sudo redis-benchmark -h server2 -p 7001 -r 10000 -n 100000 -t set,get
sudo redis-benchmark -h server3 -p 7002 -r 10000 -n 100000 -t set,get
总结
我们在滴滴云环境上,安装了 Redis 实例,并对每台云主机进行了系统参数优化;通过统一的模板进行 Redis 实例配置;并在主从打散的前提下,成功创建了 3 主 3 从的 Redis 集群;最后对集群每个实例进行的读写性能测试。