Szerkesztés

Megosztás a következőn keresztül:


Teljesítmény finomhangolása – Több háttérszolgáltatás

Azure Kubernetes Service (AKS)
Azure Cosmos DB

Ez a cikk azt ismerteti, hogy egy fejlesztői csapat hogyan használt metrikákat a szűk keresztmetszetek megtalálásához és az elosztott rendszerek teljesítményének javításához. A cikk egy mintaalkalmazás tényleges terheléstesztjén alapul. Az alkalmazás a mikroszolgáltatások Azure Kubernetes Service (AKS) alapkonfigurációjából, valamint az eredmények létrehozásához használt Visual Studio terheléstesztelési projektből származik.

Ez a cikk egy sorozat része. Olvassa el az első részt itt.

Forgatókönyv: Hívjon meg több háttérszolgáltatást az információk lekéréséhez, majd összesítse az eredményeket.

Ez a forgatókönyv egy drónkézbesítési alkalmazást is magában foglal. Az ügyfelek lekérdezhetnek egy REST API-t a legújabb számlaadatok lekéréséhez. A számla tartalmazza az ügyfél szállításainak, csomagjainak és a drónok teljes kihasználtságának összegzését. Ez az alkalmazás egy AKS-en futó mikroszolgáltatás-architektúrát használ, és a számlához szükséges információk több mikroszolgáltatásra is kiterjednek.

Ahelyett, hogy az ügyfél közvetlenül hívja meg az egyes szolgáltatásokat, az alkalmazás implementálja az átjáró-összesítési mintát. Ezzel a mintával az ügyfél egyetlen kérést küld egy átjárószolgáltatásnak. Az átjáró ezzel párhuzamosan meghívja a háttérszolgáltatásokat, majd egyetlen válasz hasznos adattá összesíti az eredményeket.

Az átjáróösszesítési mintát ábrázoló diagram

1. teszt: Alapkonfiguráció teljesítménye

Az alapkonfiguráció kialakításához a fejlesztői csapat egy lépésbetöltési teszttel indult, amely egy szimulált felhasználótól 40 felhasználóig, összesen 8 perc alatt tette el a terhelést. A Visual Studióból vett alábbi diagram az eredményeket mutatja. A lila vonal a felhasználó terhelését, a narancssárga vonal pedig az átviteli sebességet (átlagos kérések másodpercenként) jeleníti meg.

A Visual Studio terhelési teszteredményeinek grafikonja

A diagram alján látható piros vonal azt mutatja, hogy az ügyfél nem adott vissza hibát, ami biztató. Az átlagos átviteli sebesség azonban körülbelül félúton halad végig a teszten, majd a fennmaradó részre csökken, még akkor is, ha a terhelés folyamatosan növekszik. Ez azt jelzi, hogy a háttér nem tud lépést tartani. Az itt látható minta gyakori, amikor egy rendszer elkezdi elérni az erőforráskorlátokat – a maximális érték elérése után az átviteli sebesség ténylegesen jelentősen csökken. Az erőforrás-versengés, az átmeneti hibák vagy a kivételek számának növekedése mind hozzájárulhat ehhez a mintához.

Vizsgáljuk meg a monitorozási adatokat, hogy megtudjuk, mi történik a rendszerben. A következő diagram az Application Insightsból származik. Az átjáróról a háttérszolgáltatásokra irányuló HTTP-hívások átlagos időtartamát jeleníti meg.

HTTP-hívás időtartamának grafikonja

Ez a diagram azt mutatja, hogy egy művelet, különösen , GetDroneUtilizationátlagosan sokkal tovább tart – nagyságrendekkel. Az átjáró párhuzamosan hajtja végre ezeket a hívásokat, így a leglassabb művelet határozza meg, hogy mennyi ideig tart a teljes kérés végrehajtása.

A következő lépés egyértelműen a művelet feltárása és a GetDroneUtilization szűk keresztmetszetek keresése. Az egyik lehetőség az erőforrás-kimerülés. Lehet, hogy ez a háttérszolgáltatás elfogy a cpu-ból vagy a memóriából. Az AKS-fürtök esetében ezek az információk a Azure Portal érhetők el az Azure Monitor tárolóelemzési funkciójával. Az alábbi grafikonok az erőforrás-kihasználtságot mutatják a fürt szintjén:

Az AKS-csomópont kihasználtságának grafikonja

