Azure Depolama Kaynaklarını C++ dilinde listeleme

Listeleme işlemleri, Azure Depolama ile birçok geliştirme senaryosunda kilit öneme sahip olur. Bu makalede, C++ için Microsoft Azure Depolama İstemci Kitaplığı'nda sağlanan listeleme API'lerini kullanarak Azure Depolama'daki nesnelerin en verimli şekilde nasıl numaralandırıldığı açıklanır.

Not

Bu kılavuz, NuGet veya GitHub aracılığıyla kullanılabilen C++ sürüm 2.x için Azure Depolama İstemci Kitaplığı'nı hedefler.

Depolama İstemci Kitaplığı, Azure Depolama'daki nesneleri listelemek veya sorgulamak için çeşitli yöntemler sağlar. Bu makalede aşağıdaki senaryolar ele arilmektedir:

  • Hesaptaki kapsayıcıları listeleme
  • Kapsayıcı veya sanal blob dizinindeki blobları listeleme
  • Hesaptaki kuyrukları listeleme
  • Hesaptaki tabloları listeleme
  • Tablodaki varlıkları sorgulama

Bu yöntemlerin her biri farklı senaryolar için farklı aşırı yüklemeler kullanılarak gösterilir.

Zaman uyumsuz ve zaman uyumlu karşılaştırması

C++ için Depolama İstemci Kitaplığı C++ REST kitaplığının üzerinde oluşturulduğundan, pplx::task kullanarak zaman uyumsuz işlemleri doğal olarak destekliyoruz. Örnek:

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

Zaman uyumlu işlemler, karşılık gelen zaman uyumsuz işlemleri sarmalar:

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

Birden çok iş parçacığı uygulama veya hizmetiyle çalışıyorsanız, eşitleme API'lerini çağırmak için bir iş parçacığı oluşturmak yerine doğrudan zaman uyumsuz API'leri kullanmanızı öneririz. Bu da performansınızı önemli ölçüde etkiler.

Segmentlere ayrılmış listeleme

Bulut depolama ölçeği için segmentlere ayrılmış listeleme gerekir. Örneğin, bir Azure blob kapsayıcısında bir milyondan fazla blob veya bir Azure Tablosunda bir milyardan fazla varlığınız olabilir. Bunlar teorik sayılar değil, gerçek müşteri kullanım örnekleridir.

Bu nedenle, tüm nesneleri tek bir yanıtta listelemek pratik değildir. Bunun yerine, disk belleği kullanarak nesneleri listeleyebilirsiniz. Listeleme API'lerinin her biri segmentlere ayrılmış bir aşırı yüklemeye sahiptir.

Segmentlere ayrılmış listeleme işleminin yanıtı şunları içerir:

  • _segment, listeleme API'sine yapılan tek bir çağrı için döndürülen sonuç kümesini içerir.
  • continuation_token, bir sonraki sonuç sayfasını almak için bir sonraki çağrıya geçirilir. Döndürülecek başka sonuç olmadığında devamlılık belirteci null olur.

Örneğin, bir kapsayıcıdaki tüm blobları listelemek için yapılan tipik bir çağrı aşağıdaki kod parçacığı gibi görünebilir. Kod örneklerimizde bulunabilir:

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

Bir sayfada döndürülen sonuç sayısının, her API'nin aşırı yüklemesinde max_results parametresi tarafından denetlenebileceğini unutmayın, örneğin:

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)

max_results parametresini belirtmezseniz, varsayılan en fazla 5000 sonuç değeri tek bir sayfada döndürülür.

Ayrıca, Devam belirteci boş olmasa bile Azure Tablo depolamaya yönelik bir sorgunun hiçbir kayıt veya belirttiğiniz max_results parametresinin değerinden daha az kayıt döndürebileceğini unutmayın. Bunun bir nedeni, sorgunun beş saniye içinde tamamlanamadığından olabilir. Devamlılık belirteci boş olmadığı sürece sorgu devam etmeli ve kodunuz kesim sonuçlarının boyutunu varsaymamalıdır.

Çoğu senaryo için önerilen kodlama düzeni, listeleme veya sorgulamanın açık ilerlemesini ve hizmetin her isteğe nasıl yanıt verdiğini sağlayan segmentlere ayrılmış listelemedir. Özellikle C++ uygulamaları veya hizmetleri için listeleme ilerleme durumunun alt düzey denetimi belleği ve performansı denetlemeye yardımcı olabilir.

