目录
三、Redis主从
3.1 节点规划
操作系统 | IP地址 | 端口号 | 主机名称 | 软件包 |
---|---|---|---|---|
Almalinux | 192.168.44.209 | 6379 | redis1 | redis |
Almalinux | 192.168.44.210 | 6379 | redis2 | redis |
Almalinux | 192.168.44.211 | 6379 | redis3 | redis |
3.2 配置免密登录
#209
cd ~
cat >host_list.txt <<'EOF'
192.168.44.209 1
192.168.44.210 1
192.168.44.211 1
EOF
ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa -y
yum install -y sshpass
cd ~
for i in $(seq $(cat host_list.txt |wc -l));\
do \
host_ip="$(cat host_list.txt |awk "NR==${i}"'{print $1}')";\
host_password="$(cat host_list.txt |awk "NR==${i}"'{print $2}')";\
echo "start config host:${host_ip}";\
sshpass -p"${host_password}" ssh-copy-id "-o StrictHostKeyChecking=no" -i /root/.ssh/id_rsa.pub root@"${host_ip}";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${host_ip}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#验证209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "ip a";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#修改主机名称所有节点
#批量209
cd ~
num=1
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "hostnamectl set-hostname redis${num}";\
ssh root@"${i}" "hostname";\
num=$((num+1));\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#安装相关小软件所有节点
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "yum install rsync logrotate -y";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#修改host文件所有节点
#单机编辑209
vim /etc/hosts
192.168.44.209 redis1
192.168.44.210 redis2
192.168.44.211 redis3
192.168.44.200 vip
#分发209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
rsync -avzP /etc/hosts root@"${i}":/etc/hosts;\
ssh root@"${i}" "cat /etc/hosts";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#关闭防火墙和selinux 所有节点
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "systemctl stop firewalld";\
ssh root@"${i}" "systemctl disable firewalld";\
ssh root@"${i}" "sed -ri 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/sysconfig/selinux";\
ssh root@"${i}" "grep -F 'SELINUX=' /etc/sysconfig/selinux";\
ssh root@"${i}" "setenforce 0";\
ssh root@"${i}" "getenforce";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
3.3 主从实例安装
官网:Install Redis from Source | Docs
3.3.1 前置环境
=====================================
仅209单机操作即可
=====================================
#安装docker运行时209
#准备主机清单,这一步会破坏后续批量部署主机清单
#操作完后别忘了参考3.2节密码登录配置,把它还原回来
#~~~~~~~~~集群是三台机器~~~~~~~~~~~~~~~~~
cd ~
cat <<'EOF' | sudo tee ./host_list.txt
192.168.44.209 1
EOF
ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa -y
#配置免密登录209
yum install -y sshpass
cd ~
for i in $(seq $(cat host_list.txt |wc -l));\
do \
host_ip="$(cat host_list.txt |awk "NR==${i}"'{print $1}')";\
host_password="$(cat host_list.txt |awk "NR==${i}"'{print $2}')";\
echo "start config host:${host_ip}";\
sshpass -p"${host_password}" ssh-copy-id "-o StrictHostKeyChecking=no" -i /root/.ssh/id_rsa.pub root@"${host_ip}";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${host_ip}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#验证209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "ip a";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#安装小软件
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "yum install rsync -y";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#官方网站:https://docs.docker.com/engine/install/centos/
#清理环境
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
#官方源(备用)
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "curl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo";\
ssh root@"${i}" "ls -l /etc/yum.repos.d";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
=====================================================================
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
=====================================================================
#安装指定版本docker这里是20.10.14版本
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "yum install -y yum-utils";\
ssh root@"${i}" "yum list docker-ce --showduplicates | sort -r";\
ssh root@"${i}" "yum list docker-ce-cli --showduplicates | sort -r";\
ssh root@"${i}" "yum list containerd.io --showduplicates | sort -r";\
ssh root@"${i}" "yum install docker-ce-20.10.14 docker-ce-cli-20.10.14 containerd.io -y";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#阿里源(推荐)
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "curl http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo";\
ssh root@"${i}" "ls -l /etc/yum.repos.d";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
==================================================================
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
==================================================================
#等等安装GPG签名报错?
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "rpm --import https://mirrors.aliyun.com/almalinux/RPM-GPG-KEY-AlmaLinux";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#创建文件夹所有节点
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "yum install tree -y";\
ssh root@"${i}" "mkdir /etc/docker -p";\
ssh root@"${i}" "mkdir /data/docker -p";\
ssh root@"${i}" "tree /data";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#修改docker配置文件,bip172.xx.xx.1的xx.xx替换为主机ip的后两位
#单机编辑209
#参考弃用文档:https://docs.docker.com/engine/deprecated/#duplicate-keys-with-conflicting-values-in-engine-labels
#参考daemon.json配置文档:https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file
#旧版配置,graph在版本v17.05中已弃用;在版本中v23.0彻底移除;用data-root替代
vim /etc/docker/daemon.json
{
"graph": "/data/docker",
"storage-driver": "overlay2",
"insecure-registries": ["registry.access.redhat.com","quay.io","192.168.44.201:8088"],
"registry-mirrors": [
"https://uoggbpok.mirror.aliyuncs.com",
"http://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.nju.edu.cn"
],
"bip": "172.16.0.1/16",
"exec-opts": ["native.cgroupdriver=systemd"],
"live-restore": true,
"log-driver": "json-file",
"log-opts": {"max-size":"100m", "max-file":"3"}
}
#新版配置,如果发现无法启动docker守护进程,请使用这个配置
vim /etc/docker/daemon.json
{
"data-root": "/data/docker",
"storage-driver": "overlay2",
"insecure-registries": ["registry.access.redhat.com","quay.io","192.168.44.201:8088"],
"registry-mirrors": [
"https://uoggbpok.mirror.aliyuncs.com",
"http://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.nju.edu.cn"
],
"bip": "172.16.0.1/16",
"exec-opts": ["native.cgroupdriver=systemd"],
"live-restore": true,
"log-driver": "json-file",
"log-opts": {"max-size":"100m", "max-file":"3"}
}
#分发209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
rsync -avzP /etc/docker/daemon.json root@"${i}":/etc/docker/;\
ssh root@"${i}" "cat /etc/docker/daemon.json";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#所有节点
#启动docker,验证版本信息
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "systemctl daemon-reload";\
ssh root@"${i}" "systemctl enable docker";\
ssh root@"${i}" "systemctl start docker";\
ssh root@"${i}" "docker version";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#安装完成
[root@docker ~]# docker info
#Docker仓库凉凉了??
#单机配置代理209
#https://docs.docker.com/engine/daemon/proxy/#systemd-unit-file
[root@docker ~]# mkdir -p /etc/systemd/system/docker.service.d
[root@docker ~]# vim /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://192.168.1.131:8080"
Environment="HTTPS_PROXY=http://192.168.1.131:8080"
Environment="NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,192.168.44.201,registry.myhabor.com"
#分发209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "mkdir -p /etc/systemd/system/docker.service.d";\
rsync -avzP /etc/systemd/system/docker.service.d/http-proxy.conf root@"${i}":/etc/systemd/system/docker.service.d/;\
ssh root@"${i}" "cat /etc/systemd/system/docker.service.d/http-proxy.conf";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#单机还原镜像加速配置209
[root@docker ~]# vim /etc/docker/daemon.json
{
"data-root": "/data/docker",
"storage-driver": "overlay2",
"insecure-registries": ["registry.access.redhat.com","quay.io","192.168.44.201:8088"],
"bip": "172.16.0.1/16",
"exec-opts": ["native.cgroupdriver=systemd"],
"live-restore": true,
"log-driver": "json-file",
"log-opts": {"max-size":"100m", "max-file":"3"}
}
#分发
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
rsync -avzP /etc/docker/daemon.json root@"${i}":/etc/docker/;\
ssh root@"${i}" "cat /etc/docker/daemon.json";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#重启docker
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "systemctl daemon-reload";\
ssh root@"${i}" "systemctl restart docker";\
ssh root@"${i}" "docker version";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#运行java8临时容器209
[root@docker ~]# docker container run -it --rm openjdk:8 /bin/bash
root@3568980b5c9b:/# env
HOSTNAME=3568980b5c9b
JAVA_HOME=/usr/local/openjdk-8
PWD=/
HOME=/root
LANG=C.UTF-8
TERM=xterm
SHLVL=1
PATH=/usr/local/openjdk-8/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
JAVA_VERSION=8u342
_=/usr/bin/env
3.3.2 下载安装包
发行版源码包:Index of /releases/
#官方推荐源码编译安装,我们投机取巧一下。
#直接下载docker与rpm组装版本209
=> root @ linux-learn: ~------------------------------------------------------------------------------------------
➜ cd /tmp
=> root @ linux-learn: /tmp---------------------------------------------------------------------------------------
➜ yum download --destdir=/tmp redis
#把rpm转化为tar。tgz模式209
=> root @ linux-learn: /tmp---------------------------------------------------------------------------------------
➜ rpm2archive redis-5.0.3-5.module_el8.4.0+2583+b9845322.x86_64.rpm
=> root @ linux-learn: /tmp---------------------------------------------------------------------------------------
➜ ll
总用量 2.3M
-rw-r--r-- 1 root root 926K 9月 2 20:28 redis-5.0.3-5.module_el8.4.0+2583+b9845322.x86_64.rpm
-rw-r--r-- 1 root root 1.4M 9月 2 20:37 redis-5.0.3-5.module_el8.4.0+2583+b9845322.x86_64.rpm.tgz
drwx------ 3 root root 17 9月 2 20:11 systemd-private-c531182ee6b945ddb1c53618f8c26222-chronyd.service-DKdUBk
#把它解压缩到特定的目录备用209
=> root @ linux-learn: /tmp---------------------------------------------------------------------------------------
➜ mkdir -p /tmp/redis-dir
=> root @ linux-learn: /tmp---------------------------------------------------------------------------------------
➜ tar xf redis-5.0.3-5.module_el8.4.0+2583+b9845322.x86_64.rpm.tgz -C /tmp/redis-dir
=> root @ linux-learn: /tmp---------------------------------------------------------------------------------------
➜ tree /tmp/redis-dir
/tmp/redis-dir
├── etc
│ ├── logrotate.d
│ │ └── redis
│ ├── redis.conf
│ ├── redis-sentinel.conf
│ └── systemd
│ └── system
│ ├── redis-sentinel.service.d
│ │ └── limit.conf
│ └── redis.service.d
│ └── limit.conf
├── usr
│ ├── bin
│ │ ├── redis-benchmark
│ │ ├── redis-check-aof -> redis-server
│ │ ├── redis-check-rdb -> redis-server
│ │ ├── redis-cli
│ │ ├── redis-sentinel -> redis-server
│ │ └── redis-server
│ ├── lib
│ │ └── systemd
│ │ └── system
│ │ ├── redis-sentinel.service
│ │ └── redis.service
│ ├── lib64
│ │ └── redis
│ │ └── modules
│ ├── libexec
│ │ └── redis-shutdown
│ └── share
│ ├── licenses
│ │ └── redis
│ │ ├── COPYING
│ │ ├── COPYING-hiredis
│ │ ├── COPYING-jemalloc
│ │ └── COPYRIGHT-lua
│ └── man
│ ├── man1
│ │ ├── redis-benchmark.1.gz
│ │ ├── redis-check-aof.1.gz
│ │ ├── redis-check-rdb.1.gz
│ │ ├── redis-cli.1.gz
│ │ ├── redis-sentinel.1.gz -> redis-server.1.gz
│ │ └── redis-server.1.gz
│ └── man5
│ ├── redis.conf.5.gz
│ └── redis-sentinel.conf.5.gz -> redis.conf.5.gz
└── var
├── lib
│ └── redis
└── log
└── redis
26 directories, 26 files
#运行almalinux:8临时容器209
#注意你的宿主机什么操作系统就运行什么
#我的是almalinux:8
root in 🌐 linux-learn in ~
➜ docker container run --name=redis \
--rm \
-it \
almalinux:8 /bin/bash
#把临时容器放入后台运行209
root in 🌐 linux-learn in ~
➜ Ctrl + p + q
#进入容器209
root in 🌐 linux-learn in ~ took 1m55s
➜ docker container exec -it redis /bin/bash
#下载源码并编译
[root@a438ba4941d9 /]# cd /tmp/
[root@a438ba4941d9 tmp]#
[root@a438ba4941d9 tmp]# curl -L https://download.redis.io/releases/redis-6.2.6.tar.gz -o redis-6.2.6.tar.gz
[root@a438ba4941d9 tmp]# tar xf redis-6.2.6.tar.gz
[root@a438ba4941d9 tmp]# cd redis-6.2.6
[root@a438ba4941d9 redis-6.2.6]# yum install -y https://mirrors.aliyun.com/epel/epel-release-latest-8.noarch.rpm
[root@a438ba4941d9 redis-6.2.6]# yum install make gcc glibc glibc-devel openssl openssl-devel systemd-devel -y
[root@a438ba4941d9 redis-6.2.6]# make BUILD_TLS=yes USE_SYSTEMD=yes
[root@a438ba4941d9 redis-6.2.6]# make install
[root@a438ba4941d9 redis-6.2.6]# ls -l
total 244
-rw-rw-r-- 1 root root 33624 Oct 4 2021 00-RELEASENOTES
-rw-rw-r-- 1 root root 51 Oct 4 2021 BUGS
-rw-rw-r-- 1 root root 5026 Oct 4 2021 CONDUCT
-rw-rw-r-- 1 root root 3384 Oct 4 2021 CONTRIBUTING
-rw-rw-r-- 1 root root 1487 Oct 4 2021 COPYING
-rw-rw-r-- 1 root root 11 Oct 4 2021 INSTALL
-rw-rw-r-- 1 root root 6888 Oct 4 2021 MANIFESTO
-rw-rw-r-- 1 root root 151 Oct 4 2021 Makefile
-rw-rw-r-- 1 root root 21567 Oct 4 2021 README.md
-rw-rw-r-- 1 root root 3055 Oct 4 2021 TLS.md
drwxrwxr-x 7 root root 213 Sep 2 14:23 deps
-rw-rw-r-- 1 root root 93724 Oct 4 2021 redis.conf
-rwxrwxr-x 1 root root 275 Oct 4 2021 runtest
-rwxrwxr-x 1 root root 279 Oct 4 2021 runtest-cluster
-rwxrwxr-x 1 root root 1079 Oct 4 2021 runtest-moduleapi
-rwxrwxr-x 1 root root 281 Oct 4 2021 runtest-sentinel
-rw-rw-r-- 1 root root 13768 Oct 4 2021 sentinel.conf
drwxrwxr-x 3 root root 12288 Sep 2 14:29 src
drwxrwxr-x 11 root root 182 Oct 4 2021 tests
drwxrwxr-x 9 root root 4096 Oct 4 2021 utils
[root@a438ba4941d9 redis-6.2.6]# ls -l /usr/local/bin/
total 25048
-rwxr-xr-x 1 root root 6592864 Sep 2 14:29 redis-benchmark
lrwxrwxrwx 1 root root 12 Sep 2 14:29 redis-check-aof -> redis-server
lrwxrwxrwx 1 root root 12 Sep 2 14:29 redis-check-rdb -> redis-server
-rwxr-xr-x 1 root root 6804832 Sep 2 14:29 redis-cli
lrwxrwxrwx 1 root root 12 Sep 2 14:29 redis-sentinel -> redis-server
-rwxr-xr-x 1 root root 12245112 Sep 2 14:29 redis-server
#新开启一个终端,把容器里边的redis复制出来209
#创建我们redis的目录结构
root in 🌐 linux-learn in ~ took 4m36s
➜ mkdir /opt/redis-6.2.6/{bin,share,conf} -p
root in 🌐 linux-learn in ~
➜ mkdir /opt/redis-6.2.6/share/man/{man1,man5} -p
root in 🌐 linux-learn in ~ took 4s
➜ tree /opt/redis-6.2.6/
/opt/redis-6.2.6/
├── bin
├── conf
└── share
└── man
├── man1
└── man5
6 directories, 0 files
#复制容器里边的redis到安装目录209
root in 🌐 linux-learn in ~
➜ docker container cp redis:/usr/local/bin /tmp/redis-bin
root in 🌐 linux-learn in ~
➜ docker container cp redis:/tmp/redis-6.2.6/redis.conf /opt/redis-6.2.6/conf/
root in 🌐 linux-learn in ~
➜ docker container cp redis:/tmp/redis-6.2.6/sentinel.conf /opt/redis-6.2.6/conf/
root in 🌐 linux-learn in ~
➜ cp -r /tmp/redis-bin/* /opt/redis-6.2.6/bin/
root in 🌐 linux-learn in ~
➜ tree /opt/redis-6.2.6/
/opt/redis-6.2.6/
├── bin
│ ├── redis-benchmark
│ ├── redis-check-aof -> redis-server
│ ├── redis-check-rdb -> redis-server
│ ├── redis-cli
│ ├── redis-sentinel -> redis-server
│ └── redis-server
├── conf
│ ├── redis.conf
│ └── sentinel.conf
└── share
└── man
├── man1
└── man5
6 directories, 8 files
#分发Redis存档
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "yum install -y tree";\
rsync -avzP /opt/redis-6.2.6 root@"${i}":/opt/;\
ssh root@"${i}" "tree /opt -L 1";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#配置环境变量209
root in 🌐 linux-learn in ~
➜ ln -s /opt/redis-6.2.6 /opt/redis
root in 🌐 linux-learn in ~
➜ tree /opt/ -L 1
/opt/
├── containerd
├── redis -> /opt/redis-6.2.6
├── redis-6.2.6
└── tool
4 directories, 0 files
root in 🌐 linux-learn in ~
➜ vim ~/.bashrc
# redis
export PATH="/opt/redis/bin:$PATH"
#验证209
root in 🌐 linux-learn in ~
➜ redis-server --help
Usage: ./redis-server [/path/to/redis.conf] [options] [-]
./redis-server - (read config from stdin)
./redis-server -v or --version
./redis-server -h or --help
./redis-server --test-memory <megabytes>
Examples:
./redis-server (run the server with default conf)
./redis-server /etc/redis/6379.conf
./redis-server --port 7777
./redis-server --port 7777 --replicaof 127.0.0.1 8888
./redis-server /etc/myredis.conf --loglevel verbose -
./redis-server /etc/myredis.conf --loglevel verbose
Sentinel mode:
./redis-server /etc/sentinel.conf --sentinel
root in 🌐 linux-learn in ~
➜ redis-server -v
Redis server v=6.2.6 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=679f60a40763578
#分发环境变量配置
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "ln -s /opt/redis-6.2.6 /opt/redis";\
ssh root@"${i}" "tree /opt -L 1";\
rsync -avzP ~/.bashrc root@"${i}":~/.bashrc;\
ssh root@"${i}" "tail ~/.bashrc";\
ssh root@"${i}" "/opt/redis/bin/redis-server -v";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
3.3.3 安装并启动
① 创建运行目录
#创建redis系统用户209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "useradd -r -M -s /sbin/nologin redis";\
ssh root@"${i}" "id redis";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#创建redis运行相关目录209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "mkdir /data/redis/redis-6379/{data,conf} -p";\
ssh root@"${i}" "tree /data/redis";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#更改所有权209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "chown -R redis:redis /data/redis";\
ssh root@"${i}" "ls -l /data/redis";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
② 创建守护进程服务
#创建redis守护进程服务文件209
#模板文件
========================================================================================================
root in 🌐 linux-learn in ~
➜ cat /tmp/redis-dir/usr/lib/systemd/system/redis.service
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/bin/redis-server /etc/redis.conf --supervised systemd
ExecStop=/usr/libexec/redis-shutdown
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
========================================================================================================
#创建我们需要的
cat >/etc/systemd/system/redis-6379.service <<'EOF'
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/opt/redis/bin/redis-server /data/redis/redis-6379/conf/redis-6379.conf --supervised systemd
ExecStop=/opt/redis/bin/redis-shutdown redis-6379
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
#创建redis守护进程服务文件限制209
#模板
========================================================================================================
root in 🌐 linux-learn in ~
➜ cat /tmp/redis-dir/etc/systemd/system/redis.service.d/limit.conf
# If you need to change max open file limit
# for example, when you change maxclient in configuration
# you can change the LimitNOFILE value below
# see "man systemd.exec" for information
[Service]
LimitNOFILE=10240
========================================================================================================
#创建我们需要的
mkdir -p /etc/systemd/system/redis-6379.service.d
cat >/etc/systemd/system/redis-6379.service.d/limit.conf <<'EOF'
# If you need to change max open file limit
# for example, when you change maxclient in configuration
# you can change the LimitNOFILE value below
# see "man systemd.exec" for information
[Service]
LimitNOFILE=10240
EOF
#分发守护进程服务
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
rsync -avzP /etc/systemd/system/redis-6379.service root@"${i}":/etc/systemd/system/;\
ssh root@"${i}" "mkdir -p /etc/systemd/system/redis-6379.service.d";\
rsync -avzP /etc/systemd/system/redis-6379.service.d/limit.conf root@"${i}":/etc/systemd/system/redis-6379.service.d/;\
ssh root@"${i}" "cat /etc/systemd/system/redis-6379.service";\
ssh root@"${i}" "echo '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'";\
ssh root@"${i}" "echo";\
ssh root@"${i}" "echo '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'";\
ssh root@"${i}" "cat /etc/systemd/system/redis-6379.service.d/limit.conf";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
③ 创建停止脚本
#创建redis停止脚本209
#模板
========================================================================================================
root in 🌐 linux-learn in ~
➜ cat /tmp/redis-dir/usr/libexec/redis-shutdown
#!/bin/bash
#
# Wrapper to close properly redis and sentinel
test x"$REDIS_DEBUG" != x && set -x
REDIS_CLI=/usr/bin/redis-cli
# Retrieve service name
SERVICE_NAME="$1"
if [ -z "$SERVICE_NAME" ]; then
SERVICE_NAME=redis
fi
# Get the proper config file based on service name
CONFIG_FILE="/etc/$SERVICE_NAME.conf"
# Use awk to retrieve host, port from config file
HOST=`awk '/^[[:blank:]]*bind/ { print $2 }' $CONFIG_FILE | tail -n1`
PORT=`awk '/^[[:blank:]]*port/ { print $2 }' $CONFIG_FILE | tail -n1`
PASS=`awk '/^[[:blank:]]*requirepass/ { print $2 }' $CONFIG_FILE | tail -n1`
SOCK=`awk '/^[[:blank:]]*unixsocket\s/ { print $2 }' $CONFIG_FILE | tail -n1`
# Just in case, use default host, port
HOST=${HOST:-127.0.0.1}
if [ "$SERVICE_NAME" = redis ]; then
PORT=${PORT:-6379}
else
PORT=${PORT:-26379}
fi
# Setup additional parameters
# e.g password-protected redis instances
[ -z "$PASS" ] || ADDITIONAL_PARAMS="-a $PASS"
# shutdown the service properly
if [ -e "$SOCK" ] ; then
$REDIS_CLI -s $SOCK $ADDITIONAL_PARAMS shutdown
else
$REDIS_CLI -h $HOST -p $PORT $ADDITIONAL_PARAMS shutdown
fi
========================================================================================================
#创建我们需要的209
root in 🌐 linux-learn in ~
➜ vim /opt/redis-6.2.6/bin/redis-shutdown
root in 🌐 linux-learn in ~ took 5m25s
➜ cat /opt/redis-6.2.6/bin/redis-shutdown
#!/bin/bash
#
# Wrapper to close properly redis and sentinel
test x"$REDIS_DEBUG" != x && set -x
redis_cli="/opt/redis/bin/redis-cli"
# Retrieve service name
service_name="$1"
if [ -z "${service_name}" ]; then
service_name="redis"
fi
# Get the proper config file based on service name
config_file="/data/redis/${service_name}/conf/${service_name}.conf"
# Use awk to retrieve host, port from config file
redis_host="$(awk '/^[[:blank:]]*bind/ { print $2 }' "${config_file}" | tail -n1)"
redis_port="$(awk '/^[[:blank:]]*port/ { print $2 }' "${config_file}" | tail -n1)"
redis_pass="$(awk '/^[[:blank:]]*requirepass/ { print $2 }' "${config_file}" | tail -n1)"
redis_sock="$(awk '/^[[:blank:]]*unixsocket[s]?/ { print $2 }' "${config_file}" | tail -n1)"
# Just in case, use default host, port
redis_host="${redis_host:-127.0.0.1}"
if [ "${service_name}" == "redis-6379" ]; then
redis_port="${redis_port:-6379}"
else
redis_port="${redis_port:-26379}"
fi
# Setup additional parameters
# e.g password-protected redis instances
[ -z "${redis_pass}" ] || additional_params="-a ${redis_pass}"
# shutdown the service properly
if [ -e "${redis_sock}" ]; then
bash -c "${redis_cli} -s ${redis_sock} ${additional_params} shutdown"
else
bash -c "${redis_cli} -h ${redis_host} -p ${redis_port} ${additional_params} shutdown"
fi
#添加执行权限209
root in 🌐 linux-learn in ~
➜ chmod +x /opt/redis-6.2.6/bin/redis-shutdown
#分发redis停止脚本209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
rsync -avzP /opt/redis-6.2.6 root@"${i}":/opt/;\
ssh root@"${i}" "tree /opt/redis-6.2.6";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
④ 启动
#准备redis配置文件209
#模板
root in 🌐 linux-learn in ~
➜ cat /opt/redis-6.2.6/conf/redis.conf
#编辑我们需要的
root in 🌐 linux-learn in ~
➜ cp /opt/redis-6.2.6/conf/redis.conf /data/redis/redis-6379/conf/redis-6379.conf
#修改绑定IP地址,数据持久化等等
root in 🌐 linux-learn in ~
➜ vim /data/redis/redis-6379/conf/redis-6379.conf
=======================================================================================================
#IP地址
bind 0.0.0.0
#端口号
port 6379
#前台no,后台tes
daemonize no
#pid文件
pidfile /data/redis/redis-6379/redis_6379.pid
#日志级别
loglevel warning
#日志文件
logfile /data/redis/redis-6379/redis_6379.log
#持久化RDB
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
#数据目录
dir /data/redis/redis-6379/data
#持久化aof配置
appendonly yes
appendfsync everysec
appendfilename "appendonly.aof"
#安全认证
protected-mode yes
requirepass 123456
masterauth 123456
=======================================================================================================
#分发配置209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
rsync -avzP /data/redis/redis-6379/conf/redis-6379.conf root@"${i}":/data/redis/redis-6379/conf/;\
ssh root@"${i}" "tree /data/redis";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#启动看看209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "systemctl daemon-reload";\
ssh root@"${i}" "systemctl start redis-6379.service";\
ssh root@"${i}" "systemctl enable redis-6379.service";\
ssh root@"${i}" "systemctl status redis-6379.service";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#停止209
systemctl stop redis-6379.service
#连接测试209
root in 🌐 linux-learn in ~ took 12s
➜ redis-cli -h 192.168.44.209 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.44.209:6379>
3.3.4 配置man手册
#模板文件209
root in 🌐 linux-learn in ~
➜ tree /tmp/redis-dir/usr/share/man/
/tmp/redis-dir/usr/share/man/
├── man1
│ ├── redis-benchmark.1.gz
│ ├── redis-check-aof.1.gz
│ ├── redis-check-rdb.1.gz
│ ├── redis-cli.1.gz
│ ├── redis-sentinel.1.gz -> redis-server.1.gz
│ └── redis-server.1.gz
└── man5
├── redis.conf.5.gz
└── redis-sentinel.conf.5.gz -> redis.conf.5.gz
2 directories, 8 files
#复制man手册到安装目录209
root in 🌐 linux-learn in ~
➜ cp -r /tmp/redis-dir/usr/share/man/man1/* /opt/redis-6.2.6/share/man/man1/
root in 🌐 linux-learn in ~
➜ cp -r /tmp/redis-dir/usr/share/man/man5/* /opt/redis-6.2.6/share/man/man5/
root in 🌐 linux-learn in ~
➜ tree /opt/redis-6.2.6/
/opt/redis-6.2.6/
├── bin
│ ├── redis-benchmark
│ ├── redis-check-aof -> redis-server
│ ├── redis-check-rdb -> redis-server
│ ├── redis-cli
│ ├── redis-sentinel -> redis-server
│ ├── redis-server
│ └── redis-shutdown
├── conf
│ ├── redis.conf
│ └── sentinel.conf
└── share
└── man
├── man1
│ ├── redis-benchmark.1.gz
│ ├── redis-check-aof.1.gz
│ ├── redis-check-rdb.1.gz
│ ├── redis-cli.1.gz
│ ├── redis-sentinel.1.gz -> redis-server.1.gz
│ └── redis-server.1.gz
└── man5
├── redis.conf.5.gz
└── redis-sentinel.conf.5.gz -> redis.conf.5.gz
6 directories, 17 files
#验证209
root in 🌐 linux-learn in ~
➜ man redis
redis-benchmark redis-check-rdb redis.conf redis-sentinel.conf
redis-check-aof redis-cli redis-sentinel redis-server
#分发man手册209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
rsync -avzP /opt/redis-6.2.6 root@"${i}":/opt/;\
ssh root@"${i}" "tree /opt/redis-6.2.6";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
3.3.5 配置日志切割
#模板文件209
root in 🌐 linux-learn in ~ took 20s
➜ tree /tmp/redis-dir/
/tmp/redis-dir/
├── etc
│ ├── logrotate.d
│ │ └── redis
#编辑日志切割配置209
root in 🌐 linux-learn in ~ took 4s
➜ yum install logrotate -y
root in 🌐 linux-learn in ~
➜ vim /etc/logrotate.d/redis-6379
/data/redis/redis-6379/*.log {
weekly
rotate 10
copytruncate
delaycompress
compress
notifempty
missingok
}
#验证209
root in 🌐 linux-learn in ~
➜ logrotate -f /etc/logrotate.d/redis-6379
root in 🌐 linux-learn in ~
➜ tree /data/redis/
/data/redis/
└── redis-6379
├── conf
│ └── redis-6379.conf
├── data
│ ├── appendonly.aof
│ └── dump.rdb
├── redis_6379.log
├── redis_6379.log.1
├── redis_6379.log.2.gz
├── redis_6379.log.3.gz
└── redis_6379.pid
3 directories, 8 files
#分发日志切割配置209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "yum install logrotate -y";\
rsync -avzP /etc/logrotate.d/redis-6379 root@"${i}":/etc/logrotate.d/;\
ssh root@"${i}" "cat /etc/logrotate.d/redis-6379";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
3.4 主从配置
IP地址 | 主机名称 | 角色 |
---|---|---|
192.168.44.209 | redis1 | master |
192.168.44.210 | redis2 | slave |
192.168.44.211 | redis3 | slave |
开始配置主从~
节点209的操作
#编辑主从复制宣布ip
root in 🌐 redis1 in ~
➜ vim /data/redis/redis-6379/conf/redis-6379.conf
replica-announce-ip 192.168.44.209
replica-announce-port 6379
#重启redis
root in 🌐 redis1 in ~
➜ systemctl restart redis-6379.service
节点210的操作
#编辑主从复制宣布ip地址210
root in 🌐 redis2 in ~
➜ vim /data/redis/redis-6379/conf/redis-6379.conf
replica-announce-ip 192.168.44.210
replica-announce-port 6379
#重启redis服务210
root in 🌐 redis2 in ~
➜ systemctl restart redis-6379.service
#临时210
root in 🌐 redis2 in ~
➜ redis-cli -h 192.168.44.210 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.44.210:6379> REPLICAOF 192.168.44.209 6379
#永久210
root in 🌐 redis2 in ~ took 7s
➜ sed -rn '459,480p' /data/redis/redis-6379/conf/redis-6379.conf
################################# REPLICATION #################################
# Master-Replica replication. Use replicaof to make a Redis instance a copy of
# another Redis server. A few things to understand ASAP about Redis replication.
#
# +------------------+ +---------------+
# | Master | ---> | Replica |
# | (receive writes) | | (exact copy) |
# +------------------+ +---------------+
#
# 1) Redis replication is asynchronous, but you can configure a master to
# stop accepting writes if it appears to be not connected with at least
# a given number of replicas.
# 2) Redis replicas are able to perform a partial resynchronization with the
# master if the replication link is lost for a relatively small amount of
# time. You may want to configure the replication backlog size (see the next
# sections of this file) with a sensible value depending on your needs.
# 3) Replication is automatic and does not need user intervention. After a
# network partition replicas automatically try to reconnect to masters
# and resynchronize with them.
#
# replicaof <masterip> <masterport>
replicaof 192.168.44.209 6379
节点211的操作
#编辑主从复制宣布ip地址211
root in 🌐 redis3 in ~
➜ vim /data/redis/redis-6379/conf/redis-6379.conf
replica-announce-ip 192.168.44.211
replica-announce-port 6379
#重启redis服务211
root in 🌐 redis3 in ~
➜ systemctl restart redis-6379.service
#临时211
root in 🌐 redis3 in ~
➜ redis-cli -h 192.168.44.211 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.44.211:6379> REPLICAOF 192.168.44.209 6379
#永久211
root in 🌐 redis3 in ~ took 7s
➜ sed -rn '459,480p' /data/redis/redis-6379/conf/redis-6379.conf
################################# REPLICATION #################################
# Master-Replica replication. Use replicaof to make a Redis instance a copy of
# another Redis server. A few things to understand ASAP about Redis replication.
#
# +------------------+ +---------------+
# | Master | ---> | Replica |
# | (receive writes) | | (exact copy) |
# +------------------+ +---------------+
#
# 1) Redis replication is asynchronous, but you can configure a master to
# stop accepting writes if it appears to be not connected with at least
# a given number of replicas.
# 2) Redis replicas are able to perform a partial resynchronization with the
# master if the replication link is lost for a relatively small amount of
# time. You may want to configure the replication backlog size (see the next
# sections of this file) with a sensible value depending on your needs.
# 3) Replication is automatic and does not need user intervention. After a
# network partition replicas automatically try to reconnect to masters
# and resynchronize with them.
#
# replicaof <masterip> <masterport>
replicaof 192.168.44.209 6379
3.5 主从验证
master节点209的操作
#验证主从209
root in 🌐 redis3 in ~ took 1m44s
➜ redis-cli -h 192.168.44.209 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.44.209:6379> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.44.210,port=6379,state=online,offset=644,lag=1
slave1:ip=192.168.44.211,port=6379,state=online,offset=644,lag=1
master_failover_state:no-failover
master_replid:f5b54179bb2b62243bad42aa283069b9fb70945c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:644
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:644
#插入数据209
192.168.44.209:6379> set master yes
OK
192.168.44.209:6379> get master
"yes"
slave节点210,211操作
#210
root in 🌐 redis3 in ~ took 2m25s
➜ redis-cli -h 192.168.44.210 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.44.210:6379> get master
"yes"
192.168.44.210:6379> set slave210 yes
(error) READONLY You can't write against a read only replica.
#211
root in 🌐 redis3 in ~ took 40s
➜ redis-cli -h 192.168.44.211 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.44.211:6379> get master
"yes"
192.168.44.211:6379> set slave211 yes
(error) READONLY You can't write against a read only replica.
#从节点只能读,不能写
3.6 主从原理
3.6.1 相关概念
主从复制原理
Redis 在复制时底层采用的是 psync 命令完成的数据主从同步,同步主要分为:全量复制和增量复制两种
全量复制:顾名思义也就是一次性把主节点数据全部发送给从节点,所以这种情况下,当数据量比较大时,会对主节点和网络造成很大的开销。
部分复制:用于处理主从复制时因网络中断等原因造成数据丢失的场景。当从节点再次和主节点连接时,主节点会补发丢失的数据。因为是补发,所以在发送的数据量一定是小于全量的数据。
概念
在接下来讲解全量复制和部分复制前,需要明确几个概念,在底层使用 psync 命令运行时需要以下几个条件:
复制偏移量
主节点和从节点分别维护一个复制偏移量(offset),代表的是主节点向从节点传递的字节数;主节点每次向从节点传播 N 个字节数据时,主节点的 offset 增加 N;从节点每次收到主节点传来的 N 个字节数据时,从节点的 offset 增加 N。
offset 用于判断主从节点的数据库状态是否一致:如果二者 offset 相同,则一致;如果 offset 不同,则不一致,此时可以根据两个 offset 找出从节点缺少的那部分数据。例如,如果主节点的 offset 是1000,而从节点的 offset 是500,那么部分复制就需要将 offset 为501-1000 的数据传递给从节点。而 offset 为 501-1000 的数据存储的位置,就是下面要介绍的复制积压缓冲区。
复制积压缓冲区
复制积压缓冲区是由主节点维护的、固定长度的、先进先出(FIFO)队列,默认大小1MB;当主节点开始有从节点时创建,其作用是备份主节点最近发送给从节点的数据。注意,无论主节点有一个还是多个从节点,都只需要一个复制积压缓冲区。
在命令传播阶段,主节点除了将写命令发送给从节点,还会发送一份给复制积压缓冲区,作为写命令的备份;除了存储写命令,复制积压缓冲区中还存储了其中的每个字节对应的复制偏移量(offset)。由于复制积压缓冲区定长且是先进先出,所以它保存的是主节点最近执行的写命令;时间较早的写命令会被挤出缓冲区。
由于该缓冲区长度固定且有限,因此可以备份的写命令也有限,当主从节点 offset 的差距过大超过缓冲区长度时,将无法执行部分复制,只能执行全量复制。反过来说,为了提高网络中断时部分复制执行的概率,可以根据需要增大复制积压缓冲区的大小(通过配置repl-backlog-size);例如如果网络中断的平均时间是 60s,而主节点平均每秒产生的写命令(特定协议格式)所占的字节数为 100KB,则复制积压缓冲区的平均需求为 6MB,保险起见,可以设置为 12MB,来保证绝大多数断线情况都可以使用部分复制。
从节点将 offset 发送给主节点后,主节点根据 offset 和缓冲区大小决定能否执行部分复制:
如果 offset 偏移量之后的数据,仍然都在复制积压缓冲区里,则执行部分复制。
如果 offset 偏移量之后的数据已不在复制积压缓冲区中(数据已被挤出),则执行全量复制
运行 ID(runid)
每个 Redis 节点在启动时都会生成一个运行 id,即 runid,该 id 用于唯一标识 Redis 节点,它是一个由 40 位随机的十六进制的字符组成的字符串,通过 info server 命令可以查看节点的 runid
从节点在初次建立连接进行全量复制时(从节点发送 psync ? -1),主节点会将自己的 runid 告知给从节点,从节点将其保存起来。当主从节点断开重连时,从节点会将这个runid发送给主节点,主节点会根据从节点发送的 runid来判断选择何种复制:
如果从节点发送的 runid 与当前主节点的 runid 一致时,主节点则尝试进行部分复制,当然能不能进行部分复制还要看偏移量是否在复制积压缓冲区。
如果从节点发送的 runid 与当前主节点的 runid 不一致时,则进行全量复制。
psync命令流程
在了解了复制偏移量、复制积压缓冲区、节点运行 id 之后,下面我们看一下主从节点是如何确定使用全量复制还是部分复制的。
首先,从节点根据当前状态,决定如何调用 psync 命令:
如果从节点之前未执行过 slaveof 或最近执行了slaveof no one,则从节点发送命令为 psync ? -1,向主节点请求全量复制。
如果从节点之前执行了slaveof,则发送命令为 psync ,其中 runid 为上次复制的主节点的 runid,offset 为上次复制截止时从节点保存的复制偏移量。
主节点根据收到的 psync 命令,及当前服务器状态,决定执行全量复制还是部分复制:
如果主节点版本低于 Redis2.8,则返回 -ERR 回复,此时从节点重新发送 sync 命令执行全量复制。
如果主节点版本够新,且 runid 与从节点发送的 runid 相同,且从节点发送的 offset 之后的数据在复制积压缓冲区中都存在,则回复 +continue,表示将进行部分复制,从节点等待主节点发送其缺少的数据即可。
如果主节点版本够新,但是 runid 与从节点发送的 runid 不同,或从节点发送的 offset 之后的数据已不在复制积压缓冲区中(在队列中被挤出了),则回复 +fullresync ,表示要进行全量复制,其中 runid 表示主节点当前的 runid,offset 表示主节点当前的 offset,从节点保存这两个值,以备使用。
3.6.1 全量同步原理
全量复制:顾名思义也就是一次性把主节点数据全部发送给从节点,所以这种情况下,当数据量比较大时,会对主节点和网络造成很大的开销。
全量复制是 Redis 最早支持的复制方式,触发全量复制的命令是 sync 和 psync。下面我们介绍一下 Redis 中全量复制的流程:
发送 psync 命令进行数据同步,由于是第一次进行复制,从节点没有复制偏移量和主节点运行 id,所以发送 psync ?-1。
主节点接收从节点的命令后,主节点根据 psync ? -1 解析出当前为全量复制 ( 或者判断{runid}是否和自己一致,如果不一致就使用全量同步 ) ,所以回复 +FULLRESYNC,同时也会将自身的 runid 和 offset 偏移量发送给从节点,响应为 +FULLRESYNC {runid} {offset}。
从节点接受主节点的响应后,会保存主节点的 runid 和 偏移量 offset。
主节点执行 bgsave 保存 RDB 文件到本地,主节点发送 RDB 文件给从节点,从节点把接受的 RDB 文件保存在本地,并直接作为从节点的数据文件,接受完 RDB 文件后从节点打印相关日志。
从节点开始接受 RDB 文件到接受完成期间,主节点仍然响应读写命令,因此主节点会把这期间写命令保存在客户端的缓冲区中,当从节点加载完 RDB 文件后,主节点在把缓冲区的数据发送给从节点,已保证主从之间的数据一致性。如果主节点和从节点 RDB 文件的数据传输时间过长时,按上面分析可能会造成客户端的缓冲区溢出。默认配置为 client-output-buffer-limit slave 256MB 64MB 60。 如果 60 秒内缓冲区消耗大于 64MB 或者超过 256MB 时,主节点将直接关闭客户端连接,造成全量同步失败。
从节点接受完主节点传送来的全部数据后会清空自身的旧数据。
从节点清空数据后开始加载 RDB 文件,如果 RDB 文件比较大时,该操作也是比较耗时的。
从节点成功加载完 RDB 文件后,如果当前节点开启了 AOF 持久化功能,它会立刻做 bgrewriteaof 操作,为了保证全量复制后 AOF 持久化文件立刻可用
全量复制主要耗时地方如下:
主节点通过 bgsave 命令 fork 子进程进行 RDB 持久化,该过程是非常消耗 CPU、内存(页表复制)、硬盘 IO 的。
主节点通过网络将 RDB 文件发送给从节点,对主从节点的带宽都会带来很大的消耗。
从节点清空老数据、载入新 RDB 文件的过程是阻塞的,无法响应客户端的命令;如果从节点执行 bgrewriteaof,也会带来额外的消耗。
其它场景应该尽量必免使用全量复制。由于 Redis 全量复制有种种弊端,所以 Redis 提供了部分复制功能,下面我们看一下 Redis 中的部分复制功能。
3.6.2 增量同步原理
部分复制主要是 Redis 针对全量复制的过高开销做出的一种优化措施,使用 psync{runId}{offset}命令实现,当主从节点在命令传播节点发生了网络中断,出现数据丢失情况,则从节点会向主节点请求发送丢失的数据,如果请求的偏移量在复制积压缓冲区中,则主节点就将剩余的数据补发给从节点,保持主从节点数据一致,由于补发的数据一般都会比较小,所以开销相当于全量复制而言也会很小,流程如下:
当主从节点之间网络出现中断时,如果超过 repl-timeout 时间,主节点会认为从节点故障并中断复制连接。
由于主节点没有宕机,所以他依然会响应客户端命令,但因复制连接中断命令无法发送给从节点,但主节点内部会将这段时间的命令保存在客户端缓冲区中,默认大小为 1MB。
当主从节点网络恢复后,从节点会再次连接上主节点。
当主从节点连接恢复后,由于从节点之前保存了自身的偏移量和主节点的运行 id。因此会把它们当作 psync 参数发送给主节点,要求进行部分复制操作。
主节点接受从节点的 psync 命令,会先核对请求的 runid 是否和自身的的 runid 一致,如果一致,说明该从节点复制的当前主节点。然后查看请求的 offset 是否在复制积压缓冲区,如果在则进行部分复制,否则进行全量复制,部分复制回复 +continue 响应,从节点接受回复
在进行部分复制时,主节点只需要根据 offset 将复制积压缓冲区的数据发送给从节点,保证主从复制进入正常状态
心跳
在命令传播阶段,除了发送写命令,主从节点还维持着心跳机制:ping 和 replconf ack。心跳机制对于主从复制的超时判断、数据安全等有作用。
主从节点彼此都有心跳检测机制,各自模拟成对方的客户端进行通信,通过 client list 命令查看复制客户端信息,主节点的连接状态为 flags = M,从节点连接状态为 flags = S。
主节点默认每隔 10 秒对从节点发送 ping 命令,判断从节点的存活性和连接状态,可能通过 repl-ping-slave-period 参数修改发送频率。
从节点在主线程中每隔 1 秒发送 replconf ack{offset} 命令,给主节点上报自身当前的偏移量。
3.6.3 总结
本文主要讲解了主从复制之间的复制原理,分为:全量复制和部分复制。Master 区分是全量复制还是部分复制,依靠的是 runid 与 offset 参数。
第一次复制,则进行全量复制,Master 生成 RDB 文件,并将之后生成的命令存入复制积压缓冲区。Slave 断线重连后,Master 依据 offset 在复制积压缓冲区中选择传输的起始字节。如果找不到则进行全量复制。
3.7 主从优化
master节点配置优化209
repl-diskless-sync yes
#复制同步策略:磁盘或套接字。
#
#新副本和无法重新连接的副本
继续
#复制过程只是接收差异,需要做所谓的
#“完全同步”。RDB文件从主机传输到
#复制品。
#
#传输可以通过两种不同的方式发生:
#
#1)磁盘备份:Redis主机创建一个新进程来写入RDB
#磁盘上的文件。稍后,文件由家长传输
#以增量方式处理副本。
#2)无盘:Redis主机创建了一个新进程
直接写
#RDB文件到副本套接字,而无需接触磁盘。
#
#使用磁盘支持的复制,在生成RDB文件的同时,会生成更多的副本
#可以排队,并在当前子节点后立即使用RDB文件提供服务
#生成RDB文件完成了它的工作。改用无盘复制
#一旦传输开始,到达的新副本将被排队,并有一个新的
#当前传输终止时,传输将开始。
#
#当使用无盘复制时,主机会等待可配置的数量
#开始传输前的时间(秒),希望倍数
#副本将到达,传输可以并行化。
#
#对于慢速磁盘和快速(大带宽)网络,无盘复制
#效果更好。
repl-diskless-sync yes
maxmemory 4g
##############################内存管理################################
#将内存使用限制设置为指定的字节数。
#当达到内存限制时,Redis将尝试删除密钥
#根据所选的驱逐策略(请参阅maxmemory策略)。
#
#如果Redis不能根据策略删除密钥,或者如果策略是
#设置为'noeviction',Redis将开始回复命令错误
#这将使用更多的内存,如SET、LPUSH等,并将继续
#回复GET等只读命令。
#
#当使用Redis作为LRU时,此选项通常很有用
或LFU缓存,或
#为实例设置硬内存限制(使用“noeviction”策略)。
#
#警告:如果您将副本连接到启用了最大内存的实例,
#减去馈送副本所需的输出缓冲区的大小
#根据已使用的内存计数,以便网络问题/重新同步
#不触发按键被逐出的循环,进而输出
#副本缓冲区已满,驱逐的密钥DEL触发删除
#直到数据库完全清空。
#
#简而言之。。。如果您附加了副本,建议您设置较低的
#最大内存限制,以便系统上有一些可用RAM用于复制
#输出缓冲区(但如果策略为“noeviction”,则不需要)。
#
# maxmemory <bytes>
maxmemory 4<g> 4294967296<bytes>
repl-backlog-size 1mb
#设置复制积压的大小。积压是一个积累的缓冲区
#当副本断开连接一段时间时,副本数据
#复制副本希望再次重新连接,通常需要完全重新同步
#不需要,但a
#部分重新同步就足够了,只需将部分数据传递给副本即可
#断开连接时错过。
#
#复制积压越大,副本可以承受的时间就越长
#断开连接,然后能够执行部分重新同步。
#
#只有当至少有一个副本连接时,才会分配积压。
#
#repl积压大小1mb
#适当增大复制积压的大小,可以容忍从节点故障恢复的时间久一些
#同时我们应该尽可能快速地发现从节点故障并迅速恢复
#从而避免全量复制
repl-backlog-size 1mb
四、Redis哨兵
4.1 哨兵的作用与原理
哨兵作用一览
集群状态监控
master选举
一旦发现master挂了,哨兵需要在slave中选举一个作为新的master,选择的依据如下:
首先会判断slave与master断开时间的长短,如果超过指定的时间(down-after-milliseconds*10)则会排除该slave节点
然后判断slave节点的slave-priority值,越小优先级越高,如果是0则永远不会参与选举
如果slave-priority值一样,则会判断slave节点的offset值,越大说明数据同步得越全,优先级越高
最后判断slave的runid大小,越小优先级越高
自动故障转移
4.2 节点规划
IP地址 | 主机名称 | 软件包 | Redis端口 | Sentinel端口 |
---|---|---|---|---|
192.168.44.209 | redis1 | redis,sentinel | 6379 | 26379 |
192.168.44.210 | redis2 | redis,sentinel | 6379 | 26379 |
192.168.44.211 | redis3 | redis,sentinel | 6379 | 26379 |
4.3 配置免密登录
#209
cd ~
cat >host_list.txt <<'EOF'
192.168.44.209 1
192.168.44.210 1
192.168.44.211 1
EOF
ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa -y
yum install -y sshpass
cd ~
for i in $(seq $(cat host_list.txt |wc -l));\
do \
host_ip="$(cat host_list.txt |awk "NR==${i}"'{print $1}')";\
host_password="$(cat host_list.txt |awk "NR==${i}"'{print $2}')";\
echo "start config host:${host_ip}";\
sshpass -p"${host_password}" ssh-copy-id "-o StrictHostKeyChecking=no" -i /root/.ssh/id_rsa.pub root@"${host_ip}";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${host_ip}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#验证209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "ip a";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#修改主机名称所有节点
#批量209
cd ~
num=1
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "hostnamectl set-hostname redis${num}";\
ssh root@"${i}" "hostname";\
num=$((num+1));\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#安装相关小软件所有节点
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "yum install rsync logrotate -y";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#修改host文件所有节点
#单机编辑209
vim /etc/hosts
192.168.44.209 redis1
192.168.44.210 redis2
192.168.44.211 redis3
192.168.44.200 vip
#分发209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
rsync -avzP /etc/hosts root@"${i}":/etc/hosts;\
ssh root@"${i}" "cat /etc/hosts";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#关闭防火墙和selinux 所有节点
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "systemctl stop firewalld";\
ssh root@"${i}" "systemctl disable firewalld";\
ssh root@"${i}" "sed -ri 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/sysconfig/selinux";\
ssh root@"${i}" "grep -F 'SELINUX=' /etc/sysconfig/selinux";\
ssh root@"${i}" "setenforce 0";\
ssh root@"${i}" "getenforce";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
4.4 Sentinel实例安装
官网:Install Redis from Source | Docs
4.4.1 前置环境
=====================================
仅209单机操作即可
=====================================
#安装docker运行时209
#准备主机清单
#注意~~~~~~~~
#这一步会破坏集群主机清单
#~~~~~~~完成后请参考4.3节还原主机清单
#~~~~~~~~~不然后续集群批量操作会失败~~~~~~~~~~~~~~~~
cd ~
cat <<'EOF' | sudo tee ./host_list.txt
192.168.44.209 1
EOF
ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa -y
#配置免密登录209
yum install -y sshpass
cd ~
for i in $(seq $(cat host_list.txt |wc -l));\
do \
host_ip="$(cat host_list.txt |awk "NR==${i}"'{print $1}')";\
host_password="$(cat host_list.txt |awk "NR==${i}"'{print $2}')";\
echo "start config host:${host_ip}";\
sshpass -p"${host_password}" ssh-copy-id "-o StrictHostKeyChecking=no" -i /root/.ssh/id_rsa.pub root@"${host_ip}";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${host_ip}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#验证209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "ip a";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#安装小软件
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "yum install rsync -y";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#官方网站:https://docs.docker.com/engine/install/centos/
#清理环境
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
#官方源(备用)
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "curl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo";\
ssh root@"${i}" "ls -l /etc/yum.repos.d";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
=====================================================================
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
=====================================================================
#安装指定版本docker这里是20.10.14版本
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "yum install -y yum-utils";\
ssh root@"${i}" "yum list docker-ce --showduplicates | sort -r";\
ssh root@"${i}" "yum list docker-ce-cli --showduplicates | sort -r";\
ssh root@"${i}" "yum list containerd.io --showduplicates | sort -r";\
ssh root@"${i}" "yum install docker-ce-20.10.14 docker-ce-cli-20.10.14 containerd.io -y";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#阿里源(推荐)
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "curl http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo";\
ssh root@"${i}" "ls -l /etc/yum.repos.d";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
==================================================================
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
==================================================================
#等等安装GPG签名报错?
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "rpm --import https://mirrors.aliyun.com/almalinux/RPM-GPG-KEY-AlmaLinux";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#创建文件夹所有节点
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "yum install tree -y";\
ssh root@"${i}" "mkdir /etc/docker -p";\
ssh root@"${i}" "mkdir /data/docker -p";\
ssh root@"${i}" "tree /data";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#修改docker配置文件,bip172.xx.xx.1的xx.xx替换为主机ip的后两位
#单机编辑209
#参考弃用文档:https://docs.docker.com/engine/deprecated/#duplicate-keys-with-conflicting-values-in-engine-labels
#参考daemon.json配置文档:https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file
#旧版配置,graph在版本v17.05中已弃用;在版本中v23.0彻底移除;用data-root替代
vim /etc/docker/daemon.json
{
"graph": "/data/docker",
"storage-driver": "overlay2",
"insecure-registries": ["registry.access.redhat.com","quay.io","192.168.44.201:8088"],
"registry-mirrors": [
"https://uoggbpok.mirror.aliyuncs.com",
"http://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.nju.edu.cn"
],
"bip": "172.16.0.1/16",
"exec-opts": ["native.cgroupdriver=systemd"],
"live-restore": true,
"log-driver": "json-file",
"log-opts": {"max-size":"100m", "max-file":"3"}
}
#新版配置,如果发现无法启动docker守护进程,请使用这个配置
vim /etc/docker/daemon.json
{
"data-root": "/data/docker",
"storage-driver": "overlay2",
"insecure-registries": ["registry.access.redhat.com","quay.io","192.168.44.201:8088"],
"registry-mirrors": [
"https://uoggbpok.mirror.aliyuncs.com",
"http://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.nju.edu.cn"
],
"bip": "172.16.0.1/16",
"exec-opts": ["native.cgroupdriver=systemd"],
"live-restore": true,
"log-driver": "json-file",
"log-opts": {"max-size":"100m", "max-file":"3"}
}
#分发209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
rsync -avzP /etc/docker/daemon.json root@"${i}":/etc/docker/;\
ssh root@"${i}" "cat /etc/docker/daemon.json";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#所有节点
#启动docker,验证版本信息
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "systemctl daemon-reload";\
ssh root@"${i}" "systemctl enable docker";\
ssh root@"${i}" "systemctl start docker";\
ssh root@"${i}" "docker version";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#安装完成
[root@docker ~]# docker info
#Docker仓库凉凉了??
#单机配置代理209
#https://docs.docker.com/engine/daemon/proxy/#systemd-unit-file
[root@docker ~]# mkdir -p /etc/systemd/system/docker.service.d
[root@docker ~]# vim /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://192.168.1.131:8080"
Environment="HTTPS_PROXY=http://192.168.1.131:8080"
Environment="NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,192.168.44.201,registry.myhabor.com"
#分发209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "mkdir -p /etc/systemd/system/docker.service.d";\
rsync -avzP /etc/systemd/system/docker.service.d/http-proxy.conf root@"${i}":/etc/systemd/system/docker.service.d/;\
ssh root@"${i}" "cat /etc/systemd/system/docker.service.d/http-proxy.conf";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#单机还原镜像加速配置209
[root@docker ~]# vim /etc/docker/daemon.json
{
"data-root": "/data/docker",
"storage-driver": "overlay2",
"insecure-registries": ["registry.access.redhat.com","quay.io","192.168.44.201:8088"],
"bip": "172.16.0.1/16",
"exec-opts": ["native.cgroupdriver=systemd"],
"live-restore": true,
"log-driver": "json-file",
"log-opts": {"max-size":"100m", "max-file":"3"}
}
#分发
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
rsync -avzP /etc/docker/daemon.json root@"${i}":/etc/docker/;\
ssh root@"${i}" "cat /etc/docker/daemon.json";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#重启docker
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "systemctl daemon-reload";\
ssh root@"${i}" "systemctl restart docker";\
ssh root@"${i}" "docker version";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#运行java8临时容器209
[root@docker ~]# docker container run -it --rm openjdk:8 /bin/bash
root@3568980b5c9b:/# env
HOSTNAME=3568980b5c9b
JAVA_HOME=/usr/local/openjdk-8
PWD=/
HOME=/root
LANG=C.UTF-8
TERM=xterm
SHLVL=1
PATH=/usr/local/openjdk-8/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
JAVA_VERSION=8u342
_=/usr/bin/env
4.4.2 下载安装包
发行版源码包:Index of /releases/
#官方推荐源码编译安装,我们投机取巧一下。
#直接下载docker与rpm组装版本209
=> root @ linux-learn: ~------------------------------------------------------------------------------------------
➜ cd /tmp
=> root @ linux-learn: /tmp---------------------------------------------------------------------------------------
➜ yum download --destdir=/tmp redis
#把rpm转化为tar。tgz模式209
=> root @ linux-learn: /tmp---------------------------------------------------------------------------------------
➜ rpm2archive redis-5.0.3-5.module_el8.4.0+2583+b9845322.x86_64.rpm
=> root @ linux-learn: /tmp---------------------------------------------------------------------------------------
➜ ll
总用量 2.3M
-rw-r--r-- 1 root root 926K 9月 2 20:28 redis-5.0.3-5.module_el8.4.0+2583+b9845322.x86_64.rpm
-rw-r--r-- 1 root root 1.4M 9月 2 20:37 redis-5.0.3-5.module_el8.4.0+2583+b9845322.x86_64.rpm.tgz
drwx------ 3 root root 17 9月 2 20:11 systemd-private-c531182ee6b945ddb1c53618f8c26222-chronyd.service-DKdUBk
#把它解压缩到特定的目录备用209
=> root @ linux-learn: /tmp---------------------------------------------------------------------------------------
➜ mkdir -p /tmp/redis-dir
=> root @ linux-learn: /tmp---------------------------------------------------------------------------------------
➜ tar xf redis-5.0.3-5.module_el8.4.0+2583+b9845322.x86_64.rpm.tgz -C /tmp/redis-dir
=> root @ linux-learn: /tmp---------------------------------------------------------------------------------------
➜ tree /tmp/redis-dir
/tmp/redis-dir
├── etc
│ ├── logrotate.d
│ │ └── redis
│ ├── redis.conf
│ ├── redis-sentinel.conf
│ └── systemd
│ └── system
│ ├── redis-sentinel.service.d
│ │ └── limit.conf
│ └── redis.service.d
│ └── limit.conf
├── usr
│ ├── bin
│ │ ├── redis-benchmark
│ │ ├── redis-check-aof -> redis-server
│ │ ├── redis-check-rdb -> redis-server
│ │ ├── redis-cli
│ │ ├── redis-sentinel -> redis-server
│ │ └── redis-server
│ ├── lib
│ │ └── systemd
│ │ └── system
│ │ ├── redis-sentinel.service
│ │ └── redis.service
│ ├── lib64
│ │ └── redis
│ │ └── modules
│ ├── libexec
│ │ └── redis-shutdown
│ └── share
│ ├── licenses
│ │ └── redis
│ │ ├── COPYING
│ │ ├── COPYING-hiredis
│ │ ├── COPYING-jemalloc
│ │ └── COPYRIGHT-lua
│ └── man
│ ├── man1
│ │ ├── redis-benchmark.1.gz
│ │ ├── redis-check-aof.1.gz
│ │ ├── redis-check-rdb.1.gz
│ │ ├── redis-cli.1.gz
│ │ ├── redis-sentinel.1.gz -> redis-server.1.gz
│ │ └── redis-server.1.gz
│ └── man5
│ ├── redis.conf.5.gz
│ └── redis-sentinel.conf.5.gz -> redis.conf.5.gz
└── var
├── lib
│ └── redis
└── log
└── redis
26 directories, 26 files
#运行almalinux:8临时容器209
#注意你的宿主机什么操作系统就运行什么
#我的是almalinux:8
root in 🌐 linux-learn in ~
➜ docker container run --name=redis \
--rm \
-it \
almalinux:8 /bin/bash
#把临时容器放入后台运行209
root in 🌐 linux-learn in ~
➜ Ctrl + p + q
#进入容器209
root in 🌐 linux-learn in ~ took 1m55s
➜ docker container exec -it redis /bin/bash
#下载源码并编译
[root@a438ba4941d9 /]# cd /tmp/
[root@a438ba4941d9 tmp]#
[root@a438ba4941d9 tmp]# curl -L https://download.redis.io/releases/redis-6.2.6.tar.gz -o redis-6.2.6.tar.gz
[root@a438ba4941d9 tmp]# tar xf redis-6.2.6.tar.gz
[root@a438ba4941d9 tmp]# cd redis-6.2.6
[root@a438ba4941d9 redis-6.2.6]# yum install -y https://mirrors.aliyun.com/epel/epel-release-latest-8.noarch.rpm
[root@a438ba4941d9 redis-6.2.6]# yum install make gcc glibc glibc-devel openssl openssl-devel systemd-devel -y
[root@a438ba4941d9 redis-6.2.6]# make BUILD_TLS=yes USE_SYSTEMD=yes
[root@a438ba4941d9 redis-6.2.6]# make install
[root@a438ba4941d9 redis-6.2.6]# ls -l
total 244
-rw-rw-r-- 1 root root 33624 Oct 4 2021 00-RELEASENOTES
-rw-rw-r-- 1 root root 51 Oct 4 2021 BUGS
-rw-rw-r-- 1 root root 5026 Oct 4 2021 CONDUCT
-rw-rw-r-- 1 root root 3384 Oct 4 2021 CONTRIBUTING
-rw-rw-r-- 1 root root 1487 Oct 4 2021 COPYING
-rw-rw-r-- 1 root root 11 Oct 4 2021 INSTALL
-rw-rw-r-- 1 root root 6888 Oct 4 2021 MANIFESTO
-rw-rw-r-- 1 root root 151 Oct 4 2021 Makefile
-rw-rw-r-- 1 root root 21567 Oct 4 2021 README.md
-rw-rw-r-- 1 root root 3055 Oct 4 2021 TLS.md
drwxrwxr-x 7 root root 213 Sep 2 14:23 deps
-rw-rw-r-- 1 root root 93724 Oct 4 2021 redis.conf
-rwxrwxr-x 1 root root 275 Oct 4 2021 runtest
-rwxrwxr-x 1 root root 279 Oct 4 2021 runtest-cluster
-rwxrwxr-x 1 root root 1079 Oct 4 2021 runtest-moduleapi
-rwxrwxr-x 1 root root 281 Oct 4 2021 runtest-sentinel
-rw-rw-r-- 1 root root 13768 Oct 4 2021 sentinel.conf
drwxrwxr-x 3 root root 12288 Sep 2 14:29 src
drwxrwxr-x 11 root root 182 Oct 4 2021 tests
drwxrwxr-x 9 root root 4096 Oct 4 2021 utils
[root@a438ba4941d9 redis-6.2.6]# ls -l /usr/local/bin/
total 25048
-rwxr-xr-x 1 root root 6592864 Sep 2 14:29 redis-benchmark
lrwxrwxrwx 1 root root 12 Sep 2 14:29 redis-check-aof -> redis-server
lrwxrwxrwx 1 root root 12 Sep 2 14:29 redis-check-rdb -> redis-server
-rwxr-xr-x 1 root root 6804832 Sep 2 14:29 redis-cli
lrwxrwxrwx 1 root root 12 Sep 2 14:29 redis-sentinel -> redis-server
-rwxr-xr-x 1 root root 12245112 Sep 2 14:29 redis-server
#新开启一个终端,把容器里边的redis复制出来209
#创建我们redis的目录结构
root in 🌐 linux-learn in ~ took 4m36s
➜ mkdir /opt/redis-6.2.6/{bin,share,conf} -p
root in 🌐 linux-learn in ~
➜ mkdir /opt/redis-6.2.6/share/man/{man1,man5} -p
root in 🌐 linux-learn in ~ took 4s
➜ tree /opt/redis-6.2.6/
/opt/redis-6.2.6/
├── bin
├── conf
└── share
└── man
├── man1
└── man5
6 directories, 0 files
#复制容器里边的redis到安装目录209
root in 🌐 linux-learn in ~
➜ docker container cp redis:/usr/local/bin /tmp/redis-bin
root in 🌐 linux-learn in ~
➜ docker container cp redis:/tmp/redis-6.2.6/redis.conf /opt/redis-6.2.6/conf/
root in 🌐 linux-learn in ~
➜ docker container cp redis:/tmp/redis-6.2.6/sentinel.conf /opt/redis-6.2.6/conf/
root in 🌐 linux-learn in ~
➜ cp -r /tmp/redis-bin/* /opt/redis-6.2.6/bin/
root in 🌐 linux-learn in ~
➜ tree /opt/redis-6.2.6/
/opt/redis-6.2.6/
├── bin
│ ├── redis-benchmark
│ ├── redis-check-aof -> redis-server
│ ├── redis-check-rdb -> redis-server
│ ├── redis-cli
│ ├── redis-sentinel -> redis-server
│ └── redis-server
├── conf
│ ├── redis.conf
│ └── sentinel.conf
└── share
└── man
├── man1
└── man5
6 directories, 8 files
#分发Redis存档
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "yum install -y tree";\
rsync -avzP /opt/redis-6.2.6 root@"${i}":/opt/;\
ssh root@"${i}" "tree /opt -L 1";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#配置环境变量209
root in 🌐 linux-learn in ~
➜ ln -s /opt/redis-6.2.6 /opt/redis
root in 🌐 linux-learn in ~
➜ tree /opt/ -L 1
/opt/
├── containerd
├── redis -> /opt/redis-6.2.6
├── redis-6.2.6
└── tool
4 directories, 0 files
root in 🌐 linux-learn in ~
➜ vim ~/.bashrc
# redis
export PATH="/opt/redis/bin:$PATH"
#验证209
root in 🌐 linux-learn in ~
➜ redis-server --help
Usage: ./redis-server [/path/to/redis.conf] [options] [-]
./redis-server - (read config from stdin)
./redis-server -v or --version
./redis-server -h or --help
./redis-server --test-memory <megabytes>
Examples:
./redis-server (run the server with default conf)
./redis-server /etc/redis/6379.conf
./redis-server --port 7777
./redis-server --port 7777 --replicaof 127.0.0.1 8888
./redis-server /etc/myredis.conf --loglevel verbose -
./redis-server /etc/myredis.conf --loglevel verbose
Sentinel mode:
./redis-server /etc/sentinel.conf --sentinel
root in 🌐 linux-learn in ~
➜ redis-server -v
Redis server v=6.2.6 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=679f60a40763578
#分发环境变量配置
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "ln -s /opt/redis-6.2.6 /opt/redis";\
ssh root@"${i}" "tree /opt -L 1";\
rsync -avzP ~/.bashrc root@"${i}":~/.bashrc;\
ssh root@"${i}" "tail ~/.bashrc";\
ssh root@"${i}" "/opt/redis/bin/redis-server -v";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
4.4.3 安装并启动
① 创建运行目录
#创建redis系统用户209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "useradd -r -M -s /sbin/nologin redis";\
ssh root@"${i}" "id redis";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#创建Sentinel运行相关目录209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "mkdir /data/redis/redis-sentinel/{data,conf} -p";\
ssh root@"${i}" "tree /data/redis";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#更改所有权209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "chown -R redis:redis /data/redis";\
ssh root@"${i}" "ls -l /data/redis";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
② 创建守护进程服务
#创建sentinel守护进程服务文件209
#模板文件
========================================================================================================
root in 🌐 linux-learn in ~
➜ cat /tmp/redis-dir/usr/lib/systemd/system/redis-sentinel.service
[Unit]
Description=Redis Sentinel
After=network.target
[Service]
ExecStart=/usr/bin/redis-sentinel /etc/redis-sentinel.conf --supervised systemd
ExecStop=/usr/libexec/redis-shutdown redis-sentinel
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
========================================================================================================
#创建我们需要的
cat >/etc/systemd/system/redis-sentinel.service <<'EOF'
[Unit]
Description=Redis Sentinel
After=network.target
[Service]
ExecStart=/opt/redis/bin/redis-sentinel /data/redis/redis-sentinel/conf/redis-sentinel.conf --supervised systemd
ExecStop=/opt/redis/bin/redis-shutdown redis-sentinel
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
#创建sentinel守护进程服务文件限制209
#模板
========================================================================================================
root in 🌐 linux-learn in ~
➜ cat /tmp/redis-dir/etc/systemd/system/redis-sentinel.service.d/limit.conf
# If you need to change max open file limit
# for example, when you change maxclient in configuration
# you can change the LimitNOFILE value below
# see "man systemd.exec" for information
[Service]
LimitNOFILE=10240
========================================================================================================
#创建我们需要的
mkdir -p /etc/systemd/system/redis-sentinel.service.d
cat >/etc/systemd/system/redis-sentinel.service.d/limit.conf <<'EOF'
# If you need to change max open file limit
# for example, when you change maxclient in configuration
# you can change the LimitNOFILE value below
# see "man systemd.exec" for information
[Service]
LimitNOFILE=10240
EOF
#分发守护进程服务
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
rsync -avzP /etc/systemd/system/redis-sentinel.service root@"${i}":/etc/systemd/system/;\
ssh root@"${i}" "mkdir -p /etc/systemd/system/redis-sentinel.service.d";\
rsync -avzP /etc/systemd/system/redis-sentinel.service.d/limit.conf root@"${i}":/etc/systemd/system/redis-sentinel.service.d/;\
ssh root@"${i}" "cat /etc/systemd/system/redis-sentinel.service";\
ssh root@"${i}" "echo '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'";\
ssh root@"${i}" "echo";\
ssh root@"${i}" "echo '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'";\
ssh root@"${i}" "cat /etc/systemd/system/redis-sentinel.service.d/limit.conf";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
③ 创建停止脚本
#创建redis停止脚本209
#模板
========================================================================================================
root in 🌐 linux-learn in ~
➜ cat /tmp/redis-dir/usr/libexec/redis-shutdown
#!/bin/bash
#
# Wrapper to close properly redis and sentinel
test x"$REDIS_DEBUG" != x && set -x
REDIS_CLI=/usr/bin/redis-cli
# Retrieve service name
SERVICE_NAME="$1"
if [ -z "$SERVICE_NAME" ]; then
SERVICE_NAME=redis
fi
# Get the proper config file based on service name
CONFIG_FILE="/etc/$SERVICE_NAME.conf"
# Use awk to retrieve host, port from config file
HOST=`awk '/^[[:blank:]]*bind/ { print $2 }' $CONFIG_FILE | tail -n1`
PORT=`awk '/^[[:blank:]]*port/ { print $2 }' $CONFIG_FILE | tail -n1`
PASS=`awk '/^[[:blank:]]*requirepass/ { print $2 }' $CONFIG_FILE | tail -n1`
SOCK=`awk '/^[[:blank:]]*unixsocket\s/ { print $2 }' $CONFIG_FILE | tail -n1`
# Just in case, use default host, port
HOST=${HOST:-127.0.0.1}
if [ "$SERVICE_NAME" = redis ]; then
PORT=${PORT:-6379}
else
PORT=${PORT:-26379}
fi
# Setup additional parameters
# e.g password-protected redis instances
[ -z "$PASS" ] || ADDITIONAL_PARAMS="-a $PASS"
# shutdown the service properly
if [ -e "$SOCK" ] ; then
$REDIS_CLI -s $SOCK $ADDITIONAL_PARAMS shutdown
else
$REDIS_CLI -h $HOST -p $PORT $ADDITIONAL_PARAMS shutdown
fi
========================================================================================================
#创建我们需要的209
root in 🌐 linux-learn in ~
➜ vim /opt/redis-6.2.6/bin/redis-shutdown
root in 🌐 linux-learn in ~ took 5m25s
➜ cat /opt/redis-6.2.6/bin/redis-shutdown
#!/bin/bash
#
# Wrapper to close properly redis and sentinel
test x"$REDIS_DEBUG" != x && set -x
redis_cli="/opt/redis/bin/redis-cli"
# Retrieve service name
service_name="$1"
if [ -z "${service_name}" ]; then
service_name="redis"
fi
# Get the proper config file based on service name
config_file="/data/redis/${service_name}/conf/${service_name}.conf"
# Use awk to retrieve host, port from config file
redis_host="$(awk '/^[[:blank:]]*bind/ { print $2 }' "${config_file}" | tail -n1)"
redis_port="$(awk '/^[[:blank:]]*port/ { print $2 }' "${config_file}" | tail -n1)"
redis_pass="$(awk '/^[[:blank:]]*requirepass/ { print $2 }' "${config_file}" | tail -n1)"
redis_sock="$(awk '/^[[:blank:]]*unixsocket[s]?/ { print $2 }' "${config_file}" | tail -n1)"
# Just in case, use default host, port
redis_host="${redis_host:-127.0.0.1}"
if [ "${service_name}" == "redis-6379" ]; then
redis_port="${redis_port:-6379}"
else
redis_port="${redis_port:-26379}"
fi
# Setup additional parameters
# e.g password-protected redis instances
[ -z "${redis_pass}" ] || additional_params="-a ${redis_pass}"
# shutdown the service properly
if [ -e "${redis_sock}" ]; then
bash -c "${redis_cli} -s ${redis_sock} ${additional_params} shutdown"
else
bash -c "${redis_cli} -h ${redis_host} -p ${redis_port} ${additional_params} shutdown"
fi
#添加执行权限209
root in 🌐 linux-learn in ~
➜ chmod +x /opt/redis-6.2.6/bin/redis-shutdown
#分发redis停止脚本209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
rsync -avzP /opt/redis-6.2.6 root@"${i}":/opt/;\
ssh root@"${i}" "tree /opt/redis-6.2.6";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
④ 启动
#准备sentinel配置文件209
#模板
root in 🌐 linux-learn in ~
➜ cat /opt/redis-6.2.6/conf/sentinel.conf
#编辑我们需要的
root in 🌐 linux-learn in ~
➜ cp /opt/redis-6.2.6/conf/sentinel.conf /data/redis/redis-sentinel/conf/redis-sentinel.conf
#修改绑定端口,哨兵配置等等
root in 🌐 linux-learn in ~
➜ vim /data/redis/redis-sentinel/conf/redis-sentinel.conf
=======================================================================================================
#IP地址
bind 0.0.0.0
#保护模式
protected-mode yes
#端口号
port 26379
#前台no,后台tes
daemonize no
#pid文件
pidfile /data/redis/redis-sentinel/redis_sentinel.pid
#日志文件
logfile /data/redis/redis-sentinel/redis_sentinel.log
#日志级别
loglevel verbose
#数据目录
dir /data/redis/redis-sentinel/data
#监听当前Redis主从master配置
sentinel monitor mymaster 192.168.44.209 6379 2
#节点下线最大时间(毫秒),超过该时间的节点不参与选举
sentinel down-after-milliseconds mymaster 5000
#节点故障恢复超时时间(毫秒)
sentinel failover-timeout mymaster 60000
#认证信息
sentinel auth-pass mymaster 123456
#一次故障转移
sentinel parallel-syncs mymaster 1
=======================================================================================================
#分发配置209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
rsync -avzP /data/redis/redis-sentinel/conf/redis-sentinel.conf root@"${i}":/data/redis/redis-sentinel/conf/;\
ssh root@"${i}" "tree /data/redis";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#注意了,修改所有权为redis用户,因为sentinel需要权限修改配置209
#因为守护进程我们用的redis用户~~
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "chown -R redis:redis /data/redis";\
ssh root@"${i}" "ls -l /data/redis";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#启动看看209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "systemctl daemon-reload";\
ssh root@"${i}" "systemctl start redis-sentinel.service";\
ssh root@"${i}" "systemctl enable redis-sentinel.service";\
ssh root@"${i}" "systemctl status redis-sentinel.service";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
#停止209
systemctl stop redis-sentinel.service
#测试209
root in 🌐 redis1 in ~ took 4s
➜ systemctl status redis-sentinel.service
4.4.4 配置man手册
#模板文件209
root in 🌐 linux-learn in ~
➜ tree /tmp/redis-dir/usr/share/man/
/tmp/redis-dir/usr/share/man/
├── man1
│ ├── redis-benchmark.1.gz
│ ├── redis-check-aof.1.gz
│ ├── redis-check-rdb.1.gz
│ ├── redis-cli.1.gz
│ ├── redis-sentinel.1.gz -> redis-server.1.gz
│ └── redis-server.1.gz
└── man5
├── redis.conf.5.gz
└── redis-sentinel.conf.5.gz -> redis.conf.5.gz
2 directories, 8 files
#复制man手册到安装目录209
root in 🌐 linux-learn in ~
➜ cp -r /tmp/redis-dir/usr/share/man/man1/* /opt/redis-6.2.6/share/man/man1/
root in 🌐 linux-learn in ~
➜ cp -r /tmp/redis-dir/usr/share/man/man5/* /opt/redis-6.2.6/share/man/man5/
root in 🌐 linux-learn in ~
➜ tree /opt/redis-6.2.6/
/opt/redis-6.2.6/
├── bin
│ ├── redis-benchmark
│ ├── redis-check-aof -> redis-server
│ ├── redis-check-rdb -> redis-server
│ ├── redis-cli
│ ├── redis-sentinel -> redis-server
│ ├── redis-server
│ └── redis-shutdown
├── conf
│ ├── redis.conf
│ └── sentinel.conf
└── share
└── man
├── man1
│ ├── redis-benchmark.1.gz
│ ├── redis-check-aof.1.gz
│ ├── redis-check-rdb.1.gz
│ ├── redis-cli.1.gz
│ ├── redis-sentinel.1.gz -> redis-server.1.gz
│ └── redis-server.1.gz
└── man5
├── redis.conf.5.gz
└── redis-sentinel.conf.5.gz -> redis.conf.5.gz
6 directories, 17 files
#验证209
root in 🌐 linux-learn in ~
➜ man redis
redis-benchmark redis-check-rdb redis.conf redis-sentinel.conf
redis-check-aof redis-cli redis-sentinel redis-server
#分发man手册209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
rsync -avzP /opt/redis-6.2.6 root@"${i}":/opt/;\
ssh root@"${i}" "tree /opt/redis-6.2.6";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
4.4.5 配置日志切割
#模板文件209
root in 🌐 linux-learn in ~ took 20s
➜ tree /tmp/redis-dir/
/tmp/redis-dir/
├── etc
│ ├── logrotate.d
│ │ └── redis
#编辑日志切割配置209
root in 🌐 linux-learn in ~ took 4s
➜ yum install logrotate -y
root in 🌐 linux-learn in ~
➜ vim /etc/logrotate.d/redis-sentinel
/data/redis/redis-sentinel/*.log {
weekly
rotate 10
copytruncate
delaycompress
compress
notifempty
missingok
}
#验证209
root in 🌐 linux-learn in ~
➜ logrotate -f /etc/logrotate.d/redis-sentinel
root in 🌐 linux-learn in ~
➜ tree /data/redis/redis-sentinel/
/data/redis/redis-sentinel/
├── conf
│ └── redis-sentinel.conf
├── data
├── redis_sentinel.log
├── redis_sentinel.log.1
└── redis_sentinel.pid
2 directories, 4 files
#分发日志切割配置209
#批量209
cd ~
for i in $(cat host_list.txt |awk '{print $1}');\
do \
ssh root@"${i}" "yum install logrotate -y";\
rsync -avzP /etc/logrotate.d/redis-sentinel root@"${i}":/etc/logrotate.d/;\
ssh root@"${i}" "cat /etc/logrotate.d/redis-sentinel";\
echo -e "\033[36m===================================================\033[0m";\
echo -e "\033[36m${i}\033[0m";\
echo -e "\033[36m===================================================\033[0m";\
echo;\
done
4.5 配置哨兵
节点209配置
#编辑配置开启哨兵宣布ip地址209
root in 🌐 redis1 in ~ took 1m18s
➜ vim /data/redis/redis-sentinel/conf/redis-sentinel.conf
sentinel announce-ip 192.168.44.209
sentinel announce-port 6379
#重启哨兵209
root in 🌐 redis1 in ~
➜ systemctl restart redis-sentinel.service
节点210配置
#编辑配置开启哨兵宣布ip地址210
root in 🌐 redis2 in ~ took 1m18s
➜ vim /data/redis/redis-sentinel/conf/redis-sentinel.conf
sentinel announce-ip 192.168.44.210
sentinel announce-port 6379
#重启哨兵210
root in 🌐 redis2 in ~
➜ systemctl restart redis-sentinel.service
节点211配置
#编辑配置开启哨兵宣布ip地址211
root in 🌐 redis3 in ~ took 1m18s
➜ vim /data/redis/redis-sentinel/conf/redis-sentinel.conf
sentinel announce-ip 192.168.44.211
sentinel announce-port 6379
#重启哨兵211
root in 🌐 redis3 in ~
➜ systemctl restart redis-sentinel.service
4.6 哨兵测试
#查看哨兵209
=> root @ redis1: ~----------------------------------------
➜ /opt/redis/bin/redis-cli -h 192.168.44.209 -p 26379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.44.209:26379> INFO sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.44.209:6379,slaves=2,sentinels=3
#监听日志209,210,211
root in 🌐 redis1 in ~
➜ tail -F /data/redis/redis-sentinel/redis_sentinel.log
#停止master节点209
root in 🌐 redis1 in ~
➜ systemctl stop redis-6379.service
#故障转移成功209
#选了211为主,其余的成为从
=> root @ redis1: ~----------------------------------------
➜ grep -E 'sentinel (monitor|known)' /data/redis/redis-sentinel/conf/redis-sentinel.conf
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 192.168.44.211 6379 1
sentinel known-replica mymaster 192.168.44.209 6379
sentinel known-replica mymaster 192.168.44.210 6379
sentinel known-sentinel mymaster 192.168.44.211 26379 50a7e1258fd235f455c904b113f25fc64adb772e
sentinel known-sentinel mymaster 192.168.44.210 26379 5c9dd1a680d74dbf7cae16a1417def64f8c4b41b