Ebben a képernyőképen az átlag és a maximális érték is látható. Fontos, hogy ne csak az átlagot nézzük, mert az átlag elrejtheti a kiugró értékeket az adatokban. Itt az átlagos cpu-kihasználtság 50% alatt marad, de néhány kiugró érték 80%. Ez közel van a kapacitáshoz, de még mindig a tűréshatárokon belül van. Valami más okozza a szűk keresztmetszetet.

A következő diagramon a valódi bűnös látható. Ez a diagram a kézbesítési szolgáltatás háttéradatbázisából származó HTTP-válaszkódokat mutatja, amely ebben az esetben az Azure Cosmos DB. A kék vonal a sikerkódokat (HTTP 2xx), míg a zöld vonal a HTTP 429-es hibákat jelöli. A HTTP 429-es visszatérési kód azt jelenti, hogy az Azure Cosmos DB ideiglenesen szabályozza a kéréseket, mert a hívó a kiépítettnél több erőforrásegységet (RU) használ.

Szabályozott kérelmek grafikonja

A további megállapítások érdekében a fejlesztői csapat az Application Insights segítségével a kérések reprezentatív mintáinak végpontok közötti telemetriáját tekintette meg. Íme egy példány:

Képernyőkép a végpontok közötti tranzakciónézetről

Ez a nézet egyetlen ügyfélkéréshez kapcsolódó hívásokat, valamint időzítési információkat és válaszkódokat jelenít meg. A legfelső szintű hívások az átjárótól a háttérszolgáltatásokig vannak. A hívás GetDroneUtilization kibontva jelenik meg a külső függőségekhez – ebben az esetben az Azure Cosmos DB-hez – irányuló hívások megjelenítéséhez. A pirossal jelzett hívás HTTP 429-hibát adott vissza.

Figyelje meg a HTTP 429-hiba és a következő hívás közötti nagy különbséget. Amikor az Azure Cosmos DB-ügyfélkódtár HTTP 429-re vonatkozó hibaüzenetet kap, automatikusan kikapcsol, és megvárja, amíg újra megkísérli a műveletet. Ez a nézet azt mutatja, hogy a művelet 672 ms-os időtartama alatt az idő nagy részét az Azure Cosmos DB újrapróbálkozására várták.

Íme egy másik érdekes grafikon ehhez az elemzéshez. A fizikai partíciónkénti ru-használatot és a fizikai partíciónként kiosztott kérelemegységeket jeleníti meg:

A partíciónkénti RU-használat grafikonja

A gráf megértéséhez meg kell értenie, hogyan kezeli az Azure Cosmos DB a partíciókat. Az Azure Cosmos DB gyűjteményeinek partíciókulcsa is lehet. Minden lehetséges kulcsérték meghatározza a gyűjteményen belüli adatok logikai partícióját. Az Azure Cosmos DB ezeket a logikai partíciókat egy vagy több fizikai partíció között osztja el. A fizikai partíciók kezelését az Azure Cosmos DB automatikusan kezeli. Ha több adatot tárol, az Azure Cosmos DB áthelyezheti a logikai partíciókat új fizikai partíciókba, hogy a terhelést eloszthassa a fizikai partíciók között.

Ehhez a terhelési teszthez az Azure Cosmos DB-gyűjtemény 900 kérelemegységtel lett kiépítve. A diagram fizikai partíciónként 100 RU-t mutat, ami összesen kilenc fizikai partíciót jelent. Bár az Azure Cosmos DB automatikusan kezeli a fizikai partíciók horizontális felosztását, a partíciók számának ismerete betekintést nyújthat a teljesítménybe. A fejlesztői csapat ezt az információt később fogja használni, mivel továbbra is optimalizálni fogják. Ha a kék vonal átlépi a lila vízszintes vonalat, a kérelemegység-használat túllépte a kiosztott kérelemegységeket. Ez az a pont, ahol az Azure Cosmos DB megkezdi a hívások szabályozását.

2. teszt: Erőforrásegységek növelése

A második terheléses teszt során a csapat 900 RU-ról 2500 RU-ra skálázta fel az Azure Cosmos DB-gyűjteményt. Az átviteli sebesség 19 kérelemről másodpercenként 23 kérelemre/másodpercre nőtt, és az átlagos késés 669 ms-ról 569 ms-ra csökkent.

Metrika 1\. teszt 2\. teszt
Átviteli sebesség (req/sec) 19 23
Átlagos késés (ms) 669 569
Sikeres kérések 9,8 K 11 K

Ezek nem hatalmas nyereségek, de ha az idő múlásával nézzük a grafikont, teljesebb képet láthatunk:

A Visual Studio terhelési teszteredményeinek grafikonja konzisztensebb átviteli sebességet mutat.

