Georedundancia használata magas rendelkezésre állású alkalmazások tervezéséhez

Az Azure Storage-hoz hasonló felhőalapú infrastruktúrák magas rendelkezésre állású és tartós platformot biztosítanak az adatok és alkalmazások üzemeltetéséhez. A felhőalapú alkalmazások fejlesztőinek alaposan meg kell fontolniuk, hogyan használhatják ezt a platformot a felhasználóik számára elérhető előnyök maximalizálása érdekében. Az Azure Storage georedundáns lehetőségeket kínál a magas rendelkezésre állás biztosítása érdekében még regionális leállás esetén is. A georedundáns replikációhoz konfigurált tárfiókok szinkron módon replikálódnak az elsődleges régióban, és aszinkron módon replikálódnak egy több száz mérföldnyire lévő másodlagos régióba.

Az Azure Storage két lehetőséget kínál a georedundáns replikációhoz: a georedundáns tárolást (GRS) és a georedundáns tárolást (GZRS). Az Azure Storage georedundáns beállításainak használatához győződjön meg arról, hogy a tárfiók írásvédett georedundáns tárolásra (RA-GRS) vagy írásvédett georedundáns tárolásra (RA-GZRS) van konfigurálva. Ha nem, többet is megtudhat a tárfiók replikációs típusának módosításáról.

Ez a cikk bemutatja, hogyan tervezhet meg egy olyan alkalmazást, amely továbbra is működni fog, bár korlátozott kapacitással, még akkor is, ha az elsődleges régióban jelentős kimaradás tapasztalható. Ha az elsődleges régió elérhetetlenné válik, az alkalmazás zökkenőmentesen válthat, hogy olvasási műveleteket hajtson végre a másodlagos régión, amíg az elsődleges régió újra nem válaszol.

Alkalmazáskialakítási szempontok

Az alkalmazást úgy tervezheti meg, hogy kezelje az átmeneti hibákat vagy a jelentős kimaradásokat a másodlagos régióból való olvasással, ha olyan probléma merül fel, amely zavarja az elsődleges régióból történő olvasást. Ha az elsődleges régió ismét elérhető, az alkalmazás visszatérhet az elsődleges régióból történő olvasáshoz.

Tartsa szem előtt ezeket a legfontosabb szempontokat, amikor az alkalmazást az RA-GRS vagy az RA-GZRS használatával tervezi meg a rendelkezésre állás és a rugalmasság érdekében:

  • Az elsődleges régióban tárolt adatok írásvédett másolata aszinkron módon replikálódik egy másodlagos régióban. Ez az aszinkron replikáció azt jelenti, hogy a másodlagos régióban az írásvédett példány végül megegyezik az elsődleges régió adataival. A tárolási szolgáltatás határozza meg a másodlagos régió helyét.

  • Az Azure Storage-ügyfélkódtárak használatával olvasási és frissítési kéréseket hajthat végre az elsődleges régió végpontja felé. Ha az elsődleges régió nem érhető el, automatikusan átirányíthatja az olvasási kérelmeket a másodlagos régióba. Az alkalmazást úgy is konfigurálhatja, hogy olvasási kéréseket küldjön közvetlenül a másodlagos régióba, ha szükséges, még akkor is, ha az elsődleges régió elérhető.

  • Ha az elsődleges régió elérhetetlenné válik, kezdeményezhet egy fiók feladatátvételét. Amikor feladatátvételt ad át a másodlagos régióba, a rendszer az elsődleges régióra mutató DNS-bejegyzéseket a másodlagos régióra irányítja. A feladatátvétel befejezése után a rendszer visszaállítja az írási hozzáférést a GRS- és RA-GRS-fiókokhoz. További információ: Vészhelyreállítás és tárfiók feladatátvétele.

Végül konzisztens adatok használata

A javasolt megoldás feltételezi, hogy elfogadható, ha elavult adatokat ad vissza a hívó alkalmazásnak. Mivel a másodlagos régió adatai végül konzisztensek, lehetséges, hogy az elsődleges régió elérhetetlenné válhat, mielőtt a másodlagos régió frissítése befejeződött volna a replikálásban.

