Výpis prostředků Azure Storage v C++List Azure Storage resources in C++

Výpis operací je klíč k mnoha vývojářským scénářům pomocí Azure Storage.Listing operations are key to many development scenarios with Azure Storage. Tento článek popisuje, jak efektivně vytvořit výčet objektů v Azure Storage pomocí rozhraní API pro výpisy poskytované v Microsoft Azure Storage klientské knihovně pro C++.This article describes how to most efficiently enumerate objects in Azure Storage using the listing APIs provided in the Microsoft Azure Storage Client Library for C++.

Poznámka

Tato příručka cílí na Azure Storage klientskou knihovnu pro C++ verze 2. x, která je k dispozici prostřednictvím NuGet nebo GitHubu.This guide targets the Azure Storage Client Library for C++ version 2.x, which is available via NuGet or GitHub.

Klientská knihovna pro úložiště poskytuje celou řadu metod pro výpis a dotazování objektů v Azure Storage.The Storage Client Library provides a variety of methods to list or query objects in Azure Storage. Tento článek se zabývá následujícími scénáři:This article addresses the following scenarios:

  • Výpis kontejnerů v účtuList containers in an account
  • Vypsat objekty BLOB v kontejneru nebo ve virtuálním adresáři objektů BLOBList blobs in a container or virtual blob directory
  • Výpis front v účtuList queues in an account
  • Výpis tabulek v účtuList tables in an account
  • Dotazování entit v tabulceQuery entities in a table

Každá z těchto metod je zobrazena pomocí různých přetížení pro různé scénáře.Each of these methods is shown using different overloads for different scenarios.

Asynchronní versus synchronníAsynchronous versus synchronous

Vzhledem k tomu, že klientská knihovna pro úložiště pro C++ je postavená na knihovně REST jazyka c++, podstatně podporujeme asynchronní operace pomocí aplikace PPLX:: Task.Because the Storage Client Library for C++ is built on top of the C++ REST library, we inherently support asynchronous operations by using pplx::task. Například:For example:

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

Synchronní operace zabalí odpovídající asynchronní operace:Synchronous operations wrap the corresponding asynchronous operations:

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

Pokud pracujete s více aplikacemi nebo službami vláken, doporučujeme použít asynchronní rozhraní API přímo místo vytvoření vlákna pro volání rozhraní API pro synchronizaci, což významně ovlivní váš výkon.If you are working with multiple threading applications or services, we recommend that you use the async APIs directly instead of creating a thread to call the sync APIs, which significantly impacts your performance.

Segmentované výpisySegmented listing

Škálování cloudového úložiště vyžaduje segmentované výpisy.The scale of cloud storage requires segmented listing. Můžete mít například více než milion objektů BLOB v kontejneru objektů blob Azure nebo víc než miliarda entit v tabulce Azure.For example, you can have over a million blobs in an Azure blob container or over a billion entities in an Azure Table. Nejedná se o teoretická čísla, ale reálné případy využití zákazníků.These are not theoretical numbers, but real customer usage cases.

Proto je nepraktické zobrazit seznam všech objektů v jediné odpovědi.It is therefore impractical to list all objects in a single response. Místo toho můžete vypsat objekty pomocí stránkování.Instead, you can list objects using paging. Každé rozhraní API pro výpisy má segmentované přetížení.Each of the listing APIs has a segmented overload.

Odpověď pro segmentované operace výpisu zahrnuje:The response for a segmented listing operation includes:

  • _segment, která obsahuje sadu výsledků vrácených pro jedno volání rozhraní API výpisu._segment, which contains the set of results returned for a single call to the listing API.
  • continuation_token, která je předána dalšímu volání, aby se zobrazila další stránka výsledků.continuation_token, which is passed to the next call in order to get the next page of results. Pokud neexistují žádné další výsledky k vrácení, token pokračování má hodnotu null.When there are no more results to return, the continuation token is null.

