全部产品
Search
文档中心

Tair (Redis® OSS-Compatible):Implementasikan kunci terdistribusi berkinerja tinggi dengan menggunakan TairString

更新时间:Nov 10, 2025

Kunci terdistribusi merupakan salah satu fitur yang paling sering digunakan dalam aplikasi berskala besar. Anda dapat mengimplementasikan kunci terdistribusi berbasis Redis melalui berbagai metode. Topik ini menjelaskan pendekatan umum untuk mengimplementasikan kunci terdistribusi serta praktik terbaik untuk menerapkannya menggunakan Tair (Enterprise Edition). Praktik terbaik ini dikembangkan dari pengalaman Alibaba Group dalam menggunakan Tair (Enterprise Edition).

Informasi latar belakang

Kunci terdistribusi dan skenario penggunaannya

Jika sumber daya tertentu diakses secara bersamaan oleh beberapa thread dalam proses yang sama selama pengembangan aplikasi, Anda dapat menggunakan mutex atau kunci baca/tulis. Jika akses terjadi antar proses pada host yang sama, gunakan primitif sinkronisasi seperti semaphore, pipeline, atau memori bersama. Namun, jika sumber daya diakses oleh beberapa host, Anda harus menggunakan kunci terdistribusi. Kunci terdistribusi adalah mekanisme mutual exclusion dengan keberadaan global yang mencegah kegagalan logis akibat persaingan sumber daya dalam sistem terdistribusi.

Fitur kunci terdistribusi

  • Saling Eksklusif

    Pada saat tertentu, hanya satu klien yang dapat memegang kunci.

  • Tanpa Deadlock

    Kunci terdistribusi menggunakan mekanisme sewa. Jika klien memperoleh kunci lalu mengalami pengecualian, kunci akan dilepaskan otomatis setelah periode tertentu, mencegah deadlock.

  • Konsisten

    Alih bencana di ApsaraDB for Redis dapat dipicu oleh kesalahan eksternal atau internal. Kesalahan eksternal mencakup kegagalan perangkat keras dan pengecualian jaringan, sedangkan kesalahan internal mencakup query lambat dan cacat sistem. Setelah alih bencana dipicu, node replika dipromosikan menjadi node master baru untuk memastikan ketersediaan tinggi (HA). Dalam skenario ini, jika bisnis Anda memiliki persyaratan tinggi untuk mutual exclusion, kunci harus tetap sama setelah alih bencana.

Implementasikan kunci terdistribusi berbasis open source Redis

Catatan

Metode yang dijelaskan dalam bagian ini juga berlaku untuk Redis Open-Source Edition.

  • Memperoleh Kunci

    Di Redis, jalankan perintah SET untuk memperoleh kunci. Contoh perintah dan parameter disediakan di bawah:

    SET resource_1 random_value NX EX 5

    Tabel 1. Parameter atau Opsi

    Parameter/opsi

    Deskripsi

    resource_1

    Kunci dari kunci terdistribusi. Jika kunci ada, sumber daya yang sesuai terkunci dan tidak dapat diakses oleh klien lain.

    random_value

    String acak. Nilai ini harus unik di seluruh klien.

    EX

    Periode validitas kunci. Unit: detik. Anda juga dapat menggunakan opsi PX untuk menetapkan periode validitas hingga milidetik.

    NX

    Jika kunci yang akan ditetapkan sudah ada di Redis, operasi set dibatalkan.

    Dalam contoh kode, validitas kunci resource_1 diatur selama 5 detik. Jika klien tidak melepaskan kunci, kunci akan kedaluwarsa setelah 5 detik dan dapat diambil kembali oleh sistem untuk digunakan oleh klien lain.

  • Melepaskan Kunci

    Secara umum, gunakan perintah DEL untuk melepaskan kunci. Namun, pendekatan ini dapat menyebabkan masalah berikut:

    1. Pada waktu t1, kunci terdistribusi adalah resource_1 untuk Aplikasi 1, dengan validitas 3 detik.

    2. Aplikasi 1 tetap terblokir selama lebih dari 3 detik karena alasan tertentu, seperti waktu respons yang lama. Kunci resource_1 kedaluwarsa dan kunci terdistribusi dilepaskan secara otomatis pada titik waktu t2.

    3. Pada waktu t3, Aplikasi 2 memperoleh kunci terdistribusi.

    4. Aplikasi 1 melanjutkan dari kondisi terblokir dan menjalankan perintah DEL resource_1 pada titik waktu t4 untuk melepaskan kunci terdistribusi yang dimiliki oleh aplikasi 2.

    Contoh ini menunjukkan bahwa kunci hanya perlu dilepaskan oleh klien yang menetapkan kunci. Oleh karena itu, sebelum klien menjalankan perintah GET untuk memeriksa apakah kunci ditetapkan oleh klien itu sendiri. Kemudian, klien dapat menjalankan perintah DEL untuk melepaskan kunci. Dalam kebanyakan kasus, klien menggunakan skrip Lua berikut di Redis untuk melepaskan kunci yang ditetapkan oleh klien:

    if redis.call("get",KEYS[1]) == ARGV[1] then
        return redis.call("del",KEYS[1])
    else
        return 0
    end
  • Perpanjangan

    Jika klien tidak dapat menyelesaikan operasi dalam waktu sewa kunci, kunci harus diperpanjang. Hanya klien yang menetapkan kunci yang dapat memperpanjangnya. Di Redis, gunakan skrip Lua berikut untuk memperpanjang kunci:

    if redis.call("get",KEYS[1]) == ARGV[1] then
        return redis.call("expire",KEYS[1], ARGV[2])
    else
        return 0
    end

