Jadual Kandungan
 memcache实现分布式锁
Zookeeper实现分布式缓存
Perbandingan kunci pengagihan Zookeeper dan Redis
Rumah pangkalan data Redis Apakah yang perlu kita perhatikan semasa melaksanakan kunci teragih dalam Redis? [Ringkasan perkara yang memerlukan perhatian]

Apakah yang perlu kita perhatikan semasa melaksanakan kunci teragih dalam Redis? [Ringkasan perkara yang memerlukan perhatian]

Mar 04, 2022 pm 04:21 PM
redis Kunci yang diedarkan

Apakah yang perlu anda perhatikan semasa melaksanakan kunci teragih dalam Redis? Artikel berikut akan meringkaskan dan berkongsi dengan anda beberapa perkara yang perlu diberi perhatian apabila menggunakan Redis sebagai kunci yang diedarkan saya harap ia akan membantu anda!

Apakah yang perlu kita perhatikan semasa melaksanakan kunci teragih dalam Redis? [Ringkasan perkara yang memerlukan perhatian]

Redis melaksanakan kunci teragih

Baru-baru ini saya melihat satu artikel sambil melihat kunci yang diedarkan Artikel yang bagus, diproses khas untuk pemahaman saya sendiri:

Tiga elemen teras pelaksanaan kunci yang diedarkan Redis:

1 Mengunci

Cara paling mudah ialah menggunakan perintah setnx. Kuncinya ialah pengecam unik kunci, yang dinamakan mengikut perniagaan Nilai ialah ID utas urutan semasa. [Cadangan berkaitan: Tutorial video Redis]

Contohnya, jika anda ingin mengunci aktiviti jualan kilat produk, anda boleh menamakan kunci "lock_sale_ID". Dan apakah nilai yang ditetapkan? Kita boleh menetapkannya buat sementara waktu kepada 1. Kod pseudo untuk mengunci adalah seperti berikut:

setnx(key, 1)Apabila thread melaksanakan setnx dan mengembalikan 1, ini bermakna kunci itu tidak wujud dan benang berjaya memperolehnya Kunci, apabila utas lain melaksanakan setnx dan mengembalikan 0, ini bermakna kunci itu sudah wujud dan utas gagal meraih kunci.

2. Membuka kunci

Jika sesuatu dikunci, ia mesti dibuka. Apabila benang yang memperoleh kunci menyelesaikan tugasnya, ia perlu melepaskan kunci supaya benang lain boleh masuk. Cara paling mudah untuk melepaskan kunci adalah dengan melaksanakan arahan del Kod pseudo adalah seperti berikut:

del (kunci) Selepas. melepaskan kunci, benang lain Anda boleh terus melaksanakan perintah setnx untuk mendapatkan kunci.

3. Tamat masa kunci

Apakah maksud tamat masa kunci? Jika benang yang memperoleh kunci mati semasa melaksanakan tugas dan tidak mempunyai masa untuk melepaskan kunci secara eksplisit, sumber akan dikunci selama-lamanya dan utas lain tidak akan dapat masuk lagi.

Oleh itu, kunci setnx mesti menetapkan tempoh tamat masa untuk memastikan walaupun ia tidak dilepaskan secara eksplisit, kunci akan dilepaskan secara automatik selepas tempoh masa tertentu. setnx tidak menyokong parameter tamat masa, jadi arahan tambahan diperlukan kod pseudo adalah seperti berikut:

tamat tempoh (kunci, 30) Diambil bersama, langkah ketiga. pelaksanaan kunci teragih kami Versi pertama pseudokod adalah seperti berikut:

if(setnx(key,1) == 1){
    expire(key,30)
    try {
        do something ......
    }catch()  {  }  finally {
       del(key)
    }

}
Salin selepas log masuk

Oleh kerana terdapat tiga masalah maut dalam pseudokod di atas:

1 ketidakatoman setnx dan tamat tempoh

Bayangkan senario yang melampau apabila benang melaksanakan setnx, ia berjaya memperoleh kunci:

setnx baru sahaja berjaya dilaksanakan dan telah. belum sempat melaksanakan perintah tamat tempoh Nod 1 Duang Tiba-tiba menutup telefon.

if(setnx(key,1) == 1){  //此处挂掉了.....
    expire(key,30)
    try {
        do something ......
    }catch()
  {
  }
  finally {
       del(key)
    }
 
}
Salin selepas log masuk
Dengan cara ini, kunci tidak mempunyai masa tamat yang ditetapkan dan menjadi "abadi", dan benang lain tidak lagi boleh mendapatkan kunci itu.

Bagaimana untuk menyelesaikannya? Arahan setnx itu sendiri tidak menyokong lulus dalam tamat masa

