Bagikan melalui


Gunakan geo-redundansi untuk merancang aplikasi dengan ketersediaan tinggi

Infrastruktur berbasis cloud seperti Azure Storage menyediakan platform yang sangat tersedia dan tahan lama untuk menghosting data dan aplikasi. Pengembang aplikasi berbasis cloud harus mempertimbangkan dengan cermat cara memanfaatkan platform ini untuk memaksimalkan keuntungan tersebut bagi pengguna mereka. Azure Storage menawarkan opsi geo-redundansi untuk memastikan ketersediaan tinggi bahkan selama pemadaman regional. Akun penyimpanan yang dikonfigurasi untuk replikasi geo-redundan direplikasi secara sinkron di wilayah primer, dan direplikasi secara asinkron ke wilayah sekunder yang berjarak ratusan mil.

Azure Storage menawarkan dua opsi untuk replikasi geo-redundan: Penyimpanan geo-redundan (GRS) dan Penyimpanan geo-zona-redundan (GZRS). Untuk menggunakan opsi geo-redundansi Azure Storage, pastikan akun penyimpanan Anda dikonfigurasi untuk penyimpanan geo-redundan akses baca (RA-GRS) atau penyimpanan geo-zona-redundan akses baca (RA-GZRS). Jika tidak, Anda dapat mempelajari selengkapnya tentang cara mengubah jenis replikasi akun penyimpanan Anda.

Artikel ini menunjukkan cara merancang aplikasi yang akan terus berfungsi, meskipun dalam kapasitas terbatas, bahkan ketika ada pemadaman yang signifikan di wilayah utama. Jika wilayah utama menjadi tidak tersedia, aplikasi Anda dapat beralih dengan mulus untuk melakukan operasi baca terhadap wilayah sekunder hingga wilayah utama responsif lagi.

Pertimbangan desain aplikasi

Anda dapat merancang aplikasi untuk menangani kesalahan sementara atau pemadaman signifikan dengan membaca dari wilayah sekunder ketika ada masalah yang mengganggu pembacaan dari wilayah utama. Ketika wilayah utama tersedia lagi, aplikasi Anda dapat kembali membaca dari wilayah utama.

Perlu diingat pertimbangan utama ini saat merancang aplikasi Anda untuk ketersediaan dan ketahanan menggunakan RA-GRS atau RA-GZRS:

  • Salinan data baca-saja yang Anda simpan di wilayah utama direplikasi secara asinkron di wilayah sekunder. Replikasi asinkron ini berarti bahwa salinan baca-saja di wilayah sekunder pada akhirnya konsisten dengan data di wilayah utama. Layanan penyimpanan menentukan lokasi wilayah sekunder.

  • Anda dapat menggunakan pustaka klien Azure Storage untuk melakukan permintaan baca dan perbarui terhadap titik akhir wilayah utama. Jika wilayah utama tidak tersedia, Anda dapat mengalihkan permintaan baca secara otomatis ke wilayah sekunder. Anda juga dapat mengonfigurasi aplikasi untuk mengirim permintaan baca langsung ke wilayah sekunder, jika diinginkan, bahkan saat wilayah utama tersedia.

  • Jika wilayah utama tidak dapat diakses, Anda dapat melakukan failover akun. Saat Anda melakukan failover ke wilayah sekunder, entri DNS yang menunjuk ke wilayah utama diubah untuk menunjuk ke wilayah sekunder. Setelah failover selesai, akses tulis dipulihkan untuk akun GRS dan RA-GRS. Untuk informasi selengkapnya, lihat Pemulihan bencana dan kegagalan akun penyimpanan.

Bekerja dengan data yang akhirnya konsisten

Solusi yang diusulkan mengasumsikan bahwa dapat diterima untuk mengembalikan data yang berpotensi usang ke aplikasi panggilan. Karena data di wilayah sekunder pada akhirnya konsisten, ada kemungkinan bahwa wilayah utama mungkin menjadi tidak dapat diakses sebelum pembaruan ke wilayah sekunder telah selesai direplikasi.

