Scénář optimalizace výkonu: více služeb back-end

Tento článek popisuje, jak vývojový tým použil metriky k nalezení kritických bodů a zlepšení výkonu distribuovaného systému. Článek vychází ze skutečného zátěžového testování, které bylo provedeno pro ukázkovou aplikaci. aplikace pochází ze směrného plánu služby Azure Kubernetes (AKS) pro mikroslužbyspolečně s projektem Visual Studio zátěžového testu , který se používá ke generování výsledků.

Tento článek je součástí série. Přečtěte si tuprvní část.

Scénář: voláním více back-end služeb načtěte informace a pak agregované výsledky.

Tento scénář zahrnuje aplikaci pro doručování pomocí dronů. Klienti mohou zadat dotaz na REST API a získat tak nejnovější informace o faktuře. Tato faktura zahrnuje Shrnutí dodávek, balíčků a celkového využití pomocí dronů zákazníka. Tato aplikace využívá architekturu mikroslužeb běžící na AKS a informace potřebné pro fakturu jsou rozdělené mezi několik mikroslužeb.

Místo toho, aby klient vyvolal každou službu přímo, aplikace implementuje model agregace brány . Pomocí tohoto modelu klient provede jeden požadavek na službu brány. Brána zase zavolá souběžné služby back-end a poté agreguje výsledky do datové části s jednou odpovědí.

Diagram znázorňující model agregace brány

Test 1: základní výkonnost

Aby bylo možné vytvořit směrný plán, vývojový tým začal s testem krokového zatížení a vyvažování zátěže od jednoho simulovaného uživatele až 40 uživatelů po celkovou dobu trvání 8 minut. následující graf pořízený z Visual Studio zobrazuje výsledky. Fialová čára zobrazuje uživatelské zatížení a oranžová čára zobrazuje propustnost (průměrných požadavků za sekundu).

Graph výsledků zátěžového testu Visual Studio

Červená čára podél dolního okraje grafu ukazuje, že klientovi nebyly vráceny žádné chyby, což podporuje. Průměrná propustnost se ale v průběhu testu zaokrouhluje na polovinu, a to i v případě, že se zatížení stále zvětšuje. To znamená, že back-end není schopný uchovávat. Vzor, který se tady zobrazuje, je běžný, když systém začne dosáhnout limitů prostředků — po dosažení maxima, protože propustnost skutečně výrazně klesá. Spory prostředků, přechodné chyby nebo zvýšení četnosti výjimek mohou přispět k tomuto vzoru.

Pojďme se dig na data monitorování a zjistit, co se děje v rámci systému. další graf je pořízen z Application Insights. Zobrazuje průměrné doby trvání volání HTTP z brány do back-endové služby.

Graph doby trvání volání HTTP

Tento graf znázorňuje, že jedna operace je zvláště v GetDroneUtilization průměru delší než na základě — pořadí podle velikosti. Brána zpřístupňuje tato volání paralelně, takže nejpomalejší operace určuje, jak dlouho trvá dokončení celé žádosti.

Jasným dalším krokem je dig GetDroneUtilization operace a hledání všech kritických bodů. Jednou z možností je vyčerpání prostředků. Tato konkrétní back-end služba pravděpodobně nemá dostatek procesoru nebo paměti. V případě clusteru AKS jsou tyto informace k dispozici v Azure Portal prostřednictvím funkce Azure monitor for Containers . Následující grafy ukazují využití prostředků na úrovni clusteru:

Graph využití uzlu AKS

V tomto snímku obrazovky se zobrazí Průměrná i maximální hodnota. Je důležité si prohlédnout více než jenom průměr, protože průměr může skrýt špičky v datech. V tomto průměrném využití procesoru zůstává méně než 50%, ale existuje několik špiček až 80%. To je blízko kapacity, ale stále v rámci tolerance. Něco jiného způsobuje kritické body.

