クラウド環境に慣れてしまうと物理機器への対応が難しい
1.概要
クラウド環境のサービスに慣れてしまうと物理PCで同じことを実施しようとした時に予想しなかったことに遭遇します。postgresqlを十分なメモリを搭載した物理PCで動作させた時に、メモリが想定されたように利用されないことに気が付きました。ネットで調べると、shared_bufferの値を変えることが必要とわかりました。クラウド環境は便利ですが、物理PCへ移行が必要になった時に、必要な設定事項があることを再認識しました。そのことを記述します。
2.詳細
(1) 実際に遭遇したこと
Oracleなどの商用databaseを大規模サーバで動作させるときには、ベンダーに必要な設定変更を確認することができます。しかし、OSSのdatabase(postgresqlなど)を利用する場合、小規模環境を前提としており、環境に合わせた設定変更が必要になるようです。
最近は、PCのリソース(core数、物理メモリ、ストレージ)が安価になり、以前の大規模サーバレベルが個人でも利用できるようになっています。しかし、提供されたPCリソースをどのようにして効率的に利用するかはとても難しく、運用しながら調整をすることになります。
今回の事例はpostgresqlです。
共有メモリバッファ(shared_buffers)はデータをキャシュするメモリ領域です。既定値は128MBでした。
今回は16GBのメモリ搭載のPCなので、/var/lib/postgresql/data/postgresql.confのパラメータを変更しました。
shareed_buffer = 4G
(2) postgresql-clientのupgradeでエラー発生
ubuntuのupdateを実行すると、下記postgresqlでエラーになりました。導入環境からpostgresql-clientが原因と思って調べました。その内容を記述します。
N: Skipping acquire of configured file 'main/binary-i386/Packages' as repository 'https://apt.postgresql.org/pub/repos/apt focal-pgdg InRelease' doesn't support architecture 'i386'
インストール手順の最初の部分に問題があります。
# Create the file repository configuration:
sudo sh -c 'echo "deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
これを以下のように[arch=amd64]を追加して、実行します。
/etc/apt/sources.list.d/pgdg.listが変わっていることを確認します。
その後、ubuntuのupdateを実行すると問題改善です。
# Create the file repository configuration:
sudo sh -c 'echo "deb [arch=amd64] https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
または、/etc/apt/sources.list.d/pgdg.listを直接変更してもOKです
PostgreSQL本体とPostgreSQL Clientは別れて利用するものですが、Docker環境で物理的には別れていないが、コンテナ内部と外部で別れている場合があります。私は、最近、PostgreSQL本体にはPostgreSQL clientも含まれているのでコンテナ外部からコンテナ内部を利用するように変更をしています。この方式ではPostgreSQL clientインストールが不要です。
(3) postgreSQLのレコード長による処理速度比較
postgreSQLのレコード件数の性能は、データ項目が5項目の場合、200万件の挿入に7秒と高速でした。データ項目数を増加させた場合にどのようになるかを試験で確かめました。その内容を記述します。
5項目でreal部分が2項目でした。
date daytime number real real
2025-12-27,2025-12-27 16:39:16,1,0.924046,0.593909
このreal部分を100項目、200項目、300項目、400項目、500項目に変化させました。レコード件数は200万件です。
2項目 レコード長=64バイト 処理時間=7秒
100項目 レコード帳=456バイト 処理時間=60秒
200項目 レコード長=856バイト 処理時間=109秒
300項目 レコード長=1256バイト 処理時間=155秒
400項目 レコード長=1656バイト 処理時間=216秒
500項目 レコード長=2056バイト 処理時間=296秒
レコード長に比例して、処理時間を必要としています。つまり、レコード長が大きなデータをpostgreSQLに保存すると処理時間を必要で負担が増えることを示しています。postgreSQLには8KBのレコード長上限があり、それを超えることはできません。物理的な制限が来る前に、じわりとレコード長の長さによる影響が現れてくるので設計には注意が必要です。
(4) postgreSQLでexplain analyzeの出力結果を分析
昔勉強をしたことでも時間が経過すると忘れてしまうことは沢山あります。RDBでSQLが実行されるときに統計情報が参照されて具体的な検索手順が決まることは多数経験をしていました。同じような性能問題はどこでも発生するものですが、原因究明は基本を正しく把握しているか否かの影響が大きいと思います。posrgreSQLのexplain analyzeに関して調べたのでその内容を記述します。
データ項目は下記5項目で、データ件数は200万件です。
データの例
date daytime number real real
2025-12-27,2025-12-27 16:39:16,1,0.924046,0.593909
実行環境はi3-7100です。
primary keyはdaytime、2次key(index)はnumberとします。
insertで200万件のデータを登録後、下記select文を調べてみました。
select * from my_table where number = '1000000'
毎回drop tableを実施後、insertからやり直しをしました。
(a) primary keyのみ
Gather (cost=1000.00..26106.97 rows=7353 width=64) (actual time=108.051..111.861 rows=1 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Seq Scan on my_table (cost=0.00..24371.67 rows=3064 width=64) (actual time=88.469..105.677 rows=0 loops=3)
Filter: (number = 1000000)
Rows Removed by Filter: 666666
Planning Time: 0.273 ms
Execution Time: 111.895 ms
(b) primary key, 2次keyあり
Bitmap Heap Scan on my_table (cost=169.41..13512.40 rows=7353 width=64) (actual time=0.069..0.069 rows=1 loops=1)
Recheck Cond: (number = 1000000)
Heap Blocks: exact=1
-> Bitmap Index Scan on idx_number (cost=0.00..167.58 rows=7353 width=0) (actual time=0.032..0.032 rows=1 loops=1)
Index Cond: (number = 1000000)
Planning Time: 0.275 ms
Execution Time: 0.098 ms
(c) primary key, 2次keyあり,vacuumdb実行
Index Scan using idx_number on my_table (cost=0.43..8.45 rows=1 width=31) (actual time=0.038..0.039 rows=1 loops=1)
Index Cond: (number = 1000000)
Planning Time: 0.319 ms
Execution Time: 0.072 ms
3.所見
PostgreSQLの環境構築を物理機器に導入をしようとすると様々問題に遭遇します。現在のPCはハイスペックなので既定値ではパラメータ設定が合わないケースがあります。ベンダー製品でないOSS製品の場合、問い合わせ先を探すことも大変なので、KKDによることろが多数残っている気もします。
コメント
コメントを投稿