Redis 2.6.12 atau lebih tinggi menambah parameter pilihan pada arahan yang ditetapkan adalah seperti berikut: set (kunci, 1, 30, NX). supaya Boleh menggantikan arahan setnx .

2. Menggunakan del selepas tamat masa mengakibatkan secara tidak sengaja memadamkan kunci urutan lain

Satu lagi senario melampau, jika benang berjaya mendapatkan kunci dan tamat masa ditetapkan kepada 30 saat.

Jika atas sebab tertentu benang A dijalankan dengan sangat perlahan dan belum selesai dilaksanakan selepas 30 saat, kunci akan dilepaskan secara automatik apabila tamat tempoh dan benang B akan memperoleh kunci.

Selepas itu, utas A menyelesaikan tugasan dan utas A kemudian melaksanakan arahan del untuk melepaskan kunci. Tetapi pada masa ini, utas B belum selesai melaksanakan

Thread A sebenarnya telah memadamkan kunci yang ditambahkan oleh utas B .

Bagaimana untuk mengelakkan situasi ini? Anda boleh membuat pertimbangan sebelum del melepaskan kunci untuk mengesahkan sama ada kunci semasa ialah kunci yang ditambahkan oleh anda sendiri.

Bagi pelaksanaan khusus, anda boleh menggunakan ID utas semasa sebagai nilai semasa mengunci dan mengesahkan sama ada nilai yang sepadan dengan kunci itu ialah ID urutan anda sendiri sebelum memadamkannya.

加锁:
String threadId = Thread.currentThread().getId()
set(key,threadId ,30,NX)
doSomething.....
 
解锁:
if(threadId .equals(redisClient.get(key))){
    del(key)
}
Salin selepas log masuk
Walau bagaimanapun, berbuat demikian membayangkan masalah baharu,

jika penghakiman dan pelepasan kunci adalah dua operasi bebas, bukan atom.

Kami semua adalah pengaturcara yang mengejar kesempurnaan, jadi bahagian ini perlu dilaksanakan menggunakan skrip Lua:

String luaScript = 'if redis .call('get', KEYS[1]) == ARGV[1] kemudian kembalikan redis.call('del', KEYS[1]) else return 0 end' ;

redisClient.eval(luaScript , Collections.singletonList(key) , Collections.singletonList(threadId));

Dengan cara ini, proses pengesahan dan pemadaman adalah operasi atom.

3. Kemungkinan konkurensi

还是刚才第二点所描述的场景,虽然我们避免了线程A误删掉key的情况,但是同一时间有A,B两个线程在访问代码块,仍然是不完美的。

怎么办呢?我们可以让获得锁的线程开启一个守护线程,用来给快要过期的锁“续航”

当过去了29秒,线程A还没执行完,这时候守护线程会执行expire指令,为这把锁“续命”20秒。守护线程从第29秒开始执行,每20秒执行一次。

当线程A执行完任务,会显式关掉守护线程。

另一种情况,如果节点1 忽然断电,由于线程A和守护线程在同一个进程,守护线程也会停下。这把锁到了超时的时候,没人给它续命,也就自动释放了。

memcache实现分布式锁

首页top 10, 由数据库加载到memcache缓存n分钟
微博中名人的content cache, 一旦不存在会大量请求不能命中并加载数据库
需要执行多个IO操作生成的数据存在cache中, 比如查询db多次
问题
在大并发的场合,当cache失效时,大量并发同时取不到cache,会同一瞬间去访问db并回设cache,可能会给系统带来潜在的超负荷风险。我们曾经在线上系统出现过类似故障。

解决方法

if (memcache.get(key) == null) {
// 3 min timeout to avoid mutex holder crash
if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {
value = db.get(key);
memcache.set(key, value);
memcache.delete(key_mutex);
} else {
 
sleep(50);
retry();
}
}
Salin selepas log masuk

在load db之前先add一个mutex key, mutex key add成功之后再去做加载db, 如果add失败则sleep之后重试读取原cache数据。为了防止死锁,mutex key也需要设置过期时间。伪代码如下

Zookeeper实现分布式缓存

Zookeeper的数据存储结构就像一棵树,这棵树由节点组成,这种节点叫做Znode

Znode分为四种类型:

  • 1.持久节点 (PERSISTENT)

默认的节点类型。创建节点的客户端与zookeeper断开连接后,该节点依旧存在 。

  • 2.持久节点顺序节点(PERSISTENT_SEQUENTIAL)

所谓顺序节点,就是在创建节点时,Zookeeper根据创建的时间顺序给该节点名称进行编号:

  • 3.临时节点(EPHEMERAL)

和持久节点相反,当创建节点的客户端与zookeeper断开连接后,临时节点会被删除:

  • 4.临时顺序节点(EPHEMERAL_SEQUENTIAL)