Tegyük fel például, hogy az ügyfél sikeresen elküld egy frissítést, de az elsődleges régió meghiúsul, mielőtt a frissítést propagálná a másodlagos régióba. Amikor az ügyfél kéri az adatok visszaolvasását, a frissített adatok helyett a másodlagos régióból kapja meg az elavult adatokat. Az alkalmazás tervezésekor el kell döntenie, hogy ez a viselkedés elfogadható-e. Ha igen, akkor azt is figyelembe kell vennie, hogyan értesítheti a felhasználót.

A cikk későbbi részében többet is megtudhat a végleges konzisztens adatok kezeléséről , valamint arról, hogyan ellenőrizheti az Utolsó szinkronizálási idő tulajdonságot az elsődleges és a másodlagos régiók adatai közötti eltérések kiértékeléséhez.

Szolgáltatások kezelése külön-külön vagy együttesen

Bár nem valószínű, hogy egy szolgáltatás (blobok, üzenetsorok, táblák vagy fájlok) elérhetetlenné válik, míg a többi szolgáltatás továbbra is teljesen működőképes. Az egyes szolgáltatások újrapróbálkozásai külön kezelhetők, vagy az újrapróbálkozásokat általánosan is kezelheti az összes tárolási szolgáltatás esetében.

Ha például üzenetsorokat és blobokat használ az alkalmazásban, dönthet úgy, hogy külön kódot ad az egyes szolgáltatások újrapróbálkozható hibáinak kezeléséhez. Így a blobszolgáltatás hibája csak az alkalmazás blobokkal foglalkozó részét érinti, így az üzenetsorok továbbra is a szokásos módon futnak. Ha azonban úgy dönt, hogy az összes tárolási szolgáltatás újrapróbálkozásait együtt kezeli, akkor a blob- és üzenetsor-szolgáltatásoknak küldött kérések is érintettek lesznek, ha bármelyik szolgáltatás újrapróbálkozási hibát ad vissza.

Végső soron ez a döntés az alkalmazás összetettségétől függ. Előfordulhat, hogy inkább szolgáltatásonként szeretné kezelni a hibákat, hogy korlátozza az újrapróbálkozások hatását. Vagy úgy is dönthet, hogy az összes tárolási szolgáltatás olvasási kéréseit átirányítja a másodlagos régióba, amikor problémát észlel az elsődleges régióban található bármely tárolási szolgáltatással kapcsolatban.

Az alkalmazás futtatása írásvédett módban

Ha hatékonyan szeretne felkészülni az elsődleges régió leállására, az alkalmazásnak képesnek kell lennie a sikertelen olvasási és a sikertelen frissítési kérések kezelésére is. Ha az elsődleges régió meghibásodik, az olvasási kérelmek átirányíthatók a másodlagos régióba. A frissítési kérések azonban nem irányíthatók át, mert a másodlagos régióban a replikált adatok írásvédettek. Ezért meg kell terveznie az alkalmazást, hogy írásvédett módban fusson.

Beállíthatja például azt a jelzőt, amelyet a rendszer még azelőtt ellenőriz, hogy a rendszer elküldené a frissítési kéréseket az Azure Storage-ba. Amikor frissítési kérelem érkezik, kihagyhatja a kérést, és megfelelő választ adhat vissza a felhasználónak. Akár úgy is dönthet, hogy a probléma megoldásáig letilt bizonyos funkciókat, és értesíti a felhasználókat arról, hogy a funkciók átmenetileg nem érhetők el.

Ha úgy dönt, hogy az egyes szolgáltatások hibáit külön kezeli, akkor azt is kezelnie kell, hogy az alkalmazást szolgáltatásonként írásvédett módban futtathassa. Beállíthat például írásvédett jelzőket az egyes szolgáltatásokhoz. Ezután szükség szerint engedélyezheti vagy letilthatja a kódban lévő jelzőket.

Ha írásvédett módban tudja futtatni az alkalmazást, az is lehetővé teszi, hogy korlátozott funkcionalitást biztosítson egy nagyobb alkalmazásfrissítés során. Aktiválhatja az alkalmazást, hogy írásvédett módban fusson, és a másodlagos adatközpontra mutasson, így biztosítva, hogy a frissítések végrehajtása közben senki sem fér hozzá az elsődleges régióban lévő adatokhoz.

Frissítések kezelése írásvédett módban való futtatáskor

