[groonga-dev,04071] Re: io_flushが大量のメモリを確保する

Back to archive index

高見 直輝 takam****@orega*****
2016年 7月 7日 (木) 18:55:52 JST


高見です。

> >> 今のio_flushの実装はすべてのテーブル・カラムをフラッシュしま
> >> す。このとき、まだ開いていないテーブル・カラムならそのテーブ
> >> ル・カラムのファイルを開いてフラッシュします。このファイルを
> >> 開いたときにリソースを確保するのでメモリー使用量が増えます。
> > 
> > 『開いた』というのは、PostgreSQLでSelect文を発行した場合も含まれるのでしょうか?
> 
> はい。「SELECT ... WHERE column @@ "クエリー"」のように
> PGroongaのインデックスを使うSELECT文を発行したときもGroonga
> のテーブル・カラムを開きます。このとき、メモリー使用量が増え
> ます。
> 
> 念のための補足ですが、一度開くと今後は開いたテーブル・カラム
> を使いまわすので、上述のSELECT分を実行するごとにメモリー使用
> 量が増え続けることはありません。1回目のSELECT分で増え、それ
> 以降は一定です。(一時的に確保するメモリーはありますが、それ
> らは処理が終わったら開放します。)

この"一定のメモリ使用量"は、テーブルのレコード数によって増加するのでしょ
うか?それとも、レコードに登録されている文字列の合計サイズによって増加す
るのでしょうか?

> > io_flushのドキュメントを読むと、このコマンドは“Groongaデータベースへの変更量に応
> > じて処理が重くなる”とあるのですが、Select文もGroongaデータベースを変更するのでしょ
> > うか?
> 
> 変更しません。
> そのため、何度SELECT文を実行しても処理の重さは変わりません。
> 
> > また、この処理は“OSが自動的に書き出す”場合にも同様の挙動となるのでしょうか?
> 
> 「この処理」は「Groongaデータベースへの変更量に応じて処理が
> 重くなる」の「処理」であっていますか?であれば、同様の挙動に
> なります。なお、ここの「処理」は「メモリー上にだけある変更を
> ディスクに書き出す」処理になります。「処理が重くなる」のはディ
> スクに書き出されるデータ量が増えるとI/Oの時間が増えるからで
> す。

"メモリー上にだけある変更“の総量はGroongaデータベースを変更した量(又は
回数)に比例すると思っていました。

> OSが自動的に書き出す場合も、ディスクにデータを書き出すので同
> 様に、メモリー上にだけあるデータ量が多いほど重くなります。

OSが自動的に書き出す処理は、io_flushを引数無しで実行したものと同じ、全テー
ブルの分を一括処理するものなのでしょうか?
テーブル作成時のio_flushを、作成したもののみを対象とするよう改修したので
すが、自動書き出しによって同様の問題が発生するのであれば、こちらも対応す
る必要があります。

> > 現在、このコマンドを実行するとメモリの大量使用によりOSがハングアップする状況が発生
> > しているのですが、コマンドを実行しなくても同様の状況が発生し得るのでしょうか?
> 
> 発生し得ます。が、高見さんの使い方では発生しないと思います。
> 
> Groongaはテーブル・カラムを使うときに初めて「開き」ます。逆
> に言うと一度も使わないテーブル・カラムは開きません。
> 
> 高見さんの使い方は、たくさんのPGroongaのインデックスがあるが、
> 通常使うのはその一部、だと思っています。その場合は一部の
> (Groongaの)テーブル・カラムしか開かないのでメモリー使用量
> が抑えられます。
> 
> すべてのテーブルに対して「SELECT ... WHERE column @@ "XXX"」
> を実行するとio_flushを使用した時と同程度のメモリー使用量にな
> ると思います。

運用上、使われるテーブルが一部に限られる可能性は高いのですが、テーブル数
に上限が無い仕様となっているので、全テーブルに対してSELECTが実行されるも
のと考える必要があります。
ただ、検索が終わった後にテーブルを開いたままにしておく必要は無いので、テー
ブルを閉じることが出来るのであれば、プログラムによる対応も可能になります。
SELECTの実行後にquitコマンドを実行すれば良いのでしょうか?

