Share via


Azure Storage-erőforrások listázása c++ nyelven

A listázási műveletek kulcsfontosságúak az Azure Storage számos fejlesztési forgatókönyvében. Ez a cikk azt ismerteti, hogyan lehet a leghatékonyabban számba adni az objektumokat az Azure Storage-ban a C++-hoz készült Microsoft Azure Storage ügyfélkódtárban található listázási API-k használatával.

Megjegyzés

Ez az útmutató a C++ 2.x verzióhoz készült Azure Storage-ügyfélkódtárat célozza meg, amely a NuGet vagy a GitHub használatával érhető el.

A Storage-ügyfélkódtár különféle módszereket kínál az Objektumok listázásához vagy lekérdezéséhez az Azure Storage-ban. Ez a cikk a következő forgatókönyvekkel foglalkozik:

  • Tárolók listázása egy fiókban
  • Blobok listázása tárolóban vagy virtuális blobkönyvtárban
  • Üzenetsorok listázása egy fiókban
  • Egy fiók tábláinak listázása
  • Tábla entitásainak lekérdezése

Ezen módszerek mindegyike különböző túlterhelések használatával jelenik meg a különböző forgatókönyvek esetében.

Aszinkron és szinkron

Mivel a C++ tár ügyféloldali kódtára a C++ REST kódtárra épül, a pplx::task használatával eredendően támogatjuk az aszinkron műveleteket. Például:

pplx::task<list_blob_item_segment> list_blobs_segmented_async(continuation_token& token) const;

A szinkron műveletek a megfelelő aszinkron műveleteket burkolják:

list_blob_item_segment list_blobs_segmented(const continuation_token& token) const
{
    return list_blobs_segmented_async(token).get();
}

Ha több szálbefűző alkalmazással vagy szolgáltatással dolgozik, javasoljuk, hogy közvetlenül használja az async API-kat ahelyett, hogy létrehozna egy szálat a szinkronizálási API-k meghívásához, ami jelentősen befolyásolja a teljesítményt.

Szegmentált lista

A felhőbeli tárterület méretéhez szegmentált listára van szükség. Egy Azure-blobtárolóban például több mint egymillió blob, vagy egy Azure Table több mint egy milliárd entitása lehet. Ezek nem elméleti számok, hanem valós ügyfélhasználati esetek.

Ezért nem célszerű egyetlen válaszban felsorolni az összes objektumot. Ehelyett lapozással listázhatja az objektumokat. A listázási API-k mindegyike szegmentált túlterheléssel rendelkezik.

A szegmentált listázási műveletre adott válasz a következőket tartalmazza:

  • _segment, amely a listázó API egyetlen hívásához visszaadott eredményeket tartalmazza.
  • continuation_token, amelyet a következő hívásnak ad át a következő eredményoldal lekéréséhez. Ha nincs több eredmény, a folytatási jogkivonat null értékű.

Egy tároló összes blobjának listázására szolgáló tipikus hívás például az alábbi kódrészlethez hasonlóan nézhet ki. A kód a következő mintákban érhető el:

// List blobs in the blob container
azure::storage::continuation_token token;
do
{
    azure::storage::list_blob_item_segment segment = container.list_blobs_segmented(token);
    for (auto it = segment.results().cbegin(); it != segment.results().cend(); ++it)
{
    if (it->is_blob())
    {
        process_blob(it->as_blob());
    }
    else
    {
        process_directory(it->as_directory());
    }
}

    token = segment.continuation_token();
}
while (!token.empty());

Vegye figyelembe, hogy a lapon visszaadott eredmények számát az egyes API-k túlterhelésében max_results paraméter szabályozhatja, például:

list_blob_item_segment list_blobs_segmented(const utility::string_t& prefix, bool use_flat_blob_listing,
    blob_listing_details::values includes, int max_results, const continuation_token& token,
    const blob_request_options& options, operation_context context)

Ha nem adja meg a max_results paramétert, a legfeljebb 5000 találatot tartalmazó alapértelmezett maximális érték egyetlen oldalon lesz visszaadva.

Azt is vegye figyelembe, hogy az Azure Table Storage-ra vonatkozó lekérdezések nem adnak vissza rekordokat, vagy kevesebb rekordot, mint a megadott max_results paraméter értéke, még akkor is, ha a folytatási jogkivonat nem üres. Ennek egyik oka lehet, hogy a lekérdezés öt másodperc alatt nem fejezhető be. Amíg a folytatási jogkivonat nem üres, a lekérdezésnek folytatódnia kell, és a kód nem feltételezheti a szegmenseredmények méretét.

A legtöbb forgatókönyv esetében ajánlott kódolási minta a szegmentált lista, amely explicit módon biztosítja a listázás vagy lekérdezés folyamatát, valamint azt, hogy a szolgáltatás hogyan reagál az egyes kérésekre. Különösen A C++ alkalmazások és szolgáltatások esetében a listaállapot alacsonyabb szintű szabályozása segíthet a memória és a teljesítmény szabályozásában.

Mohó lista

A C++ tárolóügyfél-kódtár korábbi verziói (0.5.0 előzetes verzió és korábbi verziók) nem szegmentált listázási API-kat tartalmaztak táblákhoz és üzenetsorokhoz, az alábbi példához hasonlóan:

std::vector<cloud_table> list_tables(const utility::string_t& prefix) const;
std::vector<table_entity> execute_query(const table_query& query) const;
std::vector<cloud_queue> list_queues() const;

Ezeket a metódusokat szegmentált API-k burkolójaként implementálták. A kód a szegmentált lista minden válaszához hozzáfűzi az eredményeket egy vektorhoz, és visszaadta az összes eredményt a teljes tárolók vizsgálata után.

Ez a módszer akkor működhet, ha a tárfiók vagy a tábla kevés objektumot tartalmaz. Az objektumok számának növekedésével azonban a szükséges memória korlátlanul növekedhet, mivel az összes eredmény a memóriában maradt. Egy listázási művelet nagyon hosszú időt vehet igénybe, amelynek során a hívónak nem volt információja a folyamatról.

Ezek a mohó lista API-k az SDK-ban nem léteznek C#, Java vagy JavaScript Node.js környezetben. A kapzsi API-k használatának lehetséges problémáinak elkerülése érdekében eltávolítottuk őket a 0.6.0 előzetes verzióban.

Ha a kód meghívja ezeket a kapzsi API-kat:

std::vector<azure::storage::table_entity> entities = table.execute_query(query);
for (auto it = entities.cbegin(); it != entities.cend(); ++it)
{
    process_entity(*it);
}

Ezután módosítania kell a kódot a szegmentált lista API-k használatára:

azure::storage::continuation_token token;
do
{
    azure::storage::table_query_segment segment = table.execute_query_segmented(query, token);
    for (auto it = segment.results().cbegin(); it != segment.results().cend(); ++it)
    {
        process_entity(*it);
    }

    token = segment.continuation_token();
} while (!token.empty());

A szegmens max_results paraméterének megadásával egyensúlyba hozhatja a kérések számát és a memóriahasználatot, hogy megfeleljen az alkalmazás teljesítményével kapcsolatos szempontoknak.

Emellett, ha szegmentált listázási API-kat használ, de az adatokat egy helyi gyűjteményben tárolja "kapzsi" stílusban, határozottan javasoljuk, hogy a kód újrabontásával kezelje az adatokat a helyi gyűjteményekben, nagy léptékben.

Lusta lista

Bár a mohó lista potenciális problémákat vetett fel, kényelmes, ha nincs túl sok objektum a tárolóban.

Ha C# vagy Oracle Java SDK-kat is használ, ismernie kell az Enumerable programozási modellt, amely egy lusta stílusú listát kínál, ahol a rendszer csak akkor kéri le az adatokat egy bizonyos eltolásnál, ha szükséges. A C++-ban az iterátoralapú sablon is hasonló megközelítést biztosít.

Egy tipikus lusta listázási API, amely például list_blobs használ, a következőképpen néz ki:

list_blob_item_iterator list_blobs() const;

A lusta listamintát használó tipikus kódrészletek a következőképpen néznek ki:

// List blobs in the blob container
azure::storage::list_blob_item_iterator end_of_results;
for (auto it = container.list_blobs(); it != end_of_results; ++it)
{
    if (it->is_blob())
    {
        process_blob(it->as_blob());
    }
    else
    {
        process_directory(it->as_directory());
    }
}

Vegye figyelembe, hogy a lusta lista csak szinkron módban érhető el.

A mohó listához képest a lusta lista csak akkor olvassa be az adatokat, ha szükséges. A borítók alatt csak akkor olvassa be az adatokat az Azure Storage-ból, ha a következő iterátor a következő szegmensbe kerül. Ezért a memóriahasználat korlátozott méretű, és a művelet gyors.

A 2.2.0-s verzióban a C++-hoz készült Storage-ügyféloldali kódtár tartalmazza a lusta lista API-kat.

Összegzés

Ebben a cikkben a C++ tárolóügyfél-kódtár különböző objektumaihoz tartozó API-k listázásának különböző túlterheléseit mutattuk be. Összegezve:

  • Az aszinkron API-k erősen ajánlottak több szálkezeléses forgatókönyv esetén.
  • A szegmentált listaelem a legtöbb esetben ajánlott.
  • A lusta lista a tárban található, a szinkron forgatókönyvek kényelmes burkolójaként.
  • A mohó lista nem ajánlott, és el lett távolítva a tárból.

Következő lépések

További információ az Azure Storage-ról és a C++-hoz készült ügyfélkódtárról: