2008.08.14 PostgreSQL on ZFS まだベンチマークには耐えないだろうと思ってあんまり調べてなかっ たのだけど, ZFS version 11 にしたのと(ZIL が使えるっちゅーので), PostgreSQL(8.3.3) での興味が出たので性能評価を行ってみる(pgbench -t 100 -c 10 程度での評価)。 いちおう最大 4096 セッション, 32bit OS としては最大の共有メモ リが使用(2GB-1)できる設定にしておく(まぁテンプレってことで)。 今どきの 1GB なんかあたりまえ〜って状態だと常に設定しておいて 問題ないと思われ。kern.ipc.shmall だけがどういう計算で算出し たのか思い出せないけど(爆)。 あと PostgreSQL のインストールおよび設定については省略しておく。 構成の仕方等で差がでるかもしれないけど, 全体の傾向からすれば誤 差と思われるので。 /boot/loader.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - kern.ipc.semmni="256" kern.ipc.semmns="4352" kern.ipc.semmap="4352" kern.ipc.shmseg="256" sysvmsg_load="YES" sysvsem_load="YES" sysvshm_load="YES" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /etc/sysctl.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - kern.ipc.shmall=524288 kern.ipc.shmmax=2147483647 kern.ipc.shm_use_phys=1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /usr/local/pgsql ファイルシステムの作成 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # zfs create -o recordsize=8KB -o compression=off tank/usr/local/pgsql # chown pgsql:pgsql /usr/local/pgsql; chmod 700 /usr/local/pgsql # zfs snapshot tank/usr/local/pgsql@empty # /usr/local/etc/rc.d/postgresql initdb # zfs snapshot tank/usr/local/pgsql@initdb - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - initdb 前に recordsize を小さく(128KB → 8KB)にしておくのが味噌 みたい。512B, 4KB, 8KB と検証したけど, まぁ 8KB でもいい感じっ て結果でした。ちょっと調べた感じ 4KB, 8KB でちょうどいい感じで, 128KB は最悪(TPS が 1/2 になる)だけど, 512B は悪くないといった ところ。まぁ良くもないけど:-P。 SEE ALSO: http://blogs.sun.com/paulvandenbogaard/entry/running_postgresql_on_zfs_file データベースサーバーではないので PostgreSQL の設定(メモリ使用量 等)は抑え目で行うものとする。あとベンチマークがターゲットなんで。 当然スケールファクターは 1 ってことで(pgbench -i)。 /usr/local/pgsql/data/postgresql.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --- postgresql.conf.orig 2008-08-14 00:57:37.089981000 +0900 +++ postgresql.conf 2008-08-14 00:58:20.270346249 +0900 @@ -104,15 +104,15 @@ # - Memory - -shared_buffers = 32MB # min 128kB or max_connections*16kB +shared_buffers = 16MB # min 128kB or max_connections*16kB # (change requires restart) -#temp_buffers = 8MB # min 800kB +temp_buffers = 2MB # min 800kB #max_prepared_transactions = 5 # can be 0 or more # (change requires restart) # Note: Increasing max_prepared_transactions costs ~600 bytes of shared memory # per transaction slot, plus lock space (see max_locks_per_transaction). -#work_mem = 1MB # min 64kB -#maintenance_work_mem = 16MB # min 1MB +work_mem = 1MB # min 64kB +maintenance_work_mem = 4MB # min 1MB #max_stack_depth = 2MB # min 100kB # - Free Space Map - @@ -149,9 +149,9 @@ # - Settings - -#fsync = on # turns forced synchronization on or off +fsync = on # turns forced synchronization on or off #synchronous_commit = on # immediate fsync at commit -#wal_sync_method = fsync # the default is the first option +wal_sync_method = open_sync # the default is the first option # supported by the operating system: # open_datasync # fdatasync @@ -201,11 +201,11 @@ # - Planner Cost Constants - #seq_page_cost = 1.0 # measured on an arbitrary scale -#random_page_cost = 4.0 # same scale as above +random_page_cost = 2.0 # same scale as above #cpu_tuple_cost = 0.01 # same scale as above #cpu_index_tuple_cost = 0.005 # same scale as above #cpu_operator_cost = 0.0025 # same scale as above -#effective_cache_size = 128MB +effective_cache_size = 16MB # - Genetic Query Optimizer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 当然 ZIL(ZFS Intent Log)は有効の方向で:-)。 FreeBSD (5.0 以降かな, 少なくとも 4.x にはなかった) では open(2) システムコール時に指定できるフラグは O_SYNC のみで, fsyncdata(2) 関数が無いことから, wal_sync_method には fsync, open_sync の 2 つが指定できる。 さすがに open_sync の効率はよく, fsync との比較で常時 1.5 倍程度 の TPS 改善を確認した。もちろんそもそも fsync = off には勝てない わけだが:-)。それはいっちゃおしまいよ。ということで。まぁ参照系 がほとんどなら, そういう運用もありかもしれないけど。 さて。全体的にどーがんばっても 50TPS 程度しかでず, この状態で CPU 使用率 30% 程度。ディスク I/O がボトルネックになってる模様。 SEE ALSO: http://www.gtrc.aist.go.jp/docs/sighpc113tanimura.pdf SEE ALSO: http://opensolaris.org/os/community/databases/blogs/ どうにもまだまだ感があるみたい。同じ構成の UFS2 環境が無いのでデー タ取りは行っていないけど, たぶん 1/4 くらいの性能かな(200TPS くら いを想定)。 あと検証できないのでどうしようかってところに zpool add ... log ... ネタがあるけど, cannot add to 'tank': root pool can not have multiple vdevs or separate logs と出てログを追加できない。そりゃまあ, 全然冗長構成されてない状 態でさらに危険度が増すようなオペレーション(RAID0 的な…とか)は 許可できなわな。ミラー(zpool attach)にしやがれってところだろう けど, わかっちゃいるけど(ry。 あと zfsboot という観点からしてもログが分かれている状態でブート できるのかどうかって問題もあるので, 検証環境用意してから本番環境 に適用した方がいいかもしれない。まぁ危険なオペレーションというこ とで(^.^;。 さて。現時点での結論としては UFS2 + DIRECTIO カーネルオプション + open_sync が最強ということで。まぁディスク I/O がボトルネック になってるからたくさん HDD 並べたらどうなるかは興味あるところで はあるかな。とは言え, 典型的な 2HDD な構成のサーバーだとまだま だかな…。 Written by 重村法克