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

只是恰巧在設定這個任務的時候,我沒有足夠的經驗來獨自開發和推出這個解決方案。然後我開始用谷歌搜尋。

我不知道問題是什麼,但我再次發現這樣一個事實:即使我按照教程一步一步地完成所有操作,準備與作者相同的環境,但什麼也不起作用。我不知道問題是什麼,但是當我再次遇到這個問題時,我決定 - 當一切順利時,我會編寫自己的教程。絕對有效的方法。

網路上的指南

碰巧的是,網路並不缺少各種指南、教程、逐步指南和類似的東西。碰巧的是,我的任務是開發一種解決方案,用於方便地組織和構建一個容錯的 PostgreSQL 集群,其主要要求是從主伺服器到所有副本的流式複製,以及在主伺服器發生故障時自動引入備用伺服器。

在此階段,確定了所使用的技術堆疊:

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

安裝

我們向您展示使用 Patroni、etcd、HAProxy 建立高可用性 PostgreSQL 叢集。

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

我不建議在 patroni 和 postgresql 所在的同一台機器上安裝 etcd,因為磁碟負載對於 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=»資料節點1=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 + patron

您需要做的第一件事是設定三個虛擬機器並在其上安裝必要的軟體。安裝機器後,如果您遵循我的教程,您可以運行這個簡單的腳本,它(幾乎)可以為您完成所有事情。在 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設定檔

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 文檔,尤其是其中涉及 patronictl 實用程式的部分,它提供了方便的存取方式來管理您的叢集。

恭喜!

來源: www.habr.com

為具有 DDoS 保護、VPS VDS 服務器的站點購買可靠的主機 🔥 購買具備 DDoS 防護的可靠網站寄存服務,包括 VPS 和 VDS 伺服器 | ProHoster