[pgpool-general-jp: 1362] Re: pgpool3.3.5 ロードバランスについて

Yugo Nagata nagata @ sraoss.co.jp
2015年 3月 10日 (火) 20:28:28 JST


近藤さん

長田です。

On Sat, 7 Mar 2015 00:51:12 +0900
近藤 <skond66 @ gmail.com> wrote:

> ご回答ありがとうございます。近藤です。
> 
> 1について3.3からの仕様変更ということで理解いたしました。ただ、マニュアルで「SELECT問合わせが明示的なトランザクションブロックの内側にあるかどうかどうかで、
> レプリケーションモードの動作が変化します。詳細を表に示します」という記述や、詳細な表の内容もすべて違うとなりますと、なかなか利用が難しいレベルと感じます。

ご不便をお掛けして申し訳ございません。
マニュアルの方も正確になるよう修正しておきます。


> 2についてですが、今まで使用していた過去のpgpoolの仕様と異なるため、プログラムの改修が必要になる
> というのが一番の理由です。過去のバージョンでは、トランザクション処理の中では、更新作用のあるselect
> でも安心して使用できる仕組みになっていました。black_listなどの設定で対応は可能と理解していますが、開発側とインフラ側での連携作業が必要になるため、少し手間に感じます。

確かに、トランザクション処理の中では、更新作用のあるselectを、レプリケーション
される前提で用いている場合には対策が必要となってしまいます。
リリース時にも「互換のない変更」とは案内されてはいなかったかと思います。
混乱させてしまい申し訳ございません。

更新のあるselectをレプリケートさせるには、black_function_list に追加するほか、

/*REPLICATION*/ SELECT ...

のように、コメントをつけることでもレプリケートさせることができます。

> 
> また、ロードバランスを可能な限り行う方針というのは、パフォーマンス向上のためと思いますが、もともとがレプリケーションモードですので、
> 
> ・基本は 両方にクエリが送付される。
> ・負荷分散のために、読むだけの select は片方だけに送付される。
> 
> という理解をしていました。レプリケーションモードにもかかわらず、マスターのみにselect が送付される動作がある
> というのが、腑に落ちないと感じたのも、投稿させて頂いた理由です。

これは pgpool-II 1.1 からの仕様で、大分昔のことなので詳しい経緯はわからないのですが、
(ロードバランスできない場合は)レプリケーションモードでも select を master にのみ送信
することで余計な処理を行わず負荷を避ける、という意図だと思います。


> 
> 現在、検証を進めておりますが、SQLエラー発生時に、 idle in transaction
> 状態で接続が固まってしまう現象も発生しており、先行きは厳しい状況にあります。

こちらは別スレッドで投稿いただいていると思いますので、そちらで対応させて頂きます。

> 
> 
> 
> 2015年3月6日 16:49 Yugo Nagata <nagata @ sraoss.co.jp>:
> 
> > 近藤さん
> >
> > 長田です。
> >
> > > 1.ロードバランス条件について
> > >
> > > マニュアルには、以下のように「条件をすべて満たした場合にロードバランス」とあります。
> > >
> > > >load_balance_mode = true を設定した場合、以下の条件のすべてを満たした>時に
> > > SELECTなどの問い合わせがロードバランスされます。
> > > >◾PostgreSQLのバージョンが7.4以降である
> > > >◾問い合わせが明示的なトランクザションブロックの内側にない(つまり、>BEGINを発行していない)
> > >
> > > しかし、内部処理を見ますと pool_query_context.c においては以下のようになっています。
> > >
> > >                         else if (TSTATE(backend, MASTER_NODE_ID) == 'I'
> > ||
> > >                                          (!pool_is_writing_transaction()
> > &&
> > >                                           !pool_is_failed_transaction()
> > &&
> > >
> >  pool_get_transaction_isolation()
> > > != POOL_SERIALIZABLE))
> > >                        {
> > >                                 /* load balance */
> > >                                 pool_set_node_to_be_sent(query_context,
> > (snip)
> > > つまり、トランザクションの外部 or 他の条件を満たせばロードバランスされておりまして、内部であってもロードバランスされてしまいます。 ||
> > でなく
> > > && であるべきかと思いますが、どうでしょうか?
> >
> > すいません。マニュアルの更新漏れがありましたが、こちらは 3.3.0 より
> > 以下の通り仕様が変更がありました。
> >
> > - レプリケーションモードで、明示的なトランザクション内のロードバランスができるようになりました。(Tatsuo Ishii)
> >  -- ロードバランスが行われる条件は以下のとおりです。
> >  1. replicate_select が off
> >  2. 書き込みを行う関数が使われていない
> >  3.トランザクション分離モードが SERIALIZABLE ではない
> >  4. DML/DDL がトランザクションの中で実行されていない
> >
> > (参照:リリースノート
> > http://www.pgpool.net/docs/latest/pgpool-ja.html#release3.3.0)
> >
> > 以下のコミットによります。
> >
> > http://git.postgresql.org/gitweb/?p=pgpool2.git;a=commitdiff;h=62caae201f683f35f756fedd60c610e343d599c4
> >
> > > 2.レプリケーションモード時の挙動仕様について
> > >
> > > レプリケーションモードの場合、update や
> > >
> > deleteは全てのノードに送られます。読むだけのselectは高速化のためにロードバランス可能として頂いていると認識しています。また、トランザクション内部の場合などは、更新副作用のある場合を考慮して、ロードバランスされないと受け止めています。
> >
> > 上記の通り、3.3.0 からは可能な場合はトランザクションブロック内でも
> > select がロードバランスされます。
> >
> > >
> > > そのため、ロードバランスされない場合、レプリケーションモードを利用している場合、update や delete
> > > と同様に、全てのノードに送られる仕様であると助かります。現在は、マスターノードのみに送られます。
> >
> > すみません。これはちょっと分からなかったのですが、
> > 「レプリケーションモードで、トランザクション内の SELECT がロードバランスされない場合は
> > 全てのノードに送るようにしたい。
> > (ただし、トランザクション外では普通にロードバランスしてOK)」
> > という理解であっているでしょうか?
> >
> > 実際には上記の通り可能な場合はロードバランスさせているのですが、
> > これでは不都合がありますでしょうか。上記の要望の理由やユースケース
> > など教えていただければ幸いです。
> >
> > >
> > > これは、replicate_select を true にすると、ひとまず両方に送られますが、この対応ではselect
> > >
> > のロードバランスが全くされないため、パフォーマンスが大きく下がってしまいます。また、更新やinsertが多数ある状態ですと、タイミングによって、ノード間の不一致がごく一時的に発生している状態の単純なselect
> > > がエラーとなってしまう恐れが高いと思っています。
> >
> >
> > --
> > Yugo Nagata <nagata @ sraoss.co.jp>
> >


-- 
Yugo Nagata <nagata @ sraoss.co.jp>


pgpool-general-jp メーリングリストの案内