顾名思义,临时顺序节点结合和临时节点和顺序节点的特点:在创建节点时,Zookeeper根据创建的时间顺序给该节点名称进行编号;当创建节点的客户端与zookeeper断开连接后,临时节点会被删除。

Zookeeper分布式锁恰恰应用了临时顺序节点。具体如何实现呢?让我们来看一看详细步骤:

  • 获取锁

首先,在Zookeeper当中创建一个持久节点ParentLock。当第一个客户端想要获得锁时,需要在ParentLock这个节点下面创建一个临时顺序节点 Lock1

之后,Client1查找ParentLock下面所有的临时顺序节点并排序,判断自己所创建的节点Lock1是不是顺序最靠前的一个。如果是第一个节点,则成功获得锁。

这时候,如果再有一个客户端 Client2 前来获取锁,则在ParentLock下载再创建一个临时顺序节点Lock2

Client2查找ParentLock下面所有的临时顺序节点并排序,判断自己所创建的节点Lock2是不是顺序最靠前的一个,结果发现节点Lock2并不是最小的。

Jadi, Client2 mendaftarkan Lock1 dengan nod Watcher yang hanya berkedudukan lebih tinggi daripadanya, untuk memantau sama ada nod Lock1 wujud. Ini bermakna Client2 gagal mengambil kunci dan memasuki keadaan menunggu.

Pada masa ini, jika pelanggan lain Client3 datang untuk memperoleh kunci, muat turun dan buat nod jujukan sementara ParentLock dalam Lock3.

Client3Cari semua nod jujukan sementara di bawah ParentLock dan isikannya dan nilai sama ada nod Lock3 yang anda cipta adalah yang mempunyai susunan tertinggi. Hasilnya Juga didapati bahawa nod Lock3 bukanlah yang terkecil.

Jadi, Client3 mendaftarkan Lock2 dengan nod Watcher yang hanya berkedudukan lebih tinggi daripadanya, untuk memantau sama ada nod Lock2 wujud. Ini bermakna Client3 juga gagal mengambil kunci dan memasuki keadaan menunggu.

Dengan cara ini, Client1 mendapat kunci, Client2 memantau Lock1 dan Client3 memantau Lock2. Ini hanya membentuk baris gilir menunggu, sama seperti ReentrantLock yang AQS(AbstractQueuedSynchronizer) bergantung pada Java.

  • Lepaskan kunci

Terdapat dua situasi untuk melepaskan kunci:

1. Apabila tugasan selesai, klien memaparkan keluaran

Apabila tugasan selesai, Client1 akan memaparkan arahan untuk memanggil nod padam Lock1.

2 Semasa pelaksanaan tugas, pelanggan ranap

Mendapat kunciClient1 Semasa pelaksanaan tugas, jika Duang ranap, maka Sambungan ke pelayan Zookeeper akan diputuskan. Mengikut ciri nod sementara, nod yang berkaitan Lock1 akan dipadamkan secara automatik.

Memandangkan Client2 sentiasa memantau status kewujudan Lock1, apabila nod Lock1 dipadamkan, Client2 akan menerima pemberitahuan serta-merta. Pada masa ini, Client2 akan menanyakan semua nod di bawah ParentLock sekali lagi untuk mengesahkan sama ada nod Lock2 yang dibuat dengan sendirinya ialah nod terkecil pada masa ini. Jika ia adalah yang terkecil, maka Client2 secara semula jadi memperoleh kunci.

Begitu juga, jika Client2 turut memadamkan nod Lock2 disebabkan penyiapan tugas atau ranap nod, maka Cient3 akan menerima pemberitahuan.

Akhirnya, Client3 berjaya mendapatkan kunci.

Perbandingan kunci pengagihan Zookeeper dan Redis

Jadual di bawah Meringkaskan kelebihan dan kekurangan kunci yang diedarkan Zookeeper dan Redis:

Untuk lebih banyak pengetahuan berkaitan pengaturcaraan, sila lawati: Pengenalan kepada Pengaturcaraan ! !

Atas ialah kandungan terperinci Apakah yang perlu kita perhatikan semasa melaksanakan kunci teragih dalam Redis? [Ringkasan perkara yang memerlukan perhatian]. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Arahan sembang dan cara menggunakannya
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Cara Membina Mod Kluster Redis Cara Membina Mod Kluster Redis Apr 10, 2025 pm 10:15 PM