Misalnya, pelanggan Anda berhasil mengirimkan pembaruan, tetapi wilayah utama gagal sebelum pembaruan disebarluaskan ke wilayah sekunder. Ketika pelanggan meminta untuk membaca kembali data, mereka menerima data kedaluarsa dari wilayah sekunder alih-alih data yang diperbarui. Saat merancang aplikasi, Anda harus memutuskan apakah perilaku ini dapat diterima atau tidak. Jika ya, Anda juga perlu mempertimbangkan cara memberi tahu pengguna.

Nantinya dalam artikel ini, Anda akan mempelajari lebih lanjut tentang menangani data yang akhirnya konsisten dan cara memeriksa properti Waktu Sinkronisasi Terakhir untuk mengevaluasi perbedaan antara data di wilayah utama dan sekunder.

Menangani layanan secara terpisah atau semua bersama-sama

Meskipun tidak mungkin, satu layanan (blob, antrean, tabel, atau file) menjadi tidak tersedia sementara layanan lain masih berfungsi penuh. Anda dapat menangani percobaan ulang untuk setiap layanan secara terpisah, atau Anda dapat menangani percobaan ulang secara generik untuk semua layanan penyimpanan bersama-sama.

Misalnya, jika Anda menggunakan antrean dan blob dalam aplikasi, Anda dapat memutuskan untuk memasukkan kode terpisah untuk menangani kesalahan yang dapat diulang untuk setiap layanan. Dengan begitu, kesalahan layanan blob hanya akan memengaruhi bagian aplikasi Anda yang berkaitan dengan blob, sehingga antrean dapat terus berjalan normal. Namun, jika Anda memutuskan untuk menangani semua percobaan ulang layanan penyimpanan secara bersamaan, maka permintaan ke layanan blob dan antrean akan terdampak jika salah satu layanan mengembalikan kesalahan yang dapat diulang.

Pada akhirnya, keputusan ini tergantung pada kompleksitas aplikasi Anda. Anda mungkin lebih suka menangani kegagalan berdasarkan layanan untuk membatasi dampak pengulangan. Atau Anda dapat memutuskan untuk mengalihkan permintaan baca untuk semua layanan penyimpanan ke wilayah sekunder saat Anda mendeteksi masalah dengan layanan penyimpanan apa pun di wilayah utama.

Menjalankan aplikasi Anda dalam mode baca-saja

Untuk mempersiapkan pemadaman secara efektif di wilayah utama, aplikasi Anda harus dapat menangani permintaan baca yang gagal dan permintaan pembaruan yang gagal. Jika wilayah utama gagal, permintaan baca dapat dialihkan ke wilayah sekunder. Namun, permintaan pembaruan tidak dapat dialihkan karena data yang direplikasi di wilayah sekunder bersifat baca-saja. Untuk alasan ini, Anda perlu merancang aplikasi Anda agar dapat berjalan dalam mode baca-saja.

Misalnya, Anda dapat mengatur bendera yang dicentang sebelum permintaan pembaruan dikirimkan ke Azure Storage. Ketika permintaan pembaruan datang, Anda dapat melewati permintaan dan mengembalikan respons yang sesuai kepada pengguna. Anda bahkan dapat memilih untuk menonaktifkan fitur tertentu sama sekali sampai masalah diselesaikan, dan memberi tahu pengguna bahwa fitur tersebut sementara tidak tersedia.

Jika Anda memutuskan untuk menangani kesalahan untuk setiap layanan secara terpisah, Anda juga harus menangani kemampuan untuk menjalankan aplikasi Anda dalam mode baca-saja berdasarkan layanan. Misalnya, Anda dapat menyiapkan bendera baca-saja untuk setiap layanan. Kemudian Anda dapat mengaktifkan atau menonaktifkan bendera dalam kode, sesuai kebutuhan.

Mampu menjalankan aplikasi Anda dalam mode baca-saja juga memberi Anda kemampuan untuk memastikan fungsionalitas terbatas selama peningkatan aplikasi utama. Anda dapat memicu aplikasi Anda untuk berjalan dalam mode baca-saja dan menunjuk ke pusat data sekunder, memastikan tidak ada yang mengakses data di wilayah utama saat Anda melakukan peningkatan.

Menangani pembaruan saat berjalan dalam mode baca-saja

