このトピックでは、Hologres のモニタリングメトリックに関するよくある質問 (FAQ) について説明します。
接続数が多すぎる場合の接続の表示と強制終了
接続数には、Java Database Connectivity (JDBC) や PSQL からのアクティブな接続やアイドル状態の接続など、インスタンス内の SQL 接続の総数が含まれます。インスタンスの接続数は通常、その仕様に関連しています。接続数が多すぎる場合、インスタンスの最大接続数を超える場合、または次のエラーが発生した場合は、対処が必要です。
-
FATAL: sorry, too many clients already connection limit exceeded for superusersエラーが発生します。 -
FATAL: remaining connection slots are reserved for non-replication superuser connectionsエラーが発生します。
これは、インスタンスが接続制限に達したことを示しています。HoloWeb または SQL を使用して現在の接続を表示します。詳細については、「接続管理」をご参照ください。スーパーユーザーアカウントを使用して、予期しない接続またはアイドル状態の接続を Kill します。
クエリレイテンシーが高すぎる場合の対処法
クエリレイテンシーが高くなる原因は、多くの場合、次のとおりです。まず、スロークエリログで対応する遅い SQL ステートメントを特定し、次のシナリオに基づいて問題を解決します。詳細については、「スロークエリログの表示と分析」をご参照ください。
-
クエリ/秒 (QPS) が低いにもかかわらず、SQL ステートメントが複雑なため、クエリレイテンシーが高くなっています。
ソリューション: SQL ステートメントを最適化し、適切なインデックスを設定して、クエリパフォーマンスを向上させます。詳細については、「クエリパフォーマンスの最適化」および「MaxCompute 外部テーブルのクエリパフォーマンスの最適化」をご参照ください。
-
クエリの QPS が高いため、クエリレイテンシーが高くなっています。
ソリューション: SQL ステートメントがすでに最適化されているにもかかわらず、より高い QPS と低いレイテンシーが必要な場合は、インスタンスをスケールアウトします。リソースが増えるほど、パフォーマンスが向上します。詳細については、「インスタンスのアップグレード」をご参照ください。
-
クエリ中に多くの書き込み操作が発生し、クエリパフォーマンスに影響を与えるため、クエリレイテンシーが高くなっています。
ソリューション: 書き込み操作がクエリパフォーマンスに影響を与える場合は、次の操作を実行します。
-
クエリへの影響を軽減するため、ピーク時以外の時間帯に書き込み操作を実行します。
-
書き込み同時実行数を減らして、クエリ効率を向上させます。外部テーブルに書き込む場合は、次のパラメーターを使用して同時実行数を減らします。
-- MaxCompute 実行の最大同時実行数を設定します。デフォルト値は 128 です。1 つのクエリが他のクエリに影響を与え、システムエラーを引き起こすのを防ぐため、この値を小さく設定します。 set hg_experimental_foreign_table_executor_max_dop = 32; -- Recommended setting -- MaxCompute テーブルからの各読み取りのバッチサイズを調整します。デフォルト値は 8192 です。 set hg_experimental_query_batch_size = 1024; -- ORC ファイルを直接読み取ります。 set hg_experimental_enable_access_odps_orc_via_holo = on; -- MaxCompute テーブルにアクセスするためのスプリットサイズを設定します。これにより、同時実行タスクの数が調整されます。デフォルト値は 64 MB です。大規模なテーブルの場合、スプリットが多すぎるとパフォーマンスに影響を与えるのを防ぐため、この値を増やします。 set hg_experimental_foreign_table_split_size = 512MB;
-
メモリ使用量が高くなる原因と解決策
Hologres インスタンスのメモリ使用量は、全体的なメモリ使用率です。Hologres はメモリリソースに予約モデルを使用します。クエリがない場合でも、テーブルのメタデータ、インデックス、データキャッシュは、取得と計算を高速化するためにメモリにロードされます。この状態では、メモリ使用量がゼロより高いのは正常です。理論的には、クエリが実行されていない場合、メモリ使用量は約 30% から 40% が正常です。
場合によっては、メモリ使用量が継続的に増加し、80% に近づくことがあります。主な原因は次のとおりです。
-
テーブル数と総データ量が増加しており、データ規模が現在の計算仕様をはるかに超えています。メモリ使用量は、メタデータとインデックスの量に正の相関があります。したがって、テーブル数が多いほど、データ量が多いほど、インデックスが多いほど、メモリ使用量が高くなります。
-
インデックスが適切に設定されていません。たとえば、テーブルに多くの列があり、そのほとんどが TEXT 列であり、ビットマップインデックスまたはディクショナリインデックスが多すぎます。この場合、一部のビットマップインデックスまたはディクショナリインデックスを削除することを検討してください。詳細については、「ALTER TABLE」をご参照ください。
ただし、メモリ使用量が長時間にわたって着実に増加し、80% 近くを維持している場合、通常はメモリリソースがシステムボトルネックになっていることを意味します。これは、インスタンスの安定性やパフォーマンスに影響を与える可能性があります。安定性への影響は、過大なメタデータが通常のクエリで利用できるはずのメモリ空間を占有する場合に発生します。クエリプロセス中に、SERVER_INTERNAL_ERROR、ERPC_ERROR_CONNECTION_CLOSED、または Total memory used by all existing queries exceeded memory limitation などのエラーが時折発生する可能性があります。パフォーマンスへの影響は、過大なメタデータが通常のクエリで使用されるはずのキャッシュ空間を占有する場合に発生します。これにより、キャッシュヒット率が低下し、クエリレイテンシーが増加します。
したがって、メモリ使用量が長時間 80% 近くを維持している場合は、次の操作を検討してください。
-
クエリされなくなったデータを削除して、メタデータが占有するメモリを解放します。
-
適切なインデックスを設定します。ビジネスシナリオでビットマップインデックスとディクショナリインデックスが使用されていない場合は、それらを削除できます。ただし、ビジネス要件を具体的に分析せずに直接削除しないでください。
-
インスタンスの計算およびストレージリソースをアップグレードします。アップグレードの推奨事項は次のとおりです。
-
一般的なシナリオ: ディスクからのデータ読み取りによるレイテンシーを許容でき、応答時間要件が厳しくない場合、1 CU (1 Core + 4 GB メモリ) で 50 GB から 100 GB のデータストレージをサポートできます。
-
応答時間要件が低いサービスシナリオ: 最高のパフォーマンスを得るには、クエリのすべてのホットスポットデータがメモリキャッシュにある必要があります。デフォルトでは、キャッシュは総メモリの 30% を占有します。1 CU インスタンス (1 Core + 4 GB メモリ) の場合、1.3 GB がデータキャッシュに使用されます。このキャッシュの一部はテーブルメタデータにも使用されます。たとえば、100 GB のホットスポットデータを持つ低レイテンシーシナリオでは、少なくとも 100 GB の利用可能なキャッシュが必要です。データが読み取られ、解凍された後、100 GB を超えるメモリを占有します。したがって、少なくとも 320 GB のメモリが必要であり、これは少なくとも 96 CU の計算リソースが必要であることを意味します。
-
Hologres インスタンスの CPU 使用率が 1 つのタスクのみで 100% に達する理由
Hologres インスタンスの CPU 使用率は、インスタンス全体の CPU 使用率です。Hologres はマルチコア並列計算を最大限に活用できます。単一のクエリでも CPU 使用率をすぐに 100% にまで高めることができます。これは、計算リソースが完全に利用されていることを示しています。CPU 使用率が高いこと自体は問題ではありません。問題は、CPU 使用率が高いことがクエリや書き込みの遅延につながる場合に発生し、包括的な分析が必要です。
書き込み遅延の解決方法
insert、insert on conflict、または update コマンドに時間がかかる場合、書き込みパフォーマンスが低いことを示しています。この問題は通常、Fixed Plan を使用しない SQL クエリが原因で発生します。Fixed Plan を使用しない SQL コマンドはテーブルロックの対象となります。同時実行中に、これらのコマンドはロックを待機する必要があり、実行時間が長くなります。その結果、Real-time Write RPS モニタリングメトリックでは、書き込みタイプが insert と表示されます。クエリの特性を分析し、Fixed Plan を使用するように書き換えることができます。これにより、モニタリングメトリックの書き込みタイプが SDK に変更され、書き込みパフォーマンスが向上します。詳細については、「Fixed Plan を使用した SQL 実行の高速化」をご参照ください。
CPU 使用率が長時間 100% のままの場合の対処法
Hologres インスタンスの CPU 使用率が長時間 (たとえば、3 時間連続で 100%、または 12 時間連続で 90% 以上) 100% 近くを維持している場合、インスタンスの負荷が非常に高いことを示しています。これは通常、CPU リソースがシステムボトルネックになっていることを意味します。原因を特定するために、ビジネスシナリオとクエリを分析する必要があります。次の観点からトラブルシューティングできます。
-
トラブルシューティング 1: QPS または RPS の大幅な増加。
CPU 使用率が増加する前後の QPS および RPS モニタリングメトリックを比較します。CPU 使用率の上昇を引き起こす明確な上昇傾向がある場合は、次のソリューションに進みます。
ソリューションは次のとおりです。
-
SELECT 操作が CPU 使用率の増加を引き起こしている場合は、スロークエリログを使用して長時間実行クエリを特定し、最適化します。
-
insert、update、またはdelete操作の実行が CPU 使用率の増加を引き起こしている場合は、スロークエリログをチェックして、次の SQL に示すように、クエリが Fixed Plan を使用していないかどうかを判断します。Fixed Plan を使用しないinsert、update、またはdeleteコマンドはテーブルロックを作成します。その結果、同時実行クエリはロック待機を引き起こします。ビジネスロジックの観点から、SQL ステートメントを Fixed Plan を使用するように書き換えて、テーブルロックを回避し、CPU 使用率を削減できるかどうかを評価できます。-- 例: 過去 3 時間に Fixed Plan を使用しなかった insert/update/delete 操作を表示します。 select * from hologres.hg_query_log where query_start >= now() - interval '3 h' and command_tag in ('INSERT','UPDATE','DELETE') and 'HQE'=ANY(engine_type) order by query_start desc limit 500; -
すべての SQL ステートメントが最適化されているにもかかわらず、CPU 使用率が依然として高い場合、インスタンスリソースがボトルネックに達しています。インスタンスをスケールアウトするか、共有ストレージを持つ複数のインスタンスをデプロイして読み書き分離を実装できます。詳細については、「インスタンスのアップグレード」または「読み書き分離 (共有ストレージ) のためのプライマリおよびセカンダリインスタンスのデプロイ」をご参照ください。
-
-
トラブルシューティング 2: QPS または RPS の大幅な増加はないが、長時間実行クエリが存在する。
モニタリングメトリックで QPS または RPS の大幅な増加がないにもかかわらず、CPU 使用率が突然増加し、高い状態を維持している場合は、
Running Query Durationメトリックで長時間実行クエリをチェックします。メトリックが 30 分または 1 時間以上実行されているクエリを示している場合、これらのクエリが高い CPU 使用率の原因です。次のコマンドを使用してアクティブなクエリを見つけ、それらを終了して CPU 使用率を削減します。-- 長時間実行クエリを表示します。 SELECT current_timestamp - query_start as runtime, datname::text, usename, query, pid::text FROM pg_stat_activity WHERE state != 'idle' order by 1 desc; -- クエリをキャンセルします。 select pg_cancel_backend(<pid>); -
トラブルシューティング 3: QPS または RPS の大幅な増加はないが、高 CPU 消費クエリが存在する。
モニタリングメトリックで QPS または RPS の大幅な増加がないにもかかわらず、CPU 使用率が突然増加し、高い状態を維持している場合は、次のコマンドを使用してスロークエリログで高 CPU 消費クエリを見つけます。これにより、CPU を消費する操作を特定し、SQL ステートメントを最適化できます。
-- 過去 3 時間の高消費クエリをクエリします。 select status as "Status", duration as "Duration (ms)", query_start as "Start Time", (read_bytes/1048576)::text || ' MB' as "Read Volume", (memory_bytes/1048576)::text || ' MB' as "Memory", (shuffle_bytes/1048576)::text || ' MB' as "Shuffle", (cpu_time_ms/1000)::text || ' s' as "CPU Time", physical_reads as "Disk Reads", query_id as "QueryID", query from hologres.hg_query_log where query_start > current_timestamp - interval'3 h' and command_tag in ('SELECT','INSERT','UPDATE','DELETE') and duration > 1000 order by duration desc, read_bytes desc, shuffle_bytes desc, memory_bytes desc, cpu_time_ms desc, physical_reads desc limit 500; -
トラブルシューティング 4: PQE SQL ステートメントが CPU 使用率を 100% にする。
モニタリングメトリックで QPS または RPS の大幅な増加がない場合は、次の SQL コマンドを使用してスロークエリログで CPU 使用率の増加を引き起こしている可能性のある新しい PQE SQL ステートメントをチェックします。PQE SQL ステートメントが存在する場合は、PQE エンジンを使用する SQL 内のオペレーターを最適化します。詳細については、「クエリパフォーマンスの最適化」をご参照ください。
-- 過去 3 時間に PQE エンジンを使用したクエリをクエリします。 select * from hologres.hg_query_log where query_start > current_timestamp - interval'3 h' and 'PQE'=ANY(engine_type) order by query_start desc limit 500; -
トラブルシューティング 5: テーブルのビットマップインデックスまたはディクショナリインデックスが変更された。
テーブルのビットマップインデックスまたはディクショナリインデックスを変更すると、非同期バックグラウンドコンパクションプロセスがトリガーされ、一部の CPU リソースを消費します。インスタンスのストレージ使用量は、最初に増加し、その後減少する可能性があります。次の SQL コマンドを使用して、スロークエリログでインデックス変更レコードをチェックします。
-- 過去 3 時間のインデックス変更レコードをクエリします。 select * from hologres.hg_query_log where query_start >= now() - interval '3 h' and command_tag in ('CALL') order by query_start desc limit 500;
長時間実行クエリの処理方法
Running Query Duration メトリックは、実行時間が 1 時間を超えるクエリなど、長時間実行クエリを示します。長時間実行クエリが表示されたら、まず Active Query Tasks ページに移動して、実行中のクエリを表示します。詳細については、「クエリ管理」をご参照ください。長時間実行クエリは通常、次の状況で発生します。状況に基づいてトラブルシューティングしてください。
-
シナリオ 1: インスタンスで長時間実行の書き込み操作がある。
ソリューション: Real-time Write RPS メトリックをチェックして、クエリの実行時間を長くしている継続的な書き込みタスクがあるかどうかを確認します。
-
シナリオ 2: アイドル状態のトランザクション。
-
クライアントがトランザクションを開き、DDL 操作を実行したが、コミットしていない。次の SQL コマンドを使用してアクティブなクエリのステータスをクエリします。クエリステータスは
idle in transactionと表示され、実行時間が長くなります。-- 長時間実行クエリを表示します。 SELECT current_timestamp - query_start as runtime, datname::text, usename, query, pid::text FROM pg_stat_activity WHERE state != 'idle' order by 1 desc; -
ロック待機またはその他の理由によりクエリがスタックし、長時間実行される。
ソリューション: 次の SQL 例を使用して長時間実行クエリを見つけます。
idle in transactionが原因で実行時間が長い場合は、クライアントでトランザクションを閉じるか、適切なアイドル状態のトランザクションタイムアウトを設定します。詳細については、「アイドルクエリタイムアウトの変更」をご参照ください。-- 長時間実行クエリを表示します。 SELECT current_timestamp - query_start as runtime, datname::text, usename, query, pid::text FROM pg_stat_activity WHERE state != 'idle' order by 1 desc; -- スーパーユーザーがクエリをキャンセルします。 select pg_cancel_backend(<pid>); -
-
シナリオ 3: クエリに複雑な SQL が含まれ、PQE エンジンを使用している。
ソリューション: 次のコマンドを使用して、現在実行中の長時間実行クエリを見つけます。次に、実行計画 (`explain sql`) を使用して、SQL ステートメントが PQE エンジンを使用しているかどうか (実行計画に
External SQL (Postgres)が含まれている) を確認し、それが実行時間を長くしている原因かどうかを判断します。-- 長時間実行クエリを表示します。 SELECT current_timestamp - query_start as runtime, datname::text, usename, query, pid::text FROM pg_stat_activity WHERE state != 'idle' order by 1 desc; -- クエリの実行計画を表示します。 explain sql-
スーパーユーザーアカウントを使用して、長時間実行クエリを強制終了します。
-
PQE エンジンを使用する SQL ステートメント内のオペレーターを最適化します。詳細については、「クエリパフォーマンスの最適化」をご参照ください。
-
-
シナリオ 4: DDL の同時実行がロック競合を引き起こす。
DDL の同時実行はテーブルをロックし、ロック競合とロック待機を引き起こし、実行時間を長くします。
ソリューション:
-
次のコマンドを使用して、DDL 操作が進行中かどうかを確認し、それらを強制終了してロックを解放します。
SELECT datname::text,usename,query,pid::text,state FROM pg_stat_activity WHERE state != 'idle' ; -
DDL 操作を順次実行します。
-
失敗したクエリのトラブルシューティング
失敗したクエリは、1 秒あたりの失敗したクエリ数を示します。クエリの総数は、期間に QPS を掛けたものであり、曲線下の面積です。失敗したクエリの総数を判断するために QPS に依存しないでください。スロークエリログを使用して、失敗したクエリの総数と失敗の原因を見つけます。次に、特定のエラーに基づいて問題を解決します。詳細については、「スロークエリログの表示と分析」をご参照ください。
ワーカー間の CPU 負荷の不均衡の解決方法
Hologres では、データパーティショニング (シャード) によってデータの分散方法が決まります。ワーカーは、計算中に 1 つ以上のシャードからデータにアクセスする場合があります。同じインスタンス内では、シャードは一度に 1 つのワーカーのみがアクセスできます。インスタンス内の異なるワーカーが異なる総数のシャードにアクセスする場合、ワーカーリソースに負荷の不均衡が発生する可能性があります。主な原因は次のとおりです。
-
原因 1: データスキューが存在する。
深刻なデータスキューがある場合、ワーカーの負荷は特定のシャードに集中し、CPU 負荷の不均衡につながります。
ソリューション: 次のステートメントを使用してデータスキューをチェックします。例の結果では、1 つのシャードのカウントが他のシャードよりもはるかに大きく、データスキューを示しています。必要に応じて、スキューしたデータを処理するか、適切な分散キーを設定します。詳細については、「クエリパフォーマンスの最適化」をご参照ください。
select hg_shard_id,count(1) from <table_name> group by hg_shard_id; -- 例の結果: シャード 39 のカウントが大きく、スキューを示しています。 hg_shard_id | count -------------+-------- 53 | 29130 65 | 28628 66 | 26970 70 | 28767 77 | 28753 24 | 30310 15 | 29550 39 | 164983 -
原因 2: インスタンスに設定されたシャード数がワーカー数の整数倍ではない。
テーブルグループに設定されたシャード数がインスタンス内のワーカーの総数の整数倍ではない場合、異なる数のシャードが異なるワーカーに割り当てられます。これにより、負荷の不均衡が発生します。
ソリューション: インスタンスの仕様に基づいて適切なシャード数を設定します。詳細については、「テーブルグループとシャード数の管理」をご参照ください。この状況は通常、大規模な仕様のインスタンス (256 コア以上) で発生します。小規模な仕様のインスタンスでは、デフォルトのシャード数を使用できます。
-
原因 3: ワーカーのフェールオーバー後のシャード分散の不均衡。
メモリ不足 (OOM) エラーまたはその他の理由によりワーカーが終了 (強制終了) された場合、システムはクエリを迅速に回復するために、そのワーカーのシャードを他のワーカーに迅速に移行します。強制終了されたワーカーが再起動されると、システムは一部のシャードをそれに再割り当てします。これにより、ワーカー間のシャード分散に不均衡が生じる可能性があります。
ソリューション: インスタンスの負荷が低い場合、この負荷の不均衡を無視できます。インスタンスの負荷が高い場合は、インスタンスを再起動してシャードリソースを均等に再分散します。