sql >> Databáze >  >> NoSQL >> HBase

Uvnitř architektury Santander's Near Real-Time Data Ingest Architecture (část 2)

Děkujeme Pedro Boado a Abel Fernandez Alfonso z inženýrského týmu Santander za spolupráci na tomto příspěvku o tom, jak Santander UK používá Apache HBase jako obslužný engine téměř v reálném čase k napájení své inovativní aplikace Spendlytics.

Aplikace Spendlytics pro iOS je navržena tak, aby pomohla zákazníkům s osobními debetními a kreditními kartami Santander mít přehled o svých útratách, včetně plateb provedených prostřednictvím Apple Pay. Využívá transakční data v reálném čase, aby umožnila zákazníkům analyzovat útratu kartou v různých časových obdobích (týdně, měsíčně, ročně), podle kategorie (cestování, supermarkety, hotovost atd.) a podle maloobchodníka.

V našem předchozím příspěvku jsme popsali, jak se Apache Flume a Apache Kafka používají k transformaci, obohacení a streamování transakcí do Apache HBase. Tento příspěvek pokračuje popisem toho, jak jsou transakce uspořádány v Apache HBase za účelem optimalizace výkonu a jak využíváme koprocesory k poskytování agregací nákupních trendů podle jednotlivých zákazníků. Santander a Cloudera pokračovali (a stále pokračují) na cestě HBase s Spendlytics, na cestě, která zažila mnoho iterací a optimalizací návrhu schémat a implementací koprocesorů. Doufáme, že tato získaná ponaučení jsou klíčovými body z tohoto příspěvku.

Schéma 1.0

Dobrý návrh schématu HBase je o porozumění zamýšleným vzorům přístupu. Udělejte to správně a HBase poletí; špatně a mohli byste skončit s neoptimálním výkonem kvůli konstrukčním kompromisům, jako jsou aktivní body regionu nebo nutnost provádět velké skenování ve více regionech. (hotspot v tabulce HBase je místo, kde nerovnoměrné rozložení klíčů řádků může způsobit, že většina požadavků bude směrována do jediné oblasti, což zahltí RegionServer a má za následek pomalou odezvu.)