Další graf odhalí skutečný příčinou. tento graf znázorňuje kódy odpovědí HTTP z databáze back-endu služby doručování, která v tomto případě je Cosmos DB. Modrá čára představuje kódy úspěšnosti (HTTP 2xx), zatímco zelená čára představuje chyby HTTP 429. návratový kód HTTP 429 znamená, že Cosmos DB dočasně omezuje požadavky, protože volající spotřebovává více jednotek prostředků (RU) než zřízené.

Graph omezených požadavků

k získání dalšího přehledu se používá vývojový tým Application Insights k zobrazení ucelené telemetrie pro reprezentativní vzorek požadavků. Tady je jedna instance:

Snímek obrazovky se zobrazením kompletní transakce

Toto zobrazení ukazuje volání související s jedním klientským požadavkem spolu s informacemi o časování a kódy odpovědí. Volání nejvyšší úrovně z brány na back-endové služby. volání do GetDroneUtilization je rozšířeno, aby v tomto případě zobrazovalo volání vnějších závislostí — , Cosmos DB. Volání červeně vrátilo chybu HTTP 429.

Všimněte si vysoké mezery mezi chybou HTTP 429 a dalším voláním. když klientská knihovna Cosmos DB obdrží chybu HTTP 429, automaticky se přeloží a počká, až operaci zopakuje. v tomto zobrazení je to, že během 672 ms tato operace trvala, přičemž většina z této doby vybrala čekání na opakování Cosmos DB.

Tady je další zajímavý graf pro tuto analýzu. Zobrazuje počet hodinových spotřeby na fyzický oddíl oproti zřízeným rum na fyzický oddíl:

Graph využití RU na oddíl

pro účely tohoto grafu je potřeba pochopit, jak Cosmos DB spravuje oddíly. kolekce v Cosmos DB můžou mít klíč oddílu. Každá možná hodnota klíče definuje logický oddíl dat v rámci kolekce. Cosmos DB distribuuje tyto logické oddíly na jeden nebo více fyzických oddílů. správa fyzických oddílů je automaticky zpracována Cosmos DB. když ukládáte více dat, Cosmos DB může přesunout logické oddíly do nových fyzických oddílů, aby bylo možné rozložit zatížení mezi fyzickými oddíly.

pro tento zátěžový test se kolekce Cosmos DB zřídila 900 ru. Graf zobrazuje 100 RU na fyzický oddíl, který implikuje celkem devět fyzických oddílů. i když Cosmos DB automaticky zpracovává horizontálního dělení fyzických oddílů, znalost počtu oddílů vám může poskytnout přehled o výkonu. Vývojový tým bude tyto informace používat později, protože pokračuje v jejich optimalizaci. V případě, že se modrá čára přesáhne fialovou vodorovnou čáru, spotřeba RU překročila zřízenou ru. to je bod, ve kterém bude Cosmos DB začínat omezením volání.

Test 2: zvýšení počtu jednotek prostředků

pro druhý zátěžový test tým škáluje Cosmos DB kolekci z 900 ru na 2500 RU. Propustnost se zvýšila z 19 požadavků za sekundu na 23 požadavků za sekundu a průměrná latence se snížila z 669 MS na 569 MS.

Metric Test 1 Test 2
Propustnost (pož./s) 19 23
Průměrná latence (MS) 669 569
Úspěšné požadavky 9,8 K 11 K

Nejedná se o velké zisky, ale v grafu v průběhu času se zobrazuje úplnější obrázek:

Graph výsledků Visual Studio zátěžových testů znázorňujících jednotnější propustnost.

Zatímco předchozí test ukázal počáteční špičku následovanou ostrým přetažením, tento test ukazuje jednotnější propustnost. Maximální propustnost ale není významně vyšší.

všechny požadavky na Cosmos DB vrátily stav 2xx a chyby HTTP 429 se posunuly:

Graph volání Cosmos DB

Graf spotřeby RU oproti zřízenému ru ukazuje, že je k dispozici dostatek rezervy. K dispozici je přibližně 275 ru na fyzický oddíl a zátěžový test ve špičce o 100 ru spotřebovaný za sekundu.

