目標
このレッスンを終えると、
- PostgreSQL HA クラスターの重要なメトリクスを理解する_
- 監視する Prometheus + Grafana をセットアップ
- 構成するpostgres_exporter と patroni_exporter
- ダッシュボードとアラート ルールを作成
- etcd クラスターの健全性を監視
- 可観測性のためのベスト プラクティスを実装
1。監視が重要な理由
1.1.モニタリング目標_
可視性:
✅ Know cluster health in real-time
✅ Detect issues before users notice
✅ Track performance trends
✅ Capacity planning data
✅ Audit trail for incidents
回答すべき重要な質問:
- Is the cluster healthy?
- Is replication working?
- What's the lag?
- Is there any failover?
- Are connections saturated?
- What's the query performance?
- Is etcd healthy?
Are backups running?
1.2。 4 つのゴールデン シグナル_
Latency: リクエストにはどのくらい時間がかかりますか?
-- Query execution time
SELECT query, mean_exec_time, calls
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;
Traffic: リクエストの数はどれくらいですか?リクエスト?
-- Connection count SELECT count(*) FROM pg_stat_activity;
-- Transactions per second SELECT xact_commit + xact_rollback AS tps FROM pg_stat_database WHERE datname = 'mydb';
エラー: 何が失敗していますか?
-- Failed queries
SELECT query, calls, errors
FROM pg_stat_statements
WHERE errors > 0;
彩度: どれくらい埋まっていますか?リソース?
-- Connection usage
SELECT count(*), max_connections
FROM pg_stat_activity,
(SELECT setting::int AS max_connections FROM pg_settings WHERE name = 'max_connections') s;
2。監視する指標
2.1。クラスターレベルのメトリック
クラスターの健全性_
✅ Number of nodes up/down
✅ Current leader
✅ Failover count
✅ Timeline number
✅ Cluster configuration version
レプリケーションの健全性_
✅ Replication lag (bytes and time)
✅ WAL sender/receiver status
✅ Sync vs async replica count
✅ Replication slot usage
✅ WAL segment generation rate
2.2。 PostgreSQL メトリクス_
接続メトリクス_
-- Active connections by state SELECT state, count(*) FROM pg_stat_activity GROUP BY state;
-- state | count -- -------------------+------- -- active | 15 -- idle | 50 -- idle in transaction| 2
データベースのサイズと増加_
-- Database sizes SELECT datname, pg_size_pretty(pg_database_size(datname)) AS size FROM pg_database ORDER BY pg_database_size(datname) DESC;
-- Growth rate (need historical data) SELECT now(), pg_database_size('mydb') AS size_bytes;
トランザクション率
-- Transactions per second
SELECT datname,
xact_commit + xact_rollback AS total_xacts,
xact_commit,
xact_rollback
FROM pg_stat_database
WHERE datname = 'mydb';
キャッシュ ヒット比率
-- Buffer cache hit ratio (should be > 95%)
SELECT
sum(heap_blks_read) AS heap_read,
sum(heap_blks_hit) AS heap_hit,
sum(heap_blks_hit) / nullif(sum(heap_blks_hit) + sum(heap_blks_read), 0) * 100 AS cache_hit_ratio
FROM pg_statio_user_tables;
インデックスの使用
-- Tables with missing indexes (high seq scans)
SELECT schemaname, tablename, seq_scan, seq_tup_read,
idx_scan, seq_tup_read / nullif(seq_scan, 0) AS avg_seq_tup
FROM pg_stat_user_tables
WHERE seq_scan > 0
ORDER BY seq_tup_read DESC
LIMIT 10;
バキュームとautovacuum_
-- Last vacuum/analyze
SELECT schemaname, tablename,
last_vacuum,
last_autovacuum,
last_analyze,
last_autoanalyze,
n_dead_tup
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC;
ロック_
-- Current locks
SELECT locktype, relation::regclass, mode, granted
FROM pg_locks
WHERE NOT granted; -- Waiting locks
長時間実行クエリ_
-- Queries running > 5 minutes
SELECT pid,
now() - query_start AS duration,
state,
query
FROM pg_stat_activity
WHERE state = 'active'
AND now() - query_start > interval '5 minutes'
ORDER BY duration DESC;
2.3。 Patroni メトリクス_
REST API 経由 (http://node:8008/metrics):
# Patroni metrics patroni_patroni_info{scope="postgres",version="3.2.0"} patroni_postgres_running{scope="postgres"} 1 patroni_postmaster_start_time{scope="postgres"} 1732531200 patroni_timeline{scope="postgres"} 3 patroni_cluster_unlocked{scope="postgres"} 0Replication metrics
patroni_replication_lag_bytes{application_name="node2"} 0 patroni_xlog_location{scope="postgres"} 100663296 patroni_xlog_replayed_location{scope="postgres"} 100663296 patroni_is_leader{scope="postgres"} 1
2.4。 etcd メトリクス_
etcd メトリクス エンドポイント経由 (http://node:2379/metrics):
# etcd health etcd_server_has_leader 1 etcd_server_is_leader 0 etcd_server_leader_changes_seen_total 2Performance
etcd_disk_backend_commit_duration_seconds_bucket etcd_network_peer_round_trip_time_seconds_bucket
Cluster size
etcd_cluster_version{cluster_version="3.5"} etcd_server_id{server_id="node1"}
2.5。システムメトリクス_
# CPU usage top htopMemory
free -h
Disk I/O
iostat -x 1
Disk space
df -h
Network
netstat -s ss -s
3。プロメテウスのセットアップ_
3.1。 Prometheus_
# Download cd /tmp wget https://github.com/prometheus/prometheus/releases/download/v2.48.0/prometheus-2.48.0.linux-amd64.tar.gz tar -xzf prometheus-2.48.0.linux-amd64.tar.gz sudo mv prometheus-2.48.0.linux-amd64 /opt/prometheusCreate user
sudo useradd --no-create-home --shell /bin/false prometheus
Create directories
sudo mkdir -p /etc/prometheus /var/lib/prometheus sudo chown prometheus:prometheus /var/lib/prometheus
3.2 をインストールします。 Prometheus
# /etc/prometheus/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
cluster: 'postgres-ha'
environment: 'production'
Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
- localhost:9093
Load rules
rule_files:
- "alerts/*.yml"
Scrape configurations
scrape_configs:
Prometheus itself
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
PostgreSQL (via postgres_exporter)
- job_name: 'postgresql'
static_configs:
- targets:
- 10.0.1.11:9187 # node1
- 10.0.1.12:9187 # node2
- 10.0.1.13:9187 # node3
relabel_configs:
- source_labels: [address]
regex: '([^:]+):.*'
target_label: instance
Patroni (via REST API)
- job_name: 'patroni'
static_configs:
- targets:
- 10.0.1.11:8008
- 10.0.1.12:8008
- 10.0.1.13:8008
metrics_path: /metrics
etcd
- job_name: 'etcd'
static_configs:
- targets:
- 10.0.1.11:2379
- 10.0.1.12:2379
- 10.0.1.13:2379
scheme: http
Node exporter (system metrics)
job_name: 'node' static_configs:targets:- 10.0.1.11:9100
- 10.0.1.12:9100
10.0.1.13:9100
3.3 を構成します。 systemd サービス
# /etc/systemd/system/prometheus.service sudo tee /etc/systemd/system/prometheus.service <<EOF [Unit] Description=Prometheus Wants=network-online.target After=network-online.target[Service] User=prometheus Group=prometheus Type=simple ExecStart=/opt/prometheus/prometheus \ --config.file=/etc/prometheus/prometheus.yml \ --storage.tsdb.path=/var/lib/prometheus/ \ --storage.tsdb.retention.time=30d \ --web.console.templates=/opt/prometheus/consoles \ --web.console.libraries=/opt/prometheus/console_libraries
Restart=on-failure RestartSec=5
[Install] WantedBy=multi-user.target EOF
Set permissions
sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml
Start
sudo systemctl daemon-reload sudo systemctl start prometheus sudo systemctl enable prometheus
Verify
sudo systemctl status prometheus curl http://localhost:9090/metrics
4 を作成します。エクスポーターのセットアップ_
4.1。 postgres_exporter
# Install on each PostgreSQL node cd /tmp wget https://github.com/prometheus-community/postgres_exporter/releases/download/v0.15.0/postgres_exporter-0.15.0.linux-amd64.tar.gz tar -xzf postgres_exporter-0.15.0.linux-amd64.tar.gz sudo mv postgres_exporter-0.15.0.linux-amd64/postgres_exporter /usr/local/bin/Create monitoring user in PostgreSQL
sudo -u postgres psql -c " CREATE USER postgres_exporter WITH PASSWORD 'exporter_password'; GRANT pg_monitor TO postgres_exporter; "
Create connection file
sudo tee /etc/postgres_exporter.env <<EOF DATA_SOURCE_NAME=postgresql://postgres_exporter:exporter_password@localhost:5432/postgres?sslmode=disable EOF
sudo chmod 600 /etc/postgres_exporter.env
カスタムクエリ (オプション):
# /etc/postgres_exporter/queries.yml
pg_replication:
query: |
SELECT
application_name,
client_addr,
state,
COALESCE(pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn), 0) AS lag_bytes,
EXTRACT(EPOCH FROM replay_lag) AS replay_lag_seconds
FROM pg_stat_replication
metrics:
- application_name:
usage: "LABEL"
description: "Application name"
- client_addr:
usage: "LABEL"
description: "Client address"
- state:
usage: "LABEL"
description: "Replication state"
- lag_bytes:
usage: "GAUGE"
description: "Replication lag in bytes"
- replay_lag_seconds:
usage: "GAUGE"
description: "Replay lag in seconds"
Systemdサービス_:
# /etc/systemd/system/postgres_exporter.service sudo tee /etc/systemd/system/postgres_exporter.service <<EOF [Unit] Description=Prometheus PostgreSQL Exporter After=network.target[Service] Type=simple User=postgres EnvironmentFile=/etc/postgres_exporter.env ExecStart=/usr/local/bin/postgres_exporter \ --web.listen-address=:9187 \ --extend.query-path=/etc/postgres_exporter/queries.yml
Restart=on-failure RestartSec=5
[Install] WantedBy=multi-user.target EOF
Start
sudo systemctl daemon-reload sudo systemctl start postgres_exporter sudo systemctl enable postgres_exporter
Verify
curl http://localhost:9187/metrics | grep pg_
4.2。 node_exporter
# Install on each node cd /tmp wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz tar -xzf node_exporter-1.7.0.linux-amd64.tar.gz sudo mv node_exporter-1.7.0.linux-amd64/node_exporter /usr/local/bin/Systemd service
sudo tee /etc/systemd/system/node_exporter.service <<EOF [Unit] Description=Prometheus Node Exporter After=network.target
[Service] Type=simple ExecStart=/usr/local/bin/node_exporter \ --web.listen-address=:9100
Restart=on-failure RestartSec=5
[Install] WantedBy=multi-user.target EOF
Start
sudo systemctl daemon-reload sudo systemctl start node_exporter sudo systemctl enable node_exporter
Verify
curl http://localhost:9100/metrics | head -20
4.3。 Patroni メトリクス エンドポイント
すでに組み込まれています! Patroni は_
# Check Patroni metrics curl http://localhost:8008/metricsSample output:
patroni_postgres_running 1
patroni_postmaster_start_time 1732531200
patroni_timeline 3
patroni_cluster_unlocked 0
patroni_is_leader 1
5 でメトリクスを公開しています。 Grafana のセットアップ_
5.1。 Grafana_
# Add repository sudo apt-get install -y software-properties-common sudo add-apt-repository "deb https://packages.grafana.com/oss/deb stable main" wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -Install
sudo apt-get update sudo apt-get install -y grafana
Start
sudo systemctl start grafana-server sudo systemctl enable grafana-server
Access: http://your-server:3000
Default credentials: admin / admin
5.2 をインストールします。 Prometheus データ ソース
1. Login to Grafana (http://localhost:3000)
2. Go to Configuration → Data Sources
3. Click "Add data source"
4. Select "Prometheus"
5. URL: http://localhost:9090
6. Click "Save & Test"
5.3 を追加します。ダッシュボードのインポート_
PostgreSQL ダッシュボード:
1. Go to Dashboards → Import
2. Enter dashboard ID: 9628 (PostgreSQL Database)
3. Select Prometheus data source
4. Click Import
Patroniダッシュボード (カスタム):
{
"dashboard": {
"title": "Patroni Cluster Overview",
"panels": [
{
"title": "Cluster Status",
"targets": [
{
"expr": "patroni_postgres_running"
}
]
},
{
"title": "Leader",
"targets": [
{
"expr": "patroni_is_leader"
}
]
},
{
"title": "Timeline",
"targets": [
{
"expr": "patroni_timeline"
}
]
},
{
"title": "Replication Lag",
"targets": [
{
"expr": "patroni_replication_lag_bytes"
}
]
}
]
}
}
etcd ダッシュボード:
Dashboard ID: 3070 (etcd by Prometheus)
ノード エクスポーターダッシュボード:
Dashboard ID: 1860 (Node Exporter Full)
6。アラート ルール
6.1。 PostgreSQL アラート_
# /etc/prometheus/alerts/postgresql.yml
groups:
name: postgresql interval: 30s rules:
PostgreSQL down
- alert: PostgreSQLDown expr: pg_up == 0 for: 1m labels: severity: critical annotations: summary: "PostgreSQL instance {{ $labels.instance }} is down" description: "PostgreSQL on {{ $labels.instance }} has been down for more than 1 minute"
High replication lag
- alert: PostgreSQLReplicationLag expr: pg_replication_lag_bytes > 104857600 # 100MB for: 5m labels: severity: warning annotations: summary: "High replication lag on {{ $labels.instance }}" description: "Replication lag is {{ $value }} bytes (>100MB)"
Too many connections
- alert: PostgreSQLTooManyConnections expr: | sum(pg_stat_activity_count) by (instance) / pg_settings_max_connections * 100 > 80 for: 5m labels: severity: warning annotations: summary: "Too many connections on {{ $labels.instance }}" description: "Connection usage is {{ $value }}% (>80%)"
Replication slot lag
- alert: PostgreSQLReplicationSlotLag expr: pg_replication_slots_lag_bytes > 1073741824 # 1GB for: 10m labels: severity: warning annotations: summary: "Replication slot {{ $labels.slot_name }} lag high" description: "Slot lag is {{ $value }} bytes (>1GB)"
Long-running queries
- alert: PostgreSQLLongRunningQueries expr: pg_stat_activity_max_tx_duration > 3600 # 1 hour for: 5m labels: severity: warning annotations: summary: "Long-running query on {{ $labels.instance }}" description: "Query running for {{ $value }} seconds (>1h)"
Dead tuples
- alert: PostgreSQLDeadTuples expr: pg_stat_user_tables_n_dead_tup > 10000 for: 30m labels: severity: warning annotations: summary: "High dead tuples on table {{ $labels.table }}" description: "Table has {{ $value }} dead tuples"
Cache hit ratio low
alert: PostgreSQLCacheHitRatio expr: | sum(pg_stat_database_blks_hit) / nullif(sum(pg_stat_database_blks_hit + pg_stat_database_blks_read), 0) * 100 < 95 for: 15m labels: severity: warning annotations: summary: "Low cache hit ratio on {{ $labels.instance }}" description: "Cache hit ratio is {{ $value }}% (<95%)"
6.2。 Patroni アラート_
# /etc/prometheus/alerts/patroni.yml
groups:
name: patroni
interval: 30s
rules:
Patroni down
- alert: PatroniDown
expr: up{job="patroni"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Patroni on {{ $labels.instance }} is down"
No leader
- alert: PatroniNoLeader
expr: sum(patroni_is_leader) == 0
for: 30s
labels:
severity: critical
annotations:
summary: "Patroni cluster has no leader"
description: "No node is acting as leader in the cluster"
Multiple leaders (split-brain)
- alert: PatroniMultipleLeaders
expr: sum(patroni_is_leader) > 1
for: 10s
labels:
severity: critical
annotations:
summary: "Multiple Patroni leaders detected (split-brain)"
description: "{{ $value }} nodes claim to be leader"
Timeline mismatch
- alert: PatroniTimelineMismatch
expr: count(count by (timeline) (patroni_timeline)) > 1
for: 1m
labels:
severity: critical
annotations:
summary: "Patroni timeline mismatch"
description: "Nodes are on different timelines"
Failover detected
- alert: PatroniFailover
expr: increase(patroni_timeline[5m]) > 0
labels:
severity: warning
annotations:
summary: "Patroni failover detected"
description: "Timeline changed, indicating a failover occurred"
Cluster unlocked
alert: PatroniClusterUnlocked expr: patroni_cluster_unlocked == 1 for: 30s labels: severity: warning annotations: summary: "Patroni cluster is unlocked"
6.3。 etcd アラート_
# /etc/prometheus/alerts/etcd.yml
groups:
name: etcd
interval: 30s
rules:
etcd down
- alert: EtcdDown
expr: up{job="etcd"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "etcd node {{ $labels.instance }} is down"
No leader
- alert: EtcdNoLeader
expr: etcd_server_has_leader == 0
for: 1m
labels:
severity: critical
annotations:
summary: "etcd cluster has no leader"
High leader changes
- alert: EtcdFrequentLeaderChanges
expr: increase(etcd_server_leader_changes_seen_total[1h]) > 3
labels:
severity: warning
annotations:
summary: "etcd frequent leader changes"
description: "{{ $value }} leader changes in last hour"
High commit latency
alert: EtcdHighCommitLatency expr: | histogram_quantile(0.99, rate(etcd_disk_backend_commit_duration_seconds_bucket[5m]) ) > 0.25 for: 5m labels: severity: warning annotations: summary: "etcd high commit latency" description: "99th percentile commit latency is {{ $value }}s"
7。アラートマネージャーのセットアップ
7.1。 Alertmanager
# Download cd /tmp wget https://github.com/prometheus/alertmanager/releases/download/v0.26.0/alertmanager-0.26.0.linux-amd64.tar.gz tar -xzf alertmanager-0.26.0.linux-amd64.tar.gz sudo mv alertmanager-0.26.0.linux-amd64 /opt/alertmanagerCreate user
sudo useradd --no-create-home --shell /bin/false alertmanager
Create directories
sudo mkdir -p /etc/alertmanager /var/lib/alertmanager sudo chown alertmanager:alertmanager /var/lib/alertmanager
7.2 をインストールします。 Alertmanager
# /etc/alertmanager/alertmanager.yml
global:
resolve_timeout: 5m
slack_api_url: 'https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK'
route:
group_by: ['alertname', 'cluster', 'service']
group_wait: 10s
group_interval: 10s
repeat_interval: 12h
receiver: 'default'
routes:
- match:
severity: critical
receiver: 'critical'
- match:
severity: warning
receiver: 'warning'
receivers:
-
name: 'default'
slack_configs:
- channel: '#alerts'
title: 'PostgreSQL HA Alert'
text: '{{ range .Alerts }}{{ .Annotations.description }}{{ end }}'
-
name: 'critical'
slack_configs:
- channel: '#alerts-critical'
title: '🚨 CRITICAL: {{ .GroupLabels.alertname }}'
text: '{{ range .Alerts }}{{ .Annotations.description }}{{ end }}'
email_configs:
- to: '[email protected]'
from: '[email protected]'
smarthost: 'smtp.example.com:587'
auth_username: '[email protected]'
auth_password: 'password'
-
name: 'warning'
slack_configs:
- channel: '#alerts'
title: '⚠️ Warning: {{ .GroupLabels.alertname }}'
text: '{{ range .Alerts }}{{ .Annotations.description }}{{ end }}'
inhibit_rules:
source_match: severity: 'critical' target_match: severity: 'warning' equal: ['alertname', 'instance']
7.3 を構成します。 Alertmanager
# Systemd service sudo tee /etc/systemd/system/alertmanager.service <<EOF [Unit] Description=Prometheus Alertmanager After=network.target[Service] User=alertmanager Group=alertmanager Type=simple ExecStart=/opt/alertmanager/alertmanager \ --config.file=/etc/alertmanager/alertmanager.yml \ --storage.path=/var/lib/alertmanager/ \ --web.listen-address=:9093
Restart=on-failure RestartSec=5
[Install] WantedBy=multi-user.target EOF
Start
sudo systemctl daemon-reload sudo systemctl start alertmanager sudo systemctl enable alertmanager
Access: http://localhost:9093
8 を開始します。ベスト プラクティス
✅ DO
- 積極的に監視 - ユーザーが問題を報告するのを待たない
- 意味のある設定をするしきい値_ - ワークロードに基づく
- アラートのテスト - 通知が機能することを確認
- ランブックを文書化 - アラートを次のリンクにリンクします解決手順_
- 指標の保持 - 最低 30 日、推奨 1 年
- ラベルを賢く使用 - フィルタリングとグループ化_
- モニターを監視 - Prometheus/Grafana がダウンした場合に警告
- 定期的なダッシュボードのレビュー - 必要に応じて更新変更_
- SLO/SLI の追跡 - サービス レベルの定義と測定
- メトリクスの関連付け - CPU + ディスク + クエリ時間一緒に
❌ しないでください
- 過度に警戒しないでください - 警戒疲労は実際_
- 警告を無視しないでください - 警告は重要になります_
- 忘れずに更新してください - ダッシュボードとアラート進化
- 指標を公に公開しない - セキュリティリスク
- 単一のモニタリングに依存しない -バックアップ
- すべてを収集しない - 焦点を当てる重要なのは
- ベースラインを無視しない - 通常の状態を知る_
- テストをスキップしない - テストフェイルオーバー検出
9。ラボ演習
ラボ 1: モニタリング スタックのセットアップ
タスク: 1. モニタリング サーバーに Prometheus をインストールする 2. すべてのノードに postgres_exporter をインストールする 3. すべてのノードに node_exporter をインストールする 4. スクレイピング ターゲットを構成する5. メトリクスの収集を確認する 6. Grafana をインストールする 7. Prometheus データ ソースを追加する 8. PostgreSQL ダッシュボードをインポート_
ラボ 2: カスタム ダッシュボードを作成_
タスク_: 1. Grafana で新しいダッシュボードを作成する 2. レプリケーション ラグ用のパネルを追加する3. 接続数のパネルを追加 4. TPS のパネルを追加 5. キャッシュ ヒット率のパネルを追加 6. ノード選択の変数を作成 7. ダッシュボードの保存と共有
ラボ 3: アラートの構成
タスク: 1. アラートマネージャーのインストール2. PostgreSQL のアラート ルールを作成する 3. Patroni のアラート ルールを作成する 4. Slack 通知を構成する 5. 条件をトリガーしてアラートをテストする 6. 通知配信を確認する
ラボ 4: フェールオーバーをシミュレートおよび監視する
タスク: 1. 開くGrafana ダッシュボード 2. プライマリ ノードを停止します。 3. フェールオーバー中にメトリクスを監視します。 4. トリガーされたアラートを確認します。 5. タイムラインを文書化します。 6. メトリクスからダウンタイムを計算します
10。概要
主要指標の概要
| _カテゴリ_ | _指標_ | Thre shold |
|---|---|---|
| _レプリケーション_ | ラグバイト | < 10MB |
| レプリケーション | ラグタイム_ | < 10 代 |
| 接続 | 使用率 % | < 80% |
| キャッシュ | ヒット率 | > 95% |
| クエリ_ | 長時間実行 | < 1 時間 |
| ディスク | 使用率 % | < 85% |
| CPU | 使用率 % | < 80% 持続_ |
スタックの監視
Prometheus: Metrics collection and storage ├─ postgres_exporter: PostgreSQL metrics ├─ node_exporter: System metrics ├─ Patroni: HA cluster metrics (built-in) └─ etcd: DCS metrics (built-in)Grafana: Visualization and dashboards
Alertmanager: Alert routing and notifications
次のステップ___HTMLTAG_412__HTMLTAG_413___レッスン 18 では、パフォーマンス チューニング:
- _HT について説明します。MLTAG_418___PostgreSQL 構成
- PgBouncer による接続プーリング
- HAProxy による負荷分散
- クエリ最適化技術
- リードレプリカのスケーリング戦略