Ada banyak cara untuk menangani permintaan pembaruan saat berjalan dalam mode baca-saja. Bagian ini berfokus pada beberapa pola umum untuk dipertimbangkan.

  • Anda dapat menanggapi pengguna dan memberi tahu mereka bahwa permintaan pembaruan saat ini tidak sedang diproses. Misalnya, sistem manajemen kontak dapat memungkinkan pengguna mengakses informasi kontak tetapi tidak membuat pembaruan.

  • Anda dapat mengantrekan pembaruan Anda di wilayah lain. Dalam hal ini, Anda akan menulis permintaan pembaruan yang tertunda ke antrean di wilayah yang berbeda, lalu memproses permintaan tersebut setelah pusat data utama online lagi. Dalam skenario ini, Anda harus memberi tahu pengguna bahwa permintaan pembaruan diantrekan untuk diproses nanti.

  • Anda dapat menulis pembaruan Anda ke akun penyimpanan di wilayah lain. Ketika wilayah utama kembali online, Anda dapat menggabungkan pembaruan tersebut ke dalam data utama, tergantung pada struktur data. Misalnya, jika Anda membuat file terpisah dengan stempel tanggal/waktu dalam nama, Anda dapat menyalin file tersebut kembali ke wilayah utama. Solusi ini dapat berlaku untuk beban kerja seperti pengelogan dan data IoT.

Menangani percobaan ulang

Aplikasi yang berkomunikasi dengan layanan yang berjalan di cloud harus peka terhadap peristiwa dan kesalahan tidak terduga yang dapat terjadi. Kesalahan ini dapat bersifat sementara atau persisten, mulai dari hilangnya konektivitas sesaat hingga pemadaman yang signifikan karena bencana alam. Penting untuk merancang aplikasi cloud dengan penanganan coba lagi yang sesuai untuk memaksimalkan ketersediaan dan meningkatkan stabilitas aplikasi secara keseluruhan.

Permintaan untuk membaca

Jika wilayah utama menjadi tidak tersedia, permintaan baca dapat dialihkan ke penyimpanan sekunder. Seperti disebutkan sebelumnya, aplikasi Anda harus dapat diterima untuk berpotensi membaca data kedaluarsa. Pustaka klien Azure Storage menawarkan opsi untuk menangani percobaan ulang dan mengalihkan permintaan baca ke wilayah sekunder.

Dalam contoh ini, penanganan pengulangan untuk penyimpanan Blob dikonfigurasi di kelas BlobClientOptions dan akan berlaku untuk objek yang kita buat menggunakan opsi konfigurasi ini. Konfigurasi ini adalah pendekatan primer kemudian sekunder , di mana percobaan ulang permintaan baca dari wilayah utama dialihkan ke wilayah sekunder. Pendekatan ini paling baik ketika kegagalan di wilayah utama diperkirakan bersifat sementara.

string accountName = "<YOURSTORAGEACCOUNTNAME>";
Uri primaryAccountUri = new Uri($"https://{accountName}.blob.core.windows.net/");
Uri secondaryAccountUri = new Uri($"https://{accountName}-secondary.blob.core.windows.net/");

// Provide the client configuration options for connecting to Azure Blob storage
BlobClientOptions blobClientOptions = new BlobClientOptions()
{
    Retry = {
        // The delay between retry attempts for a fixed approach or the delay
        // on which to base calculations for a backoff-based approach
        Delay = TimeSpan.FromSeconds(2),

        // The maximum number of retry attempts before giving up
        MaxRetries = 5,

        // The approach to use for calculating retry delays
        Mode = RetryMode.Exponential,

        // The maximum permissible delay between retry attempts
        MaxDelay = TimeSpan.FromSeconds(10)
    },

    // If the GeoRedundantSecondaryUri property is set, the secondary Uri will be used for 
    // GET or HEAD requests during retries.
    // If the status of the response from the secondary Uri is a 404, then subsequent retries
    // for the request will not use the secondary Uri again, as this indicates that the resource 
    // may not have propagated there yet.
    // Otherwise, subsequent retries will alternate back and forth between primary and secondary Uri.
    GeoRedundantSecondaryUri = secondaryAccountUri
};

// Create a BlobServiceClient object using the configuration options above
BlobServiceClient blobServiceClient = new BlobServiceClient(primaryAccountUri, new DefaultAzureCredential(), blobClientOptions);

