Postgresqlのチューニング

CPUに余裕がある場合のチューニング

パラレルスキャンとは検索を複数のプロセスで並列に実行する機能。

空きCPUを有効に利用できる。

パラレルスキャンは個々のプロセス(パラレルワーカプロセス)でテーブルの結合や集約処理を行って

最終的に集約して実行結果として返却する。

見方

EXPLAN ANALYZE SELECT id, avg(value) FROM table GROUP BY id;

Finalize Aggregate  (cost=52417.44..52417.45 rows=1 width=8) (actual time=322.346..322.346 rows=1 loops=1)
   Output: count(*)
   ->  Gather  (cost=52417.02..52417.43 rows=4 width=8) (actual time=314.456..322.339 rows=5 loops=1)
         Output: (PARTIAL count(*))
         Workers Planned: 4
         Workers Launched: 4
         ->  Partial Aggregate  (cost=51417.02..51417.03 rows=1 width=8) (actual time=295.995..295.995 rows=1 loops=5)
               Output: PARTIAL count(*)

... 省略

「Workers Launchedが4」となっているがこれがプロセス数を示す。

これとは別にリーダーとなるプロセスが存在するので、全てのプロセスは5になる。

PostgreSQL10以降はWorkers Launchedのデフォルトは2。

改善

例:デフォルトが2のため、4に変更する。

set max_parallel_workers_per_gather to 4;

※通常のSETだと現在のセッションにしか適用されないので、デフォで適用するには↓

alter database <database name> set max_parallel_workers_per_gather to 4;

パラレルスキャンの並列数の制御

パラメータ名 デフォルト値 説明
max_worker_processes 8 データベース全体で作成可能な全てのワーカプロセスの上限値
max_parallel_workers 8 データベース全体で作成可能なパラレルスキャン用のワーカプロセスの上限値
max_parallel_workers_per_gather 2 1つのリーダノードで集約することのできるパラレルワーカプロセスの上限値

加えて改善

パラレルスキャンは、かなり小さいテーブルに対しても並列処理を実行しようとする。

そのため小さいテーブルのレスポンス速度が満足の場合はパラレルスキャンをさせないようにする。

例:テーブルサイズが12MBの場合はパラレルスキャンを実行させない。

set min_parallel_table_scan_size='12MB'

パラレルスキャン対象テーブルの下限サイズ

パラメータ名 デフォルト値 説明
min_parallel_table_scan_size 8MB パラレルスキャンを試みる最小のテーブルサイズ
min_parallel_index_scan_size 512KB パラレルインデックススキャンを試みる最小のインデックスサイズ

第15章 パラレルクエリ

PostgreSQLの設定を確認する

PostgreSQLの設定を確認

設定項目と設定値を確認するにはSHOW文を使う。

例:

SHOW shared_buffers;

例:

SHOW ALL;

詳細な情報を取得するには、pg_settingsを参照する。

SELECT name, setting, unit FROM pg_settings;

設定項目の変更 postgre.confの設定値を変更するにはSET文を使う。

※SET文では変更できない物もある。

例:

SET enable_seqscan = off;

SET文で変更できる設定項目を参照する。

SELECT name, context FROM pg_settings WHERE context IN ('user', 'superuser');

設定変更が反映されるタイミング
反映されるタイミングは3パターンある。

設定項目ごとにそれぞれ異なる。

タイミング 種類名称 説明
SET文実行時 user, superuser 発行したセッション内で即時反映される。他のセッションにも突然影響することはない。
PostgreSQL起動時 postmaster 起動時に反映される。再起動が必要になる。
SIGHUP シグナル受信時 sighup ポスグレのサーバがSIGHUPシグナルを受け取ったタイミング。いわゆる設定をリロードして反映する。pg_ctl reloadオプションやpg_reload_conf関数を使用する。

設定項目ごとの種類の名称を確認するには、 pg_settingsのcontext列に記載されている。

SELECT name, context from pg_settings;

pg_settings 公式 ver12

知っておきたい【SQLの実行後の流れ】

f:id:TaitoAjiki:20210513122021p:plain

プランナが重要

プランナで作成される計画のことを【実行計画】と言う。

実行計画は、さまざまな検索方法の中から処理コストが最小になる組み合わせを計算する。

そして、計算は【統計情報】を元に行われる。

統計情報とは..

テーブルやインデックス、各列のデータの重複度合いなどのこと。

または、ANALYZE文で取得する情報。

テーブルごとに3万件データからサンプリングしている。

 

データの数が数億件あったり、カーディナリが高い(データの種類が多い)とサンプリング数が足りず 正確な統計情報が取れない。

正確な統計情報が取れないことで、最適な実行計画が立てられず速度低下が起こる。

【SQLのコスト】を確認する

SQLを実行した時のコストを確認する

例:

EXPLAIN ANALYZE SELECT * FROM client;

Seq Scan on food (cost=0.00..20.70 rows=1070 width=24) (actual time=0.006..0.007 rows=13 loops=1)

Planning Time: 0.140 ms
Execution Time: 0.029 ms
actual time=0.006..0.007 a

actual timeの右の値(0.007)が総コストのため、この値が少ない方がいい。 

※秒数ではないので注意

Djangoで確認する方法

Client.objects.all().explain(analyze=True)

その他の値は今後機会があれば記事に...

【Ethernetとは?】をまとめる

Ethernet

Ethernethtは、ネットワークインターフェース層で優先のネットワーク層を提供する技術です。

一口にEthernetと言っても1つのプロトコルで定義されているわけではなく、ハードウェアを含めた様々な規格で提供されている有線LANの技術の総称のことをさします。

みなさんもルータやハブへの接続にLANケーブルを使ったことがあるでしょう。
あのLANケーブルで接続を提供しているのがEthernetです。
通信速度の発展によりEthernetにもさまざまな規格が登場しています。



Ethernetの伝送速度の発展により、10BASE-T100BASE-TX1000BASE-Tのような方式が登場しました。
それぞれ伝送速度が10Mbos, 100Mbps, 1000Mbps(1Gbps) に対応しています。

bpsは bit per second の略で、伝送速度を表す単位です。

1bpsは1秒間に1ビットのデータを転送できることを意味します。
1Mbosならば1Mビット、つまり1000000ビットのデータを転送できます。

 

ケーブルにも様々な種類が出てきています。
今は CAT5e, CAT6, CAT6aぐらいが主流です。数字が大きくなると伝送速度が上がるのがほとんどです。

【インターネットの歴史】

ARPANETの誕生 】

コンピュータによる通信が普及する前の主な通信手段は、電話の回線網でした。
遠隔の電話をつなげるために使われたのが回線交換方式で2台の電話が直接電気的につながって通信する方式でした。

 

コンピュータが登場してからは、電話のように電気でつなげるやり方ではなく、
通信したいデータを分割して転送する方法が考案されていました。
この分割したネットワーク上のデータのことをパケットと呼びます。

パケット交換方式では、遠隔のコンピュータが直接接続するのではなく、複数のマシンを経由して通信する方法が開発されました。

これがインターネットの前身となるARPANETです。

ARPANETでは複数のマシンを経由してパケットをやり取りするため、
遠隔のコンピュータと通信するときに複数の経路が存在します。


これにより、どこかのマシンに異常が発生しても別の経路で通信することが可能になり
耐障害性の高いネットワークを構築することが可能になりました。

 

【 インターネットの誕生 】

ARPANETの研究と並行して、世界では様々なコンピュータネットワークの研究が進みました。
幅広く相互接続するグローバルなネットワークを構築するためには、それらを統合する技術が必要でした。そんな中で誕生したのが、インターネットプロトコルスイートです。

プロトコルは通信規格のことで、スイートは一式を意味します。
ですのでインターネットプロトコルスイートはインターネットで使われるプロトコル群のことになります。

インターネットプロトコルスイートは異なるネットワークの相互接続を容易に実現できました。
そして世界中のコンピュータがどんどんインターネットプロトコルスイートを使って接続されていき、現代のインターネットへと発展していきます。

 

インターネットプロトコルスイート

インターネットプロトコルスイートで使われているプロトコルはいくつかの階層に分かれていて、
上位層のプロトコルが下位層のプロトコルを隠蔽することによって通信を実現しています。
これをカプセル化と言います。

カプセル化によって階層のプロトコルは隠蔽されるので、上位層のプロトコルを意識しないで自分の通信のみに注力ができます。このような階層構造を持つことで、異なるネットワーク同士でも容易にそうお接続ができるようになっています。

Webサーバの複数リクエスト処理には2種類の方法がある

Webサーバは、複数クライアントからのリクエストに同時並行で応答しないといけません。

同時並行で応答できるようになっていなければ、
1つのリクエストを処理している間は他のリクエストを受け付けることができません。
それでは多くのユーザに機能を提供できません。

複数リクエストの処理には、大きく分けてprefork型とイベント駆動型の2種類あります。

 

【 prefork型 】

OSは一つ一つのプロセスを高速に切り替えることで、
あたかも複数のプロセスが同時並行で実行されているかのように振舞います。


このOSが持つプロセスの仕組みを利用して
複数クライアントからのリクエストを同時並行で処理するのがprefork型です。

Webサーバは複数のプロセスを生成して、1つのプロセスが1つのコネクションを処理します。
プロセスの切り替えはOSがやってくれるのでWebサーバはそれぞれのプロセスで自分が担当している
リクエストの処理だけを担当すればよいことになります。


prefork型を作用している代表的なWebサーバにはApache HTTP Serverがあります。

prefork型はプロセスを使って処理をするために、
多くのリクエストを同時に処理するためには多くのプロセスを立ち上げる必要があります

しかしプロセス数が多くなるとOSによるプロセス切り替えの処理の割り合いが増えてしまい
コンピュータの処理能力が十分高くてもリクエストの処理にコンピュータの処理能力を活用できない
という問題がありました。
Webの発展によりリクエスト数が増え、コンピュータの処理能力が上がってもprefork型では十分な処理能力を提供できなくなりました。これをC10K問題(クライアント1万台問題)といいます。

この問題を解決するためにイベント駆動型のWebサーバが登場しました。

 

【 イベント駆動型 】

prefork型のように1つのプロセスで1つのリクエストを処理するやり方では、
プロセスが増えたときに効率よく処理ができなくなっていきました。

そこで1つのプロセスで複数のリクエストを処理するようにしたのがイベント駆動型です。

1つのプロセスで複数のリクエストを処理できるようにしたのがイベント駆動型です。
そうすることでプロセスの数が少なくなり、
OSによるプロセス切り替えがボトルネックになることはありません。

イベント駆動型では、1つのプロセスで複数のリクエストを処理するために非同期I/Oを使用します。

ネットワークやディスクとのデータのやり取りはCPUから見ると低速で、待ち時間が発生します。
低速なデバイスとのデータのやり取りの待ち状態のときに別の処理を実行するのが非同期I/Oです。

別の処理を実行している間は、データのやり取りの進行状況は分かりませんから、
データ受信をイベントとして受け取り処理を切り替えます。
これがイベント駆動型です。

イベント駆動型のWebサーバの登場により、
1台のPCでより多くのクライアントへ対応できるようになりました。

イベント駆動が他を採用している代表的なWebサーバにはnginxがあります、