A frissítési kérések többféleképpen is kezelhetők, ha írásvédett módban futnak. Ez a szakasz néhány megfontolandó általános mintát mutat be.

  • Válaszolhat a felhasználónak, és értesítheti őket arról, hogy a frissítési kérelmek feldolgozása jelenleg nem történik meg. Egy kapcsolatkezelő rendszer például lehetővé teheti a felhasználók számára, hogy hozzáférjenek a kapcsolattartási adatokhoz, de ne végezzenek frissítéseket.

  • A frissítéseket egy másik régióban is leküldheti. Ebben az esetben a függőben lévő frissítési kéréseket egy másik régióban lévő üzenetsorba írná, majd feldolgozná ezeket a kéréseket, miután az elsődleges adatközpont újra online állapotba kerül. Ebben a forgatókönyvben tudatnia kell a felhasználóval, hogy a frissítési kérelem várólistán van a későbbi feldolgozáshoz.

  • A frissítéseket egy másik régióban lévő tárfiókba is megírhatja. Amikor az elsődleges régió újra online állapotba kerül, ezeket a frissítéseket az adatok struktúrájától függően egyesítheti az elsődleges adatokkal. Ha például külön fájlokat hoz létre egy dátum/idő bélyeggel a névben, ezeket a fájlokat visszamásolhatja az elsődleges régióba. Ez a megoldás olyan számítási feladatokra alkalmazható, mint a naplózás és az IoT-adatok.

Újrapróbálkozések kezelése

A felhőben futó szolgáltatásokkal kommunikáló alkalmazásoknak érzékenynek kell lenniük a nem tervezett eseményekre és hibákra. Ezek a hibák átmenetiek vagy tartósak lehetnek, a kapcsolat pillanatnyi elvesztésétől a természeti katasztrófa miatt jelentős kimaradásig. Fontos, hogy megfelelő újrapróbálkozással tervezzen felhőalkalmazásokat a rendelkezésre állás maximalizálása és az alkalmazások általános stabilitásának javítása érdekében.

Olvasási kérések

Ha az elsődleges régió elérhetetlenné válik, az olvasási kérelmek átirányíthatók a másodlagos tárolóba. Ahogy korábban említettük, az alkalmazás számára elfogadhatónak kell lennie az elavult adatok olvasásához. Az Azure Storage-ügyfélkódtár lehetőséget kínál az újrapróbálkozások kezelésére és az olvasási kérelmek másodlagos régióba való átirányítására.

Ebben a példában a Blob Storage újrapróbálkozásának kezelése az BlobClientOptions osztályban van konfigurálva, és az BlobServiceClient alábbi konfigurációs beállítások használatával létrehozott objektumra lesz alkalmazva. Ez a konfiguráció egy elsődleges, majd másodlagos megközelítés, ahol a rendszer átirányítja az olvasási kérések újrapróbálkozásait az elsődleges régióból a másodlagos régióba. Ez a módszer akkor a legjobb, ha az elsődleges régióban a hibák várhatóan ideiglenesek lesznek.

string accountName = "<YOURSTORAGEACCOUNTNAME>";
Uri primaryAccountUri = new Uri($"https://{accountName}.blob.core.windows.net/");
Uri secondaryAccountUri = new Uri($"https://{accountName}-secondary.blob.core.windows.net/");

// Provide the client configuration options for connecting to Azure Blob storage
BlobClientOptions blobClientOptions = new BlobClientOptions()
{
    Retry = {
        // The delay between retry attempts for a fixed approach or the delay
        // on which to base calculations for a backoff-based approach
        Delay = TimeSpan.FromSeconds(2),

        // The maximum number of retry attempts before giving up
        MaxRetries = 5,

        // The approach to use for calculating retry delays
        Mode = RetryMode.Exponential,

        // The maximum permissible delay between retry attempts
        MaxDelay = TimeSpan.FromSeconds(10)
    },

    // If the GeoRedundantSecondaryUri property is set, the secondary Uri will be used for 
    // GET or HEAD requests during retries.
    // If the status of the response from the secondary Uri is a 404, then subsequent retries
    // for the request will not use the secondary Uri again, as this indicates that the resource 
    // may not have propagated there yet.
    // Otherwise, subsequent retries will alternate back and forth between primary and secondary Uri.
    GeoRedundantSecondaryUri = secondaryAccountUri
};

