Step 7 - Configure proxies
==========================

プロキシの構成
--------------

PGDは、プロキシを使用して、クラスターによって自動的に選択されるクラスターのノードのいずれかにトラフィックを転送できます。プロキシを使用するパフォーマンスと可用性の理由があります。

-  パフォーマンス
   すべてのトラフィック特に書き込みトラフィックを1つのノードに転送することにより、ノードは書き込み競合をローカルかつより効率的に解決できます。

-  可用性
   ノードがメンテナンスのためにダウンするか、他の理由でオフラインになると、プロキシは新しいトラフィックを、選択した新しい書き込みリーダーに転送できます。

クラスターのPGDプロキシを構成して、この動作を有効にすることをお勧めします。

プロキシのクラスターを構成する
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

プロキシを設定するには、最初にプロキシが動作するクラスターとサブグループを次の方法で準備する必要があります。

-  ログインし、サブグループの\ ``enable_raft``
   および\ ``enable_proxy_routing`` ノードグループオプションを\ ``true``
   に設定します。
   :ref:`bdr.alter_node_group_option <bdr.alter_node_group_option>` を使用し、サブグループ名、オプション名、および新しい値をパラメーターとして渡します。

-  :ref:`bdr.create_proxy <bdr.create_proxy>` を使用して、新しいプロキシ名とそれに接続するサブグループを渡す、展開する予定の数だけ一意の名前付けプロキシを作成します。
   :ref:`bdr.create_proxy <bdr.create_proxy>` は、プロキシを作成しませんが、プロキシがクラスターに自分自身を登録するためのスペースを作成します。このスペースには、後で変更できる構成値が含まれています。最初は、\ ``listen_address``
   を\ ``0.0.0.0``
   に設定するなど、デフォルトのプロキシオプションで構成されます。

-  サブグループ内の各ノードのroute_dsnを設定することにより、各ノードへのプロキシルートを構成します。
   Route_dsnは、プロキシがそのノードに接続するために使用する接続文字列です。
   :ref:`bdr.alter_node_option <bdr.alter_node_option>` を使用して、サブグループ内の各ノードのroute_dsnを設定します。

-  パスワードまたはその他の認証を使用して、クラスターにpgdproxyユーザーを作成します。

各ホストをプロキシとして構成する
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

クラスターの準備ができたら、pgd-proxyを実行するように各ホストを構成する必要があります。

-  pgdproxyローカルユーザーを作成します。

-  そのユーザーの\ ``.pgpass``
   ファイルを作成して、ユーザーがpgdproxyとしてクラスターにログインできるようにします。

-  pgdproxyユーザーを使用するようにpgdproxyのsystemdサービスファイルを変更します。

-  サブグループ内のすべてのノードの接続文字列をリストするホストのプロキシ構成ファイルを作成し、\ ``listen_address``
   や\ ``listen_port``
   などのプロキシオプションを取得するときに使用するプロキシの名前を指定します。

-  そのファイルを\ ``/etc/edb/pgd-proxy/pgd-proxy-config.yml``
   としてインストールします。

-  systemdサービスを再起動し、そのステータスを確認します。

-  プロキシにログインし、そのオペレーションを確認します。

これらすべての手順の詳細については、作業例に含まれています。

実際の例
--------

プロキシの準備
--------------

プロキシが機能するには、\ ``dc1``
サブグループがRaftとルーティングを有効にする必要があります。

psqlを使用して、enterprisedbユーザーとして\ ``bdrdb``
データベースに接続し、クラスター内の任意のノードにログインします。実行します

.. code:: sql

   SELECT bdr.alter_node_group_option(dc1, enable_raft, true);
   SELECT bdr.alter_node_group_option(dc1, enable_proxy_routing, true);

 :ref:`bdr.node_group_summary <bdr.node_group_summary>` ビューを使用して、以前に\ ``bdr.alter_node_group_option()``
で設定したオプションのステータスを確認できます。

.. code:: sql

   SELECT node_group_name, enable_proxy_routing, enable_raft
               FROM bdr.node_group_summary
              WHERE parent_group_name IS NOT NULL;
   __OUTPUT__
    node_group_name | enable_proxy_routing | enable_raft
   - ----------------+----------------------+-------------
    dc1             | t                    | t
   (1 row)

   bdrdb=#

次に、 ``bdr.create_proxy``
ファンクションを使用して、クラスター内にPGDプロキシを作成します。このファンクションは、プロキシの一意の名前とプロキシにするグループの2つのパラメーターを取ります。

この例では、\ ``dc1`` サブグループの各ホストにプロキシが必要です。

::

   SELECT bdr.create_proxy(pgd-proxy-one,dc1);
   SELECT bdr.create_proxy(pgd-proxy-two,dc1);
   SELECT bdr.create_proxy(pgd-proxy-three,dc1);

 :ref:`bdr.proxy_config_summary <bdr.proxy_config_summary>` ビューを使用して、プロキシが作成されたことを確認できます。

.. code:: sql

   SELECT proxy_name, node_group_name
                FROM bdr.proxy_config_summary;
   __OUTPUT__
      proxy_name    | node_group_name
   - ----------------+-----------------
    pgd-proxy-one   | dc1
    pgd-proxy-two   | dc1
    pgd-proxy-three | dc1

    bdrdb=#
   ``` ## データベースにpgdproxyユーザーを作成します

   pgdproxyという名前のユーザーを作成し、パスワードを設定します。この例では、 `proxysecret` を使用します。

   任意のノードで、enterprisedb/postgresとして`bdrdb` データベースにログインします。

CREATE USER pgdproxy PASSWORD proxysecret; GRANT bdr_superuser TO
pgdproxy;

::


   ##  各ノードへのプロキシルートを構成する

   プロキシが接続すると、クラスターからdsn値接続文字列を取得します。クラスターは、プロキシがサブグループ内の各ノードに使用する接続の詳細を知る必要があります。これは、各ノードの`route_dsn` オプションを、プロキシがそのノードへの接続に使用できる接続文字列に設定することにより実行されます。

   プロキシは起動時に、プロキシの構成ファイルから初期dsnを取得することに注意してください。この手順と構成ファイルで設定されたroute_dsn値は、一致する必要があります。

   任意のノードで、enterprisedb/postgresとしてbdrdbデータベースにログインします。

   ```sql
   SELECT bdr.alter_node_option(host-one, route_dsn, host=host-one dbname=bdrdb port=5444 user=pgdproxy);
   SELECT bdr.alter_node_option(host-two, route_dsn, host=host-two dbname=bdrdb port=5444 user=pgdproxy);
   SELECT bdr.alter_node_option(host-three, route_dsn, host=host-three dbname=bdrdb port=5444 user=pgdproxy);

この例のエンドポイントは\ ``port=5444``
を指定していることに注意してください。これはEDB Postgres Advanced
Serverインスタンスに必要です。 EDB Postgres
ExtendedおよびコミュニティPostgreSQLの場合、これを省略できます。

各ホストでpgdproxyユーザーを作成する
------------------------------------

.. code:: shell

   sudo adduser pgdproxy

このユーザーは、サーバーに接続するために資格情報が必要です。
``proxysecret`` パスワードを使用して\ ``.pgpass``
ファイルを作成します。次に、 ``.pgpass``
ファイルをロックダウンして、所有者のみがアクセスできるようにします。

.. code:: shell

   echo -e " *:* :*:pgdproxy:proxysecret" | sudo tee /home/pgdproxy/.pgpass
   sudo chown pgdproxy /home/pgdproxy/.pgpass
   sudo chmod 0600 /home/pgdproxy/.pgpass

各ホストでsystemdサービスを構成する
-----------------------------------

サービスファイルをrootの使用からpgdproxyユーザーの使用に切り替えます。

.. code:: shell

   sudo sed -i s/root/pgdproxy/ /usr/lib/systemd/system/pgd-proxy.service

systemdデーモンをリロードします。

.. code:: shell

   sudo systemctl daemon-reload

ホストごとにプロキシ構成ファイルを作成します
--------------------------------------------

プロキシ構成ファイルは、ホストごとに少し異なります。これは、クラスターオブジェクトを含むYAMLファイルです。クラスターオブジェクトには、3つのプロパティがあります。

-  PGDクラスターのトップレベルグループの名前\ ``name`` として

-  データベースのエンドポイントの配列\ ``endpoints`` として

-  名前とエンドポイントを持つプロキシ定義オブジェクト ``proxy`` として

最初の2つのプロパティはすべてのホストで同じです。

::

   cluster:
     name: pgd
     endpoints:
       - "host=host-one dbname=bdrdb port=5444 user=pgdproxy"
       - "host=host-two dbname=bdrdb port=5444 user=pgdproxy"
       - "host=host-three dbname=bdrdb port=5444 user=pgdproxy"

host-one、host-two、およびhost-threeは、クラスターノードnode-one、node-two、node-threeが実行されているシステムであることに注意してください。エンドポイント接続には、ノードではなくホストの名前を使用します。

再度、この例のエンドポイントは\ ``port=5444``
を指定していることに注意してください。これはEDB Postgres Advanced
Serverインスタンスに必要です。 EDB Postgres
ExtendedおよびコミュニティPostgreSQLの場合、これを\ ``port=5432``
に設定できます。

3番目のプロパティ\ ``proxy`` には、 ``name`` プロパティがあります。
``name`` プロパティは、先ほどの\ ``bdr.create_proxy``
で作成した名前であり、ホストごとに異なります。プロキシはPostgresサーバーと同じポートに存在することはできません。理想的には、ホストでPostgresサーバーが実行されていない場合でも、直接接続とは異なる一般的に使用されるポートにある必要があります。通常、PGDプロキシにはポート6432を使用します。

::

     proxy:
       name: pgd-proxy-one

この場合、エンドポイントで\ ``localhost``
を使用することは、このプロキシがプロキシが実行されているホストでリッスンすることを指定します。

各ホストにPGDプロキシ構成をインストールする
-------------------------------------------

ホストごとに、 ``/etc/edb/pgd-proxy`` ディレクトリを作成します。

::

   sudo mkdir -p /etc/edb/pgd-proxy

次に、各ホストで、適切な構成を\ ``/etc/edb/pgd-proxy``
ディレクトリの\ ``pgd-proxy-config.yml`` ファイルに書き込みます。

この例では、host-oneでこれを実行してファイルを作成できます。

::

   cat <<EOF | sudo tee /etc/edb/pgd-proxy/pgd-proxy-config.yml
   cluster:
     name: pgd
     endpoints:
       - "host=host-one dbname=bdrdb port=5444 user=pgdproxy"
       - "host=host-two dbname=bdrdb port=5444 user=pgdproxy"
       - "host=host-three dbname=bdrdb port=5444 user=pgdproxy"
     proxy:
       name: pgd-proxy-one
   EOF

サービスを再起動します
----------------------

プロキシがインストールされる各ホストで、
pgd-proxyサービスを再起動します。

::

   sudo systemctl restart pgd-proxy

正常に実行されていることを確認します。

::

   sudo systemctl status pgd-proxy

実行すると、オープニングの詳細に\ ``Active: (running)`` が表示されます。

プロキシをテストする
--------------------

この時点で、クラスター内のホストのPGDプロキシポートに接続すると、接続が現在の書き込みリードノードにルーティングされます。

たとえば、3つのホストすべてにプロキシをインストールしていると仮定すると、ホスト3でプロキシに接続すると、接続がノード1にルーティングされます。

この例では、 psqlの\ ``-d``
フラグを使用して、構成したプロキシのホスト名とプロキシポート番号を使用して、接続の詳細を渡します。

.. code:: shell

   sudo -iu enterprisedb psql -d "host=host-three dbname=bdrdb port=6432"
   __OUTPUT__
   psql (16.1.0, server 16.1.0)
   Type "help" for help.

   bdrdb=#

プロキシに接続したら、サーバーを照会して、プロキシがどのノードに接続したかを見つけることができます。

.. code:: sql

   SELECT node_name FROM bdr.local_node_summary;
   __OUTPUT__
    node_name
   - ----------
    node-one
   (1 row)
   bdrdb#

サブグループの現在の書き込みリーダーに接続している必要があります。接続しているサブグループの書き込みリーダーがどのノードであるかを照会することにより、これを確認できます。

.. code:: sql

   SELECT node_group_name, write_lead FROM bdr.node_group_routing_summary;
   __OUTPUT__
    node_group_name | write_lead
   - ----------------+------------
    dc1             | node-one
   (1 row)

   bdrdb=#

また、
write_leadもノード1であるため、書き込みリーダーにプロキシ接続されていることを確認します。
