47
PostgreSQLパラレル化に向けた取り組み 2014.10.11 (仮名)PostgreSQL勉強会 株式会社メトロシステムズ 花田茂

PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

Embed Size (px)

DESCRIPTION

2014.10.11の第30回(仮名)PostgreSQL勉強会で使用した講演資料です。

Citation preview

Page 1: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

PostgreSQLの パラレル化に向けた取り組み

2014.10.11 (仮名)PostgreSQL勉強会 株式会社メトロシステムズ

花田茂

Page 2: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

Who am I?• 氏名:花田茂 • 所属:株式会社メトロシステムズ • 連絡:@s87 • 経歴:

• PostgreSQLは7.4から • 周辺ツール開発(pg_bulkload/pg_rman/pg_lesslog/Etc.) • 最近は外部テーブル関連で本体開発 • 勉強会やOCSなどで講演

2

Page 3: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

パラレル化って?

Page 4: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

パラレル化って?• definition of Parallel

• (of lines, planes, surfaces, or objects) side by side and having the same distance continuously between them: parallel lines never meet | the road runs parallel to the Ottawa River.

• definition of Concurrent • existing, happening, or done at the same time: there are three concurrent art fairs around the city.

4

出典:アメリカ英英辞典 on OS X Mavericks

Page 5: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

パラレル化って?• parallel=パラレル=並列

!

!

!

• concurrent=コンカレント=並行

5

Page 6: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

難しいことは 置いといて

Page 7: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

パラレル=高速化• 一人でやるよりみんなでやる方が早いよね! • ただし…

• 誰が何をやれば良い? • いつから始められる? • 終わったらどうすればいい?

7

当然、一筋縄では 行きません

Page 8: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

どのあたりが難しいのか?• 対象の決定

• どの処理を高速化するか? • 問題の分割

• どの部分をパラレルに分けるか? • 動作の協調

• 処理主体(=プロセス)をどのように起動するか? • どうやって、各自が何をすべきか知るか?

• 情報の受け渡し • 入力・出力をどのように受け渡すか?

8

Page 9: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

対象の決定• 性能改善の基本は「ボトルネック解消」

• ボトルネック以外を速くしても効果は薄い • 「クリティカルパス」を明確に

• 例)データロードの場合 • 最大テーブルのロード

• 例)PostgreSQLのクエリ • SQLパース+プラン生成+最大テーブルのスキャン

9

Page 10: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

対象の決定• パラレル化で早くなるか?

• ボトルネックの原因がパラレル化で解消されるか? • リソースさえあれば分割可能な処理か? • 処理単位の依存関係が整理されているか?

10

Page 11: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

対象の決定• PostgreSQLでいうと?

• クエリ実行の要素 • プラン生成 • テーブルスキャン • 結合 • ソート • Etc.

• クエリ実行要素間 • 結合の片側をソート中にもう片方をスキャン、など

11

Page 12: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

対象の決定• PostgreSQLでいうと?

• その他 • WAL書き込み • チェックポイント • テーブルメンテナンス

• VACUUM、ANALYZE、REINDEX • ALTER TABLE • バックアップ取得

12

Page 13: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

問題の分割• どう分割したら早くなるか?

• まじめに考えると論文書けるレベルの問題がてんこ盛り • スーパーコンピュータの超並列処理はここを頑張ってる? • PostgreSQLの中の人たちの腕の見せ所

13

例題:100人分のカレーを作る

Page 14: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

問題の分割• カレーの調理手順

• 米を研ぐ • 米を炊く • 肉を切る • 肉を炒める • 野菜を切る • 野菜を炒める

14

!

• 鍋に入れる • 煮込む • カレールーを入れる • 皿にご飯を盛る • 皿にカレーを盛る • 配膳

Page 15: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

問題の分割

15

肉を切る

肉を炒める野菜を炒める

野菜を切る

鍋に入れる

米を研ぐ

米を炊く

煮込む

カレールーを入れる

皿にご飯を盛る 皿にカレーを盛る 配膳

Page 16: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

問題の分割

16

Seq Scan

SortSort

Seq Scan

Merge Join

Index Scan

Aggregate

Sort

Aggregate

Limit Append Limit

Page 17: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

PostgreSQLの アーキテクチャ

17

Page 18: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

動作の協調• PostgreSQLはプロセスベース

