Antipattern monolitické trvalosti

Pokud budete všechna data aplikace ukládat do jednoho úložiště dat, může dojít ke snížení výkonu z důvodu kolize prostředků nebo nevhodnosti úložiště dat pro některá data.

Popis problému

Aplikace dříve často používaly pouze jedno úložiště dat, bez ohledu na různé typy dat, které aplikace potřebovala uložit. Důvodem bylo obvykle zjednodušení návrhu aplikace nebo odpovídající dovednosti vývojářského týmu.

Moderní cloudové systémy mívají často další požadavky na funkce i jiné požadavky a potřebují ukládat mnoho heterogenních typů dat, jako jsou například dokumenty, obrázky, data uložená v mezipaměti, zprávy ve frontách, protokoly aplikací a telemetrická data. Použití tradičního přístupu a umístění všech těchto informací do stejného úložiště dat může snížit výkon. Existují pro to dva hlavní důvody:

  • Ukládání a načítání velkých objemů nesouvisejících dat ve stejném úložišti dat může způsobovat kolize, což následně vede ke zpomalení doby odezvy a chybám připojení.
  • Ať už zvolíte jakékoli úložiště dat, nemusí být nejvhodnější pro všechny různé typy dat, nebo nemusí být optimalizované pro operace, které aplikace provádí.

Následující příklad ukazuje kontroler rozhraní ASP.NET Web API, který přidá nový záznam do databáze a výsledek dále zaznamená do protokolu. Protokol se nachází ve stejné databázi jako obchodní data. Kompletní ukázku najdete tady.

public class MonoController : ApiController
{
    private static readonly string ProductionDb = ...;

    public async Task<IHttpActionResult> PostAsync([FromBody]string value)
    {
        await DataAccess.InsertPurchaseOrderHeaderAsync(ProductionDb);
        await DataAccess.LogAsync(ProductionDb, LogTableName);
        return Ok();
    }
}

Rychlost, kterou se generují záznamy protokolu, pravděpodobně ovlivní výkon obchodních operací. A pokud jiná komponenta, například monitorování procesu aplikace, pravidelně čte a zpracovává data protokolu, může to mít také vliv na obchodní operace.

Jak problém vyřešit

Rozdělte data podle jejich použití. Pro každou sadu dat vyberte úložiště dat, které nejlépe odpovídá způsobu použití této sady dat. V předchozím příkladu by se aplikace měla protokolovat do jiného úložiště, než ve kterém je databáze obsahující obchodní data:

public class PolyController : ApiController
{
    private static readonly string ProductionDb = ...;
    private static readonly string LogDb = ...;

    public async Task<IHttpActionResult> PostAsync([FromBody]string value)
    {
        await DataAccess.InsertPurchaseOrderHeaderAsync(ProductionDb);
        // Log to a different data store.
        await DataAccess.LogAsync(LogDb, LogTableName);
        return Ok();
    }
}

Důležité informace

  • Rozdělte data podle toho, jakým způsobem se používají a jakým způsobem se k nim přistupuje. Neukládejte například informace protokolu a obchodní data do stejného úložiště dat. Tyto typy dat mají výrazně odlišné požadavky a vzory přístupu. Záznamy protokolu jsou ze své podstaty sekvenční, zatímco obchodní data častěji vyžadují náhodný přístup a obvykle jsou relační.

  • Zvažte vzor přístupu ke každému typu dat. Můžete například ukládat formátované sestavy a dokumenty do databáze dokumentů, jako je Azure Cosmos DB, ale použít Azure Cache for Redis k ukládání dočasných dat do mezipaměti.

  • Pokud budete postupovat podle těchto pokynů a přesto narazíte na omezení databáze, možná byste měli vertikálně navýšit její kapacitu. Zvažte také horizontální škálování a rozdělení zatížení na více databázových serverů. Rozdělení ale může vyžadovat přepracování aplikace. Další informace najdete v tématu Dělení dat.

Jak zjistit problém

Systém se bude pravděpodobně výrazně zpomalovat a nakonec selže, protože mu dojdou prostředky, jako jsou třeba připojení k databázím.

Následující postup vám pomůže identifikovat příčiny problému.

  1. Instrumentujte systém, aby zaznamenával klíčové statistiky výkonu. Zachycujte informace o čase každé operace, společně s body, ve kterých aplikace čte a zapisuje data.
  2. Pokud je to možné, sledujte běh systému v produkčním prostředí v průběhu několika dnů, abyste získali skutečný přehled o způsobu využití systému. Pokud to možné není, spusťte skriptované zátěžové testy s realistickými počty virtuálních uživatelů, kteří provádějí obvyklé řady operací.
  3. K identifikaci období se špatným výkonem použijte telemetrická data.
  4. Zjistěte, ke kterým úložištím dat se během těchto období přistupovalo.
  5. Identifikujte prostředky úložišť dat, u kterých mohlo docházet ke kolizím.