Co jsme věděli o vzorech přístupu zamýšlených společností Spendlytics a jak to ovlivnilo původní návrh schématu:

  • Zákazníci analyzují pouze transakce na svých účtech:
    • Pro rychlé lineární skenování by měly být všechny transakce zákazníků ukládány postupně.
  • Čísla zákazníků se monotónně zvyšují:
    • Po sobě jdoucí čísla zákazníků zvyšují pravděpodobnost, že se novější zákazníci budou nacházet společně ve stejném regionu, což může potenciálně vytvořit horké místo v regionu. Chcete-li se tomuto problému vyhnout, měla by být čísla zákazníků solena (předpona) nebo obrácena tak, aby byla rovnoměrně distribuována napříč regiony, když se používají na začátku klíče řádku.
  • Zákazníci mají více karet
    • Pro optimalizaci skenování by měly být transakce zákazníka dále seskupeny a seřazeny podle smlouvy o kartě, tj. ID smlouvy by mělo tvořit součást klíče řádku.
  • Transakce budou přístupné jako celek, tj. atributy jako prodejce, obchodník, lokalita, měna a částka není třeba číst samostatně
    • Uložení atributů transakcí do samostatných buněk by vedlo k širší, řídké tabulce, což prodlouží dobu vyhledávání. Vzhledem k tomu, že atributy budou přístupné společně, mělo smysl je serializovat dohromady v záznamu Apache Avro. Avro je kompaktní a poskytuje nám efektivní reprezentaci s možností vyvíjet schéma.
  • K transakcím se přistupuje jednotlivě, v dávkách (podle času, kategorie a prodejce) a podle souhrnu (podle času, kategorie a prodejce).
    • Přidání jedinečného ID transakce jako kvalifikátoru sloupce umožní načtení jednotlivých transakcí, aniž by to zkomplikovalo klíč řádku.
    • Aby bylo umožněno rychlé skenování transakcí v různých časových obdobích, mělo by být časové razítko transakce součástí klíče řádku.
    • Přidání kategorie a prodejce do klíče řádku by mohlo být příliš podrobné a vedlo by k velmi vysoké a úzké tabulce se složitým klíčem řádku. Vysoké a úzké jsou v pořádku, vzhledem k tomu, že atomicita není problém, ale mít je jako kvalifikátory sloupců by rozšířilo tabulku a zároveň podporovalo sekundární agregace.
  • Data trendů by měla být co nejvíce předpočítána, aby se optimalizoval výkon čtení.
    • Více o tom později, ale prozatím víme, že jsme přidali druhou rodinu sloupců pro uložení trendů.

    Na základě výše uvedeného je počáteční návrh schématu znázorněn následovně:

    Výpočetní trendy

    Aspektem původního návrhu, ze kterého jsme se nejvíce naučili, byly počítačové trendy. Požadavkem bylo umožnit zákazníkům analyzovat jejich útratu podle kategorie a prodejce až na hodinu. Datové body zahrnovaly nejmenší a největší hodnoty transakcí, celkovou hodnotu transakce a počet transakcí. Doba odezvy musela být 200 ms nebo méně.

    Předvýpočetní trendy by nám poskytly nejrychlejší časy odezvy, takže toto byl náš první přístup. Trendy nemohly zpožďovat transakce, takže musely být počítány na cestě zápisu. To by bylo skvělé pro výkon při čtení, ale postavilo nás to před několik výzev:jak nejlépe uspořádat trendy v HBase a jak je rychle a spolehlivě vypočítat, aniž by to vážně ovlivnilo výkon zápisu.

    Experimentovali jsme s různými návrhy schémat a snažili jsme se využít některé dobře známé návrhy, kde to bylo možné (jako je schéma OpenTSDB). Po několika iteracích jsme se rozhodli pro návrh schématu znázorněný výše. Hodnoty trendu, které jsou uloženy v tabulce transakcí v samostatné rodině sloupců, jsou uspořádány společně do jednoho řádku s jedním řádkem trendu na zákazníka. Tím, že klíči řádku přiřadíte stejnou předponu, jakou mají transakce zákazníka (například <reverse_customer_id>::<contract_id> ) zajistilo, že řádek trendu bude setříděn vedle odpovídajících záznamů transakcí zákazníka. Díky definovaným hranicím regionů a vlastní zásadě rozdělení regionů můžeme také zaručit, že řádek trendu bude vždy přiřazen k záznamům transakcí zákazníka, což umožňuje, aby agregace trendů zůstala zcela na straně serveru v koprocesoru.

    Pro předvýpočet trendů jsme implementovali vlastní koprocesor pozorovatele připojit se k cestě zápisu. (Koprocesory pozorovatele jsou podobné spouštěčům v RDBMS v tom, že spouštějí uživatelský kód před nebo po výskytu konkrétní události. Například před nebo po Put nebo Get .)

    Na postPut koprocesor provede následující akce:

    1. Zaškrtne Put pro atribut trendu (příznak). Atribut se nastavuje pouze u nových záznamů transakcí, aby se zabránilo rekurzivním voláním při aktualizaci záznamu trendu. Umožňuje také přeskočení koprocesoru pro Put s, které nevyžadují aktualizaci trendů (např. vypořádání ).
    2. Získejte záznam trendu pro zákazníka. Záznam trendu zákazníka je umístěn spolu s jeho transakcemi (na základě předpony klíče řádku), takže jej koprocesor může načíst přímo z aktuální oblasti. Řádek trendu musí být uzamčen, aby se zabránilo tomu, že se několik vláken obslužné rutiny RegionServeru pokouší aktualizovat trendy paralelně.
    3. Aktualizovat datové body:
    4. Aktualizujte a odemkněte řádek trendu.

    Řešení se během testování ukázalo jako přesné a podle očekávání výkon čtení překročil požadavky. S tímto přístupem však byly určité obavy. První bylo, jak zvládnout selhání:trendy jsou uloženy v samostatném řádku, takže atomicita nemůže být zaručena. Druhým bylo, jak ověřit přesnost trendů v průběhu času; to znamená, že bychom museli zavést mechanismus pro identifikaci a nápravu jakýchkoli nepřesností trendu. Když jsme zvážili také požadavky na HA a skutečnost, že bychom potřebovali provozovat dvě, aktivní-aktivní instance HBase v různých datových centrech, mohl by to být větší problém. Nejenže by se přesnost trendu mohla v průběhu času snižovat, ale oba shluky by se také mohly posunout a je nutné je sladit v závislosti na metodě, kterou jsme použili k jejich synchronizaci. A konečně, oprava chyb nebo přidání nových datových bodů by bylo obtížné, protože bychom možná museli zpětně sledovat a přepočítávat všechny trendy.

    Poté došlo k zápisu. Pro každou novou transakci musel pozorovatel získat záznam trendu, aktualizovat 32 datových bodů a vrátit záznam trendu zpět. Navzdory tomu, co se dělo v rámci jediné oblasti, jsme zjistili, že propustnost se snížila z více než 20 000 zápisů za sekundu na 1 000 zápisů za sekundu (na RegionServer). Tento výkon byl přijatelný v krátkodobém horizontu, ale nebyl by přizpůsoben tak, aby podporoval předpokládanou dlouhodobou zátěž.

    Věděli jsme, že výkon zápisu představuje riziko, takže jsme měli plán zálohování, a to koprocesor koncového bodu . Koprocesory koncových bodů jsou podobné uloženým procedurám v RDBMS v tom, že umožňují provádět výpočty na straně serveru – na RegionServeru, kde jsou data umístěna, spíše než na klientovi. Koncové body efektivně rozšiřují HBase API.

    Místo předvýpočtu trendů je koncový bod počítá za běhu na straně serveru. V důsledku toho jsme mohli vypustit rodinu sloupců trendů ze schématu as tím bylo spojeno riziko nepřesností a odchylek. Odklon od pozorovatele vedlo k dobrému výkonu zápisu, ale bylo by čtení dostatečně rychlé? Zkrátka ano. S transakcemi zákazníka omezenými na jeden region a seřazenými podle karty a časového razítka může koncový bod rychle skenovat a agregovat, a to v rámci cíle 200 ms společnosti Spendlytics. To také znamená, že požadavek klienta (v tomto případě z rozhraní Spendlytics API) je vždy směrován pouze do jedné instance koncového bodu (jediného RegionServeru) a klient obdrží zpět jedinou odpověď s úplným výsledkem – to znamená, že nebude na straně klienta zpracování je vyžadováno pro agregaci dílčích výsledků z více koncových bodů, což by byl případ, kdy by transakce zákazníka pokrývaly více regionů.

    Poučení

    Spendlytics funguje od července 2015. Od té doby jsme pečlivě sledovali vzorce přístupu a hledali způsoby, jak optimalizovat výkon. Chceme neustále vylepšovat uživatelskou zkušenost a poskytovat zákazníkům stále lepší přehled o útratě za karty. Zbytek tohoto příspěvku popisuje lekce, které jsme se naučili ze spuštění Spendlytics v produkci, a některé optimalizace, které byly zavedeny.

    Po prvním vydání jsme identifikovali řadu bolestivých bodů, na které jsme se chtěli zaměřit. První bylo, jak filtrovat výsledky podle atributu transakce. Jak již bylo zmíněno dříve, atributy transakcí jsou zakódovány v záznamech Avro, ale zjistili jsme, že rostoucí počet vzorů přístupu chtěl filtrovat podle atributu a uživatelé byli nuceni to udělat na straně klienta. Původním řešením bylo implementovat vlastní HBase ValueFilter které akceptovaly naše vlastní komplexní filtrační výrazy, například:

    category='SUPERMARKETS' AND amount > 100 AND 
    (brand LIKE 'foo%' OR brand = 'bar')

    Výraz je vyhodnocen pro každý záznam Avro, což nám umožňuje filtrovat výsledky na straně serveru a snížit množství dat, která se vrací klientovi (úspora šířky pásma sítě a zpracování na straně klienta). Filtr má vliv na výkon skenování, ale doby odezvy zůstaly dobře v rámci cíle 200 ms.

    To skončilo jako dočasné řešení kvůli dalším změnám, které byly nutné k optimalizaci zápisů. Vzhledem k tomu, jak funguje proces zúčtování kreditní kartou, nejprve obdržíme autorizaci transakce od okamžiku prodeje (téměř v reálném čase) a poté o nějaký čas později vypořádáno transakce ze sítě kreditních karet (v dávce). Tyto transakce je třeba sladit, v podstatě sloučením vypořádaných transakce s oprávněným transakce již v HBase, připojování na ID transakce. V rámci tohoto procesu se mohou měnit atributy transakcí a lze přidávat nové atributy. To se ukázalo jako bolestivé kvůli režii nutnosti přepisování celých záznamů Avro – dokonce i při aktualizaci jednotlivých atributů. Aby byly atributy pro aktualizace přístupnější, uspořádali jsme je do sloupců, čímž jsme nahradili serializaci Avro.

    Zajímá nás také pouze atomicita na úrovni transakcí, takže seskupování transakcí po hodinách nám nepřineslo žádnou výhodu. Navíc se vyrovnal transakce, které nyní přicházejí v dávce, mají pouze úroveň podrobnosti dne, což znesnadnilo (nákladné) jejich sladění se stávajícími autorizovanými transakce uložené po hodině. Abychom tento problém vyřešili, přesunuli jsme ID transakce do klíče řádku a zkrátili zrno časového razítka na dny, nikoli hodiny. Proces odsouhlasení je nyní mnohem jednodušší, protože můžeme jednoduše hromadně načíst změny do HBase a nechat vyrovnání hodnoty mají přednost.

    Shrnuto:

    • Koprocesory Observer mohou být cenným nástrojem, ale používejte je moudře.
    • Pro některé případy použití je dobrou alternativou rozšíření HBase API pomocí koncových bodů.
    • Použijte vlastní filtry ke zlepšení výkonu oříznutím výsledků na straně serveru.
    • Serializované hodnoty dávají smysl pro správný případ použití, ale podporují silné stránky HBase tím, že upřednostňují nativní podporu pro pole a sloupce.
    • Správa předem vypočítaných výsledků je obtížná; dodatečná latence z práce na počítači se může vyplatit.
    • Vzory přístupu se změní, buďte proto agilní a otevření změnám schématu HBase, abyste se přizpůsobili a zůstali na špici.

    Cestovní mapa

    Optimalizací, kterou právě vyhodnocujeme, jsou hybridní koprocesory. Máme tím na mysli kombinaci koprocesorů pozorovatele a koncového bodu pro předvýpočet trendů. Na rozdíl od dříve bychom to však nedělali na cestě zápisu, ale na pozadí zapojením do operací proplachování a zhutňování HBase. Pozorovatel vypočítá trendy během událostí splachování a zhutňování na základě vypořádání transakce dostupné v daném okamžiku. Potom bychom použili koncový bod ke kombinaci předem vypočítaných trendů s průběžnými agregacemi delta transakcí. Doufáme, že předpočítáním trendů tímto způsobem zvýšíme výkon čtení, aniž bychom ovlivnili výkon zápisu.

    Dalším přístupem, který hodnotíme pro agregaci trendů a pro přístup HBase obecně, je Apache Phoenix. Phoenix je vzhled SQL pro HBase, který umožňuje přístup pomocí standardních rozhraní API JDBC. Doufáme, že použití SQL a JDBC zjednoduší přístup k HBase a sníží množství kódu, který musíme psát. Můžeme také využít inteligentní spouštěcí vzory společnosti Phoenix a vestavěné koprocesory a filtry pro rychlé agregace. Phoenix byl na počátku Spendlytics považován za příliš nezralý pro produkční použití, ale vzhledem k tomu, že podobné případy použití byly hlášeny například eBay a Salesforce, nyní je čas na přehodnocení. (Balík Phoenix pro CDH je k dispozici pro instalaci a vyhodnocení, ale bez podpory prostřednictvím Cloudera Labs.)

    Santander nedávno oznámila, že je první bankou, která uvedla na trh technologii hlasového bankovnictví, která zákazníkům umožňuje mluvit s její aplikací SmartBank a ptát se na útratu kartou. Platformou za touto technologií je Cloudera a architektura pro Spendlytics – jak je popsána v této sadě příspěvků – sloužila jako návrh plánu.

    James Kinley je hlavním architektem řešení ve společnosti Cloudera.

    Ian Buss je Senior Solutions Architect ve společnosti Cloudera.

    Pedro Boado je inženýr Hadoop ve společnosti Santander (Isban) UK.

    Abel Fernandez Alfonso je inženýrem Hadoop ve společnosti Santander (Isban) UK.


  1. Jak používat příkaz UNSUBSCRIBE v Redis 2.6.11

  2. jak převést řetězec na číselné hodnoty v mongodb

  3. Existuje nějaký způsob, jak obnovit nedávno smazané dokumenty v MongoDB?

  4. Aktualizace vnořeného pole uvnitř pole mongodb