工作原理:虽然redis有主从结构,但是无法解决只能单机写入数据的问题,无法实现分布式数据保存。而redis集群会预先分配16384个槽位,当客户端需要写入一个key(键值对)到服务器时,会使用CRC16(key) mod 16384计算后得到值,然后根据值对应的槽位决定写入到哪个redis节点,从而实现分布式数据写入,解决单机瓶颈。
集群特点:
redis官网集群文档:redis集群
单个redis编译安装:redis编译安装
redis4实现集群:redis4集群
集群拓扑:
系统版本 | centos 7.7 |
---|---|
redis版本 | redis-5.0.3 |
集群1 | 192.168.116.132:6379, 192.168.116.132:6380 |
集群2 | 192.168.116.133:6379, 192.168.116.133:6380 |
集群3 | 192.168.116.134:6379, 192.168.116.134:6380 |
cd /etc/yum.repos.d/ yum install -y wget wget http://mirrors.aliyun.com/repo/Centos-7.repo wget http://mirrors.aliyun.com/repo/epel-7.repo mv CentOS-Base.repo CentOS-Base.repo.bak sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo yum clean all yum makecache systemctl disable firewalld sed -i 's/SELINUX=enforcing$/SELINUX=disabled/g' /etc/selinux/config setenforce 0 yum install ntp -y 校对时间,每台服务器时间保持一致 ntpdate time1.aliyun.com
根据下面主备情况安装3个节点多实例 主:192.168.116.132:6379 备:192.168.116.132:6380 主:192.168.116.133:6379 备:192.168.116.133:6380 主:192.168.116.134:6379 备:192.168.116.134:6380 vi redis_duoshili.sh #!/bin/bash . /etc/init.d/functions #设置redis版本,密码,安装目录,端口号 VERSION=redis-5.0.3 PASSWORD=123456 INSTALL_DIR=/usr/local/redis DEFAULT_PORT=6379 #如果只要安装单个redis,设置为0就行 DSL_NUM=1 #如网络质量不好可以自行去官网下载,然后删除下面#wget https://download.redis.io/releases/${VERSION}.tar.gz || { action "源码包下载失败" false;exit; }#这句话 #redis版本下载官网:https://download.redis.io/releases/?_ga=2.164994486.889360285.1614915959-1081687905.1611193410 redis_install() { yum install -y gcc jemalloc-devel -q || { action "安装依赖失败" false;exit; } wget https://download.redis.io/releases/${VERSION}.tar.gz || { action "源码包下载失败" false;exit; } tar xf ${VERSION}.tar.gz cd ${VERSION} make PREFIX=${INSTALL_DIR}/${DEFAULT_PORT}/ install && action "redis 编译完成" || { action "redis 编译失败" false;exit; } mkdir -p ${INSTALL_DIR}/${DEFAULT_PORT}/{etc,log,data,run} cp redis.conf ${INSTALL_DIR}/${DEFAULT_PORT}/etc/redis-${DEFAULT_PORT}.conf cp sentinel.conf ${INSTALL_DIR}/${DEFAULT_PORT}/etc/redis-${DEFAULT_PORT}-sentinel.conf if id redis &>/dev/null;then action "redis 用户已经存在" false else useradd -r -s /sbin/nologin redis action "redis 用户创建成功" fi cat >> /etc/sysctl.conf <<EOF net.core.somaxconn = 1024 vm.overcommit_memory = 1 EOF sysctl -p echo "echo never > /sys/kernel/mm/transparent_hugepage/enabled">>/etc/rc.d/rc.local chmod +x /etc/rc.d/rc.local ln -s ${INSTALL_DIR}/${DEFAULT_PORT}/bin/redis-* /usr/bin/ cp src/redis-trib.rb /usr/bin/ } dsl_install() { sed -ri -e "/^bind 127.0.0.1/c bind 0.0.0.0" -e "/# requirepass/a requirepass $PASSWORD" -e "/^dir .*/c dir ${INSTALL_DIR}/${DEFAULT_PORT}/data/" -e "/logfile .*/c logfile ${INSTALL_DIR}/${DEFAULT_PORT}/log/redis-${DEFAULT_PORT}.log" -e "/^dbfilename dump.rdb$/c dbfilename dump-${DEFAULT_PORT}.rdb" -e "/^pidfile .*/c pidfile ${INSTALL_DIR}/${DEFAULT_PORT}/run/redis-${DEFAULT_PORT}.pid" -e "/^appendonly no$/c appendonly yes" ${INSTALL_DIR}/${DEFAULT_PORT}/etc/redis-${DEFAULT_PORT}.conf cat > /usr/lib/systemd/system/redis${DEFAULT_PORT}.service <<EOF [Unit] Description=Redis persistent key-value database After=network.target [Service] ExecStart=${INSTALL_DIR}/${DEFAULT_PORT}/bin/redis-server ${INSTALL_DIR}/${DEFAULT_PORT}/etc/redis-${DEFAULT_PORT}.conf --supervised systemd ExecStop=/bin/kill -s QUIT $MAINPID Type=notify User=redis Group=redis RuntimeDirectory=redis RuntimeDirectoryMode=0755 [Install] WantedBy=multi-user.target EOF if [ "$DSL_NUM" -gt 0 ];then for i in `seq $DSL_NUM` ;do let i=${DEFAULT_PORT}+i mkdir ${INSTALL_DIR}/${i}/{bin,etc,log,data,run} -p cp ${INSTALL_DIR}/${DEFAULT_PORT}/bin/* ${INSTALL_DIR}/${i}/bin/ sed "s/${DEFAULT_PORT}/${i}/g" ${INSTALL_DIR}/${DEFAULT_PORT}/etc/redis-${DEFAULT_PORT}.conf >${INSTALL_DIR}/${i}/etc/redis-${i}.conf sed "s/${DEFAULT_PORT}/${i}/g" /usr/lib/systemd/system/redis${DEFAULT_PORT}.service >/usr/lib/systemd/system/redis${i}.service cp ${INSTALL_DIR}/${DEFAULT_PORT}/etc/redis-${DEFAULT_PORT}-sentinel.conf ${INSTALL_DIR}/${i}/etc/redis-${i}-sentinel.conf done chown redis.redis -R ${INSTALL_DIR} systemctl daemon-reload [ $? -eq 0 ] &&action "${DSL_NUM}个$VERSION创建成功,请查看$INSTALL_DIR目录" || { action "redis 实例创建失败" false;exit; } elif [ "$DSL_NUM" -eq 0 ];then chown redis.redis -R ${INSTALL_DIR} systemctl daemon-reload [ $? -eq 0 ] &&action "单个$VERSION创建成功,请查看$INSTALL_DIR目录" || { action "单个redis创建失败" false;exit; } else continue; fi } redis_install dsl_install bash redis_duoshili.sh 安装脚本
vi /usr/local/redis/6379/etc/redis-6379.conf 每个节点的主实例配置这些 cluster-enabled yes cluster-config-file nodes-6379.conf cluster-require-full-coverage no vi /usr/local/redis/6380/etc/redis-6380.conf 每个节点的从实例配置这些 cluster-enabled yes cluster-config-file nodes-6379.conf cluster-require-full-coverage no masterauth 123456 将2个复制直接复制到另外2个节点替换掉原文件 scp /usr/local/redis/6379/etc/redis-6379.conf 192.168.116.133:/usr/local/redis/6379/etc/redis-6379.conf scp /usr/local/redis/6379/etc/redis-6379.conf 192.168.116.134:/usr/local/redis/6379/etc/redis-6379.conf scp /usr/local/redis/6380/etc/redis-6380.conf 192.168.116.133:/usr/local/redis/6380/etc/redis-6380.conf scp /usr/local/redis/6380/etc/redis-6380.conf 192.168.116.134:/usr/local/redis/6380/etc/redis-6380.conf systemctl start redis6379 配置修改完成后,全部节点启动实例 systemctl start redis6380 ss -tnl 确认端口打开,6379,6380是redis默认启动端口,16379,16380是集群需要启动的端口
找一个节点配置集群,以192.168.116.132为例子 前面写主节点的IP和端口,后面写从节点的IP和端口 redis-cli -a 123456 --cluster create 192.168.116.132:6379 192.168.116.133:6379 192.168.116.134:6379 192.168.116.132:6380 192.168.116.133:6380 192.168.116.134:6380 --cluster-replicas 1 --cluster-replicas 1 代表从节点有几个,这里只有1个从节点就写1就行 redis会自动分配槽位,输入yes确认就行
redis-cli -a 123456 cluster nodes 查看集群状态 redis-cli -a 123456 info replication 查看主从状态,因为是自动分配,所以主从可能不在同一台设备,这个不影响使用
redis-cli -a 123456 cluster keyslot test1 keyslot这个参数是计算值对应的槽位 redis-cli -a 123456 cluster nodes 可以看到0-5360槽都是192.168.116.132:6379这个redis节点的,弹出的提示是4768,那么这个key会保存到192.168.116.132这个节点 1218d06cfb8c08b127b86fddea6f0545fca8db47 192.168.116.132:6379@16379 myself,master - 0 1640592637000 1 connected 0-5460
客户端往其他节点设置值,比如192.168.116.133节点
redis-cli -a 123456 -h 192.168.116.133 -p 6379 -c set test1 test1
在192.168.116.133没有看到这个值,提示要去192.168.116.132查找
redis-cli -a 123456 -h 192.168.116.133 -p 6379 get test1
在192.168.116.132确认查看到了值,证明集群创建成功
redis-cli -a 123456 -h 192.168.116.132 -p 6379 get test1