Doyumsuz listeleme

C++ için Depolama İstemci Kitaplığı'nın önceki sürümleri (sürüm 0.5.0 Önizleme ve önceki sürümler), aşağıdaki örnekte olduğu gibi tablolar ve kuyruklar için bölümlenmemiş listeleme API'leri içeriyordu:

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;

Bu yöntemler, segmentlere ayrılmış API'lerin sarmalayıcıları olarak uygulandı. Segmentlere ayrılmış dökümlerin her yanıtı için kod sonuçları bir vektöre eklemiş ve tam kapsayıcılar tarandıktan sonra tüm sonuçları döndürmüştür.

Depolama hesabı veya tablosu az sayıda nesne içerdiğinde bu yaklaşım işe yarayabilir. Ancak, nesne sayısındaki artışla, tüm sonuçlar bellekte kaldığından, gereken bellek sınırsız olarak artabilir. Bir listeleme işlemi çok uzun sürebilir ve bu sırada çağıranın ilerleme durumu hakkında bilgi yoktu.

SDK'daki bu doyumsuz listeleme API'leri C#, Java veya JavaScript Node.js ortamında mevcut değildir. Bu doyumsuz API'leri kullanmayla ilgili olası sorunları önlemek için bunları sürüm 0.6.0 Önizleme'de kaldırdık.

Kodunuz bu doyumsuz API'leri çağırıyorsa:

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

Ardından kodunuzu segmentlere ayrılmış listeleme API'lerini kullanacak şekilde değiştirmeniz gerekir:

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

Segmentin max_results parametresini belirterek, uygulamanızın performans konularını karşılamak için istek sayısı ile bellek kullanımı arasında denge sağlayabilirsiniz.

Ayrıca, segmentlere ayrılmış listeleme API'leri kullanıyorsanız ancak verileri yerel bir koleksiyonda "doyumsuz" bir stilde depoluyorsanız, yerel bir koleksiyondaki verileri büyük ölçekte dikkatli bir şekilde depolamak için kodunuzu yeniden düzenlemenizi kesinlikle öneririz.

Gecikmeli listeleme

Doyumsuz listeleme olası sorunlara neden olsa da, kapsayıcıda çok fazla nesne yoksa kullanışlıdır.

C# veya Oracle Java SDK'larını da kullanıyorsanız, belirli bir uzaklıkta verilerin yalnızca gerekli olması durumunda getirildiği gecikmeli stilde bir listeleme sunan Numaralandırılabilir programlama modeli hakkında bilgi sahibi olmanız gerekir. C++ dilinde yineleyici tabanlı şablon da benzer bir yaklaşım sağlar.

Örnek olarak list_blobs kullanan tipik bir gecikmeli listeleme API'si şöyle görünür:

list_blob_item_iterator list_blobs() const;

Gecikmeli listeleme desenini kullanan tipik bir kod parçacığı şöyle görünebilir:

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

Gecikmeli listelemenin yalnızca zaman uyumlu modda kullanılabildiğini unutmayın.

Doyumsuz listelemeyle karşılaştırıldığında, gecikmeli listeleme yalnızca gerektiğinde verileri getirir. Yalnızca bir sonraki yineleyici bir sonraki segmente geçtiğinde Azure Depolama'dan veri getirir. Bu nedenle, bellek kullanımı sınırlanmış bir boyutla denetlenır ve işlem hızlıdır.

Gecikmeli listeleme API'leri, sürüm 2.2.0'da C++ için Depolama İstemci Kitaplığı'na dahildir.

Sonuç

Bu makalede, C++ için Depolama İstemci Kitaplığı'ndaki çeşitli nesneler için API'leri listelemeye yönelik farklı aşırı yüklemeleri ele aldık. Özetlemek gerekirse:

  • Zaman uyumsuz API'ler, birden çok iş parçacığı oluşturma senaryosunda kesinlikle önerilir.
  • Çoğu senaryo için segmentlere ayrılmış listeleme önerilir.
  • Zaman uyumlu senaryolarda uygun bir sarmalayıcı olarak kitaplıkta gecikmeli listeleme sağlanır.
  • Doyumsuz listeleme önerilmez ve kitaplıktan kaldırılmıştır.

Sonraki adımlar

C++ için Azure Depolama ve İstemci Kitaplığı hakkında daha fazla bilgi için aşağıdaki kaynaklara bakın.