Mod Redis cluster menyebarkan contoh Redis ke pelbagai pelayan melalui sharding, meningkatkan skalabilitas dan ketersediaan. Langkah -langkah pembinaan adalah seperti berikut: Buat contoh Redis ganjil dengan pelabuhan yang berbeza; Buat 3 contoh sentinel, memantau contoh redis dan failover; Konfigurasi fail konfigurasi sentinel, tambahkan pemantauan maklumat contoh dan tetapan failover; Konfigurasi fail konfigurasi contoh Redis, aktifkan mod kluster dan tentukan laluan fail maklumat kluster; Buat fail nodes.conf, yang mengandungi maklumat setiap contoh Redis; Mulakan kluster, laksanakan perintah Buat untuk membuat kluster dan tentukan bilangan replika; Log masuk ke kluster untuk melaksanakan perintah maklumat kluster untuk mengesahkan status kluster; buat

Cara menggunakan perintah redis Cara menggunakan perintah redis Apr 10, 2025 pm 08:45 PM

Menggunakan Arahan Redis memerlukan langkah -langkah berikut: Buka klien Redis. Masukkan arahan (nilai kunci kata kerja). Menyediakan parameter yang diperlukan (berbeza dari arahan ke arahan). Tekan Enter untuk melaksanakan arahan. Redis mengembalikan tindak balas yang menunjukkan hasil operasi (biasanya OK atau -r).

Cara menggunakan redis berulir tunggal Cara menggunakan redis berulir tunggal Apr 10, 2025 pm 07:12 PM

Redis menggunakan satu seni bina berulir untuk memberikan prestasi tinggi, kesederhanaan, dan konsistensi. Ia menggunakan I/O multiplexing, gelung acara, I/O yang tidak menyekat, dan memori bersama untuk meningkatkan keserasian, tetapi dengan batasan batasan konkurensi, satu titik kegagalan, dan tidak sesuai untuk beban kerja yang berintensifkan.

Cara membaca kod sumber redis Cara membaca kod sumber redis Apr 10, 2025 pm 08:27 PM

Cara terbaik untuk memahami kod sumber REDIS adalah dengan langkah demi langkah: Dapatkan akrab dengan asas -asas Redis. Pilih modul atau fungsi tertentu sebagai titik permulaan. Mulakan dengan titik masuk modul atau fungsi dan lihat baris kod mengikut baris. Lihat kod melalui rantaian panggilan fungsi. Berhati -hati dengan struktur data asas yang digunakan oleh REDIS. Kenal pasti algoritma yang digunakan oleh Redis.

Cara membersihkan data redis Cara membersihkan data redis Apr 10, 2025 pm 10:06 PM

Cara Mengosongkan Data Redis: Gunakan perintah Flushall untuk membersihkan semua nilai utama. Gunakan perintah flushdb untuk membersihkan nilai utama pangkalan data yang dipilih sekarang. Gunakan Pilih untuk menukar pangkalan data, dan kemudian gunakan FlushDB untuk membersihkan pelbagai pangkalan data. Gunakan perintah DEL untuk memadam kunci tertentu. Gunakan alat REDIS-CLI untuk membersihkan data.

Cara Melihat Semua Kekunci di Redis Cara Melihat Semua Kekunci di Redis Apr 10, 2025 pm 07:15 PM

Untuk melihat semua kunci di Redis, terdapat tiga cara: Gunakan perintah kunci untuk mengembalikan semua kunci yang sepadan dengan corak yang ditentukan; Gunakan perintah imbasan untuk melangkah ke atas kunci dan kembalikan satu set kunci; Gunakan arahan maklumat untuk mendapatkan jumlah kunci.

Cara Membaca Gilir Redis Cara Membaca Gilir Redis Apr 10, 2025 pm 10:12 PM

Untuk membaca giliran dari Redis, anda perlu mendapatkan nama giliran, membaca unsur -unsur menggunakan arahan LPOP, dan memproses barisan kosong. Langkah-langkah khusus adalah seperti berikut: Dapatkan nama giliran: Namakannya dengan awalan "giliran:" seperti "giliran: my-queue". Gunakan arahan LPOP: Keluarkan elemen dari kepala barisan dan kembalikan nilainya, seperti LPOP Queue: My-Queue. Memproses Baris kosong: Jika barisan kosong, LPOP mengembalikan nihil, dan anda boleh menyemak sama ada barisan wujud sebelum membaca elemen.

Cara memulakan pelayan dengan redis Cara memulakan pelayan dengan redis Apr 10, 2025 pm 08:12 PM

Langkah -langkah untuk memulakan pelayan Redis termasuk: Pasang Redis mengikut sistem operasi. Mulakan perkhidmatan Redis melalui Redis-server (Linux/macOS) atau redis-server.exe (Windows). Gunakan redis-cli ping (linux/macOS) atau redis-cli.exe ping (windows) perintah untuk memeriksa status perkhidmatan. Gunakan klien Redis, seperti redis-cli, python, atau node.js untuk mengakses pelayan.

See all articles