使用Patroni、etcd、HAProxy建構高可用的PostgreSQL叢集

碰巧的是,在問題提出時,我沒有足夠的經驗來單獨開發和推出這個解決方案。 然後我開始谷歌搜尋。

我不知道問題是什麼,但我無數次面臨這樣的事實:即使我按照教程中的步驟一步一步完成所有操作,準備與作者相同的環境,但仍然沒有任何效果。 我不知道出了什麼問題,但是當我再次遇到這種情況時,我決定等一切順利後我會編寫自己的教學。 一款絕對有效的產品。

網路上的指南

恰好網路並不缺乏各種指南、教程、逐步教程等。 碰巧,我的任務是開發一個解決方案,以便方便地組織和構建故障轉移 PostgreSQL 集群,其主要要求是從主伺服器到所有副本的流式複製,以及在主伺服器發生時自動配置保留失敗。

在這個階段,所使用的技術堆疊已經確定:

  • PostgreSQL 作為 DBMS
  • 帕特羅尼 作為集群解決方案
  • etcd 作為 Patroni 的分散式存儲
  • HAproxy 用於使用資料庫組織應用程式的單一入口點

安裝

請注意 - 使用 Patroni、etcd、HAProxy 建立高度可用的 PostgreSQL 叢集。

所有操作均在安裝了 Debian 10 作業系統的虛擬機器上執行。

我不建議將 etcd 安裝在 patoni 和 postgresql 所在的同一台機器上,因為磁碟負載對於 etcd 非常重要。 但出於教育目的,我們會這樣做。
讓我們安裝etcd。

#!/bin/bash
apt-get update
apt-get install etcd

將內容新增至 /etc/default/etcd 文件

[成員]

ETCD_NAME=datanode1 # 你機器的主機名
ETCD_DATA_DIR=”/var/lib/etcd/default.etcd”

所有 IP 位址都應該有效。 清單節點、客戶端等應設定為主機的 IP 位址

ETCD_LISTEN_PEER_URLS="http://192.168.0.143:2380» # 您汽車的地址
ETCD_LISTEN_CLIENT_URLS="http://192.168.0.143:2379,http://127.0.0.1:2379» # 您汽車的地址

[簇]

ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.0.143:2380» # 您汽車的地址
ETCD_INITIAL_CLUSTER=»datanode1=http://192.168.0.143:2380,datanode2=http://192.168.0.144:2380,datanode3=http://192.168.0.145:2380» # etcd 叢集中所有機器的位址
ETCD_INITIAL_CLUSTER_STATE="新"
ETCD_INITIAL_CLUSTER_TOKEN =“etcd-cluster-1”
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.0.143:2379» # 您汽車的地址

運行命令

systemctl restart etcd

PostgreSQL 9.6 + 守護神

您需要做的第一件事是設定三個虛擬機器並在其上安裝必要的軟體。 安裝機器後,如果您遵循我的教程,您可以運行這個簡單的腳本,它將(幾乎)為您完成所有操作。 以 root 身分運行。

請注意,該腳本使用 PostgreSQL 版本 9.6,這是由於我們公司的內部要求。 該解決方案尚未在其他版本的 PostgreSQL 上進行測試。