Implementasikan kunci terdistribusi berbasis Tair

Untuk instans berbasis DRAM Tair atau instans optimasi memori persisten, Anda dapat menggunakan perintah string yang ditingkatkan untuk mengimplementasikan kunci terdistribusi tanpa skrip Lua tambahan.

  • Memperoleh Kunci

    Metode untuk memperoleh kunci di Tair mirip dengan Redis open source, yaitu menggunakan perintah SET. Contoh perintah:

    SET resource_1 random_value NX EX 5
  • Melepaskan Kunci

    Gunakan perintah CAD dari Tair (Enterprise Edition) untuk melepaskan kunci secara efisien. Contoh perintah:

    /* if (GET(resource_1) == my_random_value) DEL(resource_1) */
    CAD resource_1 my_random_value
  • Perpanjangan

    Gunakan perintah CAS untuk memperpanjang kunci. Contoh perintah:

    CAS resource_1 my_random_value my_random_value EX 10
    Catatan

    Perintah CAS tidak memeriksa apakah nilai baru sama dengan nilai aslinya.

Contoh kode berdasarkan Jedis

  • Definisikan Perintah CAS dan CAD

    enum TairCommand implements ProtocolCommand {
        CAD("CAD"), CAS("CAS");
    
        private final byte[] raw;
    
        TairCommand(String alt) {
          raw = SafeEncoder.encode(alt);
        }
    
        @Override
        public byte[] getRaw() {
          return raw;
        }
    }
  • Memperoleh Kunci

    public boolean acquireDistributedLock(Jedis jedis,String resourceKey, String randomValue, int expireTime) {
        SetParams setParams = new SetParams();
        setParams.nx().ex(expireTime);
        String result = jedis.set(resourceKey,randomValue,setParams);
        return "OK".equals(result);
    }
  • Melepaskan Kunci

    public boolean releaseDistributedLock(Jedis jedis,String resourceKey, String randomValue) {
        jedis.getClient().sendCommand(TairCommand.CAD,resourceKey,randomValue);
        Long ret = jedis.getClient().getIntegerReply();
        return 1 == ret;
    }
  • Perpanjangan

    public boolean renewDistributedLock(Jedis jedis,String resourceKey, String randomValue, int expireTime) {
        jedis.getClient().sendCommand(TairCommand.CAS,resourceKey,randomValue,randomValue,"EX",String.valueOf(expireTime));
        Long ret = jedis.getClient().getIntegerReply();
        return 1 == ret;
    }

Metode untuk memastikan konsistensi kunci