Jika Anda menentukan bahwa wilayah utama kemungkinan tidak tersedia untuk jangka waktu yang lama, Anda dapat mengonfigurasi semua permintaan baca untuk mengarah ke wilayah sekunder. Konfigurasi ini adalah pendekatan sekunder saja . Seperti yang dibahas sebelumnya, Anda memerlukan strategi untuk menangani permintaan pembaruan selama waktu ini, dan cara untuk memberi tahu pengguna bahwa hanya permintaan baca yang sedang diproses. Dalam contoh ini, kami membuat instans BlobServiceClient baru yang menggunakan titik akhir wilayah sekunder.

string accountName = "<YOURSTORAGEACCOUNTNAME>";
Uri primaryAccountUri = new Uri($"https://{accountName}.blob.core.windows.net/");
Uri secondaryAccountUri = new Uri($"https://{accountName}-secondary.blob.core.windows.net/");

// Create a BlobServiceClient object pointed at the secondary Uri
// Use blobServiceClientSecondary only when issuing read requests, as secondary storage is read-only
BlobServiceClient blobServiceClientSecondary = new BlobServiceClient(secondaryAccountUri, new DefaultAzureCredential(), blobClientOptions);

Mengetahui kapan harus beralih ke mode baca-saja dan permintaan sekunder saja adalah bagian dari pola desain arsitektur yang disebut pola Pemutus Sirkuit, yang akan dibahas di bagian selanjutnya.

Permintaan pembaruan

Permintaan pembaruan tidak dapat dialihkan ke penyimpanan sekunder, yang bersifat baca-saja. Seperti yang dijelaskan sebelumnya, aplikasi Anda harus dapat menangani permintaan pembaruan ketika wilayah utama tidak tersedia.

Pola Circuit Breaker juga dapat diterapkan untuk memperbarui permintaan. Untuk menangani kesalahan permintaan pembaruan, Anda dapat mengatur ambang batas dalam kode, seperti 10 kegagalan berturut-turut, dan melacak jumlah kegagalan permintaan ke wilayah utama. Setelah ambang terpenuhi, Anda dapat mengalihkan aplikasi ke mode baca-saja sehingga permintaan pembaruan ke wilayah utama tidak lagi dikeluarkan.

Cara mengimplementasikan pola Pemutus Sirkuit

Menangani kegagalan yang mungkin membutuhkan waktu variabel untuk pulih adalah bagian dari pola desain arsitektur yang disebut pola Pemutus Sirkuit. Implementasi pola ini yang tepat dapat mencegah aplikasi berulang kali mencoba menjalankan operasi yang kemungkinan gagal, sehingga meningkatkan stabilitas dan ketahanan aplikasi.

Salah satu aspek pola Circuit Breaker adalah mengidentifikasi kapan ada masalah yang sedang berlangsung dengan titik akhir utama. Untuk membuat penentuan ini, Anda dapat memantau seberapa sering klien mengalami kesalahan yang dapat diulang. Karena setiap skenario berbeda, Anda perlu menentukan ambang batas yang sesuai guna membuat keputusan untuk beralih ke titik akhir sekunder dan menjalankan aplikasi dalam mode baca-saja.

Misalnya, Anda dapat memutuskan untuk melakukan pengalihan jika ada 10 kegagalan berturut-turut di wilayah utama. Anda dapat melacak ini dengan menyimpan hitungan kegagalan dalam kode. Jika ada keberhasilan sebelum mencapai ambang batas, atur hitungan kembali ke nol. Jika jumlah mencapai ambang batas, maka alihkan aplikasi untuk menggunakan wilayah sekunder untuk permintaan baca.

Sebagai pendekatan alternatif, Anda dapat memutuskan untuk menerapkan komponen pemantauan kustom dalam aplikasi Anda. Komponen ini dapat terus melakukan ping titik akhir penyimpanan utama Anda dengan permintaan baca sepele (seperti membaca blob kecil) untuk menentukan kesehatannya. Pendekatan ini akan memakan beberapa sumber daya, tetapi bukan jumlah yang signifikan. Ketika masalah ditemukan yang mencapai ambang batas Anda, Anda akan beralih ke permintaan baca sekunder saja dan mode baca-saja. Untuk skenario ini, saat ping titik akhir penyimpanan utama menjadi berhasil lagi, Anda dapat beralih kembali ke wilayah utama dan terus mengizinkan pembaruan.

