Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Deze pagina bevat richtlijnen, voorbeeldcode en een voorbeeldnotebook voor het testen van vectorzoekeindpunten. Loadtests helpen u inzicht te krijgen in de prestaties en productiegereedheid van een vectorzoekeindpunt voordat deze in productie wordt geïmplementeerd. Loadtesten kunnen u vertellen over:
- Latentie op verschillende schaalniveaus
- Doorvoerlimieten en knelpunten (aanvragen per seconde, uitsplitsing van latentie)
- Foutpercentages onder langdurige belasting
- Resourcegebruik en capaciteitsplanning
Zie Belastingstests voor het leveren van eindpunten voor meer informatie over belastingstests en gerelateerde concepten.
Requirements
Voordat u met deze stappen begint, moet u een geïmplementeerd eindpunt voor vectorzoekopdrachten en een service-principal met machtigingen voor canquery's voor het eindpunt hebben. Zie Stap 1: Authenticatie van de service-principal instellen.
Download en importeer een kopie van de volgende bestanden en voorbeeldnotebook naar uw Azure Databricks-werkruimte:
-
input.json. Dit is een voorbeeld van het
input.jsonbestand dat de nettolading aangeeft die wordt verzonden door alle gelijktijdige verbindingen met uw eindpunt. U kunt indien nodig meerdere bestanden hebben. Als u het voorbeeldnotitieblok gebruikt, wordt dit bestand automatisch gegenereerd op basis van de opgegeven invoertabel. -
fast_vs_load_test_async_load.py. Upload dit script naar uw werkruimte (bijvoorbeeld
/Workspace/Users/<your-username>/fast_vs_load_test_async_load.py) en stel de notebook parameterlocust_script_pathin op het pad. Dit script verwerkt verificatie, levering van nettoladingen en het opsporen van fouten in de verzameling metrische gegevens. - Het volgende voorbeeldnotebook, waarmee de belastingstests worden uitgevoerd. Voor de beste prestaties voert u dit notebook uit op een cluster met één knooppunt met een groot aantal kernen (Locust-schaalt voor alle beschikbare CPU's). Hoog geheugen wordt aanbevolen voor query's met vooraf gegenereerde insluitingen.
Voorbeeldnotitieblok en quickstart
Gebruik het volgende voorbeeldnotitieblok om aan de slag te gaan. Het ondersteunt twee verkenningsmodi: een geleidelijke sweeping die specifieke gelijktijdigheidsniveaus test die u definieert, en een binaire zoekmodus die automatisch het maximale duurzame QPS in een paar stappen vindt. Alle parameters worden geconfigureerd met behulp van widgets, zodat het notebook interactief of als Een Databricks-taak kan worden uitgevoerd zonder codebewerkingen.
Notebook voor het testen van locust-belasting
Framework voor belastingstests: Locust
Locust is een opensource-framework voor belastingstests waarmee u het volgende kunt doen:
- Het aantal gelijktijdige clientverbindingen variëren
- Beheer hoe snel verbindingen ontstaan
- Eindpuntprestaties tijdens de test meten
- Automatisch detecteren en gebruiken van alle beschikbare CPU-kernen
In het voorbeeldnotitieblok wordt de --processes -1 flag gebruikt om CPU-kernen automatisch te detecteren en volledig te benutten.
Als Locust een CPU-knelpunt ervaart, verschijnt er een bericht in de uitvoer.
Stap 1: Authenticatie voor service-principal instellen
Belangrijk
Gebruik voor productieachtige prestatietests altijd verificatie van de OAuth-service-principal. Service-principals bieden tot 100 ms snellere reactietijd en hogere aanvraagsnelheidslimieten in vergelijking met persoonlijke toegangstokens (PAW's).
Service-principal maken en configureren
Maak een Databricks-service-principal. Zie Service-principals toevoegen aan uw account voor instructies.
Machtigingen verlenen:
- Navigeer naar de eindpuntpagina voor vectorzoekopdrachten.
- Klik op Machtigingen.
- Geef de service-principal Kan Query-machtigingen.
OAuth-geheim maken.
- Ga naar de pagina met details van de service-principal.
- Klik op het tabblad Geheimen .
- Klik op Geheim genereren.
- Stel de levensduur in (raad 365 dagen aan voor langdurige tests).
- Kopieer zowel de client-id als het geheim onmiddellijk.
Sla referenties veilig op.
- Maak een Databricks-geheimenscope. Zie Zelfstudie: Een Databricks-geheim maken en gebruiken voor instructies.
- Zoals wordt weergegeven in het volgende codevoorbeeld, slaat u de client-id van de service-principal op als
service_principal_client_iden slaat u het OAuth-geheim op alsservice_principal_client_secret.
# In a Databricks notebook dbutils.secrets.put("load-test-auth", "service_principal_client_id", "<CLIENT_ID>") dbutils.secrets.put("load-test-auth", "service_principal_client_secret", "<SECRET>")
Stap 2: Uw belastingstest configureren
Notebookconfiguratie
Configureer de notebookparameters met behulp van de widgets boven aan het notitieblok. Wanneer u het notebook uitvoert als een Databricks-taak, geeft u deze waarden door als taakparameters. Er zijn geen codebewerkingen nodig.
| Kenmerk | Description | Aanbevolen waarde |
|---|---|---|
endpoint_name |
Naam van uw vectorzoekeindpunt | De naam van uw eindpunt |
index_name |
Volledige indexnaam (catalog.schema.index) |
Uw indexnaam |
test_table |
Brontabel naar voorbeeldquery's van (catalog.schema.table) |
De indexinvoertabel |
query_column |
Tekstkolom die moet worden gebruikt voor beheerde insluitingen | Laat staan als text of stel in als uw kolomnaam |
embedding_column |
Kolom met vooraf samengestelde insluitingsvectoren. Alleen gebruikt voor zelfbeheerde insluitingen. | Leeg laten voor beheerde insluitingen |
sample_size |
Aantal queries dat moet worden gemonsterd voor de test. | 1000 |
target_concurrencies |
Door komma's gescheiden lijst met gelijktijdige clientaantallen om te testen | 5,10,20,50 |
step_duration_seconds |
Duur in seconden per gelijktijdigheidsniveau. Eén waarde is van toepassing op alle niveaus of geef één per niveau op als een door komma's gescheiden lijst. |
300 (5 minuten) |
secret_scope_name |
Naam van uw Databricks-geheim bereik | Uw scopenaam |
locust_script_path |
Pad van de werkruimte naar het fast_vs_load_test_async_load.py script |
/Workspace/Users/<your-username>/fast_vs_load_test_async_load.py |
output_table |
(Optioneel) Delta-tabel voor het opslaan van resultaten in (catalog.schema.table). Automatisch gemaakt bij eerste uitvoering. |
catalog.schema.load_test_results |
run_name |
Naam of opmerking om deze uitvoering te taggen voor latere analyse | Een beschrijvend label |
exploration_mode |
gradual doorloopt target_concurrencies in volgorde.
binary_search bepaalt het breekpunt automatisch (zie Breekpuntverkenning). |
gradual |
max_target_qps |
(binary_search alleen) Bovengrens voor de QPS-zoekopdracht |
500 |
exploration_steps |
(binary_search alleen) Maximale aantal zoekiteraties voor binaire zoekactie |
8 |
error_rate_threshold |
(binary_search alleen) Maximaal acceptabel foutpercentage (%) om een stap te tellen als een succes |
1.0 |
num_results |
Aantal resultaten dat per query moet worden geretourneerd | 10 |
columns_to_return |
Door komma's gescheiden lijst met kolommen die moeten worden geretourneerd in queryresultaten (bijvoorbeeld id,text). Laat leeg om alle kolommen weer te geven. |
Laat leeg voor standaard |
Beheerde versus zelfbeheerde insluitingen
Het notebook ondersteunt zowel beheerde insluitingen (waarbij Databricks insluitingen genereert tijdens het uitvoeren van query's) als zelfbeheerde insluitingen (waarbij u vooraf gedefinieerde vectoren rechtstreeks doorgeeft). Configureer de juiste parameters op basis van uw indextype.
| Indextype | Parameter die moet worden ingesteld | Ongedefinieerd laten |
|---|---|---|
| Beheerde insluitingen (Delta Sync-index met door Databricks beheerd insluitmodel) |
query_column — de naam van de tekstkolom die moet worden gebruikt als de query |
embedding_column (leeg laten) |
| Zelfbeheerde insluitingen (Delta Sync of Direct Vector Access-index met vooraf samengestelde vectoren) |
embedding_column — de kolom met vooraf samengestelde insluitingsvectoren |
query_column |
Opmerking
Bij beheerde insluitingsindexen meet de loadtest de end-to-end latentie, inclusief de generatietijd van embeddings. Als het embedding-eindpunt naar nul wordt geschaald, zal de koudestart-overhead zichtbaar zijn in de eerste testrun. Zie Het knelpunt van het insluitmodel identificeren voor het isoleren van de insluitingslatentie van zoeklatentie.
Waarom 5-10 minuten?
Een minimale testduur van 5 minuten is kritiek.
- Initiële query's kunnen met opstartoverhead te maken hebben.
- Eindpunten hebben tijd nodig om stabiele prestaties te bereiken.
- Automatisch schalen van het model dat eindpunten bedient (indien ingeschakeld) kost tijd om te activeren.
- Korte tests missen het throttlinggedrag onder langdurige belasting.
In de volgende tabel ziet u de aanbevolen testduur, afhankelijk van uw testdoel.
| Testtype | Testduur | Doelstellingen van test |
|---|---|---|
| Snelle rooktest | 2-3 minuten | Basisfunctionaliteit controleren |
| Prestatiebasislijn | 5-10 minuten | Betrouwbare metriek in een stationaire toestand |
| Stresstest | 15-30 minuten | Uitputting van middelen identificeren |
| Uithoudingsvermogen testen | 1-4 uur | Degradatie, latentiestabiliteit |
Breekpuntverkenning (binaire zoekmodus)
Naast de geleidelijke sweep (exploration_mode=gradual), ondersteunt het notebook een automatische modus voor binaire zoekopdrachten die het maximale duurzame QPS zoekt zonder dat u handmatig de gelijktijdigheidsniveaus hoeft op te geven.
Hoe werkt het?
Stel exploration_mode=binary_search in en specificeer max_target_qps (bijvoorbeeld 500). Het notebook maakt gebruik van Little's Law (concurrency = QPS × avg_latency_sec) om elk QPS-doel te converteren naar een geschat gelijktijdigheidsniveau en voert vervolgens als volgt een binaire zoekopdracht uit:
- Begin bij
max_target_qps / 2(250 in het voorbeeld). - Als het foutpercentage lager is dan
error_rate_threshold(geslaagd), verhoog de ondergrenswaarde en probeer een hogere QPS (375, dan 500 enzovoort). - Als de foutfrequentie de drempelwaarde (fout) overschrijdt, verlaagt u de bovengrens en probeert u het halverwege tussen het laatste succes en de laatste fout.
- Herhaal dit voor maximaal stappen
exploration_steps(standaard 8) of totdat het zoekbereik wordt beperkt tot binnen 5% vanmax_target_qps.
In de volgende tabel ziet u hoe de zoekopdracht convergeert naar een hypothetisch eindpunt met een breekpunt rond 430 QPS:
| Stap | DoelQPS | Foutpercentage | Resultaat | Nieuw bereik |
|---|---|---|---|---|
| 1 | 250 | 0.1% | SUCCES | [250, 500] |
| 2 | 375 | 0.3% | SUCCES | [375, 500] |
| 3 | 437 | 4,5% | MISLUKKING | [375, 437] |
| 4 | 406 | 0,8% | SUCCES | [406, 437] |
| 5 | 421 | 2.1% | MISLUKKING | [406, 421] |
Na 5-8 stappen convergeert de zoekopdracht op het breekpunt, in dit voorbeeld ongeveer 406-421 QPS, met veel minder tests dan een uitgebreide sweep.
Wanneer moet elke modus worden gebruikt
| Mode | Wanneer gebruiken |
|---|---|
gradual |
U kent al het verwachte bedrijfsbereik en wilt de prestaties op specifieke gelijktijdigheidsniveaus karakteriseren. |
binary_search |
U wilt snel de maximaal duurzame QPS vinden, zonder dat u de gelijktijdigheidsniveaus van tevoren kent. |
Stap 3. Uw queryset ontwerpen
Indien mogelijk moet de queryset het verwachte productieverkeer zo dicht mogelijk weergeven. U moet proberen om met name de verwachte distributie van query's af te stemmen op het gebied van inhoud, complexiteit en diversiteit.
Gebruik realistische query's. Gebruik geen willekeurige tekst, zoals 'testquery 1234'.
Komt overeen met de verwachte distributie van productieverkeer. Als u 80% veelvoorkomende query's, 15% middelfrequentiequery's en vijf% onregelmatige query's verwacht, moet uw queryset die verdeling weerspiegelen.
Komt overeen met het type query dat u verwacht te zien in productie. Als u bijvoorbeeld verwacht dat productiequery's hybride zoeken of filters gebruiken, moet u deze ook gebruiken in uw queryset.
Voorbeeldquery met behulp van filters:
{ "query_text": "wireless headphones", "num_results": 10, "filters": { "brand": "Sony", "noise_canceling": true } }Voorbeeldquery met hybride zoekopdracht:
{ "query_text": "best noise canceling headphones for travel", "query_type": "hybrid", "num_results": 10 }
Diversiteit van query's en caching
Vectorzoekeindpunten cachen verschillende typen queryresultaten om de prestaties te verbeteren. Deze caching kan van invloed zijn op de resultaten van de belastingtest. Daarom is het belangrijk om aandacht te besteden aan de diversiteit van de queryset. Als u bijvoorbeeld herhaaldelijk dezelfde set query's verzendt, test u de cache, niet de werkelijke zoekprestaties.
| Gebruik: | Wanneer: | Example |
|---|---|---|
| Identieke of weinig queries |
|
Een productaanbevelingswidget die 'trending items' weergeeft: dezelfde query wordt duizenden keren per uur uitgevoerd. |
| Diverse queries |
|
Een e-commerce zoekopdracht waarbij elke gebruiker verschillende productzoekopdrachten typt. |
Zie Samenvatting van aanbevolen procedures voor aanvullende aanbevelingen.
Opties voor het maken van een queryset
De codetabbladen bevatten drie opties voor het maken van een diverse queryset. Er is geen one-size-fits-all. Kies degene die het beste voor u werkt.
- (Aanbevolen) Willekeurige steekproeven uit de indexinvoertabel. Dit is een goed algemeen uitgangspunt.
- Steekproeven uit productielogboeken. Dit is een goed begin als u productielogboeken hebt. Houd er rekening mee dat query's doorgaans na verloop van tijd veranderen, dus vernieuw de test die regelmatig is ingesteld om deze up-to-date te houden.
- Synthetische queries genereren. Dit is handig als u geen productielogboeken hebt of als u complexe filters gebruikt.
Willekeurige steekproeven uit invoertabel
De volgende codevoorbeelden zijn willekeurige query's uit uw indexinvoertabel.
import pandas as pd
import random
# Read the index input table
input_table = spark.table("catalog.schema.index_input_table").toPandas()
# Sample random rows
n_samples = 1000
if len(input_table) < n_samples:
print(f"Warning: Only {len(input_table)} rows available, using all")
sample_queries = input_table
else:
sample_queries = input_table.sample(n=n_samples, random_state=42)
# Extract the text column (adjust column name as needed)
queries = sample_queries['text_column'].tolist()
# Create query payloads
query_payloads = [{"query_text": q, "num_results": 10} for q in queries]
# Save to input.json
pd.DataFrame(query_payloads).to_json("input.json", orient="records", lines=True)
print(f"Created {len(query_payloads)} diverse queries from index input table")
Voorbeeld uit productielogboeken
De volgende codevoorbeelden zijn representatief afkomstig van productiequeries.
# Sample proportionally from production queries
production_queries = pd.read_csv("queries.csv")
# Take stratified sample maintaining frequency distribution
def create_test_set(df, n_queries=1000):
# Group by frequency buckets
df['frequency'] = df.groupby('query_text')['query_text'].transform('count')
# Stratified sample
high_freq = df[df['frequency'] > 100].sample(n=200) # 20%
med_freq = df[df['frequency'].between(10, 100)].sample(n=300) # 30%
low_freq = df[df['frequency'] < 10].sample(n=500) # 50%
return pd.concat([high_freq, med_freq, low_freq])
test_queries = create_test_set(production_queries)
test_queries.to_json("input.json", orient="records", lines=True)
Synthetische vragen
Als u nog geen productielogboeken hebt, kunt u synthetische diverse query's genereren.
# Generate diverse queries programmatically
import random
# Define query templates and variations
templates = [
"find {product} under ${price}",
"best {product} for {use_case}",
"{adjective} {product} recommendations",
"compare {product1} and {product2}",
]
products = ["laptop", "headphones", "monitor", "keyboard", "mouse", "webcam", "speaker"]
prices = ["500", "1000", "1500", "2000"]
use_cases = ["gaming", "work", "travel", "home office", "students"]
adjectives = ["affordable", "premium", "budget", "professional", "portable"]
diverse_queries = []
for _ in range(1000):
template = random.choice(templates)
query = template.format(
product=random.choice(products),
product1=random.choice(products),
product2=random.choice(products),
price=random.choice(prices),
use_case=random.choice(use_cases),
adjective=random.choice(adjectives)
)
diverse_queries.append(query)
print(f"Generated {len(set(diverse_queries))} unique queries")
Stap 4. Uw nettolading testen
Voordat u de volledige belastingstest uitvoert, valideert u uw payload:
- Navigeer in de Databricks-werkruimte naar uw eindpunt voor vectorzoekopdrachten.
- Klik in de linkerzijbalk op Serveren.
- Selecteer uw eindpunt.
- Klik op Gebruiken → Query.
- Plak uw
input.jsoninhoud in het queryvak. - Controleer of het eindpunt verwachte resultaten retourneert.
Dit zorgt ervoor dat uw belastingtest realistische query's meet, geen foutreacties.
Stap 5. De belastingstest uitvoeren
Connectiviteitscontrole en opwarmen
Voordat de belastingstest begint, voert het notebook twee installatiestappen uit:
Connectiviteitscontrole: verzendt één testquery met behulp van de credentials van de service principal. Als het eindpunt een 401- of 403-fout retourneert, mislukt het notebook onmiddellijk met een duidelijke melding van
PermissionErrorin plaats van een volledige belastingstest uit te voeren die uitsluitend foutgegevens produceert. Dit bespaart tijd wanneer referenties of machtigingen onjuist zijn geconfigureerd.Opwarmtest (1 minuut): voert een korte test met lage gelijktijdigheid uit waarmee eindpuntcaches worden opgewarmd en de end-to-end aanvraagstroom wordt gevalideerd. De opwarmresultaten worden niet gebruikt voor metrische prestatiegegevens. In de binaire zoekmodus wordt de opwarmlatentie ook gebruikt als de basislijn voor de gelijktijdigheidsraming van Little's Law.
Reeks hoofdbelastingstests
Het notebook voert een reeks tests uit met toenemende gelijktijdigheid van clients:
- Start: Lage gelijktijdigheid (bijvoorbeeld 5 gelijktijdige clients)
- Midden: Gemiddelde gelijktijdigheid (bijvoorbeeld 10, 20 of 50 clients)
- Einde: Hoge gelijktijdigheid (bijvoorbeeld meer dan 100 gebruikers)
Elke test wordt uitgevoerd voor de duur die is geconfigureerd in step_duration_seconds (5-10 minuten aanbevolen).
Wat de laptop meet
Het notebook meet en rapporteert het volgende:
Metrische latentiegegevens:
- P50 (mediaan): De helft van de query's is sneller dan dit.
- P95: 95% van de query's zijn sneller dan deze waarde. Dit is een belangrijke SLA-metrische waarde.
- P99: 99% query's zijn sneller dan dit.
- Max: Slechtste latentie.
Metrische gegevens over doorvoer:
- RPS (aanvragen per seconde): Succesvolle queries per seconde.
- Totaal aantal query's: Aantal voltooide query's.
- Slagingspercentage: Percentage van geslaagde queries.
Fouten:
- Queryfouten per type
- Uitzonderingsberichten
- Aantal time-outs
Resultatenopslag
Als de output_table parameter is ingesteld, slaat het notebook één rij per gelijktijdigheidsniveau (of per binaire zoekstap) op in een Unity Catalog Delta-tabel. De tabel wordt automatisch gemaakt tijdens de eerste uitvoering en toegevoegd aan volgende uitvoeringen. Elke rij bevat run_name, exploration_modegelijktijdigheid, succes-/foutpercentages, latentie percentielen, RPS en binaire zoekspecifieke velden (bs_step, bs_target_qps, ). bs_outcome Hiermee kunt u uitvoeringen in de loop van de tijd vergelijken met behulp van SQL- of BI-hulpprogramma's.
Uitvoeren als een Databricks-taak
Alle notebookparameters worden gedefinieerd als dbutils.widgets, die rechtstreeks worden toegewezen aan databricks-taakparameters. Om de belastingtesten te plannen of te automatiseren:
- Maak een taak met het notitieblok als taak.
- Stel de widgetwaarden in als taakparameters. Er zijn geen codebewerkingen nodig.
- Koppel de taak aan een cluster met één knooppunt met veel CPU-kernen (Locust profiteert van parallelle werkrollen).
- Voer op aanvraag of volgens een schema voor terugkerende basislijntests uit.
Stap 6. Resultaten interpreteren
In de volgende tabel ziet u doelen voor goede prestaties:
| Metrische gegevens | Target | Comment |
|---|---|---|
| P95-latentie | < 500 ms | De meeste query's zijn snel |
| P99-latentie | < 1 s | Redelijke prestaties voor langstaartzoekopdrachten |
| Slagingspercentage | > 99,5% | Laag storingspercentage |
| Latentie na verloop van tijd | Stabiel | Geen afname waargenomen tijdens de test |
| Queries per seconde | Voldoet aan het doel | Het eindpunt kan verwacht verkeer verwerken. |
De volgende resultaten geven slechte prestaties aan:
- P95 > 1s. Geeft aan dat query's te traag zijn voor realtime gebruik.
- P99 > 3s. Latentie bij long tail-query's kan de gebruikerservaring schaden.
- Slagingspercentage < 99%. Te veel fouten.
- Toenemende latentie. Geeft de uitputting van resources of het geheugenlek aan.
- Snelheidsbeperkingsfouten (429). Geeft aan dat een hogere eindpuntcapaciteit vereist is.
Compromis tussen RPS en latentie
De maximale RPS is niet het optimale punt voor productiedoorvoer. Latentie neemt niet-lineair toe wanneer u de maximale doorvoer nadert. Het gebruik van maximaal RPS resulteert vaak in 2-5x hogere latentie in vergelijking met 60-70% maximale capaciteit.
In het volgende voorbeeld ziet u hoe u de resultaten kunt analyseren om het optimale operationele punt te vinden.
- De maximale RPS is 480 bij 150 gelijktijdige clients.
- Het optimale bedieningspunt is 310 RPS bij 50 gelijktijdige clients (65% capaciteit).
- De latentiestraf op max: P95 is 4,3x hoger (1,5s versus 350 ms)
- In dit voorbeeld wordt aanbevolen om de capaciteit van het eindpunt aan te passen voor 480 RPS en te werken met ongeveer 310 RPS.
| Concurrency | P50 | P95 | P99 | RPS | Success | Capaciteit |
|---|---|---|---|---|---|---|
| 5 | 80 ms | 120 ms | 150 ms | 45 | 100% | 10% |
| 10 | 85 ms | 140 ms | 180 ms | 88 | 100% | 20% |
| 20 | 95 ms | 180 ms | 250 ms | 165 | 99.8% | 35% |
| 50 | 150 ms | 350 ms | 500 ms | 310 | 99.2% | 65% ← Ideale punt |
| 100 | 250 ms | 800 ms | 1.2s | 420 | 97,5% | 90% ⚠bijna maximaal |
| 150 | 450 ms | 1,5s | 2,5s | 480 | 95.0% | 100% ❌ Maximale RPS |
Werken met de maximale RPS kan leiden tot de volgende problemen:
- Latentieverslechtering. In het voorbeeld is P95 350 ms bij 65% capaciteit, maar is 1,5s bij 100% capaciteit.
- Er is geen ruimte voor verkeerstoenames of pieken. Bij 100% capaciteit veroorzaakt een piek een time-out. Bij 65% capaciteit kan een piek van 50% verkeer zonder problemen worden afgehandeld.
- Verhoogde foutpercentages. In het voorbeeld is het slagingspercentage 99,2% met een capaciteit van 65%, maar 95,0% - een foutpercentage van 5% - met een capaciteit van 100%.
- Risico op uitputting van resources. Bij maximale belasting nemen wachtrijen toe, neemt de geheugendruk toe, beginnen verbindingsgroepen te verzadiging en neemt de hersteltijd na incidenten toe.
In de volgende tabel ziet u aanbevolen besturingspunten voor verschillende gebruiksvoorbeelden.
| Gebruiksituatie | Doelcapaciteit | Motivatie |
|---|---|---|
| Latentiegevoelig (zoeken, chatten) | 50-60% van het maximum | Geef prioriteit aan lage P95/P99-latentie |
| Evenwichtig (aanbevelingen) | 60-70% van maximaal | Goede balans tussen kosten en latentie |
| Geoptimaliseerd voor kosten (batchtaken) | 70-80% van maximaal | Acceptabele hogere latentie |
| Niet aanbevolen | > 85% van maximaal | Latentiepieken, geen burstcapaciteit |
Helperfuncties voor het berekenen van de grootte van het besturingspunt en het eindpunt
Het optimale punt vinden
De volgende code plot QPS versus P95 latentie. Zoek in de plot naar het punt waar de curve scherp omhoog begint te buigen. Dit is het optimale bedieningspunt.
import matplotlib.pyplot as plt
# Plot QPS vs. P95 latency
qps_values = [45, 88, 165, 310, 420, 480]
p95_latency = [120, 140, 180, 350, 800, 1500]
plt.plot(qps_values, p95_latency, marker='o')
plt.axvline(x=310, color='green', linestyle='--', label='Optimal (65% capacity)')
plt.axvline(x=480, color='red', linestyle='--', label='Maximum (100% capacity)')
plt.xlabel('Queries Per Second (QPS)')
plt.ylabel('P95 Latency (ms)')
plt.title('QPS vs. Latency: Finding the Sweet Spot')
plt.legend()
plt.grid(True)
plt.show()
Grootte-aanbevelingsformule
def calculate_endpoint_size(target_qps, optimal_capacity_percent=0.65):
"""
Calculate required endpoint capacity
Args:
target_qps: Your expected peak production QPS
optimal_capacity_percent: Target utilization (default 65%)
Returns:
Required maximum endpoint QPS
"""
required_max_qps = target_qps / optimal_capacity_percent
# Add 20% safety margin for unexpected bursts
recommended_max_qps = required_max_qps * 1.2
return {
"target_production_qps": target_qps,
"operate_at_capacity": f"{optimal_capacity_percent*100:.0f}%",
"required_max_qps": required_max_qps,
"recommended_max_qps": recommended_max_qps,
"burst_capacity": f"{(1 - optimal_capacity_percent)*100:.0f}% headroom"
}
# Example
result = calculate_endpoint_size(target_qps=200)
print(f"Target production QPS: {result['target_production_qps']}")
print(f"Size endpoint for: {result['recommended_max_qps']:.0f} QPS")
print(f"Operate at: {result['operate_at_capacity']}")
print(f"Available burst capacity: {result['burst_capacity']}")
# Output:
# Target production QPS: 200
# Size endpoint for: 369 QPS
# Operate at: 65%
# Available burst capacity: 35% headroom
Het knelpunt van het insluitmodel identificeren
Als in uw index beheerde insluitingen worden gebruikt, legt het notebook voor de belastingtest de timing per onderdeel vast via de debug_level=1 parameter voor elke query. De resultatentabel bevat:
-
ann_time— tijd besteed aan het zoeken naar dichtstbijzijnde buren -
embedding_gen_time— tijd besteed aan het genereren van query-embeddings op het modelserve-eindpunt -
reranker_time— de tijd besteed aan het herordenen (indien ingeschakeld) -
response_time— totale end-to-end reactietijd
Als embedding_gen_time consistent groot is ten opzichte van ann_time, is het embedding-eindpunt het knelpunt, niet het eindpunt voor vectorzoekopdrachten. Veelvoorkomende oorzaken:
- Voor het embeddingmodel voor het eindpunt is schaal naar nul ingeschakeld. Schakel dit uit voor het testen van productiebelastingen. Zie Het vermijden van afschalen naar nul voor productie.
- Het embedding-eindpunt heeft niet genoeg voorziene gelijktijdigheid voor de queryfrequentie die u test.
- Het eindpunt van het insluitmodel wordt gedeeld met andere workloads. Gebruik een toegewezen eindpunt voor het testen van belasting.
Aanbeveling
Als u vectorzoekprestaties wilt isoleren van de prestaties van het insluiten van modellen, schakelt u over naar zelfbeheerde insluitingen voor belastingstests. Geef vooraf gecomputeerde vectoren door in de EMBEDDING_COLUMN parameter in plaats van tekstquery's. Hierdoor wordt de insluitingslatentie van de meting volledig verwijderd.
Stap 7: Uw eindpunt afmeten
De aanbeveling van het notitieblok gebruiken
Nadat de resultaten zijn geanalyseerd, vraagt het notebook u het volgende te doen:
- Selecteer de rij die het beste voldoet aan uw latentievereisten.
- Voer de gewenste RPS van uw toepassing in.
Het notebook geeft vervolgens een aanbevolen eindpuntgrootte weer. Hiermee wordt de vereiste capaciteit berekend op basis van het volgende:
- Uw doel-RPS
- Waargenomen latentie op verschillende gelijktijdigheidsniveaus
- Drempelwaarden voor slagingspercentage
- Veiligheidsmarge (doorgaans 2x verwachte piekbelasting)
Overwegingen met betrekking tot schaalvergroting
Standaardeindpunten:
- Automatisch omhoog schalen ter ondersteuning van de indexgrootte
- Handmatig omhoog schalen ter ondersteuning van doorvoer
- Automatisch omlaag schalen wanneer indexen worden verwijderd
- Handmatig omlaag schalen om de capaciteit te verminderen
Eindpunten die zijn geoptimaliseerd voor opslag:
- Automatisch omhoog schalen ter ondersteuning van de indexgrootte
- Automatisch omlaag schalen wanneer indexen worden verwijderd
Stap 8: Definitieve configuratie valideren
Na het bijwerken van uw eindpuntconfiguratie:
- Wacht tot het eindpunt gereed is. Dit kan enkele minuten duren.
- Voer de laatste validatietest uit in het notebook.
- Controleer of de prestaties voldoen aan uw vereisten:
- RPS ≥ doeldoorvoer
- P95-latentie voldoet aan SLA.
- Slagingspercentage > 99,5%
- Geen aanhoudende fouten
Als de validatie mislukt, probeert u het volgende:
- Eindpuntcapaciteit verhogen
- Querycomplexiteit optimaliseren
- Filterprestaties controleren
- De configuratie van het insluiten van eindpunten controleren
Wanneer moet u de test opnieuw uitvoeren
Om de zichtbaarheid van de prestaties te behouden, is het een goed idee om driemaandelijkse basislijnbelastingstests uit te voeren. U moet ook opnieuw testen wanneer u een van de volgende wijzigingen aanbrengt:
- De querypatronen of de complexiteit wijzigen
- De vectorzoekindex bijwerken
- Filterconfiguraties wijzigen
- Verwacht aanzienlijke toename van verkeer
- Nieuwe functies of optimalisaties implementeren
- Overstappen van standaard naar eindpunttypen die zijn geoptimaliseerd voor opslag
Troubleshooting
Alle aanvragen mislukken met latentie van ~10 ms en antwoorden van 240 bytes
Dit geeft aan dat de service-principal een 401/403-antwoord ontvangt. Controleren:
- De service-principal heeft kan querymachtigingen voor het eindpunt voor vectorzoekopdrachten (niet alleen de index).
- Het geheime bereik bevat geldige
service_principal_client_idenservice_principal_client_secretsleutels. - Het OAuth-geheim is niet verlopen.
Het notebook bevat een connectiviteitscontrole die dit detecteert voordat de volledige loadtest wordt uitgevoerd.
Meerdere belastingstesttaken uitvoeren op hetzelfde cluster
Als u twee loadtesttaken tegelijk uitvoert op hetzelfde cluster, kan één taak verouderde OAuth-tokens krijgen of CPU-conflicten ondervinden met de Locust-werkers van de andere taak. Voor betrouwbare resultaten voert u taaktesttaken één voor één uit op een toegewezen cluster.
Tijdsgrafieken voor onderdelen zijn leeg
De eindpunt moet ann_time retourneren in query-antwoorden voor de tijdsgrafieken van onderdelen (embedding_gen_time, reranker_time, debug_info). Als deze grafieken leeg zijn:
- Controleer of u het
fast_vs_load_test_async_load.pyscript gebruikt (datdebug_infouit antwoorden parseert) als delocust_script_path. - Sommige eindpuntconfiguraties retourneren mogelijk niet
debug_info. Zelfbeheerde indexen voor insluiten retourneren meestalann_timeenresponse_time, maar nietembedding_gen_timeofreranker_time.
Resultatentabel die niet kan worden opgevraagd vanuit een SQL-warehouse
Het notebook registreert de resultaten van de Spark-sessie van het cluster. Als in een SQL Warehouse 0 rijen worden weergegeven voor een tabel die het notebook rapporteert als gevuld, kan het probleem een vertraging in de synchronisatie van Unity Catalog metagegevens zijn. Wacht enkele minuten en probeer het opnieuw of voer een query uit op de tabel vanuit een notebook dat is gekoppeld aan hetzelfde cluster.
Samenvatting van aanbevolen procedures
Testconfiguratie
Voer tests uit gedurende ten minste 5 minuten bij piekbelasting.
Gebruik OAuth-service-principals voor verificatie.
Maak realistische querypayloads zodat ze overeenkomen met verwachte productievragen.
Test met productieachtige filters en parameters.
Neem een opwarmperiode op voordat u meet.
Test op meerdere gelijktijdigheidsniveaus.
Houd P95/P99-latenties bij, niet alleen gemiddelden.
Test zowel de gecachete prestaties als de niet-gecachete prestaties.
# Conservative approach: Size endpoint for UNCACHED performance uncached_results = run_load_test(diverse_queries, duration=600) endpoint_size = calculate_capacity(uncached_results, target_rps=500) # Then verify cached performance is even better cached_results = run_load_test(repetitive_queries, duration=300) print(f"Cached P95: {cached_results['p95']}ms (bonus performance)")
Ontwerp van queryset
- Koppel uw testquerydiversiteit aan de werkelijke verkeersdistributie (frequente en zeldzame query's).
- Gebruik werkelijke query's uit logboeken (geanonimiseerd).
- Neem verschillende complexiteitsniveaus van queries op.
- Test zowel scenario's met cache als niet-cache en volg de resultaten afzonderlijk.
- Test met verwachte filtercombinaties.
- Gebruik dezelfde parameters die u in productie gaat gebruiken. Als u bijvoorbeeld hybride zoekfuncties in een productieomgeving gebruikt, neemt u hybride zoekquery's op. Gebruik een vergelijkbare
num_resultsparameter als in productie. - Gebruik geen query's die nooit in productie worden uitgevoerd.
Optimalisatie van prestaties
Als de latentie te hoog is, probeert u het volgende:
- Gebruik OAuth-service-principals (geen persoonlijke toegangs tokens) - een verbetering van 100 ms
- Reduce
num_results- Het ophalen van 100 resultaten is langzamer dan 10 - Filters optimaliseren - Complexe of te beperkende filters vertragen query's
- Controleer het eindpunt voor insluiten: zorg ervoor dat het niet naar nul wordt geschaald of dat het voldoende bandbreedte heeft
Als u frequentielimieten bereikt, probeert u het volgende:
- Capaciteit van eindpunt verhogen - Uw eindpunt omhoog schalen
- Frequentiebeperking of verspreiding van query's aan de clientzijde op tijd implementeren
- Groepsgewijze verbindingen gebruiken - Verbindingen opnieuw gebruiken
- Logica voor opnieuw proberen toevoegen - Exponentieel uitstel gebruiken (al een deel van de Python SDK)