Míg az előző teszt kezdeti kiugrást, majd éles csökkenést mutatott, ez a teszt konzisztensebb átviteli sebességet mutat. A maximális átviteli sebesség azonban nem lényegesen magasabb.

Az Azure Cosmos DB-nek küldött összes kérés 2xx állapotot adott vissza, és a HTTP 429-hibák eltűntek:

Azure Cosmos DB-hívások grafikonja

A kérelemegység-használat és a kiosztott kérelemegységek grafikonja azt mutatja, hogy rengeteg a fejtér. Fizikai partíciónként körülbelül 275 kérelemegység van, és a terhelési teszt másodpercenként körülbelül 100 kérelemegységre tetőzött.

A kérelemegység-használat és a kiépített kérelemegységek grafikonja, amely azt mutatja, hogy sok a fejtér.

Egy másik érdekes metrika az Azure Cosmos DB-be irányuló hívások száma sikeres műveletenként:

Metrika 1\. teszt 2\. teszt
Hívások műveletenként 11 9

Ha nem történik hiba, a hívások számának meg kell egyeznie a tényleges lekérdezési tervvel. Ebben az esetben a művelet egy partíciók közötti lekérdezést tartalmaz, amely mind a kilenc fizikai partíciót eléri. Az első terhelési teszt magasabb értéke a 429-es hibát eredményező hívások számát tükrözi.

Ezt a metrikát egy egyéni Log Analytics-lekérdezés futtatásával számítottuk ki:

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)

Összefoglalva, a második terhelési teszt javulást mutat. A GetDroneUtilization művelet azonban nagyságrendekkel tovább tart, mint a következő leglassabb művelet. A végpontok közötti tranzakciók megvizsgálása segít megmagyarázni, hogy miért:

Képernyőkép a második terhelési tesztről, amely a fejlesztést mutatja.

Ahogy korábban említettük, a GetDroneUtilization művelet egy keresztpartíciós lekérdezést tartalmaz az Azure Cosmos DB-nek. Ez azt jelenti, hogy az Azure Cosmos DB-ügyfélnek minden fizikai partícióra ki kell bontania a lekérdezést, és be kell gyűjtenie az eredményeket. Ahogy a teljes körű tranzakció nézet mutatja, ezeket a lekérdezéseket soros módon hajtja végre a rendszer. A művelet mindaddig tart, amíg az összes lekérdezés összege megtelik – és ez a probléma csak az adatok méretének növekedésével és további fizikai partíciók hozzáadásával lesz rosszabb.

3. teszt: Párhuzamos lekérdezések

Az előző eredmények alapján a késés csökkentésének nyilvánvaló módja a lekérdezések párhuzamos kiadása. Az Azure Cosmos DB ügyféloldali SDK olyan beállítással rendelkezik, amely a párhuzamosság maximális fokát szabályozza.

Érték Leírás
0 Nincs párhuzamosság (alapértelmezett)
> 0 Párhuzamos hívások maximális száma
-1 Az ügyféloldali SDK optimális párhuzamossági fokot választ

A harmadik terheléses teszt esetében ez a beállítás 0-ról -1-re módosult. Az alábbi táblázat összefoglalja az eredményeket:

Metrika 1\. teszt 2\. teszt 3. teszt
Átviteli sebesség (req/sec) 19 23 42
Átlagos késés (ms) 669 569 215
Sikeres kérések 9,8 K 11 K 20 K
Szabályozott kérelmek 2.72 K 0 0

A terhelésvizsgálati grafikonon nem csak a teljes átviteli sebesség sokkal magasabb (a narancssárga vonal), hanem az átviteli sebesség is lépést tart a terheléssel (a lila vonallal).

A Visual Studio terheléstesztjének eredményeinek grafikonja magasabb általános átviteli sebességet mutat, amely lépést tart a terheléssel.

A végpontok közötti tranzakciónézet megtekintésével ellenőrizheti, hogy az Azure Cosmos DB-ügyfél párhuzamosan végez-e lekérdezéseket:

Képernyőkép a végpontok közötti tranzakciónézetről, amelyen látható, hogy az Azure Cosmos DB-ügyfél párhuzamosan végez lekérdezéseket.

Érdekes, hogy az átviteli sebesség növelésének egyik mellékhatása, hogy a másodpercenként felhasznált kérelemegységek száma is növekszik. Bár az Azure Cosmos DB nem hajtotta le a kéréseket a teszt során, a használat megközelítette a kiosztott RU-korlátot:

A kiosztott RU-korláthoz közeli ru-használat grafikonja.

Ez a gráf jelezheti az adatbázis további felskálázását. Kiderült azonban, hogy ehelyett optimalizálhatjuk a lekérdezést.

4. lépés: A lekérdezés optimalizálása

Az előző terhelési teszt jobb teljesítményt mutatott a késés és az átviteli sebesség tekintetében. A kérelmek átlagos késése 68%-kal csökkent, és az átviteli sebesség 220%-kal nőtt. A partíciók közötti lekérdezés azonban aggodalomra ad okot.

A partíciók közötti lekérdezésekkel az a probléma, hogy minden partíción fizetnie kell az RU-ért. Ha a lekérdezés csak alkalmanként fut – mondjuk óránként egyszer – nem számít. Ha azonban olyan nagy olvasási terhelést lát, amely több partíciós lekérdezést is magában foglal, látnia kell, hogy a lekérdezés optimalizálható-e egy partíciókulcs használatával. (Előfordulhat, hogy át kell terveznie a gyűjteményt egy másik partíciókulcs használatához.)

Az alábbi lekérdezés az adott forgatókönyvhöz készült:

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

Ez a lekérdezés egy adott tulajdonosazonosítónak és hónap/év rekordnak megfelelő rekordokat választ ki. Az eredeti kialakításban ezen tulajdonságok egyike sem a partíciókulcs. Ehhez az ügyfélnek ki kell bontania a lekérdezést az egyes fizikai partíciókra, és összegyűjtenie az eredményeket. A lekérdezési teljesítmény javítása érdekében a fejlesztői csapat módosította a tervet, hogy a tulajdonos azonosítója legyen a gyűjtemény partíciókulcsa. Így a lekérdezés egy adott fizikai partíciót célozhat meg. (Az Azure Cosmos DB ezt automatikusan kezeli, nem kell kezelnie a partíciókulcs-értékek és a fizikai partíciók közötti leképezést.)

Miután a gyűjteményt az új partíciókulcsra váltotta, jelentősen javult az RU-használat, ami közvetlenül alacsonyabb költségekkel jár.

Metrika 1\. teszt 2\. teszt 3. teszt 4. teszt
Kérelemegységek műveletenként 29 29 29 3.4
Hívások műveletenként 11 9 10 1

A végpontok közötti tranzakció nézet azt mutatja, hogy az előrejelzett módon a lekérdezés csak egy fizikai partíciót olvas be:

Képernyőkép a végpontok közötti tranzakciónézetről, amelyen látható, hogy a lekérdezés csak egy fizikai partíciót olvas be.

A terhelési teszt jobb átviteli sebességet és késést mutat:

Metrika 1\. teszt 2\. teszt 3. teszt 4. teszt
Átviteli sebesség (req/sec) 19 23 42 59
Átlagos késés (ms) 669 569 215 176
Sikeres kérések 9,8 K 11 K 20 K 29 K
Szabályozott kérelmek 2.72 K 0 0 0

A jobb teljesítmény egyik következménye, hogy a csomópont cpu-kihasználtsága nagyon magas lesz:

A csomópont magas cpu-kihasználtságát mutató grafikon.

A terhelési teszt vége felé az átlagos processzorhasználat elérte a 90%-ot, a maximális processzorhasználat pedig elérte a 100%-ot. Ez a metrika azt jelzi, hogy a cpu a rendszer következő szűk keresztmetszete. Ha nagyobb átviteli sebességre van szükség, a következő lépés a kézbesítési szolgáltatás további példányokra való horizontális felskálázása lehet.

Összefoglalás

Ebben a forgatókönyvben a következő szűk keresztmetszeteket azonosítottuk:

  • Az Azure Cosmos DB szabályozási kérései a kiosztott kérelemegységek elégtelensége miatt.
  • Nagy késést okozott több adatbázispartíció soros lekérdezése.
  • Nem hatékony partícióközi lekérdezés, mert a lekérdezés nem tartalmazza a partíciókulcsot.

Emellett a processzorhasználatot nagyobb léptékben is lehetséges szűk keresztmetszetként azonosították. A problémák diagnosztizálásához a fejlesztői csapat a következő szempontokat vizsgálta:

  • Késés és átviteli sebesség a terhelési tesztből.
  • Azure Cosmos DB-hibák és ru-használat.
  • A végpontok közötti tranzakció nézet az Application Insightsban.
  • Processzor- és memóriakihasználtság az Azure Monitor tárolóelemzéseiben.

Következő lépések

Teljesítményelhárítók áttekintése