#!/bin/bash
apt-get install gnupg -y
echo "deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main" >> /etc/apt/sources.list
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
apt-get update
apt-get install postgresql-9.6 python3-pip python3-dev libpq-dev -y
systemctl stop postgresql
pip3 install --upgrade pip
pip install psycopg2
pip install patroni[etcd]
echo "
[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
" > /etc/systemd/system/patroni.service
mkdir -p /data/patroni
chown postgres:postgres /data/patroni
chmod 700 /data/patroniпо
touch /etc/patroni.yml

接下來,在剛剛建立的 /etc/patroni.yml 檔案中,您需要放置以下內容,當然將所有地方的 IP 位址變更為您使用的位址。
請注意此 yaml 中的註釋。 將叢集中每台電腦上的位址變更為您自己的位址。

/etc/patroni.yml

scope: pgsql # должно быть одинаковым на всех нодах
namespace: /cluster/ # должно быть одинаковым на всех нодах
name: postgres1 # должно быть разным на всех нодах

restapi:
    listen: 192.168.0.143:8008 # адрес той ноды, в которой находится этот файл
    connect_address: 192.168.0.143:8008 # адрес той ноды, в которой находится этот файл

etcd:
    hosts: 192.168.0.143:2379,192.168.0.144:2379,192.168.0.145:2379 # перечислите здесь все ваши ноды, в случае если вы устанавливаете etcd на них же

# this section (bootstrap) will be written into Etcd:/<namespace>/<scope>/config after initializing new cluster
# and all other cluster members will use it as a `global configuration`
bootstrap:
    dcs:
        ttl: 100
        loop_wait: 10
        retry_timeout: 10
        maximum_lag_on_failover: 1048576
        postgresql:
            use_pg_rewind: true
            use_slots: true
            parameters:
                    wal_level: replica
                    hot_standby: "on"
                    wal_keep_segments: 5120
                    max_wal_senders: 5
                    max_replication_slots: 5
                    checkpoint_timeout: 30

    initdb:
    - encoding: UTF8
    - data-checksums
    - locale: en_US.UTF8
    # init pg_hba.conf должен содержать адреса ВСЕХ машин, используемых в кластере
    pg_hba:
    - host replication postgres ::1/128 md5
    - host replication postgres 127.0.0.1/8 md5
    - host replication postgres 192.168.0.143/24 md5
    - host replication postgres 192.168.0.144/24 md5
    - host replication postgres 192.168.0.145/24 md5
    - host all all 0.0.0.0/0 md5

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

postgresql:
    listen: 192.168.0.143:5432 # адрес той ноды, в которой находится этот файл
    connect_address: 192.168.0.143:5432 # адрес той ноды, в которой находится этот файл
    data_dir: /data/patroni # эту директорию создаст скрипт, описанный выше и установит нужные права
    bin_dir:  /usr/lib/postgresql/9.6/bin # укажите путь до вашей директории с postgresql
    pgpass: /tmp/pgpass
    authentication:
        replication:
            username: postgres
            password: postgres
        superuser:
            username: postgres
            password: postgres
    create_replica_methods:
        basebackup:
            checkpoint: 'fast'
    parameters:
        unix_socket_directories: '.'

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

該腳本必須在叢集的所有三台機器上執行,並且上述配置也必須放在所有機器上的 /etc/patroni.yml 檔案中。

在叢集中的所有機器上完成這些操作後,在其中任何機器上執行以下命令

systemctl start patroni
systemctl start postgresql

等待大約 30 秒,然後在叢集中的其餘電腦上執行此命令。

HA代理

我們使用出色的 HAproxy 來提供單點入口。 主伺服器將始終在部署 HAproxy 的電腦的位址上可用。

為了不讓有HAproxy的機器出現單點故障,我們將它啟動在Docker容器中;將來它可以啟動到K8的叢集中,使我們的故障轉移叢集更加可靠。

建立一個可以儲存兩個檔案的目錄 - Dockerfile 和 haproxy.cfg。 去吧。

Dockerfile

FROM ubuntu:latest

RUN apt-get update 
    && apt-get install -y haproxy rsyslog 
    && rm -rf /var/lib/apt/lists/*

RUN mkdir /run/haproxy

COPY haproxy.cfg /etc/haproxy/haproxy.cfg

CMD haproxy -f /etc/haproxy/haproxy.cfg && tail -F /var/log/haproxy.log

請注意,haproxy.cfg 檔案的最後三行應列出您的電腦的位址。 HAproxy 將聯絡 Patroni,在 HTTP 標頭中,主伺服器將始終傳回 200,而副本伺服器將始終傳回 503。

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 postgresql1 192.168.0.143:5432 maxconn 100 check port 8008
    server postgresql2 192.168.0.144:5432 maxconn 100 check port 8008
    server postgresql3 192.168.0.145:5432 maxconn 100 check port 8008

在我們的兩個檔案所在的目錄中,讓我們依次執行打包容器的命令,並透過轉發必要的連接埠來啟動它:

docker build -t my-haproxy .
docker run -d -p5000:5000 -p7000:7000 my-haproxy 

現在,透過在瀏覽器中使用 HAproxy 開啟電腦的位址並指定連接埠 7000,您將看到叢集的統計資料。

作為主伺服器的伺服器將處於 UP 狀態,而副本伺服器將處於 DOWN 狀態。 這是正常的,事實上它們是有效的,但它們之所以這樣顯示是因為它們對來自 HAproxy 的請求回傳 503。 這使我們始終能夠準確地知道三台伺服器中哪一台是目前的主伺服器。

結論

你太美了! 在短短 30 分鐘內,您就部署了一個具有串流複製和自動回退功能的優秀容錯高效能資料庫叢集。 如果您打算使用此解決方案,請查看 帶有 Patroni 官方文檔,特別是與 patonictl 實用程式相關的部分,它提供了管理叢集的便捷存取。

恭喜!

來源: www.habr.com

添加評論