• セッション障害がインスタンス全体に波及しない • オーバーヘッドはスレッドより大きい

• インスタンスに所属するプロセスの一覧を管理 • PGPROCという構造体の配列を共有メモリ上に配置 • postmaster(≒インスタンス)起動時に初期化 • PGPROCは同期機構のラッチを持つ

18

Page 19: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

動作の協調• プロセス間のやりとり

• 共有メモリ • シグナル

• プロセス間の同期 • スピンロック:超短期間(数十命令程度)用 • 軽量ロック:共有メモリ資源の保護 • ラッチ:複数プロセスからセットできる真偽値

19

Page 20: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

動作の協調• MVCC

• 概要 • Multi Version Concurrency Control • 更新時に古いバージョンを残したまま新しいバージョンを追加することで、特定タプルの可視性を効率的に判断する仕組み

• 判断材料 • 自TXのID(XID) • スナップショット(アクティブなTXのリスト) • タプルの作成/削除TX(xmin/xmax/cmin/cmax)

20

Page 21: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

情報の受け渡し• 基本的には共有メモリを使用

• 既存の仕組みをそのまま共有メモリに展開すれば…と思いますが、一筋縄(ry • PostgreSQLはヒープメモリの管理に独自アロケータを使用

• 細かく確保した後に「コンテキスト」という単位で一括解放が可能

• 共有メモリには非対応 • 既存ルーチンで扱うには「ヒープ→共有→ヒープ」というメモリコピーが必要

21

Page 22: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

パラレル化への 取り組み

Page 23: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

パラレル化への取り組み• 9.2

• スナップショットエクスポート • 9.3

• pg_dumpの--jobsオプションサポート • pg_upgradeの--jobsオプションサポート

23

Page 24: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

パラレル化への取り組み• 9.4(予定)

• 動的バックグラウンドワーカー • Allow background worker processes to be dynamically registered, started and terminated (Robert Haas)

• 動的共有メモリ • Allow dynamic allocation of shared memory segments (Robert Haas, Amit Kapila)

• 共有メッセージキュー • Add single-reader, single-writer, lightweight shared message queue (Robert Haas)

24

Page 25: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

パラレル化への取り組み• 9.5(予定)

• On partitioning (Alvaro Herrera) • 1st class objectとしてのパーティション • 議論/開発継続中

• Introducing coarse grain parallelism by postgres_fdw(Kyotaro Horiguchi) • postgres_fdwでリモートクエリを非同期実行して待機時間を節約

• 設計見直しが必要

25

Page 26: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

スナップショットの共有• pg_export_snapshot()関数

• 現在のトランザクションのスナップショットを$PGDATA/pg_snapshotsに書き出すし、スナップショットIDを返す

• ファイル名=スナップショットID • SET TRANSACTION SNAPSHOT ‘スナップショットID’; • 指定したIDのスナップショットを現在のトランザクションで使用する

26

Page 27: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

動的バックグラウンドワーカー• 概要

• 9.3で導入されたカスタムバックグラウンドワーカーの拡張 • 9.3ではインスタンス起動時にのみ起動できたが、9.4からは、バックエンドからのAPI呼び出しで任意のタイミングで起動可能

• 動的に起動したバックグラウンドワーカーの終了はSIGUSR1で通知可能

• 起動数はmax_worker_processesで制御可能 • つまり…

• クエリ内容に応じて特定処理のバックグラウンドワーカーを起動し、その終了を起動したバックエンド側で検知可能

27

Page 28: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

動的バックグラウンドワーカー• API(バックエンド用)

• RegisterDynamicBackgroundWorker() • バックエンドから動的BGWorkerを登録

• WaitForBackgroundWorkerStartup() • 動的BGWorkerの起動を待機

• GetBackgroundWorkerPid() • BGWorkerのPIDと状態を取得

• TerminateBackgroundWorker() • PostmasterにBGWorkerの停止を依頼

28

Page 29: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

動的バックグラウンドワーカー• API(BGWorker用)

• BackgroundWorkerInitializeConnection() • ローカルデータベースに接続

• BackgroundWorkerUnblockSignals() • BGWorkerプロセスへのシグナルブロックを解除

29

Page 30: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

共有メッセージキュー• 概要

• 共有メモリ上に配置したプロセス間メッセージキュー • 書き込み一人、読み込み一人の制限

• 書き込み/読み込みはロックフリー • 読み書きはそれぞれPGPROCにエントリのあるプロセス

• 読みと書きの間はプロセスラッチで同期 • メッセージ長は任意 • キューは固定長でリングバッファ構造

30

Page 31: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

共有メッセージキュー• API

• shm_mq_create() • メッセージキューを生成

• shm_mq_set_receiver()/shm_mq_set_sender() • 読み出し/書き込みプロセスを設定

• shm_mq_get_receiver()/shm_mq_get_sender() • 読み出し/書き込みプロセスのPGPROCを取得

31

Page 32: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

共有メッセージキュー• API

• shm_mq_attach() • メッセージキューにアタッチしてハンドルを取得

• shm_mq_wait_for_attach() • メッセージキューへのアタッチを待機

• shm_mq_detach() • メッセージキューからデタッチ

32

Page 33: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

共有メッセージキュー• API

• shm_mq_send()/shm_mq_receive() • 可変長のメッセージを書き込む/読み出す • ラッチでキューの空き/メッセージの到着を待機することも可能

33

Page 34: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

こんなことが できるようになる(仮)

Page 35: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

スキャンの分割• あるテーブルのスキャンを複数プロセスで分担

• ページで分割 • テーブルで分割(パーティション/シャーディング)

• 課題点 • 複数プロセスでのタプル可視性の共有 • 結果のとりまとめ

35

Page 36: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

スキャンの分割

36

ページ1

ページ2

ページ3

ページ4

ページ5

ページ6

ページ7

ページ8

ワーカー

ワーカー

ワーカーがスキャン

バック エンド

起動

起動

キュー経由で結果を渡す

Page 37: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

ソートの分割• ある結果セットのソートを複数プロセスで分担

• ページで分割 • テーブルで分割(パーティション/シャーディング)

• 課題点 • 入力の分配(HadoopでいうMap処理) • 結果のとりまとめ

37

Page 38: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

ソートの分割

38

ワーカー

ワーカー

ワーカーが部分ソート

バック エンド

起動

起動

キュー経由で結果を渡す

バックエンドで最終ソート

Page 39: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

集約の分割• 概要

• ある結果セットの集約を複数プロセスで分担 • MAX()/MIN()やCOUNT()は多段集約が容易 • AVG()などはやや困難?

• 課題点 • 入力の分配 • 結果のとりまとめ

39

Page 40: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

集約の分割

40

ワーカー

ワーカー

ワーカーが部分集約

バック エンド

起動

起動

キュー経由で結果を渡す

バックエンドで最終集約

Page 41: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

データロードの分割• 概要

• バルクINSERTやCOPYを複数プロセスで分担 • 文字列→内部表現変換もパラレル化できると効果大 • 複数セッションでのINSERT/COPYと異なり1トランザクションで完結

• 課題点 • 追加先の衝突回避 • WALバッファのボトルネック化

41

Page 42: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

もう少しローレベルに

Page 43: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

I/OとCPUの分割• 概要

• I/O待ちってもったいないよね? • その間にCPU使う処理できるんじゃない?

• スキャン開始時にfadvise()などでread ahead • postgres_fdwなどで非同期クエリ

• 課題点 • 先読み(投機的実行)はパイプライニングと相性が悪い? • effective_io_concurrencyで十分?

• スピンドル数に基づいて同時I/O発行数を制御

43

Page 44: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

CPU処理の分割• 概要

• スキャン結果のフィルタリング(WHERE句適用)などはCPU処理

• 対象行数が多い場合はCPUでの並列処理にも限界 • GPUでSIMDしちゃえば?

• 課題点 • 任意のコードをGPU側でコンパイル・実行する機能が必要 • pg_stromが開発中

44

Page 45: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

残っている課題• パラレル実行のプラン生成

• パラレル実行のコストを正しく見積もれるか? • コスト算出を現実的な時間で完了できるか?

45

Page 46: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

残っている課題• リソース制御

• プロセス数やメモリ量、CPU使用率といったリソースを核処理がどこまで使用してよいか?をクラスタ全体よりも細かい粒度で制御する仕組みが必要 • これがないと、リソース枯渇でシステムダウンも • work_memなども意味を変える必要あり?

46

Page 47: PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会

ご清聴ありがとうございました。

Questions?