Ambang kesalahan yang digunakan untuk menentukan kapan harus beralih dapat bervariasi dari layanan ke layanan dalam aplikasi Anda, jadi Anda harus mempertimbangkan untuk menjadikannya parameter yang dapat dikonfigurasi.

Pertimbangan lain adalah cara menangani beberapa instans aplikasi, dan apa yang harus dilakukan saat Anda mendeteksi kesalahan yang dapat diulang di setiap instans. Misalnya, Anda mungkin memiliki 20 VM yang berjalan dengan aplikasi yang sama yang dimuat. Apakah Anda menangani setiap instans secara terpisah? Jika satu instans mulai mengalami masalah, apakah Anda ingin membatasi respons hanya untuk satu instans itu? Atau apakah Anda ingin semua instans merespons dengan cara yang sama ketika satu instans mengalami masalah? Menangani instans secara terpisah jauh lebih sederhana daripada mencoba mengoordinasikan respons di seluruh instans, tetapi pendekatan Anda akan bergantung pada arsitektur aplikasi Anda.

Menangani data yang pada akhirnya konsisten

Penyimpanan geo-redundan berfungsi dengan mereplikasi transaksi dari wilayah utama ke sekunder. Proses replikasi menjamin bahwa data di wilayah sekunder pada akhirnya konsisten. Ini berarti bahwa semua transaksi di wilayah utama pada akhirnya akan muncul di wilayah sekunder, tetapi mungkin ada jeda sebelum muncul. Juga tidak ada jaminan bahwa transaksi akan tiba di wilayah sekunder dalam urutan yang sama seperti yang awalnya diterapkan di wilayah utama. Jika transaksi Anda tiba di wilayah sekunder tidak berurutan, Anda dapat mempertimbangkan data Anda di wilayah sekunder berada dalam status tidak konsisten sampai layanan mengejar ketinggalan.

Contoh berikut untuk penyimpanan Azure Table memperlihatkan apa yang mungkin terjadi saat Anda memperbarui detail karyawan untuk menjadikan mereka anggota peran administrator. Demi contoh ini, Anda diharuskan memperbarui entitas karyawan dan memperbarui entitas peran administrator dengan memuat hitungan jumlah total administrator. Perhatikan bagaimana pembaruan diterapkan secara tidak berurutan di wilayah sekunder.

Waktu Transaksi Replikasi Waktu Sinkronisasi Terakhir Hasil
T0 Transaksi A:
Sisipkan karyawan
entitas utama
Transaksi A yang disisipkan ke primer,
belum direplikasi.
T1 Transaksi A
direplikasi ke
sekunder
T1 Transaksi A direplikasi ke sekunder.
Waktu Sinkronisasi Terakhir diperbarui.
T2 Transaksi B:
Pemutakhiran
entitas karyawan
di utama
T1 Transaksi B ditulis ke penyimpanan utama
belum direplikasi.
T3 Transaksi C:
Pemutakhiran
administrator
entitas peran di dalam
utama
T1 Transaksi C ditulis pada penyimpanan primer.
belum direplikasi.
T4 Transaksi C
direplikasi ke
sekunder
T1 Transaksi C direplikasi ke server sekunder.
LastSyncTime tidak diperbarui karena
transaksi B belum direplikasi.
T5 Membaca entitas
dari tingkat sekunder
T1 Anda mendapatkan nilai yang sudah kadaluarsa untuk karyawan
entitas karena transaksi B belum selesai
belum direplikasi. Anda memperoleh nilai baru untuk
Karena C memiliki, entitas peran administrator.
Direplikasi. Waktu Sinkronisasi Terakhir masih belum
diperbarui karena transaksi B
belum direplikasi. Anda dapat mengetahui
entitas peran dari administrator tidak konsisten
karena tanggal/waktu entitas adalah setelah waktu yang ditentukan
Waktu Sinkronisasi Terakhir.
T6 Transaksi B
direplikasi ke
sekunder
T6 T6 – Semua transaksi yang dilakukan melalui C
telah direplikasi, Waktu Sinkronisasi Terakhir
diperbarui.