Graph využití RU oproti zřízené ru ukazuje, že existuje spousta rezerv.

další zajímavou metrikou je počet volání Cosmos DB na úspěšnou operaci:

Metric Test 1 Test 2
Počet volání na operaci 11 9

V případě žádné chyby by počet volání měl odpovídat skutečnému plánu dotazu. V takovém případě operace zahrnuje dotaz na více oddílů, který má stejný počet devět fyzických oddílů. Vyšší hodnota v prvním zátěžovém testu odráží počet volání, která vrátila chybu 429.

Tato metrika se vypočítala spuštěním vlastního dotazu Log Analytics:

let start=datetime("2020-06-18T20:59:00.000Z");
let end=datetime("2020-07-24T21:10:00.000Z");
let operationNameToEval="GET DroneDeliveries/GetDroneUtilization";
let dependencyType="Azure DocumentDB";
let dataset=requests
| where timestamp > start and timestamp < end
| where success == true
| where name == operationNameToEval;
dataset
| project reqOk=itemCount
| summarize
    SuccessRequests=sum(reqOk),
    TotalNumberOfDepCalls=(toscalar(dependencies
    | where timestamp > start and timestamp < end
    | where type == dependencyType
    | summarize sum(itemCount)))
| project
    OperationName=operationNameToEval,
    DependencyName=dependencyType,
    SuccessRequests,
    AverageNumberOfDepCallsPerOperation=(TotalNumberOfDepCalls/SuccessRequests)

Pro shrnutí, druhý zátěžový test ukazuje zlepšení. Tato operace ale GetDroneUtilization stále trvá přibližně v řádu delší než operace s nejbližším nejpomalejším. Hledání v rámci koncových transakcí pomáhá vysvětlit, proč:

Snímek obrazovky druhého zátěžového testu znázorňující vylepšení

jak už bylo zmíněno dříve, GetDroneUtilization operace zahrnuje dotaz na více oddílů pro Cosmos DB. to znamená, že klient Cosmos DB musí nahlásit dotaz do každého fyzického oddílu a shromažďovat výsledky. Jak ukazuje zobrazení pro kompletní transakce, tyto dotazy se provádějí v sériové podobě. Operace trvá tak dlouho, dokud součet všech dotazů — a problému bude horší, protože velikost dat roste a přidají se víc fyzických oddílů.

Test 3: paralelní dotazy

Na základě předchozích výsledků je zřejmé způsob, jak snížit latenci, je vydávat dotazy paralelně. sada SDK Cosmos DB klienta obsahuje nastavení, které řídí maximální stupeň paralelismu.

Hodnota Popis
0 Žádné paralelismus (výchozí)
> 0 Maximální počet paralelních volání
-1 Sada SDK klienta vybere optimální stupeň paralelismu.

U třetího zátěžového testu bylo toto nastavení změněno z 0 na-1. Následující tabulka shrnuje výsledky:

Metric Test 1 Test 2 Test 3
Propustnost (pož./s) 19 23 42
Průměrná latence (MS) 669 569 215
Úspěšné požadavky 9,8 K 11 K 20 K
Omezené žádosti 2,72 K 0 0

Z grafu zátěžového testu je nejen celková propustnost mnohem vyšší (oranžová čára), ale propustnost také udržuje tempo zatížení (fialová čára).

Graph Visual Studio výsledků zátěžových testů, které zobrazují vyšší celkovou propustnost, která udržuje tempo zatížení.

můžete ověřit, že klient Cosmos DB provádí dotazy paralelně tím, že si vyhledá kompletní zobrazení transakce:

snímek obrazovky s koncovým zobrazením transakcí ukazující, že Cosmos DB klient provádí dotazy paralelně.

V podstatě na vedlejší účinky zvýšení propustnosti se zvyšuje počet ru spotřebovaných za sekundu. i když Cosmos DB neomezila žádné požadavky v rámci tohoto testu, byla spotřeba blízko zřízeného limitu RU:

Graph hodnoty ru se blíží k zřízenému limitu ru.