// Create a BlobServiceClient object using the configuration options above
BlobServiceClient blobServiceClient = new BlobServiceClient(primaryAccountUri, new DefaultAzureCredential(), blobClientOptions);

Ha úgy dönt, hogy az elsődleges régió valószínűleg hosszú ideig nem érhető el, konfigurálhatja az összes olvasási kérést úgy, hogy a másodlagos régióra mutasson. Ez a konfiguráció csak másodlagos megközelítés. Ahogy korábban már említettem, szüksége lesz egy stratégiára a frissítési kérések kezeléséhez ebben az időszakban, és egy olyan módszerre, amellyel tájékoztathatja a felhasználókat arról, hogy csak az olvasási kérések feldolgozása folyamatban van. Ebben a példában létrehozunk egy új példányt, amely a másodlagos régió végpontját BlobServiceClient használja.

string accountName = "<YOURSTORAGEACCOUNTNAME>";
Uri primaryAccountUri = new Uri($"https://{accountName}.blob.core.windows.net/");
Uri secondaryAccountUri = new Uri($"https://{accountName}-secondary.blob.core.windows.net/");

// Create a BlobServiceClient object pointed at the secondary Uri
// Use blobServiceClientSecondary only when issuing read requests, as secondary storage is read-only
BlobServiceClient blobServiceClientSecondary = new BlobServiceClient(secondaryAccountUri, new DefaultAzureCredential(), blobClientOptions);

Annak ismerete, hogy mikor kell csak olvasási módra és másodlagos csak kérelmekre váltani, az egy áramkör-megszakító minta nevű architektúratervezési minta része, amelyet egy későbbi szakaszban tárgyalunk.

Kérések frissítése

A frissítési kérések nem irányíthatók át másodlagos tárolóba, amely írásvédett. A korábban leírtak szerint az alkalmazásnak képesnek kell lennie a frissítési kérelmek kezelésére , ha az elsődleges régió nem érhető el.

Az áramkör-megszakító minta frissítési kérelmekre is alkalmazható. A frissítési kérelmek hibáinak kezeléséhez beállíthat egy küszöbértéket a kódban, például 10 egymást követő hibát, és nyomon követheti az elsődleges régióba irányuló kérések hibáinak számát. A küszöbérték elérése után átállíthatja az alkalmazást írásvédett módra, hogy a rendszer ne adja ki a kéréseket az elsődleges régióra.

Az áramkör-megszakító minta implementálása

Az olyan hibák kezelése, amelyek miatt a helyreállítás változó ideig tarthat, egy áramkör-megszakító mintának nevezett architektúratervezési minta része. Ennek a mintának a megfelelő implementálása megakadályozhatja, hogy egy alkalmazás ismétlődően megpróbáljon végrehajtani egy valószínűleg sikertelen műveletet, ami javítja az alkalmazás stabilitását és rugalmasságát.

Az áramkör-megszakító minta egyik eleme az elsődleges végponttal kapcsolatos folyamatos probléma azonosítása. Ennek meghatározásához monitorozhatja, hogy az ügyfél milyen gyakran találkozik újrapróbálkozható hibával. Mivel mindegyik forgatókönyv eltérő, meg kell határoznia egy megfelelő küszöbértéket, amelyet a másodlagos végpontra való váltáshoz és az alkalmazás írásvédett módban való futtatásához kell használnia.

Dönthet például úgy, hogy végrehajtja a kapcsolót, ha 10 egymást követő hiba van az elsődleges régióban. Ezt nyomon követheti a kódban található hibák számának megadásával. Ha a küszöbérték elérése előtt sikeres a művelet, állítsa vissza a számot nullára. Ha a szám eléri a küszöbértéket, váltsa át az alkalmazást úgy, hogy a másodlagos régiót használja az olvasási kérelmekhez.