Ukázková diagnostika

V následujících částech se tento postup použije u ukázkové aplikace popsané výše.

Instrumentace a monitorování systému

Následující graf ukazuje výsledky zátěžového testování ukázkové aplikace popsané výše. Test použil krokové zatížení až 1000 souběžných uživatelů.

Load test performance results for the SQL-based controller

Když se zatížení zvýší na 700 uživatelů, zvýší se i propustnost. V tomto bodě se ale propustnost ustálí a zdá se, že systém běží na své maximální kapacitě. S uživatelským zatížením se postupně zvyšuje průměrná doba odezvy, což naznačuje, že systém požadavky nezvládá.

Identifikace období se špatným výkonem

Pokud monitorujete produkční systém, můžete si všimnout vzorů. Například doba odezvy se může každý den ve stejnou dobu výrazně zhoršit. Důvodem může být pravidelné zatížení nebo plánovaná dávková úloha nebo systém v určitou dobu prostě používá více uživatelů. Měli byste se zaměřit na telemetrická data těchto událostí.

Hledejte korelace mezi zvýšenými hodnotami doby odezvy a zvýšenou databázovou aktivitou nebo vstupně-výstupními operacemi u sdílených prostředků. Pokud korelace existují, znamená to, že databáze může být kritickým bodem.

Identifikace úložišť dat, ke kterým se během těchto období přistupovalo

Následující graf zobrazuje využití jednotek propustnosti databáze (DTU) během zátěžového testu. (DTU je míra dostupné kapacity a je kombinací využití procesoru, přidělení paměti, vstupně-výstupní rychlosti.) Využití DTU rychle dosáhlo 100 %. Je to přibližně ten bod, ve kterém v předchozím grafu dosáhla propustnost svého maxima. Využití databáze zůstalo až do konce testu na velmi vysoké úrovni. Ke konci nastal menší pokles, který mohl být způsoben omezováním, soupeřením o připojení k databázi a dalšími faktory.

The database monitor in the Azure classic portal showing resource utilization of the database

Prozkoumání telemetrických dat pro úložiště dat

Instrumentujte úložiště dat, abyste mohli zachytit podrobnosti nízké úrovně týkající se aktivity. Statistiky přístupu k datům zobrazily v ukázkové aplikaci velký objem operací vložení provedených vůči tabulce PurchaseOrderHeader a tabulce MonoLog.

The data access statistics for the sample application

Identifikace kolize prostředků

V tuto chvíli můžete zkontrolovat zdrojový kód a zaměřit se na body, kdy k zaneprázdněným prostředkům přistupuje aplikace. Hledejte situace jako jsou tyto:

  • Data, která jsou logicky oddělená, se zapisují do stejného úložiště. Data, jako jsou protokoly, sestavy a zprávy ve frontě, by se neměly ukládat do stejné databáze jako obchodní informace.
  • Neshoda mezi výběrem úložiště dat a typem dat, jako jsou třeba velké objekty blob nebo dokumenty XML v relační databázi.
  • Data s výrazně odlišnými vzory použití sdílejí stejné úložiště, jedná se třeba o data s vysokou aktivitou při zápisu a nízkou aktivitou při čtení uložená s daty s nízkou aktivitou při zápisu a vysokou aktivitou při čtení.

Implementace řešení a ověření výsledku

Aplikace se změnila tak, aby zapisovala protokoly do samostatného úložiště dat. Toto jsou výsledky zátěžového testu:

Load test performance results using the Polyglot controller

Vzor propustnosti se podobá předchozímu grafu, bod, ve kterém výkon dosahuje svého maxima, je ale přibližně o 500 požadavků za sekundu vyšší. Průměrná doba odezvy je nepatrně nižší. Tyto statistiky nám ale neříkají vše. Telemetrie obchodní databáze ukazuje, že využití jednotek DTU dosahuje svého maxima kolem 75 %, nikoli na 100 %.

The database monitor in the Azure classic portal showing resource utilization of the database in the polyglot scenario

Podobně i maximální využití jednotek DPU databáze protokolu dosahuje pouze 70 %. Databáze už nejsou omezujícím faktorem výkonu systému.

The database monitor in the Azure classic portal showing resource utilization of the log database in the polyglot scenario