# pg_redis_ck
**Repository Path**: tdfAndy/pg_redis_ck
## Basic Information
- **Project Name**: pg_redis_ck
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-02-05
- **Last Updated**: 2026-02-05
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Oracle Linux 数据库与中间件部署及运维手册
**文档版本**:1.0
**交付对象**:技术人员、运维人员
**适用系统**:Oracle Linux 7.9 / 8.9(兼容 RHEL 7/8)
**URS要求**: 300人同时在线,CSV日志需要记录所有的增删改操作,查(待确认),且数据需要保留5年
---
## 阅读指引
| 读者 | 建议阅读内容 | 说明 |
|------|--------------|------|
| **技术人员** | 本文「前言」、**1.3 组件信息汇总表**、**1.3.1 容量与并发能力评估**、各章小结 | 了解架构、服务器配置、容量结论(如 300 人在线+百万级业务数据是否满足)及交付范围 |
| **运维人员** | 全文;按目录从第 1 章起按顺序执行部署与运维; | 按章操作:环境准备 → PostgreSQL → Redis → ClickHouse → 自启动与启停;日常运维与故障排查见各章对应小节;|
---
## 目录
- **前言**(文档说明、组件清单、配置总表、容量评估、术语)
- **第 1 章** 前期环境准备(所有节点通用)
- **第 2 章** PostgreSQL 组件部署(主库+备库+仲裁节点)
- **第 3 章** Redis 组件部署(主节点+从节点)
- **第 4 章** ClickHouse 组件部署(日志存储+日志备份节点)
- **第 5 章** 组件自启动与统一启停(开机自启、非正常退出后自启、启停脚本)
---
# 前言
## 1.1 手册目的
本手册为 Oracle Linux 环境下 **PostgreSQL、Redis、ClickHouse** 三大组件的**部署与运维交付文档**,面向技术人员与运维人员:提供架构与配置总览、容量结论,以及从环境准备到安装配置、验证、日常运维、故障排查的完整操作步骤,便于评审与落地实施。
## 1.2 适用范围与读者
- **适用范围**:Oracle Linux 7.9/8.9,全新服务器从 0 到 1 部署;需网络连通(外网或内网 YUM 源)。
- **主要读者**:运维工程师、部署工程师;技术人员可重点阅读 1.3、1.3.1 及各章小结。
- **部署组件**:PostgreSQL(主库+备库+仲裁,Patroni 高可用)、Redis(主+从,读写分离)、ClickHouse(双节点日志存储与备份)。
## 1.3 组件信息汇总表(核心配置与业务说明)
|序号|组件名称|内存配置|CPU配置|磁盘配置|是否必填|业务场景说明|部署要求|
|---|---|---|---|---|---|---|---|
|1|PostgreSQL主库|32G|8C(高主频≥2.8GHz)|500G SSD|是|核心事务数据库,适配百万级业务数据,32G内存满足高并发查询与事务处理需求;SSD硬盘保障IO读写效率,兼顾数据存储可靠性|独立部署,避免与其他组件共享服务器,防止资源竞争|
|2|PostgreSQL备库|32G|8C(高主频≥2.8GHz)|500G SSD|是|与主库配置完全一致,确保事务数据实时同步,支持热备模式(故障时可快速切换),同时承接只读查询请求,分担主库访问压力|同机房部署,与主库网络延迟≤1ms,保障数据同步及时性|
|3|PostgreSQL仲裁节点|16G|4C(主频≥2.6GHz)|200G SSD|是|负责主备节点故障检测、自动切换决策,无需超高硬件配置,核心保障仲裁协议(Paxos)稳定运行,规避脑裂问题|独立部署,与主备库网络互通,网络延迟≤5ms|
|4|Redis主节点|32G|4C(高主频≥3.0GHz)|200G SSD|是|内存密集型缓存服务,适配百万级业务缓存需求;Redis为单线程模型,高主频CPU提升单任务处理效率;SSD保障数据持久化(RDB/AOF)读写效率|独立部署,避免内存资源被抢占|
|5|Redis从节点|32G|4C(高主频≥3.0GHz)|200G SSD|是|与主节点配置一致,通过主从复制实现缓存数据实时备份,同时承接读请求(读写分离),提升读请求并发处理能力,降低主节点压力|与主节点同机房部署,数据同步延迟≤100ms|
|6|ClickHouse节点1(日志存储)|32G|8C(多核并行优化)|1T SSD|是|核心日志存储节点,每日接收10万条日志,按5年留存(总数据量约3650万条/年×5年=1.825亿条),数据压缩后约300-400G,1T SSD预留充足冗余;8C CPU适配ClickHouse多核并行计算特性,提升日志写入与查询效率|集群主节点,独立部署|
|7|ClickHouse节点2(日志备份)|32G|8C(多核并行优化)|1T SSD|是|与节点1配置一致,作为日志数据副本节点,实现日志数据冗余备份,同时承接查询请求,实现负载均衡,保障日志查询连续性(节点1故障时可切换至节点2)|与节点1同机房部署,千兆及以上带宽,保障数据同步与查询通信效率|
### 1.3.1 容量与并发能力评估(300 人同时在线 + 百万级业务数据)
以下针对**业务数据百万级(不含日志)、300 人同时在线**场景,核对当前服务器与参数配置是否满足。
| 维度 | 需求 | 当前配置 | 结论 |
|------|------|--------------------------------------------------------------|------|
| **同时在线人数** | 300 人 | 见下(连接数与资源) | **满足** |
| **业务数据规模** | 百万级(条/行) | PG 主/备 500G SSD,32G 内存 | **满足** |
| **PostgreSQL 连接数** | 300 人在线通常对应应用连接池约 50~500 个 DB 连接(视应用层连接池大小而定) | 主库/备库 `max_connections=1000`(第 2 章) | **满足**,1000 对 300 人在线有余量 |
| **PostgreSQL 数据量与磁盘** | 百万行级业务数据,含索引与增长空间约在数 GB~数十 GB 量级 | 主库/备库各 500G SSD | **满足**,空间与 IO 充足 |
| **PostgreSQL 内存与 CPU** | 百万级数据 + 数百连接 | 主/备 32G 内存、8C 高主频;shared_buffers 8G、effective_cache_size 24G | **满足** |
| **Redis 连接数** | 300 人在线,缓存连接通常远小于 PG | 主/从 `maxclients=10000`(第 3 章) | **满足** |
| **Redis 内存** | 缓存百万级业务热点 | 主/从 32G,maxmemory 24G | **满足** |
| **ClickHouse** | 仅日志,不承载“业务数据百万” | 双节点 32G/8C/1T SSD,支持每天10万条日志写入 5 年约 1.825 亿条 | 与业务数据容量评估无关,按日志场景已配置 |
**结论:当前服务器配置满足 300 人同时在线、业务数据百万级(不含日志)需求。** 若后续在线人数或数据量显著增加,可再评估是否调大 `max_connections`、连接池或扩容 PG/Redis 节点。
## 1.4 术语说明
- 主从复制:主节点写入数据后,自动同步至从节点,实现数据冗余;从节点可承接读请求,实现读写分离
- 热备:备库实时同步主库数据,主库故障时可快速切换至备库,业务中断时间极短(秒级)
- 脑裂:集群中多个节点同时认为自己是主节点,导致数据写入冲突,仲裁节点通过投票机制规避该问题
- Patroni:PostgreSQL高可用工具,基于Paxos协议实现主备选举、故障转移,依赖etcd作为配置中心
- RDB/AOF:Redis两种数据持久化方式,RDB快照备份,AOF日志备份,结合使用保障数据不丢失
- 多核并行优化:ClickHouse核心特性,可将查询任务拆分至多个CPU核心并行处理,提升查询速度
# 第1章 前期环境准备(所有节点通用)
本章节操作需在7个节点(PostgreSQL主备仲裁、Redis主从、ClickHouse双节点)上全部执行,确保基础环境一致,为后续组件部署奠定基础。Oracle Linux与CentOS核心差异在于YUM源配置、部分系统命令,本章已全部适配。
## 1.1 系统版本确认
执行以下命令确认Oracle Linux版本为7.9或8.9(推荐版本,兼容RHEL 7/8,组件兼容性最优):
```bash
cat /etc/oracle-release
# 预期输出(Oracle Linux 7.9示例):Oracle Linux Server release 7.9
# 预期输出(Oracle Linux 8.9示例):Oracle Linux Server release 8.9
```
若版本不符,建议重装系统或升级至指定版本,避免后续组件安装兼容性问题。
## 1.2 关闭防火墙&SELinux(生产环境可按需配置白名单)
默认防火墙和SELinux会拦截组件间通信(如PostgreSQL主备同步、Redis主从复制),初期部署建议直接关闭,后续可根据生产需求配置端口白名单。Oracle Linux防火墙默认使用firewalld,与CentOS一致,但需注意服务名称无差异。
### 1.2.1 关闭防火墙
```bash
# 停止firewalld服务
systemctl stop firewalld
# 禁用firewalld开机自启
systemctl disable firewalld
# 验证防火墙状态(预期输出:inactive)
systemctl status firewalld
```
### 1.2.2 关闭SELinux
SELinux是Linux安全增强机制,会限制进程访问权限,需临时关闭+永久关闭(Oracle Linux配置文件路径与CentOS一致):
```bash
# 临时关闭SELinux(立即生效,重启后失效)
setenforce 0
# 永久关闭SELinux(修改配置文件,重启后生效)
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
# 验证SELinux状态(预期输出:Permissive)
getenforce
```
## 1.3 配置主机名&hosts映射
为每个节点配置唯一主机名,同时配置hosts文件,实现节点间通过主机名直接通信(避免依赖IP,便于运维)。Oracle Linux主机名配置命令与CentOS完全一致。
### 1.3.1 配置主机名(按节点类型执行对应命令)
每个节点执行以下命令设置主机名(替换对应节点名称,确保唯一):
```bash
# PostgreSQL主库节点
hostnamectl set-hostname pg-master
# PostgreSQL备库节点
hostnamectl set-hostname pg-standby
# PostgreSQL仲裁节点
hostnamectl set-hostname pg-arbiter
# Redis主节点
hostnamectl set-hostname redis-master
# Redis从节点
hostnamectl set-hostname redis-slave
# ClickHouse节点1(日志存储)
hostnamectl set-hostname ck-log-master
# ClickHouse节点2(日志备份)
hostnamectl set-hostname ck-log-backup
# 验证主机名(预期输出对应节点名称)
hostname
```
### 1.3.2 配置hosts映射
执行以下命令编辑/etc/hosts文件,添加所有节点的IP和主机名映射(替换以下IP为实际服务器IP):
```bash
vi /etc/hosts
# 新增以下内容(IP 替换为实际节点 IP,主机名与 1.3.1 配置一致;下文 etcd/Patroni/Redis/ClickHouse 配置示例均使用主机名,与本节映射对应)
192.168.1.10 pg-master # PostgreSQL 主库
192.168.1.11 pg-standby # PostgreSQL 备库
192.168.1.12 pg-arbiter # PostgreSQL 仲裁节点
192.168.1.20 redis-master # Redis 主节点
192.168.1.21 redis-slave # Redis 从节点
192.168.1.30 ck-log-master # ClickHouse 日志存储主节点
192.168.1.31 ck-log-backup # ClickHouse 日志备份节点
```
验证配置:执行ping命令,确保能正常ping通所有节点主机名(示例:ping pg-master -c 3,预期有正常回包)。
## 1.4 时间同步配置(关键!避免数据同步异常)
所有节点必须保持时间同步,否则会导致PostgreSQL主备同步、Redis主从复制、ClickHouse集群通信异常。**Oracle Linux 7** 可使用 ntp 或 chrony;**Oracle Linux 8** 官方已用 chrony 替代 ntp(ntp 包可能不可用),推荐统一使用 chrony,两版本均适用。
### 1.4.1 方式一:使用 chrony(推荐,OL 7/8 通用)
```bash
# 若已安装 ntpd,先停止并禁用(可选)
systemctl stop ntpd 2>/dev/null; systemctl disable ntpd 2>/dev/null
# 安装 chrony(OL 7/8 默认或可选源均有)
yum install -y chrony
# 配置同步源(阿里云)
vi /etc/chrony.conf
# 注释原有 server 行(行首加 #),新增以下三行(iburst 表示启动时快速同步):
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
server ntp3.aliyun.com iburst
# 启动并开机自启
systemctl start chronyd
systemctl enable chronyd
systemctl status chronyd
# 验证同步(预期 output 含 Leap status: Normal)
chronyc tracking
chronyc sources
```
### 1.4.2 方式二:使用 ntp(仅 Oracle Linux 7)
若坚持使用 ntp,仅在 OL7 上执行(OL8 不推荐,ntp 可能无法安装):
```bash
yum install -y ntp
vi /etc/ntp.conf
# 注释原有 server,新增:server ntp1.aliyun.com iburst 等
systemctl start ntpd
systemctl enable ntpd
ntpq -p
```
## 1.5 安装基础依赖包(Oracle Linux专属配置)
所有节点安装通用依赖包,避免后续组件安装时缺少依赖导致失败。Oracle Linux需启用官方基础源(ol7_latest/ol8_latest)和可选源(ol7_optional_latest/ol8_optional_latest),否则部分依赖包无法安装。
```bash
# 第一步:启用Oracle Linux官方可选源(关键!)
# Oracle Linux 7执行
yum-config-manager --enable ol7_latest ol7_optional_latest
# Oracle Linux 8执行
yum-config-manager --enable ol8_latest ol8_optional_latest ol8_appstream
# 第二步:安装依赖包(Oracle Linux 7/8通用,替换CentOS专属命令)
yum install -y gcc gcc-c++ make cmake wget curl openssl openssl-devel libaio libaio-devel perl perl-devel autoconf libtool
# 补充Oracle Linux缺失的依赖(CentOS默认包含,OL需单独安装)
yum install -y libstdc++-devel libicu-devel libevent-devel
```
## 1.6 磁盘挂载配置(关键!确保SSD磁盘正常使用)
所有节点需将SSD磁盘挂载至指定目录(组件数据目录),避免使用系统盘存储数据(系统盘空间有限,且IO性能可能不足)。Oracle Linux磁盘挂载命令与CentOS完全一致,以下为通用挂载步骤(按实际磁盘盘符调整)。
### 1.6.1 查看磁盘信息
```bash
# 查看所有磁盘(预期输出SSD磁盘,如/dev/sdb)
fdisk -l
# 查看磁盘挂载情况(确认SSD未挂载)
df -h
```
### 1.6.2 磁盘分区(以/dev/sdb为例,SSD磁盘)
```bash
# 执行分区命令
fdisk /dev/sdb
# 输入以下命令(按顺序执行)
n # 新建分区
p # 主分区
1 # 分区编号
(回车默认起始扇区)
(回车默认结束扇区,使用整个磁盘)
w # 保存分区配置
```
### 1.6.3 格式化磁盘(ext4文件系统,兼容性好)
```bash
mkfs.ext4 /dev/sdb1
```
### 1.6.4 创建数据目录&挂载磁盘(按组件区分目录)
不同组件数据目录不同,按节点类型执行对应命令:
```bash
# PostgreSQL主库/备库节点(数据目录:/data/pgdata)
mkdir -p /data/pgdata
mount /dev/sdb1 /data/pgdata
# PostgreSQL仲裁节点(数据目录:/data/pg-arbiter)
mkdir -p /data/pg-arbiter
mount /dev/sdb1 /data/pg-arbiter
# Redis主节点/从节点(数据目录:/data/redis)
mkdir -p /data/redis
mount /dev/sdb1 /data/redis
# ClickHouse节点1/2(数据目录:/data/clickhouse)
mkdir -p /data/clickhouse
mount /dev/sdb1 /data/clickhouse
```
### 1.6.5 配置开机自动挂载(避免重启后挂载失效)
```bash
# 查看磁盘UUID(记录/dev/sdb1的UUID)
blkid /dev/sdb1
# 编辑/etc/fstab文件,新增挂载配置(替换UUID为实际值,目录按节点类型调整)
vi /etc/fstab
# 新增一行,格式:UUID 挂载点 文件系统 选项 dump pass
# UUID 通过 blkid /dev/sdb1 获取;挂载点可为 /data/pgdata、/data/redis、/data/clickhouse 等
UUID=xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /data/pgdata ext4 defaults 0 0
# 验证挂载配置(无报错则正常)
mount -a
```
## 1.7 内核参数优化(所有节点通用,提升组件性能)
编辑sysctl.conf文件,优化内核参数,适配组件高并发、大内存使用场景。Oracle Linux内核参数与CentOS兼容,配置完全一致:
```bash
vi /etc/sysctl.conf
# 新增以下内容
# 内存优化
vm.swappiness = 10 # 减少swap使用,优先使用物理内存
vm.overcommit_memory = 1 # 允许内存过度分配(Redis/PostgreSQL推荐)
# 网络优化
net.core.somaxconn = 65535 # 最大监听队列数,提升并发连接能力
net.ipv4.tcp_max_syn_backlog = 65535 # TCP连接队列大小
net.ipv4.tcp_tw_reuse = 1 # 复用TIME_WAIT状态的连接
# net.ipv4.tcp_tw_recycle = 1 # 已在 Linux 4.12+ 废弃,勿启用,易导致 NAT 下连接异常
net.ipv4.tcp_fin_timeout = 30 # TIME_WAIT超时时间
# 文件描述符优化
fs.file-max = 655350 # 系统最大文件描述符数
fs.aio-max-nr = 1048576 # 异步IO最大请求数
# 使内核参数立即生效
sysctl -p
```
## 1.8 限制参数优化(提升进程资源限制)
编辑limits.conf文件,提升进程最大文件描述符和最大进程数,避免组件高并发时触发限制。Oracle Linux配置与CentOS一致:
```bash
vi /etc/security/limits.conf
# 新增以下内容(* 表示所有用户)
* soft nofile 65535 # 单进程最大打开文件数(软限制)
* hard nofile 65535 # 单进程最大打开文件数(硬限制)
* soft nproc 65535 # 单用户最大进程数(软限制)
* hard nproc 65535 # 单用户最大进程数(硬限制)
# 验证配置(重启后生效,或执行以下命令临时生效)
ulimit -n 65535
ulimit -u 65535
# 查看当前限制(预期输出65535)
ulimit -n
ulimit -u
```
# 第2章 PostgreSQL组件部署(主库+备库+仲裁节点)
本章部署 PostgreSQL 14 版本(稳定性最优,适配百万级业务数据),采用 Patroni+etcd 架构实现高可用,包含主库、备库、仲裁节点的完整部署流程;**支持 pgvector 扩展,可提供向量存储与相似度检索能力(如 embedding、RAG、语义检索)**。严格遵循硬件配置要求,核心适配 Oracle Linux 源配置、依赖安装等差异点。
## 2.1 部署规划
|节点类型|主机名|主机名/IP|核心端口|数据目录|
|---|---|---|---|---|
|主库|pg-master|pg-master|5432(PostgreSQL)、2379(etcd)|/data/pgdata|
|备库|pg-standby|pg-standby|5432(PostgreSQL)、2379(etcd)|/data/pgdata|
|仲裁节点|pg-arbiter|pg-arbiter|5432(PostgreSQL)、2379(etcd)|/data/pg-arbiter|
说明:etcd作为Patroni的配置中心,需在三个节点上均部署(形成etcd集群,保障高可用),PostgreSQL仲裁节点仅参与选举,不存储业务数据。
## 2.2 所有PostgreSQL节点(主备+仲裁)通用操作
以下操作需在pg-master、pg-standby、pg-arbiter三个节点上全部执行。重点适配Oracle Linux的PostgreSQL源配置(CentOS源在OL上无法直接使用)。
### 2.2.1 安装PostgreSQL 14依赖包(Oracle Linux专属)
```bash
# 确保已启用Oracle Linux可选源(已在前期准备中执行)
# 安装PostgreSQL依赖(补充OL专属依赖包)
yum install -y libxml2 libxml2-devel libxslt libxslt-devel zlib zlib-devel bzip2 bzip2-devel lz4 lz4-devel readline readline-devel
```
### 2.2.2 添加PostgreSQL官方YUM源(Oracle Linux专属)
```bash
# 下载PostgreSQL官方YUM源配置文件(适配RHEL/Oracle Linux)
# Oracle Linux 7执行
yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
# Oracle Linux 8执行
yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
# 禁用Oracle Linux默认的postgresql模块(避免冲突,OL8专属)
if [ -f /etc/os-release ] && grep -q "VERSION_ID=8" /etc/os-release; then
dnf module disable -y postgresql
fi
# 验证YUM源(预期输出PostgreSQL 14相关包)
yum list | grep postgresql14
```
### 2.2.3 安装PostgreSQL 14
```bash
yum install -y postgresql14 postgresql14-server postgresql14-contrib postgresql14-devel
```
### 2.2.3.1 安装 pgvector 扩展(向量检索,三节点均执行)
pgvector 为 PostgreSQL 的向量扩展,用于存储与检索向量(如 embedding),支持相似度搜索、ANN 等,常用于 RAG、语义检索。需在**主库、备库、仲裁**三节点均安装扩展文件,主库上 `CREATE EXTENSION vector` 后备库会随流复制自动具备该扩展。
```bash
# 1. 安装编译依赖(git、make;postgresql14-devel 已在 2.2.3 安装)
yum install -y git make
# 2. 编译安装 pgvector(以 v0.6.2 为例,可与 PG 14 配合使用)
cd /usr/local/src
git clone --branch v0.6.2 https://github.com/pgvector/pgvector.git
cd pgvector
export PG_CONFIG=/usr/pgsql-14/bin/pg_config
make
make install # 安装到 /usr/pgsql-14/lib 与 share/extension
# 3. 验证(预期列出 vector.control 等)
ls /usr/pgsql-14/share/extension/vector*
```
若无法访问 GitHub,可从 [pgvector releases](https://github.com/pgvector/pgvector/releases) 下载源码包后解压,在解压目录内执行 `export PG_CONFIG=...`、`make`、`make install`。
### 2.2.4 安装etcd(配置中心,Oracle Linux适配)
etcd用于存储Patroni集群状态(主节点信息、选举结果等),需部署三节点etcd集群。Oracle Linux无默认etcd源,需通过epel源安装(需提前启用epel源)。
```bash
# 安装epel源(Oracle Linux 7/8通用)
yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm -E %rhel).noarch.rpm
# 启用epel源
yum-config-manager --enable epel
# 安装etcd
yum install -y etcd
# 验证etcd版本(预期输出3.3+版本)
etcd --version
```
### 2.2.5 安装Patroni(高可用工具,Oracle Linux适配)
Patroni依赖Python环境,Oracle Linux 7默认Python 2.7,需安装Python 3及pip,再安装Patroni。
```bash
# 安装Python 3及pip(Oracle Linux 7/8通用)
yum install -y python3 python3-pip python3-devel
# 升级pip
pip3 install --upgrade pip
# 安装Patroni(指定版本2.1.4,稳定性最优,适配Oracle Linux)
pip3 install patroni==2.1.4 python-etcd==0.4.5 psycopg2-binary==2.9.5
# 补充OL缺失的依赖(避免Patroni启动报错)
yum install -y python3-pyOpenSSL
```
## 2.3 配置etcd集群(三个节点分别配置)
编辑etcd配置文件/etc/etcd/etcd.conf,三个节点配置不同(主要区别:ETCD_NAME、ETCD_INITIAL_ADVERTISE_PEER_URLS、ETCD_ADVERTISE_CLIENT_URLS)。配置内容与CentOS一致,仅需注意Oracle Linux的文件路径无差异。
### 2.3.1 PostgreSQL主库节点(pg-master)etcd配置
```bash
vi /etc/etcd/etcd.conf
# 修改以下核心参数(其他参数默认),每行格式为 KEY="value",# 开头为注释
ETCD_NAME="pg-master"
# 本节点在集群中的名称,与 INITIAL_CLUSTER 中对应
ETCD_DATA_DIR="/var/lib/etcd/pg-cluster"
# etcd 数据存储目录,三节点可相同
ETCD_LISTEN_PEER_URLS="http://pg-master:2380"
# 集群节点间通信监听地址(2380 为 peer 端口),填本节点 IP
ETCD_LISTEN_CLIENT_URLS="http://pg-master:2379,http://127.0.0.1:2379"
# 客户端(含 Patroni)访问 etcd 的监听地址,填本节点 IP 与本地回环
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://pg-master:2380"
# 向集群其他节点宣告的本节点 peer 地址,填本节点 IP:2380
ETCD_ADVERTISE_CLIENT_URLS="http://pg-master:2379"
# 向客户端宣告的 etcd 访问地址,填本节点 IP:2379
ETCD_INITIAL_CLUSTER="pg-master=http://pg-master:2380,pg-standby=http://pg-standby:2380,pg-arbiter=http://pg-arbiter:2380"
# 集群初始成员列表,格式为 节点名=peer地址,三节点一致
ETCD_INITIAL_CLUSTER_TOKEN="pg-etcd-cluster"
# 集群唯一 token,三节点一致,用于隔离不同集群
ETCD_INITIAL_CLUSTER_STATE="new"
# 新建集群填 new;已存在集群填 existing
```
### 2.3.2 PostgreSQL备库节点(pg-standby)etcd配置
```bash
vi /etc/etcd/etcd.conf
# 修改以下核心参数(其他参数默认),备库节点填本机 IP 与名称 pg-standby
ETCD_NAME="pg-standby"
# 本节点在集群中的名称
ETCD_DATA_DIR="/var/lib/etcd/pg-cluster"
# etcd 数据存储目录
ETCD_LISTEN_PEER_URLS="http://pg-standby:2380"
# 集群节点间通信监听地址,填本节点 IP:2380
ETCD_LISTEN_CLIENT_URLS="http://pg-standby:2379,http://127.0.0.1:2379"
# 客户端访问监听地址,填本节点 IP:2379 与 127.0.0.1:2379
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://pg-standby:2380"
# 向集群宣告的本节点 peer 地址
ETCD_ADVERTISE_CLIENT_URLS="http://pg-standby:2379"
# 向客户端宣告的 etcd 访问地址
ETCD_INITIAL_CLUSTER="pg-master=http://pg-master:2380,pg-standby=http://pg-standby:2380,pg-arbiter=http://pg-arbiter:2380"
# 集群初始成员列表,三节点一致
ETCD_INITIAL_CLUSTER_TOKEN="pg-etcd-cluster"
# 集群 token,三节点一致
ETCD_INITIAL_CLUSTER_STATE="new"
# 新建集群填 new
```
### 2.3.3 PostgreSQL仲裁节点(pg-arbiter)etcd配置
```bash
vi /etc/etcd/etcd.conf
# 修改以下核心参数(其他参数默认),仲裁节点填本机 IP 与名称 pg-arbiter
ETCD_NAME="pg-arbiter"
# 本节点在集群中的名称
ETCD_DATA_DIR="/var/lib/etcd/pg-cluster"
# etcd 数据存储目录
ETCD_LISTEN_PEER_URLS="http://pg-arbiter:2380"
# 集群节点间通信监听地址,填本节点 IP:2380
ETCD_LISTEN_CLIENT_URLS="http://pg-arbiter:2379,http://127.0.0.1:2379"
# 客户端访问监听地址,填本节点 IP:2379 与 127.0.0.1:2379
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://pg-arbiter:2380"
# 向集群宣告的本节点 peer 地址
ETCD_ADVERTISE_CLIENT_URLS="http://pg-arbiter:2379"
# 向客户端宣告的 etcd 访问地址
ETCD_INITIAL_CLUSTER="pg-master=http://pg-master:2380,pg-standby=http://pg-standby:2380,pg-arbiter=http://pg-arbiter:2380"
# 集群初始成员列表,三节点一致
ETCD_INITIAL_CLUSTER_TOKEN="pg-etcd-cluster"
# 集群 token,三节点一致
ETCD_INITIAL_CLUSTER_STATE="new"
# 新建集群填 new
```
### 2.3.4 启动etcd集群并验证
三个节点依次执行以下命令(建议按主库→备库→仲裁节点顺序启动),Oracle Linux服务管理命令与CentOS一致:
```bash
# 创建etcd数据目录
mkdir -p /var/lib/etcd/pg-cluster
chown -R etcd:etcd /var/lib/etcd/pg-cluster
# 启动etcd服务
systemctl start etcd
# 设置开机自启
systemctl enable etcd
# 验证etcd服务状态(预期输出active (running))
systemctl status etcd
# 验证etcd集群状态(任意节点执行)
# etcd v3 使用以下命令(EPEL 提供的 etcd 多为 v3)
export ETCDCTL_API=3
etcdctl --endpoints=http://127.0.0.1:2379 endpoint health --cluster
# 预期输出 3 个节点均为 healthy
etcdctl --endpoints=http://127.0.0.1:2379 member list
# 若使用 etcd v2,可用:etcdctl cluster-health
```
## 2.4 配置Patroni(三个节点分别配置)
Patroni配置文件为YAML格式,三个节点配置不同(主要区别:name、listen、connect_address、data_dir),需严格按节点类型配置。配置内容与CentOS完全一致,仅需注意Oracle Linux的目录权限无差异。
### 2.4.1 创建Patroni配置目录&日志目录
三个节点均执行:
```bash
mkdir -p /etc/patroni /var/log/patroni
chmod 755 /etc/patroni /var/log/patroni
```
### 2.4.2 PostgreSQL主库节点(pg-master)Patroni配置
```bash
vi /etc/patroni/patroni.yml
# 配置内容如下(替换 IP 为实际主库 IP),# 为 YAML 注释
# --- 集群与节点标识 ---
scope: pg-cluster # 集群名,三节点一致
name: pg-master # 本节点名称,主库固定为 pg-master
# --- 日志 ---
log:
file: /var/log/patroni/patroni.log
level: INFO
# --- Patroni REST API(用于 patronictl 与健康检查) ---
restapi:
listen: 0.0.0.0:8008 # 0.0.0.0 允许外网访问 REST API;集群内仍通过 connect_address 通信
connect_address: pg-master:8008
# --- etcd 配置中心(三节点地址一致) ---
etcd:
hosts: pg-master:2379,pg-standby:2379,pg-arbiter:2379
# --- PostgreSQL 实例 ---
postgresql:
listen: 0.0.0.0:5432 # 0.0.0.0 允许外网访问;集群内仍通过 connect_address 通信
connect_address: pg-master:5432
data_dir: /data/pgdata
bin_dir: /usr/pgsql-14/bin
pgpass: /tmp/pgpass0
authentication:
superuser:
username: postgres
password: Pg@2026! # 建议修改为复杂密码,生产环境需保密
replication:
username: replicator
password: Repl@2026! # 复制用户密码,主备同步使用
rewind:
username: rewind_user
password: Rewind@2026!
# --- PostgreSQL 参数(主库,适配 32G/8C) ---
parameters:
unix_socket_directories: '/var/run/postgresql'
listen_addresses: '*' # 允许外网访问(配合 pg_hba.conf 放行远程,见 2.4.5.4)
wal_level: replica # 支持流复制
max_wal_senders: 10 # 最大 WAL 发送进程数(备库+仲裁连接)
max_replication_slots: 10
wal_keep_size: 16GB # 主库保留 WAL 量,供备库追赶
shared_buffers: 8GB # 物理内存的25%(32G×25%=8G)
work_mem: 50MB
maintenance_work_mem: 2GB
effective_cache_size: 24GB # 物理内存的75%(32G×75%=24G)
max_connections: 1000 # 适配百万级业务并发
log_destination: 'csvlog'
logging_collector: on
log_directory: 'pg_log'
log_filename: 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age: 1d
log_rotation_size: 100MB
callbacks: # 角色切换与启动时回调脚本
on_role_change: '/usr/local/bin/on_role_change.sh'
on_start: '/usr/local/bin/on_start.sh'
# --- 节点角色标签(主库) ---
tags:
nofailover: false # 允许参与故障切换
noloadbalance: false
clonefrom: false # 主库不作为克隆源(备库从主库克隆)
nosync: false
```
### 2.4.3 PostgreSQL备库节点(pg-standby)Patroni配置
```bash
vi /etc/patroni/patroni.yml
# 配置内容如下(替换 IP 为实际备库 IP)
# --- 集群与节点标识 ---
scope: pg-cluster
name: pg-standby
# --- 日志 ---
log:
file: /var/log/patroni/patroni.log
level: INFO
# --- Patroni REST API ---
restapi:
listen: 0.0.0.0:8008
connect_address: pg-standby:8008
# --- etcd 配置中心 ---
etcd:
hosts: pg-master:2379,pg-standby:2379,pg-arbiter:2379
# --- PostgreSQL 实例(备库) ---
postgresql:
listen: 0.0.0.0:5432
connect_address: pg-standby:5432
data_dir: /data/pgdata
bin_dir: /usr/pgsql-14/bin
pgpass: /tmp/pgpass0
authentication:
superuser:
username: postgres
password: Pg@2026! # 与主库一致
replication:
username: replicator
password: Repl@2026! # 与主库一致
rewind:
username: rewind_user
password: Rewind@2026! # 与主库一致
parameters:
unix_socket_directories: '/var/run/postgresql'
listen_addresses: '*'
wal_level: replica
max_wal_senders: 10
max_replication_slots: 10
wal_keep_size: 16GB
shared_buffers: 8GB # 与主库一致(32G×25%=8G)
work_mem: 50MB
maintenance_work_mem: 2GB
effective_cache_size: 24GB # 与主库一致(32G×75%=24G)
max_connections: 1000 # 与主库一致
log_destination: 'csvlog'
logging_collector: on
log_directory: 'pg_log'
log_filename: 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age: 1d
log_rotation_size: 100MB
callbacks:
on_role_change: '/usr/local/bin/on_role_change.sh'
on_start: '/usr/local/bin/on_start.sh'
# --- 节点角色标签(备库) ---
tags:
nofailover: false
noloadbalance: false
clonefrom: true # 允许从主库克隆数据(首次或重建时)
nosync: false
```
### 2.4.4 PostgreSQL仲裁节点(pg-arbiter)Patroni配置
仲裁节点不存储业务数据,核心配置为参与选举,参数需适配16G内存、4C CPU:
```bash
vi /etc/patroni/patroni.yml
# 配置内容如下(替换 IP 为实际仲裁节点 IP),仲裁节点不存业务数据
# --- 集群与节点标识 ---
scope: pg-cluster
name: pg-arbiter
# --- 日志 ---
log:
file: /var/log/patroni/patroni.log
level: INFO
# --- Patroni REST API ---
restapi:
listen: 0.0.0.0:8008
connect_address: pg-arbiter:8008
# --- etcd 配置中心 ---
etcd:
hosts: pg-master:2379,pg-standby:2379,pg-arbiter:2379
# --- PostgreSQL 实例(仲裁节点,数据目录独立) ---
postgresql:
listen: 0.0.0.0:5432
connect_address: pg-arbiter:5432
data_dir: /data/pg-arbiter # 仲裁节点专用目录,非 /data/pgdata
bin_dir: /usr/pgsql-14/bin
pgpass: /tmp/pgpass0
authentication:
superuser:
username: postgres
password: Pg@2026! # 与主备库一致
replication:
username: replicator
password: Repl@2026! # 与主备库一致
rewind:
username: rewind_user
password: Rewind@2026! # 与主备库一致
parameters:
unix_socket_directories: '/var/run/postgresql'
listen_addresses: '*'
wal_level: replica
max_wal_senders: 5 # 仲裁节点无需过多发送进程,适配4C CPU
max_replication_slots: 5
wal_keep_size: 8GB # 适配16G内存,预留合理WAL空间
shared_buffers: 4GB # 物理内存的25%(16G×25%=4G)
work_mem: 30MB # 按需调整,避免资源浪费
maintenance_work_mem: 1GB
effective_cache_size: 12GB # 物理内存的75%(16G×75%=12G)
max_connections: 500 # 仲裁节点仅处理选举和少量查询,无需高并发配置
log_destination: 'csvlog'
logging_collector: on
log_directory: 'pg_log'
log_filename: 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age: 1d
log_rotation_size: 100MB
callbacks:
on_role_change: '/usr/local/bin/on_role_change.sh'
on_start: '/usr/local/bin/on_start.sh'
# --- 节点角色标签(仲裁节点:仅参与选举,不接业务) ---
tags:
nofailover: true # 禁止仲裁节点升主
noloadbalance: true # 不承接读负载
clonefrom: false # 不作为克隆源
nosync: false
```
### 2.4.5 配置Patroni回调脚本(三个节点均执行)
回调脚本用于角色切换(主备切换)和启动后的初始化操作,确保集群状态正常。三个节点脚本内容一致,仅需统一创建并授权。
#### 2.4.5.1 创建on_start.sh启动回调脚本
```bash
vi /usr/local/bin/on_start.sh
# 脚本内容如下
#!/bin/bash
set -e
# 定义变量(与Patroni配置一致)
PG_BIN=/usr/pgsql-14/bin
PG_DATA=$1
PG_USER=postgres
# 启动后确保数据目录权限正确
chown -R $PG_USER:$PG_USER $PG_DATA
chmod 700 $PG_DATA
# 初始化后创建业务用户(仅主库首次启动执行,备库和仲裁节点自动同步)
if [ -z "$(ls -A $PG_DATA)" ]; then
echo "首次启动,初始化数据库..."
else
echo "数据库已初始化,跳过初始化步骤"
fi
```
#### 2.4.5.2 创建on_role_change.sh角色切换回调脚本
```bash
vi /usr/local/bin/on_role_change.sh
# 脚本内容如下
#!/bin/bash
set -e
# 接收Patroni传递的参数:新角色(primary/standby)、旧角色、集群范围、节点名称
NEW_ROLE=$1
OLD_ROLE=$2
SCOPE=$3
NAME=$4
PG_BIN=/usr/pgsql-14/bin
PG_DATA=/data/pgdata
if [ "$NAME" = "pg-arbiter" ]; then
PG_DATA=/data/pg-arbiter
fi
PG_USER=postgres
# 角色切换日志记录
echo "$(date +%Y-%m-%d\ %H:%M:%S) - 角色切换:节点$NAME,旧角色$OLD_ROLE,新角色$NEW_ROLE" >> /var/log/patroni/role_change.log
# 主节点切换逻辑:确保读写权限正常,创建业务数据库(首次切换时)
if [ "$NEW_ROLE" = "primary" ]; then
echo "$(date +%Y-%m-%d\ %H:%M:%S) - 节点$NAME成为主节点,初始化业务配置..." >> /var/log/patroni/role_change.log
# 切换为超级用户执行SQL
su - $PG_USER -c "$PG_BIN/psql -U postgres -d postgres -c \"ALTER SYSTEM SET synchronous_standby_names = 'FIRST 1 (pg-standby)';\""
su - $PG_USER -c "$PG_BIN/psql -U postgres -d postgres -c \"SELECT pg_reload_conf();\""
# 检查复制槽状态
su - $PG_USER -c "$PG_BIN/psql -U postgres -d postgres -c \"SELECT slot_name, active FROM pg_replication_slots;\"" >> /var/log/patroni/role_change.log 2>&1
fi
# 备节点切换逻辑:确保同步模式正常
if [ "$NEW_ROLE" = "standby" ]; then
echo "$(date +%Y-%m-%d\ %H:%M:%S) - 节点$NAME成为备节点,启动同步..." >> /var/log/patroni/role_change.log
# 验证主备同步状态
su - $PG_USER -c "$PG_BIN/pg_controldata $PG_DATA | grep 'Database cluster state'" >> /var/log/patroni/role_change.log 2>&1
fi
```
#### 2.4.5.3 脚本授权(三个节点均执行)
```bash
# 赋予脚本执行权限
chmod +x /usr/local/bin/on_start.sh /usr/local/bin/on_role_change.sh
# 切换所有者为postgres用户(与PostgreSQL运行用户一致)
chown postgres:postgres /usr/local/bin/on_start.sh /usr/local/bin/on_role_change.sh
```
#### 2.4.5.4 外网访问:配置 pg_hba.conf(需外网时执行)
若需从外网连接 PostgreSQL,除上述 `listen: 0.0.0.0:5432` 与 `listen_addresses: '*'` 外,还须在**主库**(及需直连的备库)的 `pg_hba.conf` 中放行远程连接。Patroni 管理的数据目录下该文件路径通常为 `/data/pgdata/pg_hba.conf`(以实际 `data_dir` 为准)。在**主库节点**执行:
```bash
# 允许所有 IP 通过密码连接(生产建议改为指定网段,如 192.168.1.0/24 或应用服务器网段)
echo "host all all 0.0.0.0/0 scram-sha-256" >> /data/pgdata/pg_hba.conf
# 重载配置(无需重启)
su - postgres -c "/usr/pgsql-14/bin/psql -U postgres -c \"SELECT pg_reload_conf();\""
```
备库若需被外网直连,同样在对应节点的 `pg_hba.conf` 追加上述规则并执行 `pg_reload_conf()`。外网访问时请确保防火墙已开放 5432(见 1.2 节;若开启 firewalld 需放行 5432/6379/8123/9000),且使用强密码与限定网段(生产环境建议将 `0.0.0.0/0` 改为具体网段)。
## 2.5 启动Patroni集群并验证(核心步骤)
按“主库→备库→仲裁节点”的顺序启动Patroni服务,Patroni会自动初始化PostgreSQL数据库、创建复制槽、实现主备同步。Oracle Linux环境下需确保进程权限和目录权限正确,避免启动失败。
### 2.5.1 启动Patroni服务(三个节点依次执行)
首先创建Patroni系统服务文件(三个节点均执行,统一服务管理):
```bash
vi /usr/lib/systemd/system/patroni.service
# 服务文件内容如下(# 为注释,systemd 会忽略)
[Unit]
Description=Patroni PostgreSQL High Availability
After=network.target etcd.service # 网络与 etcd 就绪后再启动
Wants=etcd.service # 与 etcd 同启同停(etcd 先起)
[Service]
Type=simple
User=postgres
Group=postgres
ExecStart=/usr/local/bin/patroni /etc/patroni/patroni.yml
ExecReload=/bin/kill -s HUP $MAINPID # 重载配置不重启进程
KillMode=process # 仅杀主进程,不杀子进程组
Restart=always # 异常退出后自动重启
RestartSec=5 # 重启间隔 5 秒
LimitNOFILE=65535 # 最大文件描述符,与 limits 一致
[Install]
WantedBy=multi-user.target # 多用户目标下开机自启
```
重载系统服务配置并启动Patroni(三个节点依次执行,严格按主库→备库→仲裁节点顺序):
```bash
# 首次启动前:数据目录须归属 postgres,否则 Patroni 无法初始化(按节点二选一)
# 主库、备库节点执行: chown -R postgres:postgres /data/pgdata
# 仲裁节点执行: chown -R postgres:postgres /data/pg-arbiter
# 重载服务配置
systemctl daemon-reload
# 启动Patroni服务
systemctl start patroni
# 设置开机自启(确保服务器重启后自动恢复集群)
systemctl enable patroni
# 验证Patroni服务状态(预期输出active (running))
systemctl status patroni
# 查看Patroni日志(排查启动故障,首次启动需等待1-2分钟)
tail -f /var/log/patroni/patroni.log
```
### 2.5.2 验证Patroni集群状态(任意节点执行)
Patroni提供REST API和命令行工具两种验证方式,推荐使用命令行工具(需安装patroni-cli,已随Patroni安装):
```bash
# 方式1:通过patronictl命令查看集群状态(核心验证方式)
patronictl -c /etc/patroni/patroni.yml list
# 预期输出(示例):
+ Cluster: pg-cluster (6902171063975436230) ----+----+-----------+-----------------+-----------+
| Member | Host | Role | State | TL | Lag in MB |
+-------------+---------------+--------------+-----------------+-----+-----------+
| pg-master | pg-master | Leader | running | 1 | |
| pg-standby | pg-standby | Replica | running | 1 | 0 |
| pg-arbiter | pg-arbiter | Replica | running | 1 | 0 |
+-------------+---------------+--------------+-----------------+-----+-----------+
# 关键验证点:pg-master为Leader(主节点),其他节点为Replica(备节点/仲裁节点),State均为running,Lag in MB为0(同步正常)
# 方式2:通过REST API验证(需开放8008端口)
curl http://pg-master:8008/cluster
# 预期输出集群JSON信息,包含各节点角色、状态等
# 方式3:验证PostgreSQL主备同步状态(主库节点执行)
su - postgres -c "/usr/pgsql-14/bin/psql -U postgres -d postgres -c \"SELECT usename, application_name, client_addr, state, sync_state FROM pg_stat_replication;\""
# 预期输出:备库和仲裁节点的复制连接信息,sync_state为sync(同步模式)
# 方式4:验证业务数据库创建并启用 pgvector(主库节点执行)
su - postgres -c "/usr/pgsql-14/bin/psql -U postgres -d postgres -c \"CREATE DATABASE business_db;\""
su - postgres -c "/usr/pgsql-14/bin/psql -U postgres -d postgres -c \"CREATE USER business_user WITH PASSWORD 'Biz@2026!';\""
su - postgres -c "/usr/pgsql-14/bin/psql -U postgres -d postgres -c \"GRANT ALL PRIVILEGES ON DATABASE business_db TO business_user;\""
# 启用 pgvector 扩展(主库执行后,备库通过流复制自动同步)
su - postgres -c "/usr/pgsql-14/bin/psql -U postgres -d business_db -c \"CREATE EXTENSION IF NOT EXISTS vector;\""
# 验证扩展(主库执行,预期显示 vector 版本)
su - postgres -c "/usr/pgsql-14/bin/psql -U postgres -d business_db -c \"SELECT extname, extversion FROM pg_extension WHERE extname = 'vector';\""
# 备库节点验证同步(备库节点执行)
su - postgres -c "/usr/pgsql-14/bin/psql -U postgres -d postgres -c \"\l business_db;\""
su - postgres -c "/usr/pgsql-14/bin/psql -U postgres -d business_db -c \"SELECT extname FROM pg_extension WHERE extname = 'vector';\""
# 预期输出 business_db 及 vector 扩展,说明主备同步正常
```
### 2.5.3 高可用故障切换验证(关键测试,生产环境必做)
验证Patroni集群的自动故障切换能力,模拟主库故障后,备库能否自动升为主库,仲裁节点能否正常参与选举,确保集群高可用。
#### 2.5.3.1 模拟主库故障(停止主库Patroni服务)
```bash
# 在pg-master节点(主库)执行,停止Patroni服务(模拟主库故障)
systemctl stop patroni
# 查看主库状态(预期输出inactive)
systemctl status patroni
```
#### 2.5.3.2 验证故障切换结果(任意节点执行)
```bash
# 查看Patroni集群状态,确认备库升为主库
patronictl -c /etc/patroni/patroni.yml list
# 预期输出(示例):
+ Cluster: pg-cluster (6902171063975436230) ----+----+-----------+-----------------+-----------+
| Member | Host | Role | State | TL | Lag in MB |
+-------------+---------------+--------------+-----------------+-----+-----------+
| pg-master | pg-master | Replica | stopped | 1 | |
| pg-standby | pg-standby | Leader | running | 2 | |
| pg-arbiter | pg-arbiter | Replica | running | 2 | 0 |
+-------------+---------------+--------------+-----------------+-----+-----------+
# 关键验证点:pg-standby成为Leader(新主库),pg-master状态为stopped
# 验证新主库业务可用性(在pg-standby节点执行)
su - postgres -c "/usr/pgsql-14/bin/psql -U business_user -d business_db -c \"CREATE TABLE test_table (id INT PRIMARY KEY, name VARCHAR(50));\""
su - postgres -c "/usr/pgsql-14/bin/psql -U business_user -d business_db -c \"INSERT INTO test_table VALUES (1, 'test');\""
su - postgres -c "/usr/pgsql-14/bin/psql -U business_user -d business_db -c \"SELECT * FROM test_table;\""
# 预期输出正常插入的数据,说明新主库业务可用
```
#### 2.5.3.3 恢复原主库(模拟故障修复)
```bash
# 在pg-master节点(原主库)执行,重启Patroni服务
systemctl start patroni
# 等待1-2分钟,查看集群状态(任意节点执行)
patronictl -c /etc/patroni/patroni.yml list
# 预期输出(示例):
+ Cluster: pg-cluster (6902171063975436230) ----+----+-----------+-----------------+-----------+
| Member | Host | Role | State | TL | Lag in MB |
+-------------+---------------+--------------+-----------------+-----+-----------+
| pg-master | pg-master | Replica | running | 2 | 0 |
| pg-standby | pg-standby | Leader | running | 2 | |
| pg-arbiter | pg-arbiter | Replica | running | 2 | 0 |
+-------------+---------------+--------------+-----------------+-----+-----------+
# 关键验证点:原主库恢复后成为备库,自动同步新主库数据,Lag in MB为0
# 验证数据同步(原主库pg-master节点执行)
su - postgres -c "/usr/pgsql-14/bin/psql -U business_user -d business_db -c \"SELECT * FROM test_table;\""
# 预期输出新主库插入的数据,说明数据同步正常
```
## 2.6 PostgreSQL日常运维操作(核心运维指令)
本章节汇总PostgreSQL集群日常运维常用操作,涵盖服务启停、状态检查、备份恢复、日志查看等,适配Oracle Linux环境,所有操作均基于root用户或postgres用户执行。
### 2.6.1 服务启停与重启(所有节点通用)
```bash
# 启动Patroni服务(间接启动PostgreSQL)
systemctl start patroni
# 停止Patroni服务(间接停止PostgreSQL)
systemctl stop patroni
# 重启Patroni服务(谨慎操作,生产环境建议低峰期执行)
systemctl restart patroni
# 查看Patroni服务状态
systemctl status patroni
# 查看PostgreSQL进程(验证是否正常启动)
ps -ef | grep postgres
# 查看PostgreSQL端口占用(默认5432)
netstat -an | grep 5432
ss -an | grep 5432
```
### 2.6.2 集群状态监控(任意节点执行)
```bash
# 查看Patroni集群详细状态(核心监控指令)
patronictl -c /etc/patroni/patroni.yml list
# 查看Patroni集群日志(实时监控)
tail -f /var/log/patroni/patroni.log
# 查看角色切换日志
tail -f /var/log/patroni/role_change.log
# 查看PostgreSQL日志(主库为例)
tail -f /data/pgdata/pg_log/postgresql-$(date +%Y-%m-%d)_*.log
# 查看PostgreSQL配置参数
su - postgres -c "/usr/pgsql-14/bin/psql -U postgres -d postgres -c \"SHOW ALL;\""
# 查看主备同步状态(主库执行)
su - postgres -c "/usr/pgsql-14/bin/psql -U postgres -d postgres -c \"SELECT * FROM pg_stat_replication;\""
# 查看复制槽状态(主库执行)
su - postgres -c "/usr/pgsql-14/bin/psql -U postgres -d postgres -c \"SELECT * FROM pg_replication_slots;\""
# 查看已安装扩展(含 pgvector)
su - postgres -c "/usr/pgsql-14/bin/psql -U postgres -d business_db -c \"SELECT extname, extversion FROM pg_extension WHERE extname = 'vector';\""
```
### 2.6.2.1 pgvector 扩展使用说明(向量检索)
部署时已在 `business_db` 中执行 `CREATE EXTENSION vector`,该库可直接使用向量类型与操作符。其他数据库若需向量能力,在主库执行:
```sql
\c your_database_name
CREATE EXTENSION IF NOT EXISTS vector;
```
示例:创建带向量列的表并做相似度查询(主库或备库只读连接均可):
```sql
-- 建表(向量维度按业务 embedding 维度修改,如 1536、768)
CREATE TABLE items (
id BIGSERIAL PRIMARY KEY,
content TEXT,
embedding vector(1536) -- 维度须与业务一致
);
CREATE INDEX ON items USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100); -- 可选,加速相似度检索
-- 插入与查询(示例为余弦相似度)
INSERT INTO items (content, embedding) VALUES ('示例文本', '[0.1,0.2,...]'::vector);
SELECT id, content, 1 - (embedding <=> '[0.1,0.2,...]'::vector) AS similarity FROM items ORDER BY embedding <=> '[0.1,0.2,...]'::vector LIMIT 10;
```
备库通过流复制自动同步扩展与数据,只读查询可直接连备库以分担主库压力。
### 2.6.3 数据备份与恢复(主库执行备份,备库/新节点执行恢复)
采用pg_dump工具进行逻辑备份(适配业务数据备份),结合PostgreSQL基础备份进行物理备份(适配全量恢复),确保数据安全。
#### 2.6.3.1 逻辑备份(备份业务数据库,主库执行)
```bash
# 备份business_db数据库(包含数据和结构)
su - postgres -c "/usr/pgsql-14/bin/pg_dump -U postgres -d business_db -F c -f /data/backup/business_db_$(date +%Y%m%d).dump"
# 备份指定表(示例:备份test_table表)
su - postgres -c "/usr/pgsql-14/bin/pg_dump -U postgres -d business_db -t test_table -F c -f /data/backup/test_table_$(date +%Y%m%d).dump"
# 备份所有数据库
su - postgres -c "/usr/pgsql-14/bin/pg_dumpall -U postgres -F c -f /data/backup/all_databases_$(date +%Y%m%d).dump"
# 说明:-F c表示自定义格式,压缩率高;-f指定备份文件路径,建议存储在非数据目录(避免占用SSD空间)
```
#### 2.6.3.2 逻辑恢复(恢复业务数据,目标节点执行)
```bash
# 恢复business_db数据库(需先创建空数据库)
su - postgres -c "/usr/pgsql-14/bin/psql -U postgres -d postgres -c \"DROP DATABASE IF EXISTS business_db;\""
su - postgres -c "/usr/pgsql-14/bin/psql -U postgres -d postgres -c \"CREATE DATABASE business_db;\""
su - postgres -c "/usr/pgsql-14/bin/pg_restore -U postgres -d business_db /data/backup/business_db_$(date +%Y%m%d).dump"
# 恢复指定表(需确保表结构已存在)
su - postgres -c "/usr/pgsql-14/bin/pg_restore -U postgres -d business_db -t test_table /data/backup/test_table_$(date +%Y%m%d).dump"
```
#### 2.6.3.3 物理备份(全量备份,主库执行)
```bash
# 创建基础备份目录(建议挂载独立备份磁盘),-D 目标目录须存在
mkdir -p /data/backup/base_backup/$(date +%Y%m%d)
chown -R postgres:postgres /data/backup/base_backup
# 执行基础备份(使用pg_basebackup工具)
su - postgres -c "/usr/pgsql-14/bin/pg_basebackup -D /data/backup/base_backup/$(date +%Y%m%d) -F t -X stream -P -U replicator -h pg-master -p 5432"
# 说明:-D指定备份目录;-F t表示tar格式;-X stream表示流式备份WAL日志;-P显示备份进度;-U使用复制用户
```
### 2.6.4 常见故障排查(核心排查指令)
```bash
# 1. 集群无法启动:查看Patroni日志
tail -n 200 /var/log/patroni/patroni.log | grep -i error
# 2. 主备同步失败:查看主库WAL日志和备库同步日志
# 主库查看WAL发送日志
tail -n 200 /data/pgdata/pg_log/postgresql-$(date +%Y-%m-%d)_*.log | grep -i wal
# 备库查看同步日志
tail -n 200 /data/pgdata/pg_log/postgresql-$(date +%Y-%m-%d)_*.log | grep -i standby
# 3. 连接失败:检查端口、防火墙、用户权限
# 检查端口是否开放
firewall-cmd --list-ports | grep 5432 # 若已配置防火墙白名单
# 测试端口连通性(从应用节点执行)
telnet pg-master 5432
nc -zv pg-master 5432
# 检查用户权限
su - postgres -c "/usr/pgsql-14/bin/psql -U business_user -d business_db -h pg-master"
# 4. 资源不足:查看系统资源使用情况
# 查看内存使用
free -h
top | grep postgres
# 查看磁盘使用(数据目录)
df -h /data/pgdata
# 查看CPU使用
top | grep -i postgres
# 5. etcd集群故障:查看etcd日志和状态
systemctl status etcd
tail -n 200 /var/log/etcd/etcd.log | grep -i error
etcdctl cluster-health
```
## 2.7 本章小结
本章完成了PostgreSQL 14集群(主库+备库+仲裁节点)在Oracle Linux环境下的完整部署,包含etcd配置中心、Patroni高可用工具的安装配置,实现了主备同步、读写分离、自动故障切换等核心功能。通过故障切换测试和日常运维指令汇总,确保集群在生产环境中稳定运行,适配百万级业务数据处理需求。后续章节将继续部署Redis和ClickHouse组件,完成三大核心组件的全流程部署与运维配置。
# 第3章 Redis组件部署(主节点+从节点)
本章部署Redis 6.2版本(稳定性最优,适配高并发缓存场景),采用主从复制架构实现数据冗余,结合读写分离提升并发处理能力。严格适配Oracle Linux环境的源配置、依赖安装差异,遵循32G内存、4C高主频CPU的硬件配置要求,确保缓存服务高性能、高可靠。
## 3.1 部署规划
|节点类型|主机名|主机名/IP|核心端口|数据目录|核心功能|
|---|---|---|---|---|---|
|主节点|redis-master|redis-master|6379(Redis服务端口)|/data/redis|接收写请求,存储缓存数据,同步数据至从节点|
|从节点|redis-slave|redis-slave|6379(Redis服务端口)|/data/redis|同步主节点数据,承接读请求,实现读写分离|
说明:Redis主从架构中,主节点负责所有写操作和数据同步,从节点仅负责读操作,通过主从复制实现数据实时冗余,主节点故障时可手动切换至从节点(后续可结合哨兵模式实现自动切换)。
## 3.2 所有Redis节点(主+从)通用操作
以下操作需在redis-master和redis-slave两个节点上全部执行,重点适配Oracle Linux环境下的Redis安装源和依赖配置,避免使用CentOS专属源导致安装失败。
### 3.2.1 安装Redis依赖包(Oracle Linux专属)
```bash
# 确保已启用Oracle Linux官方源和epel源(前期准备已执行)
# 安装Redis依赖(适配Oracle Linux 7/8)
yum install -y gcc gcc-c++ make tcl openssl openssl-devel libevent-devel
# 补充Oracle Linux 8专属依赖(解决编译报错问题)
if [ -f /etc/os-release ] && grep -q "VERSION_ID=8" /etc/os-release; then
yum install -y glibc-langpack-en
fi
```
### 3.2.2 下载并编译安装Redis 6.2.7(通用编译方式,适配OL)
Oracle Linux官方源中Redis版本较低,采用源码编译安装方式,确保安装指定的6.2.7版本(稳定性最优,兼容高并发场景)。
```bash
# 1. 下载Redis 6.2.7源码包(官网地址,若无法访问可替换为国内镜像)
cd /usr/local/src
wget https://download.redis.io/releases/redis-6.2.7.tar.gz
# 国内镜像备选(阿里云)
# wget https://mirrors.aliyun.com/redis/releases/redis-6.2.7.tar.gz
# 2. 解压源码包
tar -zxvf redis-6.2.7.tar.gz
cd redis-6.2.7
# 3. 编译(适配Oracle Linux,禁用jemalloc,使用系统malloc)
make MALLOC=libc
# 编译验证(无报错则编译成功)
make test
# 说明:make test若报错“tclsh not found”,需安装tcl包(已在3.2.1中安装)
# 4. 安装Redis(指定安装目录为/usr/local/redis)
make PREFIX=/usr/local/redis install
# 5. 验证安装(预期输出redis-server 6.2.7版本)
/usr/local/redis/bin/redis-server --version
```
### 3.2.3 创建Redis用户与目录(权限管控,安全规范)
```bash
# 创建Redis专用用户(避免使用root用户运行Redis,提升安全性)
useradd -r -s /sbin/nologin redis
# 创建Redis相关目录(数据目录、日志目录、配置目录、PID目录)
mkdir -p /data/redis # 数据目录(已在前期磁盘挂载中创建,此处确认权限)
mkdir -p /var/log/redis
mkdir -p /etc/redis
mkdir -p /var/run/redis
# 赋予目录权限(Redis用户专属)
chown -R redis:redis /data/redis
chown -R redis:redis /var/log/redis
chown -R redis:redis /etc/redis
chown -R redis:redis /var/run/redis
chmod 750 /data/redis /var/log/redis /etc/redis /var/run/redis
```
### 3.2.4 复制Redis配置文件并创建 systemd 服务
```bash
# 复制源码包中的配置文件到/etc/redis目录
cp /usr/local/src/redis-6.2.7/redis.conf /etc/redis/redis.conf
# 赋予配置文件权限
chown redis:redis /etc/redis/redis.conf
chmod 640 /etc/redis/redis.conf
# 创建 systemd 服务文件(直接写入,避免源码包模板差异导致启动失败)
cat > /usr/lib/systemd/system/redis.service << 'EOF'
[Unit]
Description=Redis In-Memory Data Store
After=network.target # 网络就绪后启动
[Service]
Type=notify # Redis 支持 systemd notify,用于就绪通知
User=redis
Group=redis
ExecStart=/usr/local/redis/bin/redis-server /etc/redis/redis.conf --supervised systemd
PIDFile=/var/run/redis/redis.pid # 与 redis.conf 中 pidfile 一致
TimeoutStopSec=0 # 不限制停止超时,等待 Redis 安全退出
Restart=always # 异常退出后自动重启
RestartSec=5 # 重启间隔 5 秒
[Install]
WantedBy=multi-user.target # 开机自启
EOF
```
## 3.3 配置Redis主节点(redis-master)
编辑Redis配置文件/etc/redis/redis.conf,按主节点角色配置,重点优化内存使用、持久化策略、并发连接等参数,适配32G内存、4C高主频CPU的硬件配置。
```bash
vi /etc/redis/redis.conf
# 核心配置参数修改(以下为必改项,其他参数默认或按需调整)
# 1. 基础配置
bind 0.0.0.0 # 监听所有网卡,允许外网访问;须配合 requirepass 与防火墙(见 1.2 节),生产建议限定来源网段
protected-mode yes # 开启保护模式;外网访问时务必设置 requirepass
port 6379 # 默认服务端口
daemonize no # 禁止后台运行(由systemd管理)
supervised systemd # 启用systemd管理
pidfile /var/run/redis/redis.pid # PID文件路径
logfile /var/log/redis/redis.log # 日志文件路径
databases 16 # 数据库数量(默认16,按需调整)
# 2. 数据持久化配置(RDB+AOF结合,确保数据不丢失)
save 900 1 # 900秒内有1次写入则触发RDB快照
save 300 10 # 300秒内有10次写入则触发RDB快照
save 60 10000 # 60秒内有10000次写入则触发RDB快照
dbfilename dump.rdb # RDB快照文件名
dir /data/redis # 数据文件存储目录(已挂载SSD)
appendonly yes # 开启AOF日志持久化
appendfilename "appendonly.aof" # AOF日志文件名
appendfsync everysec # 每秒同步一次AOF日志(平衡性能和可靠性)
no-appendfsync-on-rewrite yes # 重写AOF时禁止同步,提升性能
auto-aof-rewrite-percentage 100 # AOF文件大小增长100%时触发重写
auto-aof-rewrite-min-size 64mb # AOF文件最小重写大小
aof-load-truncated yes # 加载截断的AOF文件时忽略错误
# 3. 内存优化配置(适配32G内存)
maxmemory 24gb # Redis最大使用内存(32G×75%=24G,预留系统和其他进程内存)
maxmemory-policy allkeys-lru # 内存满时,淘汰所有键中最近最少使用的键
maxmemory-samples 5 # LRU淘汰算法采样数量(Redis 仅支持此参数,无 memory-samples)
# 4. 并发连接配置
timeout 300 # 客户端空闲超时时间(300秒,超时后关闭连接)
tcp-keepalive 300 # TCP保活时间
maxclients 10000 # 最大客户端连接数(适配高并发场景)
# 5. 主从复制配置(主节点无需配置slaveof,仅需开启复制权限)
repl-enable yes # 开启复制功能
repl-backlog-size 1gb # 复制积压缓冲区大小(提升从节点重连同步效率)
repl-backlog-ttl 3600 # 复制积压缓冲区过期时间(3600秒)
repl-diskless-sync yes # 开启无盘复制(减少磁盘IO,提升同步效率)
repl-diskless-sync-delay 5 # 无盘复制延迟时间(5秒)
# 6. 安全配置
requirepass Redis@2026! # 设置Redis登录密码(生产环境需修改为复杂密码)
masterauth Redis@2026! # 主从复制认证密码(与requirepass一致,从节点需相同配置)
rename-command CONFIG "" # 禁用CONFIG命令,防止未授权访问修改配置
rename-command FLUSHDB "" # 禁用FLUSHDB命令,防止误删数据库
rename-command FLUSHALL "" # 禁用FLUSHALL命令,防止误删所有数据库
# 7. 其他优化配置
lazyfree-lazy-eviction yes # 惰性删除过期键,提升性能
lazyfree-lazy-expire yes # 惰性删除过期键
lazyfree-lazy-server-del yes # 惰性删除服务器端删除的键
replica-lazy-flush yes # 从节点同步数据时惰性刷新数据,提升同步效率
```
## 3.4 配置Redis从节点(redis-slave)
从节点配置文件基于主节点修改,核心差异在于添加slaveof配置(指定主节点IP和端口),其他参数(内存、持久化、安全等)与主节点保持一致,确保主从同步兼容。
```bash
vi /etc/redis/redis.conf
# 核心配置参数修改(仅列出与主节点差异项,其他参数与主节点一致)
# 1. 基础配置(从节点与主节点一致,允许外网访问时 bind 0.0.0.0)
bind 0.0.0.0 # 监听所有网卡,允许外网访问;须配合 requirepass 与防火墙
# 2. 主从复制配置(从节点必配,主节点无此段)
slaveof redis-master 6379 # 主节点主机名与端口,从节点启动后自动同步主节点数据
replica-read-only yes # 从节点只读,写请求需发往主节点
replica-priority 100 # 哨兵/故障切换时优先级,数值越小越优先升主
# 3. 其他参数(与主节点完全一致,否则主从可能异常)
requirepass Redis@2026! # 与主节点一致,客户端连接从节点时使用
masterauth Redis@2026! # 连接主节点做复制时的认证密码,须与主节点 requirepass 一致
maxmemory 24gb
appendonly yes
save 900 1
# 并发、持久化、安全等其余项与主节点保持一致,此处不重复列出
```
## 3.5 启动Redis集群并验证
按“主节点→从节点”的顺序启动Redis服务,通过systemd管理服务,验证主从复制状态、读写分离功能,确保集群正常运行。
### 3.5.1 启动Redis服务(主从节点依次执行)
```bash
# 重载systemd服务配置(仅首次启动或修改服务文件后执行)
systemctl daemon-reload
# 启动Redis服务
systemctl start redis
# 设置开机自启(确保服务器重启后自动恢复)
systemctl enable redis
# 验证Redis服务状态(预期输出active (running))
systemctl status redis
# 查看Redis进程(预期输出redis-server进程,绑定指定IP和端口)
ps -ef | grep redis
# 查看Redis端口占用(预期输出6379端口监听)
netstat -an | grep 6379
ss -an | grep 6379
```
### 3.5.2 验证主从复制状态(核心验证步骤)
#### 3.5.2.1 主节点状态验证(redis-master节点执行)
```bash
# 登录Redis主节点(使用密码登录)
/usr/local/redis/bin/redis-cli -h redis-master -p 6379 -a Redis@2026!
# 查看主节点信息(重点关注connected_slaves参数)
redis-master:6379> INFO replication
# 预期输出关键信息(示例):
# replication
# role:master
# connected_slaves:1 # 已连接1个从节点
# slave0:ip=redis-slave,port=6379,state=online,offset=12345,lag=0 # 从节点信息,state为online,lag为0(同步正常)
# master_replid:xxxxxxxxx
# master_replid2:00000000000000000000000000000000
# master_repl_offset:12345
# second_repl_offset:-1
# repl_backlog_active:1
# repl_backlog_size:1073741824
# repl_backlog_first_byte_offset:1
# repl_backlog_histlen:12345
# 测试主节点写操作
redis-master:6379> SET test_key "redis-master-test"
OK
redis-master:6379> GET test_key
"redis-master-test"
```
#### 3.5.2.2 从节点状态验证(redis-slave节点执行)
```bash
# 登录Redis从节点(使用密码登录)
/usr/local/redis/bin/redis-cli -h redis-slave -p 6379 -a Redis@2026!
# 查看从节点信息(重点关注role、master_link_status参数)
redis-slave:6379> INFO replication
# 预期输出关键信息(示例):
# replication
# role:slave
# master_host:redis-master
# master_port:6379
# master_link_status:up # 主从连接正常(up)
# master_last_io_seconds_ago:1
# master_sync_in_progress:0
# slave_repl_offset:12345
# slave_priority:100
# slave_read_only:1 # 已开启只读模式
# connected_slaves:0
# 验证主从数据同步(读取主节点写入的test_key)
redis-slave:6379> GET test_key
"redis-master-test" # 预期输出主节点写入的数据,说明同步正常
# 验证从节点只读模式(尝试写操作,预期报错)
redis-slave:6379> SET test_key2 "redis-slave-test"
(error) READONLY You can't write against a read only replica. # 报错说明只读模式生效
```
### 3.5.3 读写分离验证(业务场景核心验证)
模拟业务读写分离场景,主节点处理写请求,从节点处理读请求,验证集群并发处理能力:
```bash
# 1. 主节点执行批量写操作(模拟业务写入)
# 登录主节点
/usr/local/redis/bin/redis-cli -h redis-master -p 6379 -a Redis@2026!
# 批量写入100条测试数据
redis-master:6379> MULTI
OK
redis-master:6379(TX)> for i in {1..100}; do SET "user:$i" "user_$i"; done
(error) ERR unknown command `for`, with args beginning with: `i`, `in`, `{1..100}`, `;`, `do`, `SET`, `"user:$i"`, `"user_$i"`, `;`, `done`,
# 注:redis-cli不支持直接执行shell循环,可通过shell脚本执行
exit
# 编写shell脚本批量写入
vi /tmp/redis_write_test.sh
#!/bin/bash
for i in {1..100}; do
/usr/local/redis/bin/redis-cli -h redis-master -p 6379 -a Redis@2026! SET "user:$i" "user_$i"
done
# 执行脚本
chmod +x /tmp/redis_write_test.sh
/tmp/redis_write_test.sh
# 2. 从节点执行批量读操作(模拟业务读取)
# 登录从节点
/usr/local/redis/bin/redis-cli -h redis-slave -p 6379 -a Redis@2026!
# 批量读取数据(示例读取前10条)
redis-slave:6379> for i in {1..10}; do GET "user:$i"; done
"user_1"
"user_2"
...
"user_10" # 预期正常读取主节点写入的数据,说明读写分离生效
```
## 3.6 Redis日常运维操作(核心运维指令)
汇总Redis集群日常运维常用操作,适配Oracle Linux环境,涵盖服务管理、状态监控、备份恢复、故障排查等场景,确保缓存服务稳定运行。
### 3.6.1 服务启停与重启(所有节点通用)
```bash
# 启动Redis服务
systemctl start redis
# 停止Redis服务
systemctl stop redis
# 重启Redis服务(生产环境低峰期执行,会短暂中断服务)
systemctl restart redis
# 查看服务状态
systemctl status redis
# 重启后验证主从同步(从节点执行)
/usr/local/redis/bin/redis-cli -h redis-slave -p 6379 -a Redis@2026! INFO replication | grep master_link_status
```
### 3.6.2 状态监控与日志查看
```bash
# 查看Redis详细状态信息(任意节点执行)
/usr/local/redis/bin/redis-cli -h redis-master -p 6379 -a Redis@2026! INFO
# 查看内存使用情况(重点关注used_memory、maxmemory参数)
/usr/local/redis/bin/redis-cli -h redis-master -p 6379 -a Redis@2026! INFO memory
# 查看客户端连接情况
/usr/local/redis/bin/redis-cli -h redis-master -p 6379 -a Redis@2026! INFO clients
# 实时查看Redis日志(主节点为例)
tail -f /var/log/redis/redis.log
# 查看日志中错误信息
grep -i error /var/log/redis/redis.log
# 查看Redis进程资源占用
top -p $(ps -ef | grep redis-server | grep -v grep | awk '{print $2}')
```
### 3.6.3 数据备份与恢复
Redis数据备份基于持久化文件(RDB/AOF),结合redis-cli工具实现备份与恢复,确保缓存数据安全:
#### 3.6.3.1 数据备份(主节点执行,推荐每日定时备份)
```bash
# 方式1:手动触发RDB快照备份(即时备份,不影响业务)
/usr/local/redis/bin/redis-cli -h redis-master -p 6379 -a Redis@2026! BGSAVE
# 验证备份是否成功(查看日志或数据目录)
grep -i "Background saving started" /var/log/redis/redis.log
ls -lt /data/redis/dump.rdb # 确认最新快照文件生成
# 方式2:备份持久化文件(RDB+AOF,完整备份)
# 创建备份目录(建议挂载独立备份磁盘,避免占用数据盘空间)
mkdir -p /data/backup/redis/$(date +%Y%m%d)
chown -R redis:redis /data/backup/redis
# 复制RDB和AOF文件到备份目录
cp /data/redis/dump.rdb /data/backup/redis/$(date +%Y%m%d)/
cp /data/redis/appendonly.aof /data/backup/redis/$(date +%Y%m%d)/
# 方式3:配置定时备份(通过crontab实现每日凌晨2点自动备份)
crontab -e
# 新增以下内容
0 2 * * * /usr/local/redis/bin/redis-cli -h redis-master -p 6379 -a Redis@2026! BGSAVE && cp /data/redis/dump.rdb /data/backup/redis/$(date +%Y%m%d)/dump_$(date +%H%M%S).rdb && cp /data/redis/appendonly.aof /data/backup/redis/$(date +%Y%m%d)/appendonly_$(date +%H%M%S).aof
# 说明:定时任务执行后,会生成带时间戳的备份文件,便于追溯
```
#### 3.6.3.2 数据恢复(目标节点执行,恢复前需停止服务)
恢复场景:主节点数据丢失、从节点故障重建等,恢复前需确保目标节点Redis服务已停止,且备份文件完整。
```bash
# 1. 停止Redis服务(目标节点执行)
systemctl stop redis
# 2. 清空目标节点数据目录(避免旧数据干扰,谨慎操作!)
rm -rf /data/redis/*
# 3. 复制备份文件到数据目录(以恢复当日备份为例)
cp /data/backup/redis/$(date +%Y%m%d)/dump.rdb /data/redis/
cp /data/backup/redis/$(date +%Y%m%d)/appendonly.aof /data/redis/
# 4. 赋予文件权限(Redis用户专属)
chown -R redis:redis /data/redis/*
chmod 640 /data/redis/dump.rdb /data/redis/appendonly.aof
# 5. 启动Redis服务并验证恢复结果
systemctl start redis
# 登录Redis验证数据(目标节点执行)
/usr/local/redis/bin/redis-cli -h redis-master -p 6379 -a Redis@2026!
# 查看数据(示例:查看之前批量写入的user:1键)
redis-master:6379> GET user:1
"user_1" # 预期输出备份数据,说明恢复成功
# 6. 若为从节点恢复,需验证主从同步
# 从节点执行
/usr/local/redis/bin/redis-cli -h redis-slave -p 6379 -a Redis@2026! INFO replication | grep master_link_status
# 预期输出master_link_status:up,说明同步正常
```
### 3.6.4 常见故障排查(核心排查指令与场景)
针对Redis集群常见故障(服务启动失败、主从同步异常、连接超时等),提供排查思路和实操指令,适配Oracle Linux环境:
```bash
# 1. 服务启动失败
# 排查步骤:查看服务状态→查看日志→检查配置文件→检查目录权限
systemctl status redis # 查看服务状态,获取错误提示
tail -n 200 /var/log/redis/redis.log | grep -i error # 查看日志错误信息
redis-check-conf /etc/redis/redis.conf # 检查配置文件语法正确性
ls -ld /data/redis /var/log/redis # 检查目录权限(需为redis:redis所有)
# 2. 主从同步异常(从节点INFO replication显示master_link_status:down)
# 排查步骤:检查网络连通性→检查主节点密码→检查主节点复制权限→检查防火墙
# 从节点测试主节点端口连通性
nc -zv redis-master 6379
telnet redis-master 6379
# 验证主节点密码正确性(从节点执行)
/usr/local/redis/bin/redis-cli -h redis-master -p 6379 -a Redis@2026! PING
# 主节点检查复制权限(确认repl-enable yes)
grep -i "repl-enable" /etc/redis/redis.conf
# 检查防火墙(若已开启,需放行6379端口)
firewall-cmd --list-ports | grep 6379
firewall-cmd --permanent --add-port=6379/tcp && firewall-cmd --reload
# 3. 客户端连接超时/拒绝连接
# 排查步骤:检查服务是否运行→检查绑定IP→检查保护模式→检查最大连接数
ps -ef | grep redis-server # 确认服务正常运行
grep -i "bind" /etc/redis/redis.conf # 确认绑定了客户端所在IP
grep -i "protected-mode" /etc/redis/redis.conf # 若需外网访问,可临时关闭保护模式(生产环境不推荐)
/usr/local/redis/bin/redis-cli -h redis-master -p 6379 -a Redis@2026! INFO clients | grep connected_clients # 查看当前连接数,确认未达maxclients限制
# 4. 内存占用过高
# 排查步骤:查看内存使用情况→分析键占用→清理过期键/冗余键
/usr/local/redis/bin/redis-cli -h redis-master -p 6379 -a Redis@2026! INFO memory # 查看used_memory、used_memory_ratio等参数
# 查看占用内存前10的键
/usr/local/redis/bin/redis-cli -h redis-master -p 6379 -a Redis@2026! --bigkeys
# 手动清理过期键(触发惰性删除)
/usr/local/redis/bin/redis-cli -h redis-master -p 6379 -a Redis@2026! FLUSHDB # 清理当前数据库(谨慎操作!)
/usr/local/redis/bin/redis-cli -h redis-master -p 6379 -a Redis@2026! DEL key1 key2 # 清理指定键
# 5. 持久化文件损坏(启动报错“Bad file format reading the append only file”)
# 排查步骤:修复AOF文件→修复RDB文件→重新恢复数据
# 修复AOF文件
/usr/local/redis/bin/redis-check-aof --fix /data/redis/appendonly.aof
# 修复RDB文件
/usr/local/redis/bin/redis-check-rdb /data/redis/dump.rdb
# 修复后重启服务
systemctl restart redis
```
### 3.6.5 性能优化建议(适配高并发场景)
结合Redis 6.2版本特性和Oracle Linux环境优化,提供针对性性能优化建议,保障缓存服务高性能运行:
- **内存优化**:根据业务场景调整maxmemory参数(建议为物理内存的70%-80%),合理选择内存淘汰策略(热点数据场景推荐allkeys-lru,非热点数据场景推荐volatile-lru);开启内存碎片整理(配置activerehashing yes),减少内存碎片占用。
- **持久化优化**:AOF同步策略选择everysec(平衡性能和可靠性),避免选择always(性能损耗大);开启AOF重写自动触发机制,合理设置auto-aof-rewrite-percentage和auto-aof-rewrite-min-size参数;非核心业务场景可关闭RDB快照,仅保留AOF持久化。
- **网络优化**:开启TCP_NODELAY(配置tcp-nodelay yes),减少网络延迟;合理设置tcp-keepalive参数(建议300秒),及时清理无效连接;避免Redis暴露在外网,通过内网访问,提升安全性和访问速度。
- **并发优化**:增大maxclients参数(适配高并发场景,建议10000-20000);开启redis-cli管道模式(pipeline),批量处理请求,减少网络往返次数;结合业务场景使用Redis集群(Redis Cluster),分担单节点压力(本手册为双节点主从,高并发场景可扩展为集群)。
- **系统优化**:优化内核参数(已在前期环境准备中配置),提升系统网络和IO性能;关闭Redis透明大页(echo never > /sys/kernel/mm/transparent_hugepage/enabled),避免内存访问延迟升高;使用SSD磁盘存储数据和持久化文件,提升IO读写效率。
## 3.7 本章小结
本章完成了Redis 6.2集群(主节点+从节点)在Oracle Linux环境下的完整部署,通过源码编译安装适配了OL环境的版本需求,配置主从复制实现了数据冗余和读写分离,满足高并发缓存场景的业务需求。同时,汇总了日常运维、备份恢复、故障排查和性能优化等核心内容,确保Redis服务在生产环境中稳定、高效运行。下一章将部署ClickHouse组件,完成三大核心组件的全流程部署,最终实现业务数据处理、缓存加速、日志存储的完整架构搭建。
# 第4章 ClickHouse组件部署(日志存储节点+日志备份节点)
本章部署ClickHouse 23.3版本(稳定性最优,适配日志存储和大数据查询场景),采用双节点集群架构(日志存储主节点+日志备份节点),实现日志数据冗余存储和查询负载均衡。严格适配Oracle Linux环境的源配置、依赖安装差异,遵循32G内存、8C多核CPU、1T SSD磁盘的硬件配置要求,确保日志数据的高效写入和快速查询。
## 4.1 部署规划
|节点类型|主机名|主机名/IP|核心端口|数据目录|核心功能|
|---|---|---|---|---|---|
|日志存储主节点|ck-log-master|ck-log-master|8123(HTTP接口)、9000(TCP接口)、9009(集群通信)|/data/clickhouse|接收业务日志写入请求,存储核心日志数据,作为集群主节点|
|日志备份节点|ck-log-backup|ck-log-backup|8123(HTTP接口)、9000(TCP接口)、9009(集群通信)|/data/clickhouse|同步主节点日志数据,实现数据冗余备份,承接查询请求实现负载均衡|
说明:ClickHouse双节点集群采用副本表(ReplicatedMergeTree)引擎实现数据同步,两个节点互为副本,日志存储主节点主要负责写入,日志备份节点主要负责备份和查询分担;集群通信通过9009端口实现,HTTP接口(8123)用于Web端管理和查询,TCP接口(9000)用于客户端连接。
## 4.2 所有ClickHouse节点(主+备份)通用操作
以下操作需在ck-log-master和ck-log-backup两个节点上全部执行,重点适配Oracle Linux环境下的ClickHouse官方源配置和依赖安装,避免使用CentOS专属源导致安装失败或兼容性问题。
### 4.2.1 安装ClickHouse依赖包(Oracle Linux专属)
```bash
# 确保已启用Oracle Linux官方源和epel源(前期准备已执行)
# 安装ClickHouse依赖(适配Oracle Linux 7/8)
yum install -y libicu-devel libstdc++-devel openssl-devel libtool-ltdl-devel zlib-devel
# 补充Oracle Linux 8专属依赖(解决libcrypt.so.1缺失问题)
if [ -f /etc/os-release ] && grep -q "VERSION_ID=8" /etc/os-release; then
yum install -y libxcrypt-compat
fi
# 补充Oracle Linux 7专属依赖(解决libssl.so.1.1缺失问题)
if [ -f /etc/os-release ] && grep -q "VERSION_ID=7" /etc/os-release; then
yum install -y openssl11 openssl11-devel
ln -s /usr/lib64/openssl11/libssl.so.1.1 /usr/lib64/libssl.so.1.1
ln -s /usr/lib64/openssl11/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1
fi
```
### 4.2.2 添加ClickHouse官方YUM源(Oracle Linux专属)
ClickHouse官方提供了适配RHEL/Oracle Linux的YUM源,需手动添加并启用,确保安装指定的23.3版本。
```bash
# 1. 下载ClickHouse官方源配置文件(适配RHEL/OL 7/8)
yum install -y wget
wget -O /etc/yum.repos.d/clickhouse.repo https://packages.clickhouse.com/rpm/clickhouse.repo
# 2. 编辑源配置文件,指定安装 23.3 版本(避免安装最新版导致兼容性问题)
vi /etc/yum.repos.d/clickhouse.repo
# 修改以下参数:baseurl 中指定 23.3 与 x86_64;OL7 用 7,OL8 用 8
# 示例(Oracle Linux 7):
[clickhouse-main]
name=ClickHouse Main Repository
baseurl=https://packages.clickhouse.com/rpm/stable/23.3/x86_64 # 固定 23.3,替换 $releasever 为 7 或 8
enabled=1 # 启用
gpgcheck=1 # 校验包签名
gpgkey=https://packages.clickhouse.com/rpm/clickhouse-key.gpg
repo_gpgcheck=1
[clickhouse-testing]
name=ClickHouse Testing Repository
baseurl=https://packages.clickhouse.com/rpm/testing/23.3/x86_64
enabled=0 # 测试源默认关闭
gpgcheck=1
gpgkey=https://packages.clickhouse.com/rpm/clickhouse-key.gpg
repo_gpgcheck=1
# 3. 导入GPG密钥(验证包完整性)
rpm --import https://packages.clickhouse.com/rpm/clickhouse-key.gpg
# 4. 验证源配置(预期输出clickhouse-server、clickhouse-client等包)
yum list | grep clickhouse
```
### 4.2.3 安装ClickHouse 23.3版本
```bash
# 安装ClickHouse服务器和客户端(两个节点均执行)
yum install -y clickhouse-server-23.3 clickhouse-client-23.3
# 验证安装(预期输出23.3.x版本)
clickhouse-server --version
clickhouse-client --version
# 查看ClickHouse安装目录(默认安装在/var/lib/clickhouse,后续需迁移至SSD数据目录)
ls -ld /var/lib/clickhouse
```
### 4.2.4 迁移数据目录(核心!适配SSD磁盘存储)
ClickHouse默认数据目录为/var/lib/clickhouse(系统盘),需迁移至前期挂载的SSD磁盘目录/data/clickhouse,确保日志数据写入和查询的IO性能,两个节点均需执行迁移操作。
```bash
# 1. 停止ClickHouse服务(迁移前必须停止,避免数据损坏)
systemctl stop clickhouse-server
# 2. 复制默认数据目录内容到SSD数据目录
cp -a /var/lib/clickhouse/* /data/clickhouse/
# 3. 删除默认数据目录,创建软链接(指向SSD数据目录)
rm -rf /var/lib/clickhouse
ln -s /data/clickhouse /var/lib/clickhouse
# 4. 赋予目录权限(ClickHouse用户专属,用户名为clickhouse)
chown -R clickhouse:clickhouse /data/clickhouse
chown -R clickhouse:clickhouse /var/lib/clickhouse # 软链接权限
chmod 750 /data/clickhouse /var/lib/clickhouse
# 5. 验证迁移(预期输出软链接指向/data/clickhouse)
ls -ld /var/lib/clickhouse
```
### 4.2.5 配置ClickHouse日志目录(可选,优化日志存储)
ClickHouse默认日志目录为/var/log/clickhouse-server,可根据需求迁移至SSD目录或保留默认,此处优化日志轮转配置,避免日志占用过多空间:
```bash
# 编辑日志轮转配置文件
vi /etc/logrotate.d/clickhouse-server
# 优化配置(按天与大小轮转,保留30天,压缩旧日志)
/var/log/clickhouse-server/*.log {
daily # 按天轮转
size 100M # 单文件超 100M 也轮转
rotate 30 # 保留 30 份
compress # 压缩旧日志
delaycompress # 最近一份不压缩便于查看
missingok # 文件不存在不报错
notifempty # 空文件不轮转
create 0640 clickhouse clickhouse # 新日志文件属主与权限
sharedscripts # 所有匹配文件轮转完只执行一次 postrotate
postrotate
systemctl kill -s USR1 clickhouse-server > /dev/null 2>&1 || true # 通知 ClickHouse 重新打开日志
endscript
}
```
## 4.3 配置 ClickHouse 主节点与备份节点
两个节点需分别配置 `config.xml` 与 `config.d/` 下的集群与监听地址,并创建副本集群元数据。主节点与备份节点除 `listen_host`、`host`、`replica_name` 等区分外,其余保持一致。
### 4.3.1 公共配置(config.d 片段,两节点通用)
先创建集群与宏配置(两节点均创建,宏值按节点不同见下节):
```bash
mkdir -p /etc/clickhouse-server/config.d
chown -R clickhouse:clickhouse /etc/clickhouse-server/config.d
```
**集群与副本配置(两节点均创建,cluster_name 与 replica 名按 4.3.2/4.3.3 区分):**
```bash
vi /etc/clickhouse-server/config.d/cluster.xml
```
主节点(ck-log-master)内容示例(XML 注释用 ):
```xml
ck-log-master
9000
ck-log-backup
9000
01
ck-log-master
```
备份节点(ck-log-backup)的 `cluster.xml` 中 `remote_servers` 相同,仅 `macros` 不同:
```xml
01
ck-log-backup
```
### 4.3.2 主节点(ck-log-master)listen 与路径配置
```bash
vi /etc/clickhouse-server/config.d/listen.xml
```
```xml
0.0.0.0
/data/clickhouse/
/data/clickhouse/tmp/
/data/clickhouse/user_files/
/var/log/clickhouse-server/clickhouse-server.log
/var/log/clickhouse-server/clickhouse-server.err.log
```
说明:`listen_host` 为 `0.0.0.0` 时允许外网访问 8123/9000,须配合防火墙开放端口(见 1.2 节);生产建议在 ClickHouse 中配置用户与 `networks` 限制来源 IP。`path`/`tmp_path`/`user_files_path` 为数据与临时目录(SSD);`logger` 为日志路径。
### 4.3.3 备份节点(ck-log-backup)listen 与路径配置
```bash
vi /etc/clickhouse-server/config.d/listen.xml
```
```xml
0.0.0.0
/data/clickhouse/
/data/clickhouse/tmp/
/data/clickhouse/user_files/
/var/log/clickhouse-server/clickhouse-server.log
/var/log/clickhouse-server/clickhouse-server.err.log
```
说明:备份节点与主节点一致,`listen_host` 均为 `0.0.0.0` 以支持外网访问;须配合防火墙开放 8123、9000。
### 4.3.4 内存与并发参数(两节点通用,适配 32G 内存、8C CPU)
```bash
vi /etc/clickhouse-server/config.d/custom.xml
```
```xml
25769803776
16
100
```
## 4.4 启动 ClickHouse 集群并验证
### 4.4.1 启动服务(两节点依次执行)
```bash
# 创建 tmp、user_files 目录并授权
mkdir -p /data/clickhouse/tmp /data/clickhouse/user_files
chown -R clickhouse:clickhouse /data/clickhouse
# 启动 ClickHouse
systemctl start clickhouse-server
systemctl enable clickhouse-server
# 检查状态与端口
systemctl status clickhouse-server
ss -tlnp | grep -E '8123|9000|9009'
```
### 4.4.2 创建日志表并验证写入与查询
**方式一:无 ZooKeeper 时先用本地表验证(两节点各自建表,仅验证单机写入与查询)**
在任一两节点执行:
```bash
clickhouse-client --host ck-log-master --port 9000
```
```sql
CREATE DATABASE IF NOT EXISTS app_logs;
-- 本地 MergeTree 表(不依赖 ZooKeeper,部署后即可验证)
CREATE TABLE IF NOT EXISTS app_logs.log_events_local (
event_time DateTime,
level String,
message String,
host String
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_time)
ORDER BY (event_time, level);
INSERT INTO app_logs.log_events_local VALUES (now(), 'INFO', 'test from ck-log-master', 'ck-log-master');
SELECT * FROM app_logs.log_events_local;
```
**方式二:生产环境使用副本表(需先部署 ZooKeeper 或 ClickHouse Keeper)**
使用 ReplicatedMergeTree 前,必须在 ClickHouse 配置中声明 ZooKeeper/Keeper 地址,否则建表会报错。在两节点任一 `config.d` 下新增(示例):
```bash
# 示例:vi /etc/clickhouse-server/config.d/zookeeper.xml
# ZK或Keeper节点IP2181
```
在已部署并配置好 Keeper 的前提下,两节点执行相同建表语句(ZooKeeper 路径按实际环境修改):
```sql
CREATE TABLE IF NOT EXISTS app_logs.log_events (
event_time DateTime,
level String,
message String,
host String
) ENGINE = ReplicatedMergeTree('/clickhouse/tables/01/log_events', '{replica}')
PARTITION BY toYYYYMM(event_time)
ORDER BY (event_time, level);
```
主节点插入后,在备份节点查询 `app_logs.log_events`,可验证副本同步。日常约 10 万条/日、5 年约 1.825 亿条,压缩后约 300–400G,1T SSD 预留充足空间。
### 4.4.3 HTTP 健康与集群状态
```bash
# HTTP 健康
curl http://ck-log-master:8123/ping
curl http://ck-log-backup:8123/ping
# 集群节点列表(若配置了 distributed 表或 cluster 函数)
clickhouse-client --host ck-log-master -q "SELECT * FROM system.clusters"
```
## 4.5 ClickHouse 日常运维(核心指令)
### 4.5.1 服务启停与状态
```bash
systemctl start clickhouse-server
systemctl stop clickhouse-server
systemctl restart clickhouse-server
systemctl status clickhouse-server
tail -f /var/log/clickhouse-server/clickhouse-server.log
```
### 4.5.2 磁盘与表容量(适配 1T SSD 与 5 年日志量)
```sql
-- 各表与分区占用
SELECT table, formatReadableSize(sum(bytes_on_disk)) AS size
FROM system.parts
WHERE database = 'app_logs'
GROUP BY table;
-- 数据目录磁盘使用
SELECT * FROM system.disks;
```
### 4.5.3 备份与恢复思路
- 冷备份:停止服务后拷贝 `/data/clickhouse` 下对应库/表目录。
- 热备份:使用 `BACKUP TABLE app_logs.log_events TO Disk('backup_disk', 'path')` 或外部工具(如 clickhouse-backup),将备份目录定期拷贝至备份节点或对象存储。
### 4.5.4 常见故障排查
```bash
# 启动失败:查错误日志
tail -n 200 /var/log/clickhouse-server/clickhouse-server.err.log
# 副本不同步:查 ZooKeeper/Keeper 连接与副本状态
clickhouse-client -q "SELECT * FROM system.replicas"
# 端口与连接
ss -tlnp | grep clickhouse
nc -zv ck-log-master 9000
```
## 4.6 本章小结
本章在 Oracle Linux 上完成了 ClickHouse 23.3 双节点(日志存储主节点 + 日志备份节点)的部署:安装依赖与 23.3 版本、迁移数据目录到 1T SSD、配置 listen/集群/宏与内存参数、启动服务并创建副本表示例。配合第 1 章环境准备与第 2、3 章 PostgreSQL、Redis 部署,三大组件(PostgreSQL、Redis、ClickHouse)已在 Oracle Linux 上按既定服务器规格完成部署,可支撑百万级业务数据、缓存与约 5 年日志存储(约 1.825 亿条,300–400G 压缩)及查询负载均衡。
---
# 第5章 组件自启动与统一启停(类似 docker-compose)
本章实现“组件停止后自启动”以及类似 docker-compose 的**按依赖顺序一键启停**:开机自启依赖各服务的 `systemctl enable`;手动停机后可用脚本按正确顺序统一拉起或停止本机/集群服务。
## 5.0.1 开机自启说明(已具备)
部署时已对以下服务执行 `systemctl enable`,故**重启服务器后会自动启动**,无需人工干预:
| 节点类型 | 本机服务 | 说明 |
|----------|----------|------|
| PostgreSQL 主库/备库/仲裁 | etcd、patroni | 先起 etcd,再起 patroni(systemd 已配置 Wants=etcd.service) |
| Redis 主/从 | redis | 单服务 |
| ClickHouse 节点1/2 | clickhouse-server | 单服务 |
依赖顺序由 systemd 保证:Patroni 的 unit 中 `After=etcd.service`、`Wants=etcd.service`,因此 etcd 会先于 patroni 启动。
## 5.0.2 集群启动顺序(类似 compose 依赖)
若**整集群停机后**需按顺序拉起(或排查问题时需按顺序重启),建议顺序如下:
| 阶段 | 节点 | 服务启动顺序 | 说明 |
|------|------|--------------|------|
| 1 | pg-master、pg-standby、pg-arbiter | 先 etcd,再 patroni | 三节点 etcd 可并行;patroni 建议主→备→仲裁 |
| 2 | redis-master | redis | 主节点先起 |
| 3 | redis-slave | redis | 从节点后起,便于连主复制 |
| 4 | ck-log-master、ck-log-backup | clickhouse-server | 两节点可并行 |
## 5.0.3 本机“栈”启停脚本(类似 compose up/down)
在每台服务器上放置**同一套脚本**,通过主机名自动识别节点类型,按上述顺序启停**本机**服务,实现“类似 docker-compose”的 `up`/`down` 体验。
- **脚本位置**:`deploy/oracle-linux/scripts/start-stack.sh`、`stop-stack.sh`
- **用法**:拷贝到目标节点(如 `/usr/local/bin/` 或 `/opt/db-stack/`),赋予执行权限后:
- 启动本机所有组件:`./start-stack.sh`
- 停止本机所有组件:`./stop-stack.sh`
脚本会根据 `hostname` 判断当前是 PG 主/备/仲裁、Redis 主/从、ClickHouse 节点1/2,仅操作本机对应服务,并按依赖顺序执行(如先 etcd 再 patroni)。
### 5.0.3.1 使用步骤
```bash
# 1. 将脚本拷贝到节点(以 /opt/db-stack 为例,7 个节点均需拷贝)
scp deploy/oracle-linux/scripts/start-stack.sh deploy/oracle-linux/scripts/stop-stack.sh root@pg-master:/opt/db-stack/
# 对其他 6 台重复或使用 ansible 批量分发
# 2. 赋予执行权限(各节点执行)
chmod +x /opt/db-stack/start-stack.sh /opt/db-stack/stop-stack.sh
# 3. 停机后统一启动本机组件(各节点执行)
/opt/db-stack/start-stack.sh
# 4. 需要停机时统一停止本机组件(各节点执行)
/opt/db-stack/stop-stack.sh
```
### 5.0.3.2 主机名与节点类型对应关系
脚本通过 `hostname` 识别类型,请与第 1 章主机名配置一致:
| hostname | 识别为 | 启动顺序 |
|----------|--------|----------|
| pg-master、pg-standby、pg-arbiter | PostgreSQL 节点 | etcd → patroni |
| redis-master、redis-slave | Redis 节点 | redis |
| ck-log-master、ck-log-backup | ClickHouse 节点 | clickhouse-server |
若主机名不同,可修改脚本内 `HOSTNAME=$(hostname -s)` 后的判断逻辑,或通过环境变量覆盖(见脚本内说明)。
## 5.0.4 全集群顺序启动(可选)
若希望从**一台跳板机**一次性按顺序拉起全集群,可编写脚本依次 SSH 到各节点执行 `start-stack.sh`。示例(需配置免密 ssh 或密码):
```bash
# 示例:按 5.0.2 顺序在跳板机上执行(需将下方 IP 改为实际 IP)
ORDER="pg-master pg-standby pg-arbiter redis-master redis-slave ck-log-master ck-log-backup"
for ip in $ORDER; do
ssh root@$ip "/opt/db-stack/start-stack.sh" && echo "OK $ip" || echo "FAIL $ip"
done
```
生产环境建议配合 Ansible 或现有运维平台,按 5.0.2 表格定义 play 顺序。
## 5.0.5 非正常结束进程后自启动(崩溃/杀进程后自动拉起)
进程被**异常终止**(如 kill -9、OOM、段错误、崩溃)后,由 systemd 的 **Restart=** 策略自动拉起,无需人工干预。
### 5.0.5.1 已配置 Restart 的服务
本手册中**自行创建**的 unit 已包含自动重启配置:
| 服务 | 配置 | 说明 |
|------|------|------|
| patroni | `Restart=always`、`RestartSec=5` | 见 2.5.1 节 patroni.service |
| redis | `Restart=always`、`RestartSec=5` | 见 3.2.4 节 redis.service |
即:Patroni、Redis 在非正常退出后约 5 秒会被 systemd 自动重新启动。
### 5.0.5.2 为 etcd 与 clickhouse-server 增加自动重启(推荐)
etcd 和 clickhouse-server 来自 YUM 包,默认 unit 可能未设置 `Restart=always`。建议用 **systemd drop-in** 统一加上,与 Patroni/Redis 行为一致。
**etcd(在 pg-master、pg-standby、pg-arbiter 三节点执行):**
```bash
mkdir -p /etc/systemd/system/etcd.service.d
# drop-in 仅追加 [Service] 片段,不修改原 unit;异常退出后自动重启
cat > /etc/systemd/system/etcd.service.d/restart.conf << 'EOF'
[Service]
Restart=always # 任意退出均重启
RestartSec=5 # 间隔 5 秒
EOF
systemctl daemon-reload
# 若需立即生效可重启: systemctl restart etcd
```
**clickhouse-server(在 ck-log-master、ck-log-backup 两节点执行):**
```bash
mkdir -p /etc/systemd/system/clickhouse-server.service.d
# drop-in:异常退出后自动重启
cat > /etc/systemd/system/clickhouse-server.service.d/restart.conf << 'EOF'
[Service]
Restart=always
RestartSec=5
EOF
systemctl daemon-reload
# 若需立即生效可重启: systemctl restart clickhouse-server
```
完成后,etcd、patroni、redis、clickhouse-server 在**非正常退出后均会在约 5 秒内被 systemd 自动拉起**。
### 5.0.5.3 验证自动重启
```bash
# 以 redis 为例:强杀进程后观察是否自动起来
systemctl status redis # 确认 running
kill -9 $(cat /var/run/redis/redis.pid) # 模拟异常退出
sleep 8
systemctl status redis # 应再次为 active (running)
```