Mendownload objek besar di Cloud Storage secara berurutan melalui satu koneksi dapat menyebabkan bandwidth jaringan yang tersedia tidak digunakan. Dengan membagi objek menjadi segmen rentang byte yang disebut stripe dan membaca segmen tersebut secara serentak, Anda dapat meningkatkan throughput download untuk objek besar menggunakan Library Klien Cloud untuk Rust.
Dokumen ini menunjukkan cara menyisipkan objek pengujian besar menggunakan
komposisi objek, mendownload rentang byte secara serentak dengan
ReadRange::segment, dan menulis stripe ke file lokal pada offset tetap. Jika
Anda baru menggunakan library klien, lihat
Menggunakan Cloud Storage dengan Rust terlebih dahulu.
Sebelum memulai
Sebelum menjalankan kode dalam dokumen ini, selesaikan prasyarat berikut:
- Buat atau pilih projectGoogle Cloud dengan penagihan diaktifkan.
- Buat bucket Cloud Storage pengujian khusus di project Anda.
- Konfigurasikan Kredensial Default Aplikasi untuk lingkungan Anda.
- Beri akun utama Anda peran Identity and Access Management (IAM) dengan izin untuk
membaca, menulis, menyusun, dan menghapus objek di bucket, seperti Storage Admin
(
roles/storage.admin).
Dependensi
Tambahkan library klien Cloud Storage dan crate pendukung ke file Cargo.toml Anda:
cargo add google-cloud-storage google-cloud-gax anyhow bytes futures
cargo add tokio --features macros,rt-multi-thread
Membuat objek pengujian besar
Untuk menguji download bergaris tanpa mengupload gigabyte data melalui jaringan, upload objek seed kecil dan gunakan operasi compose Cloud Storage untuk menggabungkan salinan di sisi server. Di dalam
fungsi seed asinkron yang menerima client, control, dan bucket_name
dalam format projects/_/buckets/BUCKET_ID, selesaikan
langkah-langkah berikut:
Untuk mereferensikan objek yang ada dalam permintaan compose, impor
SourceObject:Upload objek seed 1 MiB bernama
1MiB.txt:Untuk membuat objek 32 MiB bernama
32MiB.txt, gabungkan 32 salinan1MiB.txtdi server:Untuk membuat objek 1 GiB bernama
1GiB.txt, gabungkan 32 salinan32MiB.txt:Untuk membuat objek pengujian pangkat dua dari
1GiB.txt(2GiB.txt,4GiB.txt,8GiB.txt,16GiB.txt, dan32GiB.txt), ulangi operasi compose:
Mengoordinasikan download stripe serentak
Untuk mendownload objek secara paralel, buat kueri ukuran dan generasi-nya,
alokasikan file tujuan lokal terlebih dahulu, dan buat satu future per stripe. Di dalam
fungsi download yang menerima client, control, bucket_name,
object_name, stripe_size, dan destination, selesaikan langkah-langkah berikut:
Ambil metadata objek menggunakan
StorageControl::get_objectagar Anda dapat memeriksa ukuran total objek dan mengunci pembacaan berikutnya ke satu generasi:Buat file tujuan dan alokasikan terlebih dahulu ke ukuran objek yang tepat sehingga tugas worker dapat menulis pada offset byte independen:
Hitung setiap offset stripe menggunakan
stripe_sizesebagailimitdan buatwrite_stripefuture per segmen, dengan menambahkan stripe parsial akhir jika ukuran objek tidak dapat dibagi rata olehlimit:Jalankan semua stripe future secara serentak dengan
futures::future::join_alldan propagasi error apa pun:
Mendownload dan menulis stripe satu per satu
Setiap tugas write_stripe membaca satu rentang byte dari Cloud Storage dan menulis potongan yang diterima pada offset yang sesuai di pengendali file lokal bersama. Untuk menerapkan write_stripe, selesaikan langkah-langkah berikut:
Impor
ReadRangedan tentukan fungsiwrite_stripe:Buat builder permintaan
ReadObjectdenganStorage::read_object, dan kirim permintaan setelah mengonfigurasi opsi pembuatan dan rentang baca di langkah-langkah berikut:Untuk menyematkan semua stripe ke pembuatan objek yang sama dan mencegah pembacaan yang tidak konsisten jika proses lain menimpa objek, panggil
set_generationpada builder permintaan sebelum memanggilsend:Untuk membatasi pembacaan ke rentang byte stripe, panggil
set_read_rangedenganReadRange::segment(offset, limit)pada builder permintaan:Streaming potongan dari pembaca dan tulis setiap potongan ke file tujuan di
current_posdi dalamtokio::task::spawn_blocking. Karena library standar Rust tidak memiliki metode penulisan posisi lintas platform, contoh ini menggunakanFileExt::write_all_atdi Unix danFileExt::seek_writedi Windows:
Pertimbangan performa
Beberapa faktor menentukan throughput efektif download bergaris:
- Kecepatan disk lokal. Menulis potongan ke penyimpanan lokal yang lambat dapat menjadi bottleneck. Menggunakan penyimpanan SSD lokal dengan throughput tinggi membantu menjaga I/O disk tetap lebih cepat daripada pembacaan jaringan.
- Kapasitas CPU VM. Cloud Storage mengenkripsi data objek dalam pengiriman, sehingga klien mendekripsi setiap potongan yang diterimanya. Pastikan VM Anda memiliki vCPU yang cukup untuk menangani dekripsi TLS serentak di seluruh stripe.
- Lokasi bucket dan VM. Mendownload di seluruh region akan menimbulkan latensi jaringan area luas dan membatasi throughput. Tempatkan VM Anda di region yang sama dengan bucket Anda jika memungkinkan.
Anda juga dapat bereksperimen dengan menyesuaikan stripe_size untuk menghindari sisa stripe yang sangat kecil atau membuat terlalu banyak permintaan rentang kecil.
Kode lengkap
Contoh berikut menggabungkan fungsi seed, download, dan write_stripe
menjadi modul lengkap:
Saat Anda menjalankan download pada objek 32 MiB dengan stripe_size 1 MiB,
outputnya mirip dengan berikut ini, yang melaporkan ukuran yang didownload, waktu
yang berlalu, jumlah stripe, dan bandwidth efektif:
Completed 32.00 MiB download in 412.5ms, using 32 stripes, effective bandwidth = 77.58 MiB/s
Pembersihan
Agar akun Google Cloud Anda tidak dikenai biaya untuk objek pengujian yang dibuat oleh seed, hapus objek pengujian dan hapus bucket pengujian Anda setelah selesai. Hapus juga file tujuan lokal.