AWS OpenSearch RAG GenAI wektorowa baza danych

Skoki opóźnienia w OpenSearch Serverless: diagnostyka nasycenia OCU w obciążeniach wektorowego wyszukiwania

Rozwiązanie degradacji opóźnień w wyszukiwaniu wektorowym w OpenSearch Serverless spowodowanej nasyceniem OCU.

·
Zapytania RAG, które normalnie zwracały wyniki w 200ms, teraz trwają 2-5 sekund? Twoje Search OCU w OpenSearch Serverless są nasycone. Zapytania trafiają do kolejki, ale nie są zatrzymywane - po prostu stają się coraz wolniejsze w miarę wzrostu obciążenia.

Objawy

Krok pobierania w Twoim systemie RAG degraduje się pod obciążeniem:

  • Wyszukiwanie wektorowe k-NN spowalnia z 200ms (p50) do 2-5 sekund (p50)
  • Brak błędów w CloudWatch - requesty się kończą, ale wolno
  • Degradacja koreluje ze skokami ruchu (godziny szczytu, wsadowe przetwarzanie)
  • Dashboard OpenSearch Serverless pokazuje SearchOCU na poziomie 90-100%
  • Opóźnienie end-to-end RAG przekracza akceptowalne progi (>5s łącznie)

Metryki CloudWatch do sprawdzenia:

Namespace: AWS/AOSS
Metric: SearchOCU (Average)
Expected: < 70% for healthy operation
Actual: 90-100% sustained

Przyczyna

OpenSearch Serverless przydziela stałą liczbę Search OCU do Twojej kolekcji. Każde OCU zapewnia jednostkę obliczeniową do wykonywania zapytań. Gdy wszystkie OCU są zajęte:

  1. Nowe zapytania trafiają do wewnętrznej kolejki
  2. Długość kolejki rośnie proporcjonalnie do ruchu
  3. Opóźnienie rośnie liniowo - brak odcięcia (circuit breaker), brak błędów, tylko spowolnienie

Typowe przyczyny:

  • Wzrost ruchu - Twoje zapytania RAG się podwoiły, ale OCU zostały na minimum (2 Search OCU)
  • Duże wartości k - użycie k=20 lub więcej sprawia, że każde zapytanie jest kosztowne obliczeniowo
  • Brak pre-filtrów - każde zapytanie przeszukuje cały indeks wektorowy zamiast przefiltrowanego podzbioru
  • Wysoki ef_search - domyślne ef_search=512 jest kosztowne; większość obciżąeń działa dobrze z 100-200
  • Równoczesny ingestion wsadowy - OCU indeksowania na pełnej pojemności mogą pośrednio wpływać na wydajność wyszukiwania na współdzielonych zasobach

Rozwiązanie

Krok 1: Potwierdź nasycenie OCU

Sprawdź dashboard CloudWatch dla swojej kolekcji:

aws cloudwatch get-metric-statistics \
  --namespace AWS/AOSS \
  --metric-name SearchOCU \
  --start-time $(date -u -v-1H +%Y-%m-%dT%H:%M:%S) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
  --period 300 \
  --statistics Average \
  --region eu-central-1

Jeśli średnia jest stale powyżej 80%, potrzebujesz więcej pojemności lub optymalizacji zapytań.

Krok 2: Zmniejsz koszt zapytań (natychmiastowa ulga)

Zmniejsz wartość k:

{
  "size": 5,
  "query": {
    "knn": {
      "embedding": {
        "vector": [0.1, 0.2, ...],
        "k": 5
      }
    }
  }
}

Zmiana z k=20 na k=5 redukuje koszt obliczeniowy per zapytanie o ~60%. Dla większości przypadków RAG 5 chunków zapewnia wystarczający kontekst.

Dodaj pre-filtry metadanych:

{
  "size": 5,
  "query": {
    "knn": {
      "embedding": {
        "vector": [0.1, 0.2, ...],
        "k": 5,
        "filter": {
          "bool": {
            "must": [
              {"term": {"tenant_id": "customer-123"}},
              {"term": {"doc_type": "policy"}}
            ]
          }
        }
      }
    }
  }
}

Pre-filtry zawężają przestrzeń wyszukiwania przed obliczeniem k-NN. Jeśli masz 1M wektorów, ale filtr zawęża do 10K, każde zapytanie jest 100x tańsze.

Obniż ef_search (ustawienie indeksu):

{
  "settings": {
    "index": {
      "knn.algo_param.ef_search": 100
    }
  }
}

Domyślne 512 zapewnia recall >99.5%. Obniżenie do 100 daje ~98% recall przy 3-5x niższym koszcie obliczeniowym. Zmierz na swoim zbiorze testowym.

Krok 3: Zwiększ pojemność OCU

OpenSearch Serverless automatycznie skaluje OCU w ramach skonfigurowanych limitów, ale maksimum może być zbyt niskie. Skontaktuj się z AWS Support lub dostosuj przez konsolę:

  1. Przejdź do OpenSearch Serverless > Collections > Twoja kolekcja
  2. Sprawdź ustawienia “Capacity”
  3. Zwiększ maksymalną liczbę Search OCU (np. z 2 do 4 lub 8)

Uwaga: zwiększenie OCU zaczyna działać w ciągu minut. Każde dodatkowe Search OCU kosztuje ~$0.24/godzinę (~£140/miesiąc).

Krok 4: Rozważ dedykowany klaster OpenSearch (przy stałym wysokim obciążeniu)

Jeśli stale potrzebujesz >4 Search OCU, dedykowana domena OpenSearch z pluginem k-NN może być bardziej opłacalna:

  • Dedykowany klaster: kontrolujesz rozmiar i liczbę instancji, autoskalowanie przez alarmy CloudWatch
  • Typowo: 2x r6g.large.search z k-NN = ~$350/miesiąc z przewidywalną wydajnością
  • Kompromis: zarządzasz klastrem samodzielnie (aktualizacje, shardy, snapshoty), ale zyskujesz pełną kontrolę nad pojemnością

Walidacja

Po zastosowaniu poprawek potwierdź, że opóźnienie wróciło do normy:

# Odpytaj kolekcję i zmierz czas odpowiedzi
time curl -s -X POST "https://your-collection.eu-central-1.aoss.amazonaws.com/your-index/_search" \
  -H "Content-Type: application/json" \
  --aws-sigv4 "aws:amz:eu-central-1:aoss" \
  -d '{"size":5,"query":{"knn":{"embedding":{"vector":[0.1,0.2],"k":5}}}}'

Oczekiwany wynik: czas odpowiedzi < 300ms.

Monitoruj CloudWatch:

  • SearchOCU średnia < 70%
  • SearchLatency p99 < 500ms

Powiązane