


Artikel yang menerangkan secara terperinci cara menggunakan Redis untuk melaksanakan kunci teragih
Pembelajaran yang disyorkan: Tutorial video Redis
1. Apakah itu kunci teragih
Bila Apabila kami menulis kod berbilang utas, utas yang berbeza mungkin bersaing untuk mendapatkan sumber Untuk mengelakkan ralat yang disebabkan oleh persaingan sumber, kami akan mengunci sumber Hanya utas yang telah memperoleh kunci boleh terus dilaksanakan.
Kunci dalam proses pada asasnya ialah pembolehubah dalam ingatan Apabila benang menjalankan operasi untuk memohon kunci, jika ia berjaya menetapkan nilai pembolehubah yang mewakili kunci kepada 1, ini bermakna. kunci telah diperoleh.
Apa yang kita bincangkan di atas ialah kunci antara benang yang berbeza dalam proses pelayan Kunci ini diletakkan dalam ingatan, dan untuk aplikasi yang diedarkan Katakan, aplikasi yang berbeza (proses atau benang) digunakan pada pelayan yang berbeza, jadi kunci tidak boleh diwakili oleh pembolehubah dalam ingatan.
Memandangkan kunci boleh diwakili oleh ruang memori yang dikongsi pada pelayan, untuk aplikasi yang diedarkan, sistem storan boleh dikongsi untuk menyimpan kunci yang dikongsi Ini adalah kunci yang diedarkan , Redis
dilaksanakan dengan sangat pantas dan sangat sesuai sebagai sistem storan kongsi untuk melaksanakan kunci teragih.
2. Gunakan Redis untuk melaksanakan kunci yang diedarkan
Untuk kunci, sebenarnya hanya terdapat dua operasi, mengunci dan melepaskan kunci Mari lihat di bawah lihat bagaimana untuk mencapainya melalui Redis
?
2.1 Perintah mengunci
Redis
setnx
akan menentukan sama ada nilai kunci wujud Jika wujud, tiada operasi akan dilakukan dan 0 akan dilakukan dikembalikan. Jika ia wujud, buat dan tetapkan nilai, dan kembalikan 1, supaya kita boleh melaksanakan setnx
untuk menetapkan nilai untuk kunci kunci wakil Jika tetapan berjaya, ini bermakna kunci itu diperolehi. kunci tidak boleh diperolehi.
# 使用key为lock来表示一个锁 setnx lock 1
2.2 Lepaskan kunci
Selepas menjalankan operasi, apabila anda ingin melepaskan kunci, hanya padamkan nilai kunci Redis
dalam lock
supaya proses lain boleh menetapkan semula dan mendapatkan kunci melalui perintah setnx
.
# 释放锁 del lock
Melalui dua arahan di atas, kami telah melaksanakan kunci teragih mudah, tetapi terdapat masalah di sini: jika proses dikunci melalui perintah setnx
, ralat berlaku semasa operasi tertentu. Jika tiada cara untuk melepaskan kunci dalam masa, maka proses lain tidak akan dapat mendapatkan kunci, dan sistem tidak akan dapat meneruskan pelaksanaan Cara untuk menyelesaikan masalah ini adalah dengan menetapkan tempoh sah untuk kunci , dan selepas tempoh sah ini, kunci akan dilepaskan secara automatik.
2.3 Tetapkan tempoh sah untuk kunci
Sangat mudah untuk menetapkan tempoh sah untuk kunci Hanya gunakan perintah Redis
expire
, seperti:
# 加锁 setnx lock 1 # 给锁设置10s有效期 expire lock 10
Walau bagaimanapun, masalah lain timbul sekarang jika kita menetapkan kunci dan proses digantung sebelum melaksanakan perintah expire
, maka expire
tidak akan berjaya dilaksanakan dan kunci akan. tidak dilepaskan, jadi kita mesti memastikan bahawa kedua-dua arahan di atas dilaksanakan bersama-sama.
mempunyai dua kaedah, satu ialah menggunakan skrip yang ditulis dalam bahasa LUA
, dan satu lagi ialah menggunakan perintah Redis
set
Perintah set
diikuti oleh nx
parameter, dan kesan pelaksanaan adalah Ia konsisten dengan setnx
, dan perintah set
boleh digunakan dengan parameter ex
untuk menetapkan masa tamat tempoh, jadi kita boleh menggunakan perintah set
untuk bergabung setnx
dan expire
bersama-sama, supaya pelaksanaan boleh dijamin Ia atom.
# 判断是否键值是否存在,ex后面跟着的是键值的有效期,10s set lock 1 nx ex 10
Setelah menyelesaikan masalah penguncian yang berkesan, kini mari kita lihat masalah lain.
Seperti yang ditunjukkan dalam gambar di atas, kini terdapat proses A
, B
dan C
pada tiga pelayan berbeza yang perlu mendapatkan kunci apabila melakukan operasi tertentu Kunci mesti dilepaskan selepas pelaksanaan.
现在的情况是进程A
执行第2步时卡顿了(上面绿色区域所示),且时间超出了锁有效期,所以进程A
设置的锁自动释放了,这时候进程B
获得了锁,并开始执行操作,但由于进程A
只是卡顿了而已,所以会继续执行的时候,在第3步的时候会手动释放锁,但是这个时候,锁由线程B
所拥有,也就是说进程A删除的不是自己的锁,而进程B的锁,这时候进程B
还没执行完,但锁被释放后,进程C
可以加锁,也就是说由于进程A卡顿释放错了锁,导致进程B和进程C可以同时获得锁。
怎么避免这种情况呢?如何区分其他进程的锁,避免删除其他进程的锁呢?答案就是每个进程在加锁的时候,给锁设置一个唯一值,并在释放锁的时候,判断是不是自己设置的锁。
2.4 给锁设置唯一值
给锁设置唯一值的时候,一样是使用set
命令,唯一的不同是将键值1改为一个随机生成的唯一值,比如uuid。
# rand_uid表示唯一id set lock rand_id nx ex 10
当锁里的值由进程设置后,释放锁的时候,就需要判断锁是不是自己的,步骤如下:
- 通过
Redis
的get
命令获得锁的值 - 根据获得的值,判断锁是不是自己设置的
- 如果是,通过
del
命令释放锁。
此时我们看到,释放锁需要执行三个操作,如果三个操作依次执行的话,是没有办法保证原子性的,比如进程A
在执行到第2步后,准备开始执行del
命令时,而锁由时有效期到了,被自动释放了,并被其他服务器上的进程B
获得锁,但这时候线程A
执行del
还是把线程B
的锁给删掉了。
解决这个问题的办法就是保证上述三个操作执行的原子性,即在执行释放锁的三个操作中,其他进程不可以获得锁,想要做到这一点,需要使用到LUA脚本。
2.5 通过LUA脚本实现释放锁的原子性
Redis
支持LUA
脚本,LUA
脚里的代码执行的时候,其他客户端的请求不会被执行,这样可以保证原子性操作,所以我们可以使用下面脚本进行锁的释放:
if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end
将上述脚本保存为脚本后,可以调用Redis
客户端命令redis-cli
来执行,如下:
# lock为key,rand_id表示key里保存的值 redis-cli --eval unlock.lua lock , rand_id
推荐学习:Redis视频教程
Atas ialah kandungan terperinci Artikel yang menerangkan secara terperinci cara menggunakan Redis untuk melaksanakan kunci teragih. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Mulakan semula Redis dengan menyatakan fail konfigurasi: 1. Cari fail konfigurasi (redis.conf biasanya terletak di subdirektori conf); 2. Ubah suai konfigurasi yang diperlukan (seperti menukar port); 3. Gunakan perintah redis-server /path/to/redis.conf untuk memulakan semula redis melalui fail konfigurasi (di mana /path/to/redis.conf adalah laluan fail konfigurasi yang diubahsuai); 4. Gunakan Redis-CLI untuk mengesahkan bahawa ia telah berjaya dimulakan semula.

Data masih wujud selepas Redis dimulakan semula. Redis menyimpan data dalam ingatan, dan memulakan semula tidak memadam data memori. REDIS juga menyediakan kegigihan, menyimpan data ke cakera keras melalui fail RDB atau AOF, memastikan data dapat dipulihkan dari fail yang berterusan selepas dimulakan semula.

Bagaimana untuk memulakan semula perkhidmatan REDIS dalam sistem pengendalian yang berbeza: Linux/macOS: Gunakan perintah SystemCTL (SistemCTL Restart Redis-Server) atau Perintah Perkhidmatan (Perkhidmatan Redis-Server Restart). Windows: Gunakan alat perkhidmatan.msc (masukkan "Services.msc" dalam kotak dialog Run dan tekan Enter) dan klik kanan perkhidmatan "Redis" dan pilih "mulakan semula".

Perintah Redis Restart adalah Redis-Server. Perintah ini digunakan untuk memuatkan fail konfigurasi, membuat struktur data, memulakan pelayan Redis, dan mendengar sambungan klien. Pengguna boleh melaksanakan perintah "Redis-Server [Options]" di terminal untuk memulakan semula pelayan Redis. Pilihan umum termasuk operasi latar belakang, menentukan laluan fail konfigurasi, menentukan port mendengar, dan memuatkan semula gambar hanya apabila data hilang. Perhatikan bahawa memulakan semula pelayan akan memutuskan semua sambungan klien, pastikan anda menyimpan data yang diperlukan sebelum dimulakan semula.

Cara Membersihkan Semua Data Redis: Redis 2.8 dan kemudian: Perintah Flushall memadam semua pasangan nilai utama. Redis 2.6 dan lebih awal: Gunakan perintah DEL untuk memadam kekunci satu demi satu atau gunakan klien Redis untuk memadam kaedah. Alternatif: Mulakan semula perkhidmatan Redis (gunakan dengan berhati -hati), atau gunakan klien Redis (seperti Flushall () atau Flushdb ()).

Terdapat beberapa mekanisme untuk komunikasi antara Redis Contoh: Pub/Sub: Mod Terbitan/Sub, yang membolehkan pemesejan yang cekap dan rendah. Mod Kluster: Kaedah penempatan yang diedarkan, menyediakan ketersediaan dan toleransi kesalahan yang tinggi. Perintah Cross-Instance: Membolehkan arahan dihantar terus ke contoh lain, sesuai untuk tujuan operasi atau pentadbiran sementara.

REDIS Restart tidak membersihkan data kerana Redis menyimpan data dalam memori dan memuat data dari storan berterusan seperti RDB atau AOF. Terdapat dua jenis penyimpanan berterusan: RDB dan AOF, yang memastikan data tidak hilang selepas dimulakan semula. Di samping itu, Redis mempunyai perlindungan lain seperti pilihan snapshot, replikasi dan sentinel untuk mengelakkan kehilangan data. Walau bagaimanapun, dalam kes -kes yang jarang berlaku, seperti rasuah penyimpanan yang berterusan atau penamatan tidak sengaja, ia boleh menyebabkan kehilangan data.

Redis menyediakan dua arahan untuk melihat penggunaan memori semua kekunci dalam pangkalan data: Penggunaan memori AllKeys: Mengembalikan penggunaan memori semua kunci, dalam format: "Kunci" (jenis) # Memory Used (Bytes) Keyspace Memori Info: Menyediakan senarai terperinci maklumat memori untuk semua kunci dalam setiap pangkalan data.