Například typické volání pro výpis všech objektů BLOB v kontejneru může vypadat jako následující fragment kódu.For example, a typical call to list all blobs in a container may look like the following code snippet. Kód je k dispozici v našich ukázkách:The code is available in our samples:

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

Všimněte si, že počet výsledků vrácených na stránce může být řízen parametrem max_results v přetížení každého rozhraní API, například:Note that the number of results returned in a page can be controlled by the parameter max_results in the overload of each API, for example:

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)

Pokud nezadáte parametr max_results , vrátí se výchozí maximální hodnota až 5000 výsledků na jednu stránku.If you do not specify the max_results parameter, the default maximum value of up to 5000 results is returned in a single page.

Všimněte si také, že dotaz na službu Azure Table Storage nemůže vracet žádné záznamy nebo méně záznamů než hodnota parametru max_results , který jste zadali, a to i v případě, že token pro pokračování není prázdný.Also note that a query against Azure Table storage may return no records, or fewer records than the value of the max_results parameter that you specified, even if the continuation token is not empty. Jedním z důvodů může být, že dotaz nelze dokončit za pět sekund.One reason might be that the query could not complete in five seconds. Pokud token pro pokračování není prázdný, dotaz by měl pokračovat a váš kód by neměl předpokládat velikost výsledků segmentů.As long as the continuation token is not empty, the query should continue, and your code should not assume the size of segment results.

Doporučený vzor kódování pro většinu scénářů je segmentující výpis, který poskytuje explicitní průběh výpisu nebo dotazování a způsob, jakým služba reaguje na jednotlivé požadavky.The recommended coding pattern for most scenarios is segmented listing, which provides explicit progress of listing or querying, and how the service responds to each request. Zejména pro aplikace nebo služby v jazyce C++ může být řízení průběhu výpisu na nižší úrovni při řízení paměti a výkonu.Particularly for C++ applications or services, lower-level control of the listing progress may help control memory and performance.

Hladový výpisGreedy listing

Starší verze klientské knihovny pro úložiště pro C++ (verze 0.5.0 Preview a starší) zahrnovaly nesegmentované rozhraní API pro tabulky a fronty, jako v následujícím příkladu:Earlier versions of the Storage Client Library for C++ (versions 0.5.0 Preview and earlier) included non-segmented listing APIs for tables and queues, as in the following example:

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;

Tyto metody byly implementovány jako obálky segmentovaná rozhraní API.These methods were implemented as wrappers of segmented APIs. Pro každou odpověď segmentované výpisu kód přidal výsledky do vektoru a vrátil všechny výsledky po prohledání úplných kontejnerů.For each response of segmented listing, the code appended the results to a vector and returned all results after the full containers were scanned.

Tento přístup může fungovat, když účet úložiště nebo tabulka obsahuje malý počet objektů.This approach might work when the storage account or table contains a small number of objects. U zvýšení počtu objektů se ale požadovaná paměť může zvýšit bez omezení, protože všechny výsledky zůstaly v paměti.However, with an increase in the number of objects, the memory required could increase without limit, because all results remained in memory. Jedna operace výpisu může trvat velmi dlouhou dobu, během které volající nedostal žádné informace o jeho průběhu.One listing operation can take a very long time, during which the caller had no information about its progress.

Tato hladce vypisující rozhraní API v sadě SDK neexistují v jazyce C#, Java nebo JavaScript Node.js prostředí.These greedy listing APIs in the SDK do not exist in C#, Java, or the JavaScript Node.js environment. Abyste se vyhnuli potenciálním problémům s používáním těchto hladových rozhraní API, odebrali jsme je ve verzi Preview 0.6.0 Preview.To avoid the potential issues of using these greedy APIs, we removed them in version 0.6.0 Preview.

Pokud váš kód volá tato hladce rozhraní API:If your code is calling these greedy APIs:

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

