当前位置: 首页 > news >正文

PGSQL + patroni + timescaledb 集群搭建

PGSQL + patroni + timescaledb 集群搭建

三台主机(192.168.1.169 / 192.168.1.188 / 192.168.1.189) 的全部配置文件都生成好了,基于你指定的镜像 timescale/timescaledb:2.15.3-pg16,每个容器都使用 network_mode: host 并挂载 /etc/localtime:/etc/localtime:ro

下面直接给出每台主机需要的文件内容与启动步骤(你可以直接 scp 或复制到相应主机对应路径并执行)。

安全提示:示例中使用的数据库密码 superpass / replication 密码 replpass 为演示用,请在部署前改为你自己的强密码并避免把明文提交到版本库。


目录与前置操作(每台主机都做)

在三台主机上统一创建目录并设置权限(以 root 或有 sudo 的用户执行):

mkdir -p /opt/timescaledb/{data,config}
chown -R $(id -u):$(id -g) /opt/timescaledb

我们将在 /opt/timescaledb/config 放配置文件,数据目录放 /opt/timescaledb/data


构建基础镜像

pgsql官方镜像没有patroni与timescaledb,需要重新构建进行集成

dockerfile如下:

# 基础镜像
FROM postgres:16LABEL maintainer="Lang <dev@example.com>" \description="PostgreSQL 16 + TimescaleDB + Patroni"USER root# 安装构建依赖、TimescaleDB 编译依赖、Python 和 Patroni
RUN apt-get update && apt-get install -y \build-essential cmake git libssl-dev libperl-dev libreadline-dev \python3 python3-pip python3-venv libpq-dev curl wget gcc postgresql-server-dev-16 \&& rm -rf /var/lib/apt/lists/*
# TimescaleDB 版本
ENV TIMESCALEDB_VERSION=2.15.3# 下载并编译 TimescaleDB
COPY timescaledb /tmp/timescaledb
RUN cd /tmp/timescaledb \&& cd /tmp/timescaledb \&& ./bootstrap \&& cd build && make install \&& rm -rf /tmp/timescaledb# 安装 Patroni
#RUN pip3 install --no-cache-dir --break-system-packages "patroni[etcd3]==3.3.0" psycopg>=3.1
RUN python3 -m venv /opt/venv \&& /opt/venv/bin/pip install --upgrade pip \&& /opt/venv/bin/pip install --no-cache-dir "patroni[etcd3]==3.3.0" psycopg>=3.1# 更新 PATH
ENV PATH="/opt/venv/bin:$PATH"# TimescaleDB 自动加载
RUN echo "shared_preload_libraries = 'timescaledb'" >> /usr/share/postgresql/postgresql.conf.sample# 暴露端口
EXPOSE 5432 8008# 切换回 postgres 用户
USER postgres# 启动 Patroni
ENTRYPOINT ["patroni"]
CMD ["/config/patroni.yml"]

clone timescaledb

git clone --branch 2.15.3 https://github.com/timescale/timescaledb.git

构建镜像

docker build --no-cache -t timescaledb-patroni:16 .

1) node1 — 主机 192.168.1.169

/opt/timescaledb/config/etcd.env (node1)

由于本文中的patroni 连接etcd使用的api接口为V2,etcd3默认关闭v2接口,需要单独开启

ETCD_NAME=node1
ETCD_INITIAL_ADVERTISE_PEER_URLS=http://192.168.1.169:2380
ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379
ETCD_ADVERTISE_CLIENT_URLS=http://192.168.1.169:2379
ETCD_INITIAL_CLUSTER=node1=http://192.168.1.169:2380,node2=http://192.168.1.188:2380,node3=http://192.168.1.189:2380
ETCD_INITIAL_CLUSTER_STATE=new
ETCD_INITIAL_CLUSTER_TOKEN=tsdb-cluster
ALLOW_NONE_AUTHENTICATION=yes
ETCD_ENABLE_V2=true  # 开启v2接口

/opt/timescaledb/config/patroni.yml (node1)

scope: tsdb
namespace: /service/
name: node1restapi:listen: 0.0.0.0:8008connect_address: 192.168.1.169:8008etcd:hosts:- 192.168.1.169:2379- 192.168.1.188:2379- 192.168.1.189:2379bootstrap:dcs:ttl: 30loop_wait: 10retry_timeout: 10maximum_lag_on_failover: 1048576postgresql:use_pg_rewind: truepg_hba:# 本地访问- local   all             all                                   trust- host    all             all             127.0.0.1/32          trust- host    all             all             ::1/128               trust# 允许本地 replication 连接(非常关键)- host    replication     replicator      127.0.0.1/32          trust# 集群内复制 (根据你集群 IP 段修改)- host    replication     replicator      192.168.1.0/24        md5- host    all             root            192.168.1.0/24        md5- host    all             all             192.168.1.0/24        md5parameters:shared_buffers: "256MB"max_connections: 200wal_level: replicahot_standby: "on"logging_collector: "on"log_directory: "/var/lib/postgresql/data/log"log_filename: "postgresql.log"initdb:- encoding: UTF8- data-checksumsusers:admin:password: superpassoptions:- createrole- createdbpostgresql:listen: 0.0.0.0:5432connect_address: 192.168.1.169:5432data_dir: /var/lib/postgresql/databin_dir: /usr/lib/postgresql/16/binauthentication:superuser:username: rootpassword: superpassreplication:username: replicatorpassword: replpass

/opt/timescaledb/config/haproxy.cfg (放 node1)

globalmaxconn 200defaultslog globalmode tcpretries 2timeout connect 5stimeout client  1mtimeout server  1moption tcp-checklisten statsbind *:7000mode httpstats enablestats uri /frontend write_frontbind *:5000default_backend write_backbackend write_backoption httpchk GET /masterhttp-check expect status 200server node1 192.168.1.169:5432 check port 8008server node2 192.168.1.188:5432 check port 8008server node3 192.168.1.189:5432 check port 8008frontend read_frontbind *:5001default_backend read_backbackend read_backoption httpchk GET /replicahttp-check expect status 200server node1 192.168.1.169:5432 check port 8008server node2 192.168.1.188:5432 check port 8008server node3 192.168.1.189:5432 check port 8008

/opt/timescaledb/docker-compose.yml (node1)

version: '3.8'services:etcd:image: quay.io/coreos/etcd:v3.5.12env_file: ./config/etcd.envvolumes:- ./data/etcd:/etcd-data- /etc/localtime:/etc/localtimenetwork_mode: hostrestart: alwayspg-node1:build: .image: timescaledb-patroni:16container_name: pg-node1volumes:- ./data/postgres:/var/lib/postgresql/data- ./config/patroni.yml:/config/patroni.yml:ro- /etc/localtime:/etc/localtimenetwork_mode: hostrestart: alwaysenvironment:PATRONI_LOG_LEVEL: INFOdepends_on:- etcdhaproxy:image: haproxy:2.8volumes:- ./config/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro- /etc/localtime:/etc/localtimenetwork_mode: hostrestart: always

2) node2 — 主机 192.168.1.188

/opt/timescaledb/config/etcd.env (node2)

ETCD_NAME=node2
ETCD_INITIAL_ADVERTISE_PEER_URLS=http://192.168.1.188:2380
ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379
ETCD_ADVERTISE_CLIENT_URLS=http://192.168.1.188:2379
ETCD_INITIAL_CLUSTER=node1=http://192.168.1.169:2380,node2=http://192.168.1.188:2380,node3=http://192.168.1.189:2380
ETCD_INITIAL_CLUSTER_STATE=new
ETCD_INITIAL_CLUSTER_TOKEN=tsdb-cluster
ALLOW_NONE_AUTHENTICATION=yes
ETCD_ENABLE_V2=true

/opt/timescaledb/config/patroni.yml (node2)

scope: tsdb
namespace: /service/
name: node2restapi:listen: 0.0.0.0:8008connect_address: 192.168.1.188:8008etcd:hosts:- 192.168.1.169:2379- 192.168.1.188:2379- 192.168.1.189:2379bootstrap:dcs:ttl: 30loop_wait: 10retry_timeout: 10maximum_lag_on_failover: 1048576postgresql:use_pg_rewind: truepg_hba:# 本地访问- local   all             all                                   trust- host    all             all             127.0.0.1/32          trust- host    all             all             ::1/128               trust# 允许本地 replication 连接(非常关键)- host    replication     replicator      127.0.0.1/32          trust# 集群内复制 (根据你集群 IP 段修改)- host    replication     replicator      192.168.1.0/24        md5- host    all             root            192.168.1.0/24        md5- host    all             all             192.168.1.0/24        md5parameters:shared_buffers: "256MB"max_connections: 200wal_level: replicahot_standby: "on"logging_collector: "on"log_directory: "/var/lib/postgresql/data/log"log_filename: "postgresql.log"initdb:- encoding: UTF8- data-checksumsusers:admin:password: jiuqi@2020options:- createrole- createdbpostgresql:listen: 0.0.0.0:5432connect_address: 192.168.1.188:5432data_dir: /var/lib/postgresql/databin_dir: /usr/lib/postgresql/16/binauthentication:superuser:username: rootpassword: jiuqi@2020replication:username: replicatorpassword: replpass

/opt/timescaledb/docker-compose.yml (node2)

version: '3.8'services:etcd:image: quay.io/coreos/etcd:v3.5.12env_file: ./config/etcd.envvolumes:- /etc/localtime:/etc/localtime- ./data/etcd:/etcd-datanetwork_mode: hostrestart: alwayspg-node2:  image: timescaledb-patroni:16container_name: pg-node2   # node03 改为 pg-node3volumes:- ./data/postgres:/var/lib/postgresql/data- ./config/patroni.yml:/config/patroni.yml:ro- /etc/localtime:/etc/localtimenetwork_mode: hostrestart: alwaysenvironment:PATRONI_LOG_LEVEL: INFOdepends_on:- etcd

3) node3 — 主机 192.168.1.189

/opt/timescaledb/config/etcd.env (node3)

ETCD_NAME=node3
ETCD_INITIAL_ADVERTISE_PEER_URLS=http://192.168.1.189:2380
ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379
ETCD_ADVERTISE_CLIENT_URLS=http://192.168.1.189:2379
ETCD_INITIAL_CLUSTER=node1=http://192.168.1.169:2380,node2=http://192.168.1.188:2380,node3=http://192.168.1.189:2380
ETCD_INITIAL_CLUSTER_STATE=new
ETCD_INITIAL_CLUSTER_TOKEN=tsdb-cluster
ALLOW_NONE_AUTHENTICATION=yes
ETCD_ENABLE_V2=true

/opt/timescaledb/config/patroni.yml (node3)

scope: tsdb
namespace: /service/
name: node3restapi:listen: 0.0.0.0:8008connect_address: 192.168.1.189:8008etcd:hosts:- 192.168.1.169:2379- 192.168.1.188:2379- 192.168.1.189:2379bootstrap:dcs:ttl: 30loop_wait: 10retry_timeout: 10maximum_lag_on_failover: 1048576postgresql:use_pg_rewind: truepg_hba:# 本地访问- local   all             all                                   trust- host    all             all             127.0.0.1/32          trust- host    all             all             ::1/128               trust# 允许本地 replication 连接(非常关键)- host    replication     replicator      127.0.0.1/32          trust# 集群内复制 (根据你集群 IP 段修改)- host    replication     replicator      192.168.1.0/24        md5- host    all             root            192.168.1.0/24        md5- host    all             all             192.168.1.0/24        md5parameters:shared_buffers: "256MB"max_connections: 200wal_level: replicahot_standby: "on"logging_collector: "on"log_directory: "/var/lib/postgresql/data/log"log_filename: "postgresql.log"initdb:- encoding: UTF8- data-checksumsusers:admin:password: jiuqi@2020options:- createrole- createdbpostgresql:listen: 0.0.0.0:5432connect_address: 192.168.1.189:5432data_dir: /var/lib/postgresql/databin_dir: /usr/lib/postgresql/16/binauthentication:superuser:username: rootpassword: jiuqi@2020replication:username: replicatorpassword: replpass

/opt/timescaledb/docker-compose.yml (node3)

version: '3.8'services:etcd:image: quay.io/coreos/etcd:v3.5.12env_file: ./config/etcd.envvolumes:- ./data/etcd:/etcd-data- /etc/localtime:/etc/localtimenetwork_mode: hostrestart: alwayspg-node3:   # node03 改为 pg-node3image: timescaledb-patroni:16container_name: pg-node3   # node03 改为 pg-node3volumes:- /etc/localtime:/etc/localtime- ./data/postgres:/var/lib/postgresql/data- ./config/patroni.yml:/config/patroni.yml:ronetwork_mode: hostrestart: alwaysenvironment:PATRONI_LOG_LEVEL: INFOdepends_on:- etcd

启动步骤(按顺序在三台上执行)

  1. 在每台主机上分别把对应的 etcd.envpatroni.ymldocker-compose.yml 放入 /opt/timescaledb/config/opt/timescaledb(见上文)。
  2. 在每台主机创建数据目录并调整权限:
mkdir -p /opt/timescaledb/data/postgres /opt/timescaledb/data/etcd
chown -R 999:999 /opt/timescaledb/data/postgres || true

999 是容器中常见 postgres uid,若不确定可跳过 chown,或根据镜像实际 uid 设置)

  1. 先启动三台的 etcd(在每台运行):
cd /opt/timescaledb
docker compose up -d etcd
  1. 等 etcd 集群就绪(在任意一台执行):
# 如果 etcdctl 在容器内可用,可进入容器检查;简单 HTTP 检查:
curl http://192.168.1.169:2379/v2/members || true
# 或查看容器日志
docker logs -f etcd
  1. 启动 Patroni(在每台执行):
docker compose up -d pg-node1 #pg-node2 pg-node3
  1. 在 node1 启动 HAProxy(可只在 node1):
docker compose up -d haproxy

验证 & 常用命令

  • 查看 Patroni REST 状态(每台):
curl http://192.168.1.169:8008
curl http://192.168.1.188:8008
curl http://192.168.1.189:8008
# 返回 JSON 中的 "role" 字段显示 leader/replica
  • 在 leader 上启用 TimescaleDB 扩展(通过 HAProxy 写端口或直接 leader host):
psql -h 192.168.1.169 -p 5000 -U postgres -d postgres
# 然后:
CREATE EXTENSION IF NOT EXISTS timescaledb;
  • 用 HAProxy 写端口连接(会路由到当前 leader):
psql -h 192.168.1.169 -p 5000 -U postgres -d postgres
  • 强制切换测试(在当前 leader 主机执行):
# find which node is leader via curl -> then stop patroni on that node:
docker stop patroni
# 等待另一台成为 leader(检查 REST role)
  • 查看复制状态(在 leader psql):
SELECT client_addr, state, sync_state, sent_lsn, write_lsn, flush_lsn, replay_lsn FROM pg_stat_replication;

注意事项与建议(简要)

  • 更换默认密码:把 superpass / replpass 改为强密码,或使用 secrets 管理。
  • 防火墙:确保三台允许互通端口:2379、2380、5432、8008、5000、5001、7000(若 haproxy 在别处则开放相应端口)。
  • 时间同步:宿主机启用 chrony/ntpd,已挂载 /etc/localtime 保证容器时区一致。
  • etcd TLS(可选):生产建议为 etcd 开启 TLS,避免明文传输。
  • 备份:制定 WAL + basebackup 备份方案(pg_basebackup / pgBackRest)。
  • 连接池:在高并发场景下,建议在 HAProxy 前放置 PgBouncer 作为连接池。
http://www.hskmm.com/?act=detail&tid=28018

相关文章:

  • 随着种植精细化需求提升,草莓滴灌管、圆柱式滴灌管及 PVC 滴灌管成为节水灌溉核心装备,盘点五家实力厂家的特色产品
  • 2025 年最新推荐 OCR 图片识别软件厂商榜单:全面解析文字识别与格式转换服务商技术实力及服务能力ocr图片转excel/ocr图片转word厂商推荐
  • 2025 年高纯硼酸生产厂家最新推荐榜单:覆盖多领域优选,助力企业精准找高性能产品制造商核级/半导体/医用/电子/颗粒高纯硼酸厂家推荐
  • 计数集锦2
  • app.Environment.IsDevelopment()了解
  • 2025 年最新注浆管生产厂家综合实力排行榜:聚焦高精度与国企合作案例的优质厂家推荐管棚管/地质/边坡支护/袖阀/锚杆/岩心注浆管厂家推荐
  • 微算法科技(NASDAQ:MLGO)基于任务迁移的弹性框架重塑动态扩缩容,赋能边缘智能计算
  • 从小时级到分钟级:多点DMALL如何用Apache SeaTunnel把数据集成成本砍到1/3?
  • 2025 最新隔音棉生产厂家口碑推荐榜:甄选实力与品质兼具的品牌,含西南 / 昆明高性价比厂商最新推荐防火墙/内衬/鸡蛋/聚酯纤维/装修/吊顶隔音棉厂家推荐
  • 2025 升降杆厂家TOP 榜:梁山信达恒泰,专注多领域设备供应,气动型升降杆源头厂家推荐!
  • Playwright MCP 与 Claude 的完美协作:打造网页操作智能体
  • 2025 年高强钢板厂家最新推荐排行榜:聚焦国内优质企业,涵盖多型号产品,助力工业采购精准选型Q550D/合金/HG785D/ Q690D/S960QL/700L高强钢板厂家推荐
  • 2025 年最新推荐耐磨钢板生产厂家排行榜:涵盖高锰 / 堆焊 / 双金属 / NM 系列及无磁类型,解决采购难题助力企业选高性价比品牌
  • 高纯气体管道工程安装公司厂家推荐/管道施工队哪家好?
  • 找ant组件库对应样式
  • 指针
  • 达芬奇中文入门到精通视频教程DaVinci Resolve常用快捷键
  • 2025 年最新推荐!涵盖系统智能断桥窄边等多类型铝门窗厂家榜单,优秀生产厂家实力盘点智能/断桥/窄边/定制/全景/阳光房/隐框铝门窗厂家推荐
  • 读书笔记:**Oracle 中的数字类型:怎么选?怎么用?**
  • 什么是Symbol?
  • 2025 年门窗厂家推荐排行榜,新标门窗从型材到成品实现全链新标造铝合金门窗 / 系统门窗推荐这十家公司
  • PyCharm 2025.1重磅升级:AI驱动开发+全功能免费核心,Python开发者必看
  • Oracle案例:SOLARIS RAC平台模拟节点crash后强制删除与增加
  • 学习笔记——计算机程序设计
  • CAD文件处理控件Aspose.CAD教程:在 Python 中将 SVG 转换为 PDF
  • 电子打气泵方案(工作原理和组成以及功能参数)
  • 2025 年电源滤波器源头厂家最新推荐排行榜:精选优质国内品牌,覆盖单相 / 三相 / 直流等多类型产品直流/IEC插座式/定制化电源滤波器厂家推荐
  • (六)重构的艺术:简化困难条件逻辑的秘诀
  • 2025 年压力表厂家最新推荐排行榜重磅发布!聚焦耐腐蚀耐震性能,助力企业精准选优质产品数显/耐高温/数字/抗震/膜盒/隔膜压力表厂家推荐
  • 故障诊断:奇怪的ORA-01000故障处理