> >> ただ、まだ開いていないテーブル・カラムはフラッシュする必要は
> >> ないので、本当は開く必要はありません。近い将来、このケースの
> >> ときは開かないようにする予定です。
> > 
> > 現時点でクラッシュ時の破損を回避しつつ、メモリ消費量を減らす事は可能でしょうか?
> 
> はい、可能です。
> 
> > io_flushコマンドで--target_nameを指定してインデックスを1つずつ処理することでメモリ
> > 使用量を抑えられるのは確認したのですが、これでクラッシュ時の問題を解決できるのかが
> > 不明です。
> 
> 変更がある(Groongaの)テーブル・カラムを網羅できていれば大
> 丈夫です。
> 
> DDLを教えてもらえればどんなio_flushを発行すれば網羅できてい
> るかを伝えることができます。

Sources〜に対して実行した後、データベースに対して実行してます。
他に必要な処理はありますか?

> 「SELECT pgroonga.flush("INDEX_NAME")」とすれば大丈夫になるよ
> うな関数を提供するのがいい気がしてきました。

そうですね。現状プログラムでインデックス名からのGROONGAテーブル名(Sources〜)
を取得するSQLを発行する必要があるので、このコストが省けるようになるのは
大きいと思います。

> > つまり、テーブル毎に実行するにしても、作成もしくはtruncate直後のみにした方が良いと
> > いうことですね。
> 
> いえ、それだと(SQLの)INSERT/UPDATEで追加・更新されたデータ
> が失われる可能性があるので、インデックスの破損を防ぐ目的なら、
> 直後だけでなくデータ更新後のタイミングでも実行する必要があり
> ます。

書き込み途中のデータについては、破損の可能性を0にすることは出来ないと考
えています。
ドキュメントのload と deleteの書き出し対象を見ると、データベースが対象に
含まれていないので、破損した場合このテーブルに対するREINDEXだけで回復で
きるのではありませんか?
まずいのは書き込みが完了している、他のテーブルのデータに影響が出ることな
ので、データベースに対するフラッシュが必要な処理以外は現状では対応不要と
考えています。

> >> > テーブルに対して一切の操作を行っていない、つまり、上記Selectコマンドを連
> >> > 続実行した場合でも、毎回同程度の容量が確保されています。
> >> 
> >> これは、実行する毎にメモリー使用量が増えていくということです
> >> か?たとえば、↑の「データサイズ250MBのテーブルが1つ」のとき
> >> は
> >> 
> >>   * 1回実行したら初期状態から135MB増え、
> >>   * 2回実行したら初期状態から270MB増え、
> >>   * 3回実行したら初期状態から405MB増え、
> >>   * ...
> >> 
> >> ということですか?であればメモリーリークな気がするので調べて
> >> 直した方がよさそうに思っています。
> > 
> > いいえ。1回目を実行して5秒後に2回目を実行してもメモリー使用量が変わらなかったとい
> > うことです。
> 
> よかったです。
> 
>    * 1回実行したら初期状態から135MB増えた状態になり、
>    * 2回実行したら初期状態から135MB増えた状態になり、
>    * 3回実行したら初期状態から135MB増えた状態になり、
>    * ...
> 
> ということですね。
> 
> > ドキュメントの
> >  メモリー上に多くの変更があるなら、それらをディスクに書き出す処理は重い処理になります。
> > の記述から、このコマンドを実行してからDBに一切変更が加えられていない場合、次回実行
> > 時には殆どリソースを消費しない(処理が軽い)と考えていました。
> 
> なるほど。
> 「処理が重い」がどういうことかの認識が違うということがわかり
> ました。
> 
> 私は「処理が重い」は「実行に時間がかかる」という意味で使って
> いて、「メモリー使用量については何も触れていない」というつも
> りでした。
> 
> > 上記の例で言うと、1回目が135MBなら、DBに変更を加えていない状態で実行された2回目は
> > ほぼ0MBとなるはず、といった感じです。
> 
> つまり、こういうことですよね。
> 
>    * 1回実行したら初期状態から135MB増えた状態になりまた初期状態と同じ状態に戻り、
>    * 2回実行したら初期状態から135MB増えた状態になりまた初期状態と同じ状態に戻り、
>    * 3回実行したら初期状態から135MB増えた状態になりまた初期状態と同じ状態に戻り、
>    * ...
> 
> 実際は、1回目で確保したメモリーは以後も使い回すため、メモリー
> 使用量は「初期状態から135MB増えた状態」から変わりません。
> 「135MB増えた状態から初期状態に戻り」ません。

書き出すデータの量と、確保するメモリの量に相関関係はあまり無いということ
ですね。

----------------------------- 
高見 直輝 <takam****@orega*****>
株式会社オレガ
TEL:03-3267-0150
FAX:03-3267-0180




groonga-dev メーリングリストの案内
Back to archive index