Tento graf může být signálem k dalšímu horizontálnímu navýšení kapacity databáze. Ale zapíná, že místo toho můžeme optimalizovat dotaz.

Krok 4: optimalizace dotazu

Předchozí zátěžový test ukázal vyšší výkon z hlediska latence a propustnosti. Průměrná latence požadavku byla snížena o 68% a propustnost vzrostla 220%. Dotaz na více oddílů se ale týká.

Problém s mezioddílovým dotazem je, že platíte za RU v každém oddílu. Je-li dotaz spuštěn pouze občas — , stačí jednou za hodinu, — kterou nezáleží. Kdykoli ale uvidíte úlohu, která zahrnuje dotaz pro více oddílů, měli byste vidět, jestli se dotaz dá optimalizovat zahrnutím klíče oddílu. (Možná budete muset změnit návrh kolekce tak, aby používal jiný klíč oddílu.)

Tady je dotaz pro tento konkrétní scénář:

SELECT * FROM c
WHERE c.ownerId = <ownerIdValue> and
      c.year = <yearValue> and
      c.month = <monthValue>

Tento dotaz vybere záznamy, které odpovídají konkrétnímu ID vlastníka a měsíci/roku. V původním návrhu žádná z těchto vlastností není klíč oddílu. To vyžaduje, aby klient nahlásil dotaz do každého fyzického oddílu a shromáždil výsledky. Pro zlepšení výkonu dotazů vývojový tým změnil návrh tak, že ID vlastníka je klíč oddílu pro kolekci. Tímto způsobem může dotaz cílit na konkrétní fyzický oddíl. (Cosmos DB to zpracovává automaticky; nemusíte spravovat mapování mezi hodnotami klíče oddílu a fyzickými oddíly.)

Po přepnutí kolekce na nový klíč oddílu bylo výrazné zvýšení spotřeby RU, které se překládá přímo na nižší náklady.

Metric Test 1 Test 2 Test 3 Test 4
Ru na operaci 29 29 29 3.4
Počet volání na operaci 11 9 10 1

Zobrazení koncových transakcí ukazuje, že v podobě předpovědi dotaz čte pouze jeden fyzický oddíl:

Snímek obrazovky s koncovým zobrazením transakcí ukazující, že dotaz čte pouze jeden fyzický oddíl

Zátěžový test ukazuje lepší propustnost a latenci:

Metric Test 1 Test 2 Test 3 Test 4
Propustnost (pož./s) 19 23 42 59
Průměrná latence (MS) 669 569 215 176
Úspěšné požadavky 9,8 K 11 K 20 K 29 K
Omezené žádosti 2,72 K 0 0 0

Důsledkem zlepšení výkonu je to, že využití procesoru uzlů je velmi vysoké:

Graph zobrazení využití procesoru s vysokým zatížením.

Na konci zátěžového testu dosáhlo průměrného počtu PROCESORů přibližně 90% a maximálního počtu PROCESORů dosáhl 100%. Tato metrika indikuje, že procesor je dalším kritickým bodem v systému. Pokud je potřeba vyšší propustnost, může další krok škálovat službu Delivery Service na více instancí.

Souhrn

V tomto scénáři byly zjištěny následující kritické body:

  • Cosmos Požadavky na omezení databáze z důvodu nedostatečného zřízení ru.
  • Vysoká latence způsobená dotazování více oddílů databáze v sériovém tvaru.
  • Neefektivní dotaz mezi oddíly, protože dotaz neobsahoval klíč oddílu.

Využití procesoru se navíc identifikovalo jako potenciální kritický bod ve větším měřítku. Chcete-li diagnostikovat tyto problémy, vývojový tým vyhledal:

  • Latence a propustnost zátěžového testu.
  • Cosmos Chyby databáze a využití RU
  • Zobrazení koncových transakcí v nástroji Application Insight.
  • Využití CPU a paměti v Azure Monitor pro kontejnery.

Další kroky

Zkontrolovat antipatterny výkonu