Replikasi antara node master dan node replika bersifat asinkron. Jika node master gagal setelah perubahan data ditulis ke node master dan pergantian HA dipicu, perubahan dalam buffer mungkin tidak direplikasi ke node master baru, menyebabkan ketidaksesuaian data. Bagian ini menjelaskan tiga metode untuk memastikan konsistensi kunci.

  • Gunakan Algoritma Redlock

    Algoritma Redlock diajukan oleh pendiri proyek open source Redis untuk memastikan konsistensi kunci. Algoritma Redlock sepenuhnya tentang perhitungan probabilitas. Sebuah instans Redis master-replika tunggal mungkin kehilangan kunci selama alih bencana HA dengan probabilitas k%. Jika Anda menggunakan algoritma Redlock untuk mengimplementasikan kunci terdistribusi, Anda dapat menghitung probabilitas N instans Redis independen kehilangan kunci pada saat yang sama berdasarkan rumus berikut: Probabilitas kehilangan kunci = (k%)^N. Karena stabilitas tinggi Redis, kunci jarang hilang dan persyaratan layanan Anda dapat dengan mudah dipenuhi.

    Catatan

    Saat Anda mengimplementasikan algoritma Redlock, Anda tidak perlu memastikan bahwa semua kunci di N instans Redis berlaku pada saat yang sama. Dalam kebanyakan kasus, algoritma Redlock dapat memenuhi persyaratan bisnis Anda jika Anda memastikan bahwa kunci di M(1<M=<N) node Redis berlaku pada saat yang sama.

    Algoritma Redlock memiliki beberapa kelemahan:

    • Klien membutuhkan waktu lama untuk memperoleh atau melepaskan kunci.

    • Algoritma Redlock tidak dapat digunakan dalam instans cluster atau master-replika standar.

    • Algoritma Redlock mengonsumsi jumlah sumber daya yang besar. Untuk menggunakan algoritma Redlock, Anda harus membuat beberapa instans ApsaraDB for Redis independen atau instans Redis yang dikelola sendiri.

  • Gunakan Perintah WAIT

    Perintah WAIT dari Redis memblokir klien saat ini, sampai semua perintah tulis sebelumnya disinkronkan dari node master ke sejumlah node replika yang ditentukan. Dalam perintah WAIT, Anda dapat menentukan periode timeout yang diukur dalam milidetik. Perintah WAIT digunakan di Tair (Redis OSS-compatible) untuk memastikan konsistensi kunci terdistribusi. Contoh perintah:

    SET resource_1 random_value NX EX 5
    WAIT 1 5000

    Saat Anda menjalankan perintah WAIT, klien hanya melanjutkan untuk melakukan operasi lain dalam dua skenario setelah klien memperoleh kunci. Satu skenario adalah bahwa data disinkronkan ke node replika. Skenario lainnya adalah bahwa periode timeout tercapai. Dalam contoh ini, periode timeout adalah 5.000 milidetik. Jika output dari perintah WAIT adalah 1, data disinkronkan antara node master dan node replika. Dalam hal ini, konsistensi data terjamin. Perintah WAIT jauh lebih hemat biaya daripada algoritma Redlock.

    Catatan:

    • Perintah WAIT hanya memblokir klien yang mengirim perintah dan tidak memengaruhi klien lain.

    • Jika perintah WAIT mengembalikan nilai valid, kunci telah disinkronkan ke node replika. Namun, jika pergantian HA dipicu sebelum respons sukses, data mungkin hilang. Output perintah WAIT hanya menunjukkan kemungkinan kegagalan sinkronisasi, dan integritas data tidak dapat dipastikan. Setelah perintah WAIT mengembalikan kesalahan, Anda dapat memperoleh kunci lagi atau memverifikasi data.

    • Anda tidak perlu menjalankan perintah WAIT untuk melepaskan kunci karena kunci terdistribusi saling eksklusif. Kegagalan logis tidak terjadi meskipun kunci dilepaskan setelah periode tertentu.

  • Gunakan Tair

    • Perintah CAS dan CAD membantu mengurangi biaya pengembangan dan manajemen kunci terdistribusi serta meningkatkan kinerja kunci.

    • Instans berbasis DRAM Tair memberikan performa tiga kali lebih tinggi dibandingkan Redis open source. Kontinuitas layanan terjamin bahkan untuk implementasi kunci terdistribusi konkurensi tinggi. Anda juga dapat mengonfigurasi replikasi semi-sinkron antara node master dan node replika di instans berbasis DRAM. Mode ini memastikan data ditulis ke node master dan disinkronkan ke node replika sebelum respons sukses dikembalikan ke klien, mencegah kehilangan data setelah pergantian HA. Mode replikasi semi-sinkron berubah menjadi mode asinkron jika kegagalan node replika atau pengecualian jaringan terjadi selama sinkronisasi data.