Pak byste měli kód upravit tak, aby používal rozhraní API segmentovaná v seznamu:Then you should modify your code to use the segmented listing APIs:

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

Zadáním parametru max_results segmentu můžete vyrovnávat počet požadavků a využití paměti, aby splňovala požadavky na výkon vaší aplikace.By specifying the max_results parameter of the segment, you can balance between the numbers of requests and memory usage to meet performance considerations for your application.

Pokud navíc používáte segmentovaná rozhraní API, ale ukládáte data do místní kolekce ve stylu "hladce", důrazně doporučujeme, abyste si kód rehlásili do místní kolekce pečlivě v rozsahu.Additionally, if you're using segmented listing APIs, but store the data in a local collection in a "greedy" style, we also strongly recommend that you refactor your code to handle storing data in a local collection carefully at scale.

Opožděný výpisLazy listing

Přestože hladový výpis vyvolal potenciální problémy, je vhodné, pokud v kontejneru není příliš mnoho objektů.Although greedy listing raised potential issues, it is convenient if there are not too many objects in the container.

Pokud používáte také jazyky C# nebo Oracle Java SDK, měli byste být obeznámeni se Vyčíslitelném programovacím modelem, který nabízí seznam opožděného použití, kde data na určitém posunu jsou načtena pouze v případě, že jsou požadována.If you're also using C# or Oracle Java SDKs, you should be familiar with the Enumerable programming model, which offers a lazy-style listing, where the data at a certain offset is only fetched if it is required. V jazyce C++ poskytuje šablona založená na iterátoru také podobný přístup.In C++, the iterator-based template also provides a similar approach.

Typické rozhraní API opožděného výpisu, které používá list_blobs jako příklad, vypadá takto:A typical lazy listing API, using list_blobs as an example, looks like this:

list_blob_item_iterator list_blobs() const;

Typický fragment kódu, který používá model opožděného výpisu, může vypadat takto:A typical code snippet that uses the lazy listing pattern might look like this:

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

Upozorňujeme, že opožděný výpis je k dispozici pouze v synchronním režimu.Note that lazy listing is only available in synchronous mode.

V porovnání se hladovým seznamem načte opožděné výpisy dat pouze v případě potřeby.Compared with greedy listing, lazy listing fetches data only when necessary. V rámci pokrývání načte data z Azure Storage pouze v případě, že se další iterátor přesune do dalšího segmentu.Under the covers, it fetches data from Azure Storage only when the next iterator moves into next segment. Proto je využití paměti řízeno pomocí ohraničené velikosti a operace je rychlá.Therefore, memory usage is controlled with a bounded size, and the operation is fast.

Rozhraní API pro opožděné výpisy jsou součástí knihovny klienta úložiště pro C++ ve verzi 2.2.0.Lazy listing APIs are included in the Storage Client Library for C++ in version 2.2.0.

ZávěrConclusion

V tomto článku jsme probrali různá přetížení pro výpisy rozhraní API pro různé objekty v klientské knihovně pro úložiště pro C++.In this article, we discussed different overloads for listing APIs for various objects in the Storage Client Library for C++ . Shrnutí:To summarize:

  • Asynchronní rozhraní API se ve scénářích s více vlákny důrazně doporučuje.Async APIs are strongly recommended under multiple threading scenarios.
  • Segmentace je doporučena pro většinu scénářů.Segmented listing is recommended for most scenarios.
  • Opožděný výpis je v knihovně k dispozici jako vhodná obálka v synchronních scénářích.Lazy listing is provided in the library as a convenient wrapper in synchronous scenarios.
  • Hladový výpis není doporučen a byl odebrán z knihovny.Greedy listing is not recommended and has been removed from the library.

Další krokyNext steps

Další informace o Azure Storage a klientské knihovně pro C++ najdete v následujících zdrojích informací.For more information about Azure Storage and Client Library for C++, see the following resources.