使用Patroni和HAProxy创建高度可用的PostgreSQL集群

什么是PostgreSQL?

PostgreSQL(Postgres)是一个开源的,完全符合ACID标准的关系数据库,可在所有主要操作系统上运行。虽然Postgres是一个功能丰富且功能强大的数据库,但它没有内置的高可用性解决方案。

本教程介绍如何使用Patroni创建三个服务器的高可用性Postgres集群。

开始之前

更新您的系统:

sudo apt update && sudo apt upgrade

在您的帐户中创建五个服务器。记下每个服务器的IP地址

安装PostgreSQL

在您的设置中的三个服务器安装Postgres。由于本教程中的配置使用专用IP地址的服务器之间进行通信。

本教程中的例子分配三个Postgres的服务器的私有IP地址192.0.2.11192.0.2.12192.0.2.13

在要安装Postgres的三个服务器上,更新软件包列表:

  sudo apt update

安装Postgres:

  sudo apt install postgresql-9.5 -y

安装后,Postgres会自动作为服务运行。 停止Postgres服务,以便Patroni可以开始管理:

  sudo systemctl stop postgresql

Patroni使用与Postgres一起安装的实用程序,默认情况下位于/usr/lib/postgresql/9.5/bin目录。 在PATH中创建符号链接以确保Patroni可以找到实用程序:

  sudo ln -s /usr/lib/postgresql/9.5/bin/* /usr/sbin/

您可以在PATH中包含/usr/lib/postgresql/9.5/bin目录,而不是创建符号链接。

在三个服务器中的每一个上重复这些步骤。

安装Patroni

Patroni是一个管理Postgres配置的开源Python软件包。 它可以配置为处理复制,备份和恢复等任务。

在本教程中,您将使用Patroni:

  • 配置在同一服务器上运行的Postgres实例
  • 配置从主服务器到从服务器的复制
  • 在主站发生故障时自动故障转移到最佳从站。

安装pythonpip

  sudo apt install python python-pip -y

确保您拥有最新版本的setuptoolspython包:

  sudo pip install --upgrade setuptools

使用pip安装Patroni

  sudo pip install patroni

在三个服务器中的每一个上重复这些步骤。

安装etcd

Etcd是一个容错的分布式键值存储,用于存储Postgres集群的状态。通过Patroni,所有Postgres节点都使用etcd来保持Postgres群集的正常运行。

在本教程中,您将使用单服务器etcd群集。但是,在生产中,最好使用更大的etcd集群,以防一个etcd节点发生故障,它不会影响Postgres服务器。

在您想要安装etcd的服务器上,更新包列表:

  sudo apt update

安装etcd:

  sudo apt install etcd -y

本教程的其余部分使用192.0.2.21作为此服务器的专用IP地址。

安装HAProxy

在开发使用数据库的应用程序时,如果数据库端点不断变化,则跟踪数据库端点可能很麻烦。使用HAProxy通过提供可以连接应用程序的单个端点来简化此操作。

HAProxy将连接转发到当前为主节点的节点。 它使用Patroni提供的REST端点来完成此操作。 Patroni确保在任何给定时间只有主Postgres节点显示为在线,强制HAProxy连接到正确的节点。

在要安装HAProxy的服务器上,更新软件包列表:

  sudo apt update

安装HAProxy:

  sudo apt install haproxy -y

本教程使用192.0.2.31作为此服务器的专用IP地址,使用203.0.113.1作为其公共IP地址。

当前状态

在这个阶段,你应该总共有五个服务器:

私有IP地址示例

已安装软件

示例公共IP地址

192.0.2.11

Postgres,Patroni

192.0.2.12

Postgres,Patroni

192.0.2.13

Postgres,Patroni

192.0.2.21

ETCD

192.0.2.31

HAProxy

203.0.113.1

配置etcd

编辑/etc/default/etcd文件以添加以下配置:

/etc/default/etcd

ETCD_LISTEN_PEER_URLS="http://192.0.2.21:2380"

ETCD_LISTEN_CLIENT_URLS="http://localhost:2379,http://192.0.2.21:2379"

ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.0.2.21:2380"

ETCD_INITIAL_CLUSTER="etcd0=http://192.0.2.21:2380,"

ETCD_ADVERTISE_CLIENT_URLS="http://192.0.2.21:2379"

ETCD_INITIAL_CLUSTER_TOKEN="cluster1"

ETCD_INITIAL_CLUSTER_STATE="new"

保存文件,然后重启etcd服务:

  sudo systemctl restart etcd

配置Patroni

可以使用可放置在任何位置的YAML文件来配置Patroni。在本教程中,您将把此文件放在/etc/patroni.yml

在安装了Postgres和Patroni的所有三个服务器上创建一个patroni.yml文件(本指南中为192.0.2.11,192.0.2.12192.0.2.13)。 将name更改为唯一的名称,并将listenconnect_address(在postgresqlrestapi下)更改为每个服务器上的相应值。

编辑此文件以包含以下内容:

/etc/patroni.yml

scope: postgres
namespace: /db/
name: postgresql0

restapi:
    listen: 192.0.2.11:8008
    connect_address: 192.0.2.11:8008

etcd:
    host: 192.0.2.21:2379

bootstrap:
    dcs:
        ttl: 30
        loop_wait: 10
        retry_timeout: 10
        maximum_lag_on_failover: 1048576
        postgresql:
            use_pg_rewind: true

    initdb:
    - encoding: UTF8
    - data-checksums

    pg_hba:
    - host replication replicator 127.0.0.1/32 md5
    - host replication replicator 192.0.2.11/0 md5
    - host replication replicator 192.0.2.12/0 md5
    - host replication replicator 192.0.2.13/0 md5
    - host all all 0.0.0.0/0 md5

    users:
        admin:
            password: admin
            options:
                - createrole
                - createdb

postgresql:
    listen: 192.0.2.11:5432
    connect_address: 192.0.2.11:5432
    data_dir: /data/patroni
    pgpass: /tmp/pgpass
    authentication:
        replication:
            username: replicator
            password: rep-pass
        superuser:
            username: postgres
            password: secretpassword
    parameters:
        unix_socket_directories: '.'

tags:
    nofailover: false
    noloadbalance: false
    clonefrom: false
    nosync: false

记下data_dir上述文件中的值。postgres用户需要写入此目录的能力。如果此目录不存在,请创建它:

 sudo mkdir /data/patroni -p

使postgres成为/ data / patroni的所有者:

sudo chown postgres:postgres /data/patroni

更改此目录的权限,使其仅对postgres用户可访问:

sudo chmod 700 /data/patroni

上述文件中的每个选项都是可配置的。在Patroni的Github存储库中查看最新版本的postgres0.yml文件

创建一个systemd脚本,允许您启动,停止和监视Patroni。 在/etc/systemd/system/patroni.service上创建一个文件,其中包含以下内容:

etc/systemd/system/patroni.service

[Unit]
Description=Runners to orchestrate a high-availability PostgreSQL
After=syslog.target network.target

[Service]
Type=simple

User=postgres
Group=postgres

ExecStart=/usr/local/bin/patroni /etc/patroni.yml

KillMode=process

TimeoutSec=30

Restart=no

[Install]
WantedBy=multi-user.targ

如果patroni安装在您计算机上/ usr / local / bin / patroni以外的位置,请相应地更新上述文件。

启动Patroni和Postgres:

sudo systemctl start patroni

检查Patroni的状态:

sudo systemctl status patroni

如果一切设置正确,第一个节点的输出将类似于:

● patroni.service - Runners to orchestrate a high-availability PostgreSQL
Loaded: loaded (/etc/systemd/system/patroni.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2017-07-29 16:49:18 UTC; 8min ago
Main PID: 13097 (patroni)

.
.
.

... INFO: Lock owner: postgresql0; I am postgresql0
... INFO: no action.  i am the leader with the lock

启动后续节点时,日志将类似于:

INFO: no action.  i am a secondary and i am following a leader
Lock owner: postgresql0; I am postgresql2

在安装了Postgres的三个服务器中的每一个上重复这些步骤,以创建具有一个主服务器和两个从服务器的高可用性Postgres集群。

配置HAProxy

设置Postgres群集后,无论群集中的哪个服务器是主服务器,都需要一种连接到主服务器的方法。 这就是HAProxy的用武之地。所有Postgres客户端(您的应用程序,psql等)都将连接到HAProxy,这将确保您连接到群集中的主服务器。

在安装了HAProxy的服务器上,编辑/etc/haproxy/haproxy.cfg中的配置文件以包含以下内容:

/etc/haproxy/haproxy.cfg

global
    maxconn 100

defaults
    log global
    mode tcp
    retries 2
    timeout client 30m
    timeout connect 4s
    timeout server 30m
    timeout check 5s

listen stats
    mode http
    bind *:7000
    stats enable
    stats uri /

listen postgres
    bind *:5000
    option httpchk
    http-check expect status 200
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
    server postgresql_192.0.2.11_5432 192.0.2.11:5432 maxconn 100 check port 8008
    server postgresql_192.0.2.12_5432 192.0.2.12:5432 maxconn 100 check port 8008
    server postgresql_192.0.2.13_5432 192.0.2.13:5432 maxconn 100 check port 8008

此配置在公共URL上公开HAProxy统计信息。

重新启动HAProxy以使用新设置:

sudo systemctl restart haproxy

如果HAProxy无法启动,请检查语法错误:

/usr/sbin/haproxy -c -V -f /etc/haproxy/haproxy.cfg

测试设置

将Postgres客户端连接到端口5000上安装了HAProxy的服务器的公共IP地址(在本指南中为203.0.113.1)。

您还可以在端口7000上连接到HAProxy 服务器以查看HAProxy仪表板:

HAProxy仪表板 - 所有服务器都在运行

postgres部分中,postgresql_192.0.2.11_5432行以绿色突出显示。这表明192.0.2.11目前正在充当master。

如果您终止主服务器(使用sudo systemctl stop patroni或关闭服务器),仪表板将类似于:

HAProxy仪表板 - 主要故障时

postgres部分中,postgresql_192.0.2.11_5432行现在为红色,postgresql_192.0.2.13_5432行以绿色突出显示。这表明192.0.2.13目前正在充当master。

注意

在这种情况下,恰好第三个Postgres服务器被提升为master。 情况可能并非总是如此。 同样可能的是,第二服务器可以被提升为主服务器。

当您现在启动第一台服务器时,它将作为从属服务器重新加入群集并与主服务器同步。

您现在可以使用功能强大,高度可用的Postgres集群。

可能的后续步骤

虽然本教程中的设置应该会使Postgres部署具有高可用性,但您可以采取以下步骤进一步改进它:

  1. 使用更大的etcd群集来提高可用性。
  2. 使用PgBouncer池连接。
  3. 添加另一个HAProxy服务器并配置IP故障转移以创建高可用性HAProxy群集。

更多信息

有关此主题的其他信息,您可能需要参考以下资源:


参考文献:《Create a Highly Available PostgreSQL Cluster Using Patroni and HAProxy》

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏晓晨的专栏

ASP.NET Core 2.1 使用Docker运行

这里我们需要用到官方的镜像:microsoft/dotnet:2.1-aspnetcore-runtime

2582
来自专栏吴伟祥

Docker学习——Dockerfile 指令详解(五) 顶

我们已经介绍了 FROM (指定基础镜像) , RUN(执行命令) ,还提及了 COPY , ADD ,其实 Dockerfile 功能很强大,它提供了十多个指...

1443
来自专栏北京马哥教育

24条 Docker 建议

在TES GLOBAL,我们已经爱上Docker并从Docker的0.8版本开始就在生产环境中使用它。我们的很多开发者都参加了在DockerCon欧洲上的培训...

3794

将基于MicroProfile的Java应用程序部署到Bluemix

Eclipse MicroProfile是一个开源项目,用于优化Microservices框架的Java企业级开发,基于MicroProfile的应用程序可以被...

22710
来自专栏刺客博客

基于Docker制作H5ai+SSH+Aria2镜像(附带Dockerfile)

2793
来自专栏A周立SpringCloud

Docker系列教程07-Dockerfile指令详解

Dockerfile有十多个指令。本节我们来系统讲解这些指令,指令的一般格式为 指令名称参数。 ADD 复制文件 ADD指令用于复制文件,格式为: ADD<sr...

3917
来自专栏北京马哥教育

架构师分享 Docker 新手入门完全指南

下面的图片比较了 Docker 和传统虚拟化方式的不同之处,可见容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件层面实现。

1723
来自专栏吴伟祥

使用 Dockerfile定制Java Web镜像

对使用 Docker 搭建 Java Web 运行环境(利用 commit 理解镜像构成  来源:黄勇 )的博文的归纳:

1974
来自专栏晓晨的专栏

ASP.NET Core 2.1 使用Docker运行

2092
来自专栏python3

Docker安装

安装之前,我们首先确保自己的linux系统内核版本高于3.10,并且系统是64位,才能体验Docker。所以我用的是Centos7.3

3902

扫码关注云+社区

领取腾讯云代金券