Skalierung für Workloads mit großem Umfang
Da Vektorarbeitslasten über das hinaus wachsen, was ein einzelner Datenbankserver effizient verarbeiten kann, benötigen Sie Strategien, um die Kapazität zu skalieren und gleichzeitig Kosten zu verwalten. Azure Database for PostgreSQL bietet mehrere Skalierungsoptionen, die sich auf verschiedene Aspekte der Leistungsabfrage beziehen.
Vertikale Skalierung in Azure
Die vertikale Skalierung erhöht die Compute- und Arbeitsspeicherressourcen, die für Ihren Datenbankserver verfügbar sind. Bei Vektorworkloads geht dies direkt auf die CPU-intensive Art von Ähnlichkeitsberechnungen und die Speicheranforderungen für die Aufbewahrung von Indizes im Cache ein.
Azure Database for PostgreSQL bietet drei Computeebenen mit unterschiedlichen Ressourcenzuordnungen. Jede Ebene zielt auf unterschiedliche Arbeitsauslastungsprofile ab, wobei die Kosten mit den Leistungsfunktionen ausgeglichen werden. Bei Vektorsuchworkloads ist das Verhältnis zwischen Arbeitsspeicher und vCore wichtig, da sie bestimmt, wie viele Indexdaten im Arbeitsspeicher zwischengespeichert werden können.
| Tarif | V-Kerne | Arbeitsspeicher pro V-Kern | Am besten geeignet für: |
|---|---|---|---|
| Burstfähig | 1–20 | 2 GB | Entwicklung, Workloads mit geringem Datenverkehr |
| Allgemeiner Zweck | 2-96 | 4GB | Ausgewogene Produktionsarbeitslasten |
| Arbeitsspeicheroptimiert | 2-96 | 8 GB | Große Arbeitssätze, Vektorworkloads |
Für das Produktempfehlungsszenario mit zwei Millionen Vektoren und hoher Parallelität bieten speicheroptimierte Ebenen die beste Passform. Der zusätzliche Arbeitsspeicher pro vCore hilft dabei, HNSW-Indizes zwischengespeichert zu halten und die Datenträger-E/A während Abfragen zu reduzieren.
Die Leistung von Vektorabfragen skaliert sowohl mit den CPU-Kernen (für parallele Distanzberechnungen) als auch mit dem Arbeitsspeicher (für die Zwischenspeicherung von Indizes). Beginnen Sie für Datasets unter einer Million Vektoren mit General Purpose 4-8 vCores, überwachen Sie speicherdruck- und Cachetrefferverhältnisse und skalieren Sie, wenn die CPU-Auslastung bei Spitzenlast konsistent 70% überschreitet. Für Datasets von 1 bis zehn Millionen Vektoren beginnen Sie mit speicheroptimierten 8-16 vCores, stellen Sie sicher, dass der Speicher die Vektorindexgröße um mindestens 50%überschreitet und 32+ vCores für hohe Parallelität (Hunderte gleichzeitiger Abfragen) in Betracht ziehen. Für Datensätze über zehn Millionen Vektoren sind in der Regel speicheroptimierte 32+ vCores erforderlich. Bewerten Sie, ob Lesereplikate Lasten verteilen können, und berücksichtigen Sie Architekturänderungen (Partitionierung, Zwischenspeicherungsebene).
Die vertikale Skalierung hat abnehmende Renditen und harte Grenzwerte. Skalieren Sie auf einen größeren Server, wenn die Latenz einer Einzelanfrage zu hoch ist, der Arbeitsspeicherdruck übermäßige Datenträger-E/A verursacht oder Sie die maximalen Ressourcen der Ebene noch nicht erreicht haben. Skalieren Sie nach außen (Replikate oder Zwischenspeicherung), wenn das Gesamtabfragevolumen das übersteigt, was ein Server bewältigen kann, Sie eine leseintensive Arbeitslast mit akzeptablem Veraltungsgrad haben oder Sie an vertikale Skalierungsgrenzen stoßen. Die vertikale Skalierung ist einfacher zu implementieren und zu verwalten. Beginnen Sie mit der Skalierung, bis Sie Grenzwerte erreichen oder Kosten unertraglich werden, und fügen Sie dann die horizontale Skalierung hinzu.
Lesereplikate für die Abfrageverteilung
Lesereplikate verwalten Kopien Ihrer primären Datenbank, die Leseabfragen unabhängig voneinander verarbeiten. Bei Vektorsuchworkloads, die überwiegend gelesen werden, können Replikate Ihre Abfragekapazität multiplizieren.
Azure Database for PostgreSQL verwendet physische Streamingreplikation, um Replikate mit dem primären Server zu synchronisieren. Änderungen, die in die primäre Datei geschrieben wurden, werden an Replikate gestreamt, die sie asynchron anwenden. Der primäre Server behandelt sowohl Lese- als auch Schreibvorgänge, während jedes Replikat nur Leseabfragen verarbeitet. Sie können bis zu fünf Lesereplikate pro primären Instanz erstellen, und Replikate können sich in verschiedenen Azure-Regionen befinden. Jedes Replikat verfügt über einen eigenen Verbindungsendpunkt, sodass Ihre Anwendung Abfragen an den entsprechenden Server weiterleiten muss.
Da die Replikation asynchron ist, können Replikate geringfügig hinter der primären Replikation stehen. Diese Verzögerung beträgt unter normalen Bedingungen typischerweise Millisekunden bis Sekunden, kann jedoch bei intensiver Schreibaktivität auf dem primären System, großen Transaktionen oder Massenladungen, Netzwerküberlastung zwischen Regionen oder bei Einschränkungen der Replikatressourcen zunehmen. Bei Produktempfehlungen ist die Replikationsverzögerung häufig akzeptabel. Wenn ein neues Produkt hinzugefügt wird, wirkt sich die Darstellung in Empfehlungen einige Sekunden später nicht auf die Benutzererfahrung aus. Wenn Ihre Anwendung jedoch eine sofortige Konsistenz erfordert (z. B. um die soeben aktualisierten Einstellungen eines Benutzers anzuzeigen), sollten diese Abfragen an den Primärserver gesendet werden. Überwachen sie die Replikatverzögerung mithilfe von Azure Monitor-Metriken oder abfragen Sie das Replikat direkt mit SELECT EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp())) AS lag_seconds;.
Ihre Anwendung muss Abfragen an geeignete Server weiterleiten. Allgemeine Muster sind Routing auf Anwendungsebene (Auswahl der Verbindung basierend auf dem Abfragetyp), DNS-basiertes Routing (mit Azure Traffic Manager oder benutzerdefiniertem DNS zum Verteilen von Verbindungen über Replikate hinweg) und Verbindungsproxy (PgBouncer oder ähnliche Proxys, die Abfragen basierend auf Mustern weiterleiten). Im Szenario der Empfehlungsengine sind Vektorähnlichkeitssuchen ideale Kandidaten für das Replikat-Routing, da sie schreibgeschützt sind und eine hohe Toleranz gegenüber geringfügiger Veralterung aufweisen.
Replikate können unabhängig von der Größe des Primären dimensioniert werden. Bei leselastigen Vektorarbeitslasten können Sie kleinere Replikate verwenden, wenn das Abfragevolumen die Einschränkung darstellt (mehr Replikate, kleinere jeweils), gleich große oder größere Replikate verwenden, wenn die Leistung einzelner Abfragen wichtig ist, oder Replikate in Regionen nahe bei den Benutzern platzieren, um eine niedrigere Latenz zu erreichen.
Cachestrategien für die Vektorsuche
Durch das Zwischenspeichern wird die Datenbanklast reduziert, indem wiederholte Abfragen aus schnellerem Speicher bereitgestellt werden. Vektorsucharbeitslasten haben spezifische Zwischenspeicherungsmöglichkeiten.
Nicht alle Vektorsuchergebnisse profitieren gleichermaßen von der Zwischenspeicherung. Die besten Kandidaten verfügen über hohe Anforderungshäufigkeit, niedrige Änderungsraten und begrenzungsgebundene Schlüsselplätze. Zufällige Ähnlichkeitsabfragen mit beliebigen Vektoren weisen einen unendlichen Abfragebereich auf und können nicht gut zwischengespeichert werden, aber Nachschlagevorgänge für bestimmte Elemente oder vorkomputierte Empfehlungen können effektiv zwischengespeichert werden. Gute Caching-Kandidaten umfassen häufig angeforderte beliebte Einbettungen, vorkomputierte "ähnliche Elemente" für Top-Produkte, das Nachschlagen von Benutzereinbettungen für Personalisierung und Aggregateinbettungen auf Kategorieebene. Schlechte Zwischenspeicherungskandidaten umfassen beliebige Vektor-Ähnlichkeitsabfragen (unendlicher Abfrageraum), schnell ändernde Daten (hohe Ungültigkeitsrate) und Abfragen mit vielen Filterkombinationen.
Azure Cache for Redis bietet Unter millisekunden-Antwortzeiten für zwischengespeicherte Daten. Berücksichtigen Sie bei Vektorworkloads die Zwischenspeicherung von Einbettungsabfragen und vorberechneten Empfehlungen. Im folgenden Beispiel wird das Zwischenspeichern von Produkteinbettungen mit einer einstündigen TTL veranschaulicht.
import redis
import json
redis_client = redis.Redis(host='your-cache.redis.cache.windows.net',
port=6380, ssl=True, password='your-key')
def get_product_embedding(product_id):
cache_key = f"embedding:{product_id}"
cached = redis_client.get(cache_key)
if cached:
return json.loads(cached)
# Fetch from database
embedding = fetch_embedding_from_db(product_id)
# Cache for 1 hour
redis_client.setex(cache_key, 3600, json.dumps(embedding))
return embedding
Veraltete Empfehlungen sind in der Regel für kurze Zeiträume akzeptabel, aber schließlich ist es erforderlich, die Cache-Speicher zu aktualisieren. Die richtige Ungültigkeitsstrategie hängt davon ab, wie schnell sich Ihre Daten ändern und wie sensibel Benutzer auf veraltete Ergebnisse reagieren. Die meisten Vektorsuchanwendungen können eine kurze Zeitspanne tolerieren, in der die Daten nicht verfügbar sind, wodurch eine einfache zeitbasierte Ablaufsteuerung effektiv ist. Legen Sie TTL (Time to Live) basierend auf akzeptabler Veralterung fest. Für Produktempfehlungen sind 15-60 Minuten oft sinnvoll. Löschen Sie für ereignisgesteuerte Ungültigheit bestimmte Cacheeinträge, wenn sich die zugrunde liegenden Daten ändern. Für die Hintergrundaktualisierung sollten Sie beliebte Elemente proaktiv vor dem Ablauf aktualisieren, um Cache-Verluste zu vermeiden.
Überwachen der Kapazität und Planung des Wachstums
Die proaktive Überwachung hilft Ihnen, zu skalieren, bevor die Leistung spürbar beeinträchtigt wird.
Über Azure Monitor können Sie Metriken auf Datenbankebene verfolgen, darunter die CPU-Auslastung (ein dauerhafter Wert von >70 % deutet auf Skalierungsbedarf hin), die Speicherauslastung (das Erreichen der Grenzwerte führt zu Auslagerungen), die Speicher-E/A-Auslastung (hohe Werte deuten auf unzureichendes Caching hin) und die aktiven Verbindungen (das Erreichen von max_connections deutet auf Pooling-Probleme hin). Sie können Metriken auf Abfrageebene verfolgen, einschließlich der P95/P99-Abfragelatenz für Vektorsuchen, des Abfragedurchsatzes (Abfragen pro Sekunde) und der Cache-Trefferquote (wenn der Puffercache von PostgreSQL effektiv verwendet wird).
Konfigurieren Sie Azure Monitor-Warnungen, um Sie zu benachrichtigen, bevor Probleme sich auf Benutzer auswirken. Legen Sie eine Warnung fest, wenn der CPU-Prozentsatz 80% für 5 Minuten überschreitet, um E-Mails an das Ops-Team zu senden. Setzen Sie eine kritische Warnung, wenn der Arbeitsspeicheranteil für 5 Minuten 90 % überschreitet, um den Bereitschaftstechniker zu benachrichtigen.
Für eine effektive Kapazitätsplanung müssen Sie Ihre aktuellen Nutzungsmuster verstehen und zukünftige Anforderungen projizieren. Ohne diese Grundlage riskieren Sie entweder die Überbereitstellung (Budget verschwenden) oder die Unterbereitstellung (beeinträchtigt die Benutzerfreundlichkeit während des Wachstums). Richten Sie Basispläne ein, indem Sie das aktuelle Abfragevolumen, die Latenz und die Ressourcenauslastung während normaler und Spitzenzeiten messen. Identifizieren Sie Wachstumstreiber wie z. B. Kataloggrößeswachstum, Benutzerwachstum oder Abfragekomplexitätsänderungen. Modellieren Sie die zukünftige Last, indem Sie den Ressourcenbedarf basierend auf der Wachstumsrate projizieren. Wenn Ihr Katalog jährlich verdoppelt wird und Sie mit 60% CPU arbeiten, sollten Sie die Skalierung innerhalb von sechs Monaten planen. Testen Sie Skalierungsoptionen, bevor Sie sie benötigen, indem Sie die vertikale Skalierung und Replikatbereitstellung in Nicht-Produktionsumgebungen überprüfen. Dokumentschwellenwerte, die definieren, wann jede Skalierungsaktion ausgelöst werden soll.
Kostenoptimierung
Die Leistungsoptimierung muss mit Budgeteinschränkungen ausgeglichen werden. Mehrere Strategien helfen dabei, Die Kosten zu steuern und gleichzeitig eine akzeptable Leistung zu gewährleisten.
Die Überbereitstellung verschwendet Geld, während die Unterbereitstellung den Benutzern schadet. Überprüfen Sie die Ressourcenauslastung regelmäßig. Wenn die durchschnittliche CPU unter 30%liegt, erwägen Sie die Skalierung nach unten. Wenn die Speicherauslastung konsistent niedrig ist, genügt "General Purpose" möglicherweise anstelle von "Speicher optimiert". Wenn Sie Replikate mit geringer Auslastung haben, konsolidieren Sie.
Azure bietet erhebliche Rabatte (bis zu 65%) für ein- oder dreijährige reservierte Kapazitätsverpflichtungen. Wenn Ihre geplante Arbeitsauslastung vorhersagbar ist, reduzieren Reservierungen die Kosten erheblich. Berechnen Sie Ihren Basisplan (mindeste Always-On-Kapazität) und reservieren Sie diesen Betrag. Verwenden Sie On-Demand-Preise für zusätzliche Kapazität über dem Basisniveau.
Speicherkosten sammeln sich für große Vektordatensätze an. Entfernen Sie nicht verwendete Indizes (jeder HNSW-Index fügt ~50% zum Vektorspeicher hinzu). Archivieren Sie alte Vektoren, die selten abgefragt werden. Verwenden Sie geeignete Genauigkeit (float4 vs float8) für Ihre Genauigkeitsanforderungen.
Nicht produktionsbezogene Umgebungen benötigen keine Ressourcen im Produktionsmaßstab. Verwenden Sie den bustfähigen Tarif zur Entwicklung. Reduzieren Sie die Staging-Umgebung, wenn kein aktiver Test läuft. Verwenden Sie kleinere Datasets in Nichtproduktionen (repräsentative Stichproben, nicht vollständige Kopien).