sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQLでpgBouncerを使用するためのガイド

    PostgreSQLの開始を読むと、次の行が表示されます。「PostgreSQLサーバーはクライアントからの複数の同時接続を処理できます。これを実現するために、接続ごとに新しいプロセスを開始(「フォーク」)します。その時点から、クライアントと新しいサーバープロセスは、元のpostgresプロセスの介入なしに通信します。したがって、マスターサーバープロセスは常に実行され、クライアント接続を待機しますが、クライアントおよび関連するサーバープロセスは出入りします。

    素晴らしいアイデア。それでも、新しい接続ごとに新しいプロセスがスピンし、RAMが予約され、複数のセッションで重くなりすぎる可能性があることを意味します。問題を回避するために、postgresにはデフォルトの100接続でmax_connections設定があります。もちろん増やすこともできますが、そのようなアクションには再起動が必要になります(pg_settings.contextは「postmaster」です):

    t=# select name,setting,short_desc,context from pg_settings where name = 'max_connections';
    -[ RECORD 1 ]--------------------------------------------------
    name       | max_connections
    setting    | 100
    short_desc | Sets the maximum number of concurrent connections.
    context    | postmaster
    いくつかのエキサイティングな読み物PgBouncerの使用法バウンスのポイントは何ですか?スタックオーバーフローの「pgbouncer」を含むPgBouncerChangelog投稿2ndQuadrantの「pgbouncer」とタグ付けされた投稿

    そして、増加した後でも、ある時点で、より多くの接続が必要になる場合があります(もちろん、prodの実行時にいつものように緊急に)。なぜそれを増やすのはとても不快ですか?それが快適であれば、クラスターが遅れ始めるまで、制御できない自発的な数の増加に終わる可能性があるためです。つまり、古い接続は低速です。つまり、接続に時間がかかるため、さらに多くの新しい接続が必要になります。このような雪崩の可能性を回避し、柔軟性を追加するために、superuser_reserved_connectionsがあります。これにより、max_connectionsが使い果たされたときにSUに接続して問題を修正できます。そして、明らかに接続プールの必要性がわかります。新しい接続候補が例外FATALで失敗するのではなく、キューで待機するようにしたいので、申し訳ありませんが、すでにクライアントが多すぎて、ポストマスターのリスクを冒していません。

    接続プールは、多くの人気のある「クライアント」によってある程度提供されています。かなり長い間、jdbcで使用できます。最近、node-postgresは独自のnode-pg-poolを提供しました。多かれ少なかれ実装は単純です(アイデアがそうであるように):プーラーはデータベースへの接続を開始し、それらを保持します。 dbに接続しているクライアントは、「共有」された既存の接続のみを取得し、それを閉じた後、接続はプールに戻ります。また、pgPoolのようなはるかに洗練されたソフトウェアもあります。それでも、pgbouncerはこのタスクで非常に人気のある選択肢です。なんで?それはプーリング部分だけを実行しますが、それは正しく実行するからです。それは無料です。設定はかなり簡単です。そして、citusdata、aws、heroku、その他の高く評価されているリソースなど、推奨または使用されているほとんどの最大のサービスプロバイダーでそれを満たしています。

    それでは、それが何ができるのか、そしてそれをどのように使用するのかを詳しく見てみましょう。私のセットアップでは、デフォルトのpool_mode =transaction([pgbouncer]セクション)を使用します。これは非常に一般的な選択肢です。このようにして、max_connectionsを超える接続をキューに入れるだけでなく、前の接続が閉じるのを待たずにセッションを再利用します。

    [databases]
    mon = host=1.1.1.1 port=5432 dbname=mon
    mons = host=1.1.1.1 port=5432 dbname=mon pool_mode = session pool_size=2 max_db_connections=2
    monst = host=1.1.1.1 port=5432 dbname=mon pool_mode = statement
    [pgbouncer]
    listen_addr = 1.1.1.1
    listen_port = 6432
    unix_socket_dir = /tmp
    auth_file = /pg/pgbouncer/bnc_users.txt
    auth_type = hba
    auth_hba_file = /pg/pgbouncer/bnc_hba.conf
    admin_users = root vao
    pool_mode = transaction
    server_reset_query = RESET ALL; --DEALLOCATE ALL; /* custom */
    ignore_startup_parameters = extra_float_digits
    application_name_add_host = 1
    max_client_conn = 10000
    autodb_idle_timeout = 3600
    default_pool_size = 100
    max_db_connections = 100
    max_user_connections = 100
    #server_reset_query_always = 1 #uncomment if you want older global behaviour

    最も人気のある設定とヒントとコツの簡単な概要:

    • server_reset_queryは非常に便利で重要です。セッションプーリングモードでは、前のセッションの「アーティファクト」を「ワイプ」します。そうしないと、プリペアドステートメントの同じ名前、次のセッションに影響するセッション設定などで問題が発生します。デフォルトはDISCARDALLで、すべてのセッション状態を「リセット」します。それでも、より洗練された値を選択できます。たとえば、すべてリセットします。すべてを割り当て解除します。 SET SESSIONとプリペアドステートメントのみを忘れ、TEMPテーブルとプランを「共有」します。またはその逆-任意のセッションから「グローバル」なプリペアドステートメントを作成したい場合があります。このような構成は、リスクはありますが実行可能です。 pgbouncerにすべてのセッションを再利用させる必要があります(したがって、プールサイズを非常に小さくするか、セッションを雪崩させます)。これは完全に信頼できるものではありません。とにかく-それは便利な能力です。特に、クライアントセッションを最終的に(すぐにではなく)構成済みのプールされたセッション設定に変更する必要があるセットアップでは。ここで非常に重要な点は、セッションプールモードです。 1.6より前では、この設定は他のプールモードにも影響を与えたため、これに依存する場合は、新しい設定server_reset_query_always =1を使用する必要があります。代わりにclient_reset_query)。ただし、現在の執筆時点である2018年3月の時点では、これはオプションではありません。この設定をデフォルトでセッションモードでのみ有効にすることの背後にある考え方は、トランザクションまたはステートメントレベルで接続を共有する場合、セッション設定にまったく依存できないというものでした。

    • Auth_type=hba。 1.7より前の、pgbouncerの大きな問題は、ホストベースの認証(「postgresファイアウォール」)がないことでした。もちろん、postgresクラスター接続用にまだ持っていましたが、pgbouncerはどのソースに対しても「オープン」でした。これで、同じhba.confを使用して、接続ネットワークに基づいてhost / db/userの接続を制限できます。

    • connect_queryは、pgbouncerへのすべてのクライアントの「接続」で実行されるのではなく、pgbouncerがPostgresインスタンスに接続するときに実行されます。したがって、「デフォルト」設定の設定またはオーバーライドに使用することはできません。セッションモードでは、他のセッションは相互に影響を与えず、切断時にリセットクエリはすべてを破棄するため、混乱させる必要はありません。トランザクションプーリングモードでは、他のセッションによって誤って設定された設定をオーバーライドするために使用したいと思うでしょうが、残念ながら機能しません。例えば。トランザクションモードの「セッション」間でプリペアドステートメントを共有したいので、次のように設定します

      trns = dbname=mon pool_mode = transaction connect_query = 'do $$ begin raise warning $w$%$w$, $b$new connection$b$; end; $$; prepare s(int) as select $1;'

      そして確かに-すべての新しいクライアントは準備されたステートメントを見る(server_reset_query_alwaysをonのままにした場合を除いて、pgbouncerはコミット時にそれを破棄する)。ただし、一部のクライアントがDISCARDを実行している場合。そのセッションでは、この接続上のすべてのクライアントに影響し、それに接続する新しいクライアントには、プリペアドステートメントが表示されなくなります。ただし、pgbouncerからのpostgres接続の初期設定が必要な場合は、ここが最適です。

    • application_name_add_hostは1.6で追加されましたが、同様の制限があります。クライアントIPをapplication_nameに「配置」するため、不正なクエリソースを簡単に取得できますが、application_nameを「wasn'tme」に設定するだけで簡単に上書きされます。それでも、ビューを使用してこれを「修復」できます。この投稿に従ってアイデアを得るか、これらの短い手順を使用してください。基本的には、クライアントに表示するという考え方です。クライアントのIPが表示されるので、pg_stat_activityから選択するたびにpgbouncerデータベースから直接クエリを実行して、リセットされているかどうかを確認できます。しかしもちろん、単純な設定を使用する方がはるかに簡単で快適です。結果を保証するものではありませんが...

    • pool_modeは、デフォルトとして、データベースごと、およびユーザーごとの両方で指定でき、非常に柔軟になります。混合モードにより、pgbouncerはプーリングに非常に効果的です。これは強力な機能ですが、使用する際には注意が必要です。 pgbouncerのプーリングモードが異なるため、ユーザーは結果を理解せずに、トランザクションごと/セッションごと/ユーザーごと/データベースごと/グローバル設定の完全にアトミックな組み合わせで同じユーザーまたはデータベースに対して異なる動作をすることがよくあります。これは、監督なしで子供に与えないマッチの箱です。また、他の多くのオプションは、デフォルト、データベースごと、およびユーザーごとに構成できます。

    • 文字通りに解釈しないでください。ただし、iniのさまざまなセクションをSETおよびALTERと「比較」できます。SETLOCALはトランザクションに影響し、poll_mode =transactionの場合に使用すると便利です。SETSESSIONはセッションに影響し、poll_mode=sessionの場合は安全に使用できます。 、ALTER USER SETは役割に影響し、セクション[users]のpgbouncer.ini部分に干渉します。ALTERDATABASESETはデータベースに影響し、セクション[databases]のpgbouncer.ini部分に干渉します。ALTERSYSTEMSETまたはpostgres.confの編集はデフォルトにグローバルに影響します。効果的には、pgbouncer.iniのデフォルトセクションに匹敵します。

    • もう一度-責任を持ってプールモードを使用してください。プリペアドステートメントまたはセッション全体の設定は、トランザクションプーリングモードでは混乱します。 SQLトランザクションと同じように、ステートメントプーリングモードでは意味がありません。適切な接続に適したプーリングモードを選択します。良い習慣は、次のような考えで役割を作成することです。

      • 一部は高速選択のみを実行するため、重要ではない数百の同時選択に対して、トランザクションなしで1つのセッションを共有できます。
      • 一部のロールメンバーは、セッションレベルの同時実行に対して安全であり、常にトランザクションを使用します。したがって、何百もの同時トランザクションに対して複数のセッションを安全に共有できます。
      • 一部の役割は、他の人とセッションを共有するには複雑すぎます。したがって、すべての「スロット」がすでに使用されている場合の接続エラーを回避するために、セッションプーリングモードを使用します。
    • HAProxyやその他のロードバランサーの代わりに使用しないでください。 pgbouncerには、dns_max_ttlなどのロードバランサーがアドレス指定するものに対応するいくつかの構成可能な機能があり、DNS構成をセットアップできますが、ほとんどの製品環境では、HAProxyまたはHA用の他のロードバランサーを使用します。これは、HAProxyが、pgbouncerよりも、ラウンドロビン方式でライブサーバー間での負荷分散に非常に優れているためです。 pgbouncerはpostgres接続プールに適していますが、2つのタスクを実行する大きなデーモンではなく、1つのタスクを完全に実行する1つの小さなデーモンを使用する方が良い場合があります。

    • 構成の変更には注意が必要です。 pgbouncer.iniへの一部の変更には再起動(listen_portなど)が必要ですが、admin_usersなどの他の変更にはリロードまたはSIGHUPが必要です。 auth_hba_file内の変更にはリロードが必要ですが、auth_fileへの変更にはリロードは必要ありません。

    上記の設定の非常に短い概要は、形式によって制限されます。完全なリストをご覧になることをお勧めします。 Pgbouncerは、「退屈な設定」が非常に少ない種類のソフトウェアです。これらはすべて大きな可能性を秘めており、非常に興味深いものです。

    今日のホワイトペーパーをダウンロードするClusterControlを使用したPostgreSQLの管理と自動化PostgreSQLの導入、監視、管理、スケーリングを行うために知っておくべきことについて学ぶホワイトペーパーをダウンロードする

    そして最後に、短い熱狂的なレビューから、あなたがあまり満足していないかもしれない何か、つまりインストールに移ります。このプロセスは、ドキュメントのこのセクションで明確に説明されています。説明されている唯一のオプションは、gitソースからビルドすることです。しかし、誰もがパッケージがあることを知っています!最も人気のある両方を試してみてください:

    sudo yum install pgbouncer
    sudo apt-get install pgbouncer

    働ける。ただし、追加の手順を実行する必要がある場合もあります。たとえば、pgbouncerパッケージが利用できない場合は、これを試してください。

    または:

    sudo yum install pgbouncer
    Loaded plugins: priorities, update-motd, upgrade-helper
    amzn-main                                                                                                                    | 2.1 kB  00:00:00
    amzn-updates                                                                                                                 | 2.5 kB  00:00:00
    docker-ce-edge                                                                                                               | 2.9 kB  00:00:00
    docker-ce-stable                                                                                                             | 2.9 kB  00:00:00
    docker-ce-test                                                                                                               | 2.9 kB  00:00:00
    pgdg10                                                                                                                       | 4.1 kB  00:00:00
    pgdg95                                                                                                                       | 4.1 kB  00:00:00
    pgdg96                                                                                                                       | 4.1 kB  00:00:00
    pglogical                                                                                                                    | 3.0 kB  00:00:00
    sensu                                                                                                                        | 2.5 kB  00:00:00
    (1/3): pgdg96/x86_64/primary_db                                                                                              | 183 kB  00:00:00
    (2/3): pgdg10/primary_db                                                                                                     | 151 kB  00:00:00
    (3/3): pgdg95/x86_64/primary_db                                                                                              | 204 kB  00:00:00
    50 packages excluded due to repository priority protections
    Resolving Dependencies
    --> Running transaction check
    ---> Package pgbouncer.x86_64 0:1.8.1-1.rhel6 will be installed
    --> Processing Dependency: libevent2 >= 2.0 for package: pgbouncer-1.8.1-1.rhel6.x86_64
    --> Processing Dependency: c-ares for package: pgbouncer-1.8.1-1.rhel6.x86_64
    --> Processing Dependency: libcares.so.2()(64bit) for package: pgbouncer-1.8.1-1.rhel6.x86_64
    --> Running transaction check
    ---> Package c-ares.x86_64 0:1.13.0-1.5.amzn1 will be installed
    ---> Package pgbouncer.x86_64 0:1.8.1-1.rhel6 will be installed
    --> Processing Dependency: libevent2 >= 2.0 for package: pgbouncer-1.8.1-1.rhel6.x86_64
    --> Finished Dependency Resolution
    Error: Package: pgbouncer-1.8.1-1.rhel6.x86_64 (pgdg10)
               Requires: libevent2 >= 2.0
     You could try using --skip-broken to work around the problem
     You could try running: rpm -Va --nofiles --nodigest

    もちろん、pgdgを/etc/yum.repos.d/に追加してももう役に立ちません。 --skip-brokenもrpm-Va--nofiles--nodigestもありません。シンプル

    sudo yum install libevent2
    Loaded plugins: priorities, update-motd, upgrade-helper
    50 packages excluded due to repository priority protections
    No package libevent2 available.
    Error: Nothing to do

    簡単すぎるでしょう。したがって、libevent2を自分でビルドして、自分でコンパイルする必要があるときに元の位置に戻す必要があります。 pgbouncerまたはその依存関係の1つです。

    繰り返しますが、インストールの特殊性を深く掘り下げることは範囲外です。パッケージとしてインストールする可能性が高いことを知っておく必要があります。

    最後に、「postgresがネイティブセッションプーラーを提供しない理由」などの質問が何度も出てきます。非常に新鮮な提案や考えさえあります。しかし、これまでのところ、ここで最も一般的なアプローチはpgbouncerを使用することです。


    1. MariaDBクラスターにmaxctrlを使用したMaxScale管理の概要

    2. Postgres配列に値が存在するかどうかを確認します

    3. MySQLのcaseステートメント

    4. PARSENAME()を使用して、SQLServerのオブジェクト名の一部を返します