Dalam contoh ini, asumsikan klien mulai membaca dari wilayah sekunder di T5. Ini dapat berhasil membaca entitas peran administrator saat ini, tetapi entitas berisi nilai untuk jumlah administrator yang tidak konsisten dengan jumlah entitas karyawan yang ditandai sebagai administrator di wilayah sekunder saat ini. Klien Anda dapat menampilkan nilai ini, dengan risiko informasi tidak konsisten. Atau, klien dapat mencoba menentukan bahwa peran administrator berada dalam status yang berpotensi tidak konsisten karena pembaruan telah terjadi secara tidak berurutan, dan kemudian memberi tahu pengguna tentang fakta ini.

Untuk menentukan apakah akun penyimpanan memiliki data yang berpotensi tidak konsisten, klien dapat memeriksa nilai properti Waktu Sinkronisasi Terakhir . Waktu Sinkronisasi Terakhir memberi tahu Anda waktu ketika data di wilayah sekunder terakhir konsisten dan ketika layanan telah menerapkan semua transaksi sebelum titik waktu tersebut. Dalam contoh yang ditunjukkan di atas, setelah layanan menyisipkan entitas karyawan di wilayah sekunder, waktu sinkronisasi terakhir diatur ke T1. Ini tetap di T1 hingga layanan memperbarui entitas karyawan di wilayah sekunder ketika diubah menjadi T6. Jika klien mengambil waktu sinkronisasi terakhir saat membaca entitas di T5, klien dapat membandingkannya dengan tanda waktu pada entitas. Jika tanda waktu pada entitas lebih lambat dari waktu sinkronisasi terakhir, maka entitas dalam status yang berpotensi tidak konsisten, dan Anda dapat mengambil tindakan yang sesuai. Menggunakan bidang ini meminta Anda untuk mengetahui kapan pembaruan terakhir ke data utama selesai.

Untuk mempelajari cara memeriksa waktu sinkronisasi terakhir, lihat Periksa properti Waktu Sinkronisasi Terakhir untuk akun penyimpanan.

Pengujian

Penting untuk menguji bahwa aplikasi Anda bertingkah seperti yang diharapkan ketika mengalami kesalahan yang dapat dicoba kembali. Misalnya, Anda perlu menguji bahwa aplikasi beralih ke wilayah sekunder ketika mendeteksi masalah, lalu beralih kembali ketika wilayah utama tersedia lagi. Untuk menguji perilaku ini dengan benar, Anda memerlukan cara untuk mensimulasikan kesalahan yang dapat dicoba kembali dan mengontrol seberapa sering mereka terjadi.

Salah satu opsinya adalah menggunakan Fiddler untuk mencegat dan memodifikasi respons HTTP dalam skrip. Skrip ini dapat mengidentifikasi respons yang berasal dari titik akhir utama Anda dan mengubah kode status HTTP menjadi salah satu yang dikenali pustaka klien Storage sebagai kesalahan yang dapat diulang. Cuplikan kode ini menunjukkan contoh sederhana skrip Fiddler yang mencegat respons dalam permintaan baca terhadap tabel employeedata untuk mengembalikan status 502.

static function OnBeforeResponse(oSession: Session) {
    ...
    if ((oSession.hostname == "\[YOURSTORAGEACCOUNTNAME\].table.core.windows.net")
      && (oSession.PathAndQuery.StartsWith("/employeedata?$filter"))) {
        oSession.responseCode = 502;
    }
}

Anda dapat memperluas contoh ini untuk mencegat beragam permintaan dan hanya mengubah responseCode pada beberapa di antaranya untuk mensimulasikan skenario dunia nyata dengan lebih baik. Untuk informasi selengkapnya tentang menyesuaikan skrip Fiddler, lihat Mengubah permintaan atau respons dalam dokumentasi Fiddler.

Jika Anda telah menyiapkan ambang batas yang dapat dikonfigurasi untuk mengalihkan aplikasi Anda ke baca-saja, akan lebih mudah untuk menguji perilaku dengan volume transaksi non-produksi.


Langkah berikutnya

Untuk sampel lengkap yang menunjukkan cara beralih bolak-balik antara titik akhir utama dan sekunder, lihat Sampel Azure – Menggunakan Pola Pemutus Sirkuit dengan penyimpanan RA-GRS.