Alternatív megközelítésként dönthet úgy, hogy egyéni monitorozási összetevőt implementál az alkalmazásban. Ez az összetevő folyamatosan pingelheti az elsődleges tárolóvégpontot triviális olvasási kérésekkel (például egy kis blob olvasásával) az állapotának meghatározásához. Ez a megközelítés bizonyos erőforrásokat igényelne, de nem jelentős összeget. Ha olyan probléma merül fel, amely eléri a küszöbértéket, átválthat másodlagos csak olvasási kérelmekre és írásvédett módra. Ebben a forgatókönyvben, amikor az elsődleges tárvégpont pingelése ismét sikeres lesz, visszaállhat az elsődleges régióra, és folytathatja a frissítések engedélyezését.

A váltás időpontjának meghatározásához használt hibaküszöb az alkalmazáson belüli szolgáltatásonként eltérő lehet, ezért érdemes megfontolnia a konfigurálható paramétereket.

Egy másik szempont egy alkalmazás több példányának kezelése, és mi a teendő, ha újrapróbálkozható hibákat észlel az egyes példányokban. Előfordulhat például, hogy 20 virtuális gép fut ugyanazzal az alkalmazással. Minden példányt külön kezel? Ha egy példány problémákba ütközik, csak arra a példányra szeretné korlátozni a választ? Vagy azt szeretné, hogy az összes példány ugyanúgy válaszoljon, ha egy példánynak problémája van? A példányok külön kezelése sokkal egyszerűbb, mint a válasz koordinálása velük, de a megközelítés az alkalmazás architektúrájától függ.

Végül konzisztens adatok kezelése

A georedundáns tárolás úgy működik, hogy az elsődleges régióból a másodlagos régióba replikálja a tranzakciókat. A replikációs folyamat garantálja, hogy a másodlagos régióban lévő adatok végül konzisztensek legyenek. Ez azt jelenti, hogy az elsődleges régióban lévő összes tranzakció végül megjelenik a másodlagos régióban, de előfordulhat, hogy késés van a megjelenésük előtt. Arra sincs garancia, hogy a tranzakciók a másodlagos régióba érkeznek az eredetileg az elsődleges régióban alkalmazott sorrendben. Ha a tranzakciók sorrendben érkeznek meg a másodlagos régióba , előfordulhat, hogy a másodlagos régióban lévő adatai inkonzisztens állapotban lesznek, amíg a szolgáltatás fel nem áll.

Az Azure Table Storage-hoz készült alábbi példa bemutatja, mi történhet, ha frissíti az alkalmazott adatait, hogy a rendszergazdai szerepkör tagja legyen. A példa kedvéért ehhez frissítenie kell az alkalmazotti entitást, és frissítenie kell egy rendszergazdai szerepkör entitást a rendszergazdák teljes számának számával. Figyelje meg, hogyan alkalmazzák a frissítéseket a másodlagos régióban.

Idő Tranzakció Replikáció Utolsó szinkronizálás időpontja Eredmény
T0 A tranzakció:
Alkalmazott beszúrása
entitás az elsődlegesben
Az elsődlegesbe beszúrt A tranzakció,
még nincs replikálva.
T1 A tranzakció
replikálva
Másodlagos
T1 Az A tranzakció másodlagosra replikálva.
Legutóbbi szinkronizálási idő frissítve.
T2 B tranzakció:
Frissítés
alkalmazotti entitás
az elsődleges
T1 A B tranzakció az elsődlegesbe írva,
még nincs replikálva.
T3 C tranzakció:
Frissítés
adminisztrátor
szerepkör-entitás a következőben:
Elsődleges
T1 C tranzakció az elsődlegesbe írva,
még nincs replikálva.
T4 C tranzakció
replikálva
Másodlagos
T1 A C tranzakció másodlagosra replikálva.
A LastSyncTime nem frissült, mert
A B tranzakciót még nem replikálták.
T5 Entitások olvasása
másodlagosról
T1 Az alkalmazott elavult értékét kapja meg
entitás, mert a B tranzakció nem
replikálva. Az új értéket a következőhöz kapja:
rendszergazdai szerepkör entitás, mert a C
Replikált. A legutóbbi szinkronizálási idő még mindig nem
frissítésre került, mert a B tranzakció
nem replikált. Megadhatja, hogy a
a rendszergazdai szerepkör entitása inkonzisztens
mert az entitás dátuma/időpontja a következő:
az utolsó szinkronizálási időpont.
T6 B tranzakció
replikálva
Másodlagos
T6 T6 – A C-n keresztüli összes tranzakció rendelkezik
replikálva, utolsó szinkronizálási idő
frissítésre kerül.

Ebben a példában feltételezzük, hogy az ügyfél a T5 másodlagos régióból való olvasásra vált. Jelenleg sikeresen beolvassa a rendszergazdai szerepkör entitást, de az entitás olyan értéket tartalmaz a rendszergazdák számára, amelyek nem összhangban vannak a másodlagos régióban rendszergazdaként megjelölt alkalmazott entitások számával. Az ügyfél megjelenítheti ezt az értéket, azzal a kockázattal, hogy az információk inkonzisztensek. Másik lehetőségként az ügyfél megpróbálhatja megállapítani, hogy a rendszergazdai szerepkör inkonzisztens állapotban van-e, mert a frissítések sorrendben történtek, majd erről tájékoztatja a felhasználót.

Annak megállapításához, hogy egy tárfiók rendelkezik-e esetleg inkonzisztens adatokkal, az ügyfél ellenőrizheti a Legutóbbi szinkronizálási idő tulajdonság értékét. A legutóbbi szinkronizálási idő azt az időpontot jelzi, amikor a másodlagos régió adatai utoljára konzisztensek voltak, és hogy a szolgáltatás mikor alkalmazta az összes tranzakciót az adott időpont előtt. A fenti példában, miután a szolgáltatás beszúrta az alkalmazott entitást a másodlagos régióba, az utolsó szinkronizálási idő T1 lesz. A T1 értéken marad, amíg a szolgáltatás nem frissíti az alkalmazotti entitást a másodlagos régióban, amikor az T6 értékre van állítva. Ha az ügyfél lekéri az utolsó szinkronizálási időpontot, amikor beolvassa az entitást a T5-ben, összehasonlíthatja az entitás időbélyegével. Ha az entitás időbélyege későbbi, mint az utolsó szinkronizálási idő, akkor az entitás inkonzisztens állapotban van, és végrehajthatja a megfelelő műveletet. A mező használatához tudnia kell, hogy mikor fejeződött be az elsődlegesre vonatkozó utolsó frissítés.

Az utolsó szinkronizálási időpont ellenőrzéséről további információt a Tárfiók utolsó szinkronizálási ideje tulajdonságának ellenőrzése című témakörben talál.

Tesztelés

Fontos tesztelni, hogy az alkalmazás a várt módon viselkedik-e, amikor újrapróbálható hibákba ütközik. Például tesztelnie kell, hogy az alkalmazás átvált-e a másodlagos régióra, amikor problémát észlel, majd vissza kell váltania, amikor az elsődleges régió ismét elérhetővé válik. A viselkedés megfelelő teszteléséhez módot kell használnia az újrapróbálható hibák szimulálására és azok előfordulásának szabályozására.

Az egyik lehetőség a Fiddler használata a HTTP-válaszok elfogására és módosítására egy szkriptben. Ez a szkript azonosítja az elsődleges végponttól érkező válaszokat, és a HTTP-állapotkódot olyanra módosítja, amelyet a Storage-ügyfélkódtár újrapróbálható hibaként ismer fel. Ez a kódrészlet egy egyszerű fiddler-szkriptet mutat be, amely elfogja az employeedata tábla olvasási kérelmeire adott válaszokat, és 502-állapotot ad vissza:

static function OnBeforeResponse(oSession: Session) {
    ...
    if ((oSession.hostname == "\[YOURSTORAGEACCOUNTNAME\].table.core.windows.net")
      && (oSession.PathAndQuery.StartsWith("/employeedata?$filter"))) {
        oSession.responseCode = 502;
    }
}

Ezt a példát kiterjesztheti a kérések szélesebb körének elfogására, és csak néhányon módosíthatja a responseCode-ot egy valós forgatókönyv jobb szimulálása érdekében. További információ a Fiddler-szkriptek testreszabásáról: Kérés vagy válasz módosítása a Fiddler dokumentációjában.

Ha konfigurálható küszöbértékeket állított be az alkalmazás írásvédettre váltásához, egyszerűbben tesztelheti a viselkedést nem éles tranzakciós kötetekkel.


Következő lépések

Az elsődleges és másodlagos végpontok közötti váltást bemutató teljes minta: Azure-minták – Az áramkör-megszakító minta használata RA-GRS-tárolóval.