Patroni、etcd、HAProxy を使用した高可用性 PostgreSQL クラスターの構築

たまたま、問題​​が提起された当時、私にはこのソリューションを一人で開発して立ち上げるのに十分な経験がありませんでした。 それから私はグーグルを始めました。

何が問題なのかは分かりませんが、チュートリアルに従ってすべてを段階的に実行し、作者と同じ環境を準備しても、何もうまくいかないという事実に何度も直面しました。 何が問題なのか全く分かりませんが、再びこの問題に遭遇したとき、すべてがうまくいったときに独自のチュートリアルを書こうと決心しました。 間違いなく活躍するXNUMX本。

インターネット上のガイド

たまたま、インターネットにはさまざまなガイド、チュートリアル、ステップバイステップなどの欠如がありません。 たまたま、フェイルオーバー PostgreSQL クラスターを簡単に編成および構築するためのソリューションを開発するというタスクが与えられました。その主な要件は、マスター サーバーからすべてのレプリカへのストリーミング レプリケーションと、障害発生時の予備の自動プロビジョニングでした。マスターサーバー障害。

この段階で、使用されるテクノロジーのスタックが決定されました。

  • DBMS としての PostgreSQL
  • パトローニ クラスタリングソリューションとして
  • Patroni の分散ストレージとしての etcd
  • データベースを使用してアプリケーションの単一のエントリ ポイントを整理するための HAproxy

インストール

注意してください - Patroni、etcd、HAProxy を使用して高可用性 PostgreSQL クラスターを構築します。

すべての操作は、Debian 10 OS がインストールされた仮想マシン上で実行されました。

etcd

etcd ではディスク負荷が非常に重要であるため、patroni と 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 + パトローニ

最初に行う必要があるのは、XNUMX つの仮想マシンをセットアップして、必要なソフトウェアをインストールすることです。 マシンをインストールした後、私のチュートリアルに従えば、(ほぼ) すべてを行ってくれるこの単純なスクリプトを実行できます。 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

スクリプトはクラスターの XNUMX 台のマシンすべてで実行する必要があり、上記の構成もすべてのマシンの /etc/patroni.yml ファイルに配置する必要があります。

クラスター内のすべてのマシンでこれらの操作を完了したら、いずれかのマシンで次のコマンドを実行します。

systemctl start patroni
systemctl start postgresql

約 30 秒待ってから、クラスター内の残りのマシンでこのコマンドを実行します。

HAプロキシ

私たちは素晴らしい HAproxy を使用して単一のエントリ ポイントを提供します。 マスター サーバーは、HAproxy がデプロイされているマシンのアドレスで常に使用できます。

HAproxy を備えたマシンが単一障害点にならないように、Docker コンテナ内でマシンを起動します。将来的には、K8 のクラスタ内で起動して、フェールオーバー クラスタの信頼性をさらに高めることができます。

Dockerfile と haproxy.cfg という XNUMX つのファイルを保存できるディレクトリを作成します。 行ってください。

ドッカーファイル

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 ファイルの最後の 200 行にはマシンのアドレスがリストされていることに注意してください。 HAproxy は Patroni に接続します。HTTP ヘッダーでは、マスター サーバーは常に 503 を返し、レプリカは常に XNUMX を返します。

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 を返すため、このように表示されます。 これにより、XNUMX つのサーバーのうちどれが現在のマスターであるかを常に正確に知ることができます。

まとめ

あなたは素晴らしいです! わずか 30 分で、ストリーミング レプリケーションと自動フォールバックを備えた、優れたフォールト トレラントで高パフォーマンスのデータベース クラスターをデプロイできました。 このソリューションの使用を計画している場合は、次を確認してください。 パトローニの公式ドキュメント付き特に、クラスター管理への便利なアクセスを提供する patronictl ユーティリティに関する部分です。

おめでとう!

出所: habr.com

コメントを追加します