Runbook: Rate limit exhausted (per supplier credential)
Severity (default): P2. Owner: ingestion team / on-call. Связанные алерты:
etm_credential_usage_ratio{credential_id} > 0.85за час.- 5+ подряд
429/403на одной credential. circuit_breaker_open_total{credential_id} > 0.
Симптом
- Падает rate observations для конкретной credential / поставщика.
- Pricing отвечает с
freshness_status=staleдля затронутых клиентов. - Customer credential может уйти в
failing.
Диагностика
# 1. Состояние бакетов в Redis
kubectl -n tracium exec deploy/redis -- redis-cli --scan --pattern 'ratelimit:etm:*' | head -20
kubectl -n tracium exec deploy/redis -- redis-cli GET "ratelimit:etm:<CRED_ID>:goods_read"# 2. Метрики
# Через Grafana: дашборд "Ingestion → <supplier>"
# Смотреть: usage_ratio, requests_total{status=429}# 3. Какие endpoints горят
kubectl -n tracium logs deploy/ingestor --since=15m \
| grep -E "credential_id=<CRED_ID>" \
| grep -E "status=429|status=403|backoff" \
| awk '{print $NF}' | sort | uniq -c | sort -rnВозможные причины:
- A: Естественный пик (полный rebuild каталога после обновления identity profiles).
- B: Баг в коннекторе — request loop без backoff.
- C: Несколько реплик ingestor’а пишут одновременно (rate limiter не работает корректно).
- D: ETM (или другой supplier) уменьшил лимит в одностороннем порядке.
Смягчение
A: Естественный пик
# Временно уменьшить параллелизм worker pool
kubectl -n tracium exec deploy/admin-api -- \
curl -X PATCH localhost:8080/v1/admin/connectors/<supplier>/workers \
-d '{"max_concurrent_per_credential":1,"ttl":"2h"}'B: Баг коннектора
Срочно — pause connector:
kubectl -n tracium exec deploy/admin-api -- \
curl -X POST localhost:8080/v1/admin/connectors/<supplier>/pause \
-d '{"reason":"investigation","ttl":"30m"}'Потом — поиск root cause в логах коннектора.
C: Распределённый rate limiter не работает
# Проверить, что Redis достижим из всех реплик
for pod in $(kubectl -n tracium get pods -l app=ingestor -o name); do
kubectl -n tracium exec $pod -- redis-cli -h redis ping
doneЕсли Redis нестабилен → fail-safe локальный limiter (более консервативный) должен включаться автоматически. Проверить метрику rate_limiter_fallback_local_total > 0.
D: Supplier изменил лимит
Снизить нашу конфигурацию через override:
kubectl -n tracium exec deploy/admin-api -- \
curl -X PATCH localhost:8080/v1/admin/connectors/<supplier>/rate-limits \
-d '{"<endpoint>":{"rate":1,"period":"2s"},"ttl":"24h"}'Параллельно — открыть тикет на пересмотр <supplier>/rate-budget.md и официальное согласование с поставщиком.
Устранение root cause
- A: лучшее планирование пиковых rebuild’ов (off-peak окна).
- B: integration tests против mock с rate-limit assertion.
- C: e2e тест распределённого rate limiter с N репликами.
- D: договор с поставщиком на минимальный гарантированный rate.
Эскалация
- 1 ч без mitigation →
#oncall-ingestion. - Затронуты > 50% клиентских credentials →
#oncall-product(массовая stale).
Связано
- ADR-0008 (rate limiter).
40-operations/rate-limits.md30-services/ingestion/connectors/etm/rate-budget.mdetm-session-failure.md