Aracılığıyla paylaş


Azure Depolama Kaynaklarını C++ dilinde listeleme

Listeleme işlemleri, Azure Depolama ile birçok geliştirme senaryosunda kilit öneme sahiptir. Bu makalede, C++ için Microsoft Azure Depolama İstemci Kitaplığı'nda sağlanan listeleme API'lerini kullanarak Azure Depolama'daki nesneleri en verimli şekilde listeleme açıklanmaktadı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 verilmiştir:

  • 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. Örneğin:

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ış liste

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 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 tek bir çağrı için döndürülen sonuç kümesini içerir.
  • continuation_token, 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, kapsayıcıdaki tüm blobları listelemeye yönelik tipik bir çağrı aşağıdaki kod parçacığı gibi görünebilir. Kod örneklerimizde mevcuttur:

// 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, Azure Tablo depolamaya yönelik bir sorgunun, devamlılık belirteci boş olmasa bile belirttiğiniz max_results parametresinin değerinden daha az kayıt döndüremediğini unutmayın. Bunun bir nedeni, sorgunun beş saniye içinde tamamlanamadı olması 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 bölümlenmiş listelemedir. Özellikle C++ uygulamaları veya hizmetleri için liste 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üre boyunca çağıranın ilerleme durumu hakkında bilgi yoktu.

SDK'daki bu doyumsuz liste 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ı olur.

C# veya Oracle Java SDK'larını da kullanıyorsanız, belirli bir uzaklıkta verilerin yalnızca gerekli olduğunda getirildiği gecikmeli stilde bir liste 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;

Yavaş 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, yavaş listeleme yalnızca gerektiğinde verileri getirir. Yalnızca bir sonraki yineleyici bir sonraki segmente geçtiğinde azure depolamadan veri getirir. Bu nedenle, bellek kullanımı sınırlanmış bir boyutla denetlenilir ve işlem hızlıdır.

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

Sonuç

Bu makalede, C++ için Depolama İstemci Kitaplığı'ndaki çeşitli nesneler için API'leri listelemeye yönelik farklı aşırı yüklemeler ele alınmıştı. Ö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.
  • Gecikmeli listeleme, kitaplıkta zaman uyumlu senaryolarda kullanışlı bir sarmalayıcı olarak 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.