NGINX を使った TCP/UDP Proxy の構築 (その 2)

こんにちは。サイオステクノロジー OSS サポート担当 Y です。

今回は NGINX で PostgreSQL へのアクセス (Slave サーバに対する参照アクセスのみ) を負荷分散する Reverse Proxy サーバ (TCP/UDP Proxy) を構築してみました。(※以下の内容は NGINX 1.13.12/PostgreSQL 10.4 にて検証しています。)

■はじめに

前回 NGINX を使って TCP/UDP Proxy を構築してみましたが、バックエンドが Web サーバであり、前々回 の HTTP Proxy との違いが分かり辛い内容になってしまっていました。

そこで、今回は Web サーバではなく、DB サーバ (PostgreSQL) をバックエンドにして TCP/UDP Proxy を構築してみました。

今回の検証では以下のモジュールを利用して TCP/UDP の Reverse Proxy を構築してみます。

ngx_stream_core_module

ngx_stream_upstream_module

ngx_stream_proxy_module

■構成情報

今回は以下の様な環境を構築してみました。

上記の通り、2つのネットワーク (192.168.10.0/24, 192.168.20.0/24) を用意した上で、各ノードに以下の様な IP アドレスを設定し、client から直接 DB サーバにはアクセスできないようにしています。(proxy サーバには 2つの NIC を用意し、両方のネットワークに接続できるようにしています。)

また、今回は PostgreSQL のストリーミングレプリケーション環境を構築し、各 Slave サーバを NGINX による Reverse Proxy のバックエンドとして設定します。NGINX を使って “クライアントから PostgreSQL の Slave サーバに対する接続” を振り分けるイメージ (いわゆる DB の参照負荷分散) です。

上記構成では、client から proxy サーバにリクエストを送信すると、バックエンドの DB1 ~ DB3 にリクエストが振り分けられ、いずれかの DB (Slave) サーバからレスポンスが返ってくることを想定しています。

それでは、上記構成を実現するための各 proxy, DB サーバの設定について見ていきます。(※各ディレクティブの詳細等は割愛していますので、前述したドキュメントも併せてご参照下さい。また、今回は NGINX に主眼を置いた内容なので、PostgreSQL のストリーミングレプリケーション環境の構築方法等については割愛します。)

まず初めに、proxy サーバの設定です。proxy サーバには以下の様な設定ファイル nginx.conf (/usr/local/nginx/conf/nginx.conf) を配置します。

前回前々回と同じように、この nginx.conf では、エラーログ等の基本的な設定を行なっています。そして、stream コンテキスト内の include ディレクティブにて /usr/local/nginx/conf.d/ 配下にある *.stream.conf ファイルを読み込むように設定しています。

次に、クライアントからのアクセスを各 DB に振り分けるための設定を行います。この設定を行う設定ファイルは、前述した /usr/local/nginx/conf.d/ 配下の *.stream.conf ファイルとして作成し、エラーログ等の基本的な設定を行なっている nginx.conf から読み込まれるようにします。

はじめに、upstream ディレクティブにて任意の名前 (backend) を付けたグループを作成しています。グループ内に登録するサーバは upstream コンテキスト内の server ディレクティブで指定します。(※少しややこしいのですが、後述する server ディレクティブとは異なる server ディレクティブです。)

今回はバックエンドのサーバである DB1 ~ DB3 を upstream コンテキスト内の server ディレクティブに指定しています。(upstream コンテキスト内の server ディレクティブには、FQDN や IP アドレスを指定することが可能です。)

また、upstream コンテキスト内の server ディレクティブによるバックエンドサーバの指定では、リクエストを転送する先の port 番号 “5432” (DB サーバ上 PostgreSQL が listen している port) を指定しています。

次に、server ディレクティブ (upstream コンテキスト内の server ディレクティブとは異なる server ディレクティブ) にて proxy サーバがクライアントからのリクエストを受け取るための設定 (listen) 及びバックエンドサーバにリクエスト転送する設定 (proxy_pass) を行います。

listen ディレクティブでは proxy サーバがクライアントからリクエストを受け付ける IP アドレス及び port 番号 (ソケット) を指定します。

proxy_pass ディレクティブではリクエストを転送する設定を行いますが、今回は upstream ディレクティブにて設定したグループ “backend” を転送先に指定するため、引数に “backend” を指定しています。

Reverse Proxy (TCP/UDP Proxy) として動作させる NGINX の設定は上記で終了です。

前述した通り、今回 PostgreSQL 側の設定やレプリケーション環境の構築方法については割愛するのですが、後述する動作検証のために各 DB (PostgreSQL) の Slave サーバで以下の様な設定を行なっておきます。

PostgreSQL のストリーミングレプリケーションは、バイナリレベル (物理的なファイルレベル) でデータをレプリケーションするので、基本的に各 Slave の内容は完全に一致します。

しかし、今回の検証ではクライアントから Reverse Proxy (TCP/UDP Proxy) 経由で PostgreSQL に接続した際に、どの Slave サーバに接続が振り分けられているかを確認する必要があるため、上記の通り各 Slave サーバの設定ファイルにユーザ定義の設定値 (user_conf.slave_name) 及び値 (slave1 ~ slave3) を設定しておきます。

各サーバの設定については以上です。

■検証

では、前述した設定の環境で実際に動作を確認してみます。

まず、Master の PostgreSQL にてテスト用のテーブル “hoge” を作成し、適当な値 (a = 0) のレコードを一行格納します。

次に、各 Slave にデータがレプリケーションされているかを確認します。

上記の通り、各 Slave にて Master で作成したテーブル “hoge” 及び INSERT したデータ (a = 0 のレコード) がレプリケーションされていることが確認できます。

それでは、NGINX にて構築した Reverse Proxy (TCP/UDP Proxy) 経由で各 Slave に接続し、DB 内のデータを参照できるか確認してみます。

上記の通り、client から “proxy サーバ上の NGINX が listen している 5555 port” に対して psql で接続すると、バックエンドにある PostgreSQL からの応答を得る (“hoge” テーブルの内容を参照する) ことができました。

今度は、NGINX にて各 PostgreSQL の Slave に接続が振り分けられているかを確認してみます。

接続先の Slave を確認するために設定しておいた “user_conf.slave_name” の値を取得すると、上記の様に各 Slave に対して順番に接続している (NGINX が順番にリクエストを振り分けている) ことが確認できます。

■最後に

今回は PostgreSQL をバックエンドにして NGINX の TCP/UDP Proxy 環境を構築してみました。stream ディレクティブを利用した TCP/UDP Proxy では、パケットをそのままバックエンドに中継 (分散) してくれるので、今回検証した PostgreSQL のように、HTTP 以外の接続も負荷分散することができます。

PostgreSQL の場合は TCP を利用した接続ですが、DNS 等の UDP を利用した接続を負荷分散することも可能であり、様々なシステムでクライアント数が増加している昨今において、今後 NGINX が活躍する場が増えていくのではないかと思います。

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメント投稿

メールアドレスは表示されません。


*