Dela via


Lista över Azure Storage-resurser i C++

Liståtgärder är viktiga för många utvecklingsscenarier med Azure Storage. Den här artikeln beskriver hur du mest effektivt räknar upp objekt i Azure Storage med hjälp av list-API:erna i Microsoft Azure Storage-klientbiblioteket för C++.

Kommentar

Den här guiden riktar sig till Azure Storage-klientbiblioteket för C++ version 2.x, som är tillgängligt via NuGet eller GitHub.

Lagringsklientbiblioteket innehåller en mängd olika metoder för att lista eller fråga efter objekt i Azure Storage. Den här artikeln beskriver följande scenarier:

  • Visa en lista över containrar i ett konto
  • Visa en lista över blobar i en container eller en virtuell blobkatalog
  • Lista köer i ett konto
  • Lista tabeller i ett konto
  • Fråga entiteter i en tabell

Var och en av dessa metoder visas med olika överlagringar för olika scenarier.

Asynkron kontra synkron

Eftersom lagringsklientbiblioteket för C++ bygger på C++ REST-biblioteket stöder vi asynkrona åtgärder med hjälp av pplx::task. Till exempel:

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

Synkrona åtgärder omsluter motsvarande asynkrona åtgärder:

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

Om du arbetar med flera trådprogram eller tjänster rekommenderar vi att du använder asynkrona API:er direkt i stället för att skapa en tråd för att anropa synkroniserings-API:erna, vilket avsevärt påverkar dina prestanda.

Segmenterad lista

Skalningen av molnlagring kräver segmenterad lista. Du kan till exempel ha över en miljon blobar i en Azure-blobcontainer eller över en miljard entiteter i en Azure-tabell. Det här är inte teoretiska tal, utan verkliga kundanvändningsfall.

Det är därför opraktiskt att lista alla objekt i ett enda svar. I stället kan du visa en lista över objekt med hjälp av växling. Var och en av api:erna i listan har en segmenterad överlagring.

Svaret för en segmenterad listningsåtgärd omfattar:

  • _segment, som innehåller den uppsättning resultat som returneras för ett enda anrop till list-API:et.
  • continuation_token, som skickas till nästa anrop för att få nästa resultatsida. När det inte finns några fler resultat att returnera är fortsättningstoken null.

Ett vanligt anrop för att visa en lista över alla blobar i en container kan till exempel se ut som följande kodfragment. Koden finns i våra exempel:

// 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());

Observera att antalet resultat som returneras på en sida kan styras av parametern max_results i överbelastningen för varje API, till exempel:

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)

Om du inte anger parametern max_results returneras det maximala standardvärdet på upp till 5 000 resultat på en enda sida.

Observera också att en fråga mot Azure Table Storage kanske inte returnerar några poster eller färre poster än värdet för den max_results parameter som du angav, även om fortsättningstoken inte är tom. En orsak kan vara att frågan inte kunde slutföras på fem sekunder. Så länge fortsättningstoken inte är tom bör frågan fortsätta och koden bör inte förutsätta storleken på segmentresultatet.

Det rekommenderade kodningsmönstret för de flesta scenarier är segmenterad lista, som ger explicit förlopp för att lista eller fråga och hur tjänsten svarar på varje begäran. Särskilt för C++-program eller -tjänster kan kontroll på lägre nivå av listförloppet hjälpa till att kontrollera minne och prestanda.

Girig lista

Tidigare versioner av Lagringsklientbiblioteket för C++ (version 0.5.0 Förhandsversion och tidigare) inkluderade icke-segmenterade list-API:er för tabeller och köer, som i följande exempel:

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;

Dessa metoder implementerades som omslutning av segmenterade API:er. För varje svar i segmenterad lista lägger koden till resultaten i en vektor och returnerar alla resultat efter att de fullständiga containrarna genomsökts.

Den här metoden kan fungera när lagringskontot eller tabellen innehåller ett litet antal objekt. Men med en ökning av antalet objekt kan det minne som krävs öka utan begränsning, eftersom alla resultat kvarstod i minnet. En liståtgärd kan ta mycket lång tid, under vilken anroparen inte hade någon information om dess förlopp.

Dessa giriga list-API:er i SDK finns inte i C#, Java eller JavaScript-Node.js miljön. För att undvika potentiella problem med att använda dessa giriga API:er har vi tagit bort dem i version 0.6.0 Preview.

Om koden anropar dessa giriga API:er:

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

Sedan bör du ändra koden så att den använder de segmenterade list-API:erna:

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());

Genom att ange max_results-parametern för segmentet kan du balansera mellan antalet begäranden och minnesanvändningen för att uppfylla prestandaöverväganden för ditt program.

Om du använder segmenterade list-API:er, men lagrar data i en lokal samling i ett "girigt" format, rekommenderar vi också starkt att du omstrukturerar koden för att hantera lagring av data i en lokal samling noggrant i stor skala.

Lazy-lista

Även om giriga listor gav upphov till potentiella problem är det praktiskt om det inte finns för många objekt i containern.

Om du också använder C# eller Oracle Java SDK:er bör du vara bekant med den uppräkningsbara programmeringsmodellen, som erbjuder en lista med lata format, där data vid en viss förskjutning endast hämtas om det behövs. I C++ger den iteratorbaserade mallen också en liknande metod.

Ett typiskt API för lat listning, med list_blobs som exempel, ser ut så här:

list_blob_item_iterator list_blobs() const;

Ett typiskt kodfragment som använder det lata listmönstret kan se ut så här:

// 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());
    }
}

Observera att lazy-listan endast är tillgänglig i synkront läge.

Jämfört med giriga listor hämtar lazy-listan endast data när det behövs. Under täcket hämtar den endast data från Azure Storage när nästa iterator flyttas till nästa segment. Därför styrs minnesanvändningen med en begränsad storlek och åtgärden är snabb.

API:er med lat lista ingår i lagringsklientbiblioteket för C++ i version 2.2.0.

Slutsats

I den här artikeln diskuterade vi olika överlagringar för att lista API:er för olika objekt i Lagringsklientbiblioteket för C++ . Sammanfattningsvis:

  • Asynkrona API:er rekommenderas starkt under flera trådningsscenarier.
  • Segmenterad lista rekommenderas för de flesta scenarier.
  • Lazy-listan finns i biblioteket som en praktisk omslutning i synkrona scenarier.
  • Giriga listor rekommenderas inte och har tagits bort från biblioteket.

Nästa steg

Mer information om Azure Storage och klientbiblioteket för C++finns i följande resurser.