Apa yang saya ingin kongsikan dengan anda hari ini ialah kunci yang diedarkan Artikel ini menggunakan lima kes, rajah, analisis kod sumber, dan lain-lain untuk menganalisis.
Kunci biasa disegerakkan, Kunci, dsb. adalah berdasarkan satu JVM dilaksanakan, apakah yang perlu kita lakukan dalam senario yang diedarkan? Pada masa ini, kunci yang diedarkan muncul. JVM的实现的,如果分布式场景下怎么办呢?这时候分布式锁就出现了。
关于分布式的实现方案,在业界流行的有三种:
1、基于数据库
2、基于Redis
3、基于Zookeeper
另外,还有使用etcd、consul
Mengenai penyelesaian pelaksanaan yang diedarkan, terdapat tiga penyelesaian yang popular dalam industri: 🎜🎜1 Berdasarkan pangkalan data 🎜🎜2 Berdasarkan Redis🎜🎜3. BerdasarkanZookeeper🎜🎜Selain itu, terdapat juga penggunaan etcd, consul. 🎜
Yang paling biasa digunakan dalam pembangunan ialah Redis dan Zookeeper mempunyai dua penyelesaian, dan yang paling kompleks daripada kedua-dua penyelesaian dan yang paling mungkin menyebabkan masalah ialah Redis pelan pelaksanaan, jadi hari ini kami akan meletakkan Redis penyelesaian pelaksanaan. Redis和Zookeeper两种方案,并且两种方案中最复杂的,最容易出问题的就是Redis的实现方案,所以,我们今天就来把Redis实现方案都聊聊。
本文主要内容
分布式锁场景
估计部分朋友还不太清楚分布式的使用场景,下面我简单罗列三种:
案例1
如下代码模拟了下单减库存的场景,我们分析下在高并发场景下会存在什么问题
@RestController
public class IndexController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* 模拟下单减库存的场景
* @return
*/
@RequestMapping(value = "/duduct_stock")
public String deductStock(){
// 从redis 中拿当前库存的值
int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));
if(stock > 0){
int realStock = stock - 1;
stringRedisTemplate.opsForValue().set("stock",realStock + "");
System.out.println("扣减成功,剩余库存:" + realStock);
}else{
System.out.println("扣减失败,库存不足");
}
return "end";
}
}
Salin selepas log masuk
假设在Redis
Kandungan utama artikel ini
Senario kunci teragih < / span>
Dianggarkan sesetengah rakan tidak jelas tentang senario penggunaan yang diedarkan saya akan menyenaraikan secara ringkas tiga jenis di bawah:
🎜
Kes 1 span >
🎜Kod berikut mensimulasikan senario membuat pesanan untuk mengurangkan inventori Mari kita analisis masalah yang akan wujud dalam senario konkurensi tinggi🎜
int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));
Salin selepas log masuk
Salin selepas log masuk
🎜Andaikan bahawa dalam Nilai awal stok dalam Redis ialah 100. 🎜🎜Kini terdapat 5 pelanggan meminta antara muka ini pada masa yang sama, dan mungkin terdapat pelaksanaan serentak🎜
int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));
Permintaan 1 perlu dilaksanakan selama 15 saat selepas dikunci terlebih dahulu, tetapi kunci menjadi tidak sah dan dilepaskan selepas 10 saat pelaksanaan.
Selepas permintaan 2 masuk, ia dikunci dan dilaksanakan Apabila permintaan 2 dilaksanakan selama 5 saat, permintaan 1 dilaksanakan dan kunci dilepaskan, tetapi kunci permintaan 2 dilepaskan pada masa ini.
Permintaan 3 mula dilaksanakan apabila permintaan 2 dilaksanakan selama 5 saat, tetapi apabila permintaan 2 dilaksanakan selama 3 saat, kunci permintaan 3 dilepaskan.
Kita boleh melihat masalah dengan hanya mensimulasikan 3 permintaan sekarang Jika ia berada dalam senario yang benar-benar tinggi, kunci mungkin menghadapi "selalu tidak sah" atau "tidak sah kekal".
Jadi di manakah masalah khusus? Diringkaskan dalam perkara berikut:
1 Apabila terdapat permintaan untuk melepaskan kunci, kunci yang dilepaskan bukan milik anda
2 laksanakan. dan melakukan perbandingan pemerolehan dahulu apabila melepaskan, dan kemudian meneruskan apabila perbandingan adalah sama, supaya masalah melepaskan kunci permintaan lain dapat diselesaikan.
Sebagai jawapan kepada soalan 2, adakah wajar untuk kita teruskan memanjangkan masa tamat tempoh? Jika tetapan pendek, akan ada masalah pelepasan automatik dari semasa ke semasa. Jika tetapan panjang, kunci tidak akan dilepaskan untuk tempoh masa selepas penutupan, walaupun "kematian" tidak akan berlaku lagi. Bagaimana untuk menyelesaikan masalah ini?
Seperti yang kita semua tahuRedis Dalam penggunaan dan penggunaan sebenar, ia digunakan dalam kelompok. Dalam senario konkurensi tinggi, kami mengunci. Selepas menulis kunci kepada nod induk, induk ranap sebelum ia disegerakkan ke nod hamba. asal Nod hamba menjadi nod induk baharu selepas pilihan raya Pada masa ini, masalah kegagalan kunci mungkin berlaku.
在思考解决方案时我们首先想到CAP原则(一致性、可用性、分区容错性),那么现在的Redis就是满足AP(可用性、分区容错性),如果想要解决该问题我们就需要寻找满足CP(一致性、分区容错性)的分布式系统。首先想到的就是Zookeeper,Zookeeper🎜Melalui mekanisme pelaksanaan kunci teragih, kami tahu bahawa dalam senario konkurensi tinggi, hanya permintaan yang berjaya dikunci boleh terus memproses logik perniagaan. Kemudian semua orang datang untuk mengunci, tetapi hanya satu kunci yang berjaya, dan yang lain sedang menunggu. Sebenarnya, kunci teragih dan konkurensi tinggi adalah bercanggah dari segi semantik Walaupun permintaan kami semuanya serentak, Redis membantu kami membuat baris gilir permintaan untuk pelaksanaan, yang bermaksud menukar selari kami kepada bersiri. Pasti tiada masalah konkurensi dalam kod yang dilaksanakan secara bersiri, tetapi prestasi program pasti akan terjejas.
Sebagai tindak balas kepada masalah ini, kami memikirkan tentang penyelesaian sekali lagi
🎜🎜🎜Apabila memikirkan tentang penyelesaian, kita mula-mula memikirkan Prinsip CAP ( Ketekalan, ketersediaan, toleransi partition), kemudian Redis memenuhi AP (ketersediaan, toleransi partition). Jika kita ingin menyelesaikan masalah ini, kita perlu mencari penyelesaian yang memenuhi CP (konsistensi, toleransi kerosakan partition) sistem teragih. Perkara pertama yang terlintas di fikiran ialah Zookeeper , Zookeepermekanisme penyegerakan data antara kelompok ialah apabila nod induk menerima data, ia tidak akan segera mengembalikan maklum balas kejayaan kepada pelanggan. Ia akan menyegerakkan data dengan nod anak dahulu, dan kemudian maklumkan klien selepas lebih separuh daripada nod telah menyelesaikan penyegerakan Terminal berjaya diterima.Dan jika nod induk turun, menurut Zookeeper的Zab协议(Zookeeper原子广播)重新选举的主节点一定是已经同步成功的。
关于第二个提升性能的问题,我们可以参考ConcurrentHashMap的锁分段技术的思想,例如我们代码的库存量当前为1000,那我们可以分为10段,每段100,然后对每段分别加锁,这样就可以同时执行10个请求的加锁与处理,当然有要求的同学还可以继续细分。但其实Redis的Qps已经达到10W+, ia benar-benar mencukupi dalam senario tanpa konkurensi yang tinggi.
Atas ialah kandungan terperinci Kunci yang diedarkan: 5 kes, dari kemasukan ke pengebumian. 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
Panduan Nombor Sempurna di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor Perfect dalam Java?, contoh dengan pelaksanaan kod.
Dalam artikel ini, kami telah menyimpan Soalan Temuduga Spring Java yang paling banyak ditanya dengan jawapan terperinci mereka. Supaya anda boleh memecahkan temuduga.
Java 8 memperkenalkan API Stream, menyediakan cara yang kuat dan ekspresif untuk memproses koleksi data. Walau bagaimanapun, soalan biasa apabila menggunakan aliran adalah: bagaimana untuk memecahkan atau kembali dari operasi foreach?
Gelung tradisional membolehkan gangguan awal atau pulangan, tetapi kaedah Foreach Stream tidak menyokong secara langsung kaedah ini. Artikel ini akan menerangkan sebab -sebab dan meneroka kaedah alternatif untuk melaksanakan penamatan pramatang dalam sistem pemprosesan aliran.
Bacaan Lanjut: Penambahbaikan API Java Stream
Memahami aliran aliran
Kaedah Foreach adalah operasi terminal yang melakukan satu operasi pada setiap elemen dalam aliran. Niat reka bentuknya adalah
Panduan untuk TimeStamp to Date di Java. Di sini kita juga membincangkan pengenalan dan cara menukar cap waktu kepada tarikh dalam java bersama-sama dengan contoh.
Java ialah bahasa pengaturcaraan popular yang boleh dipelajari oleh pembangun pemula dan berpengalaman. Tutorial ini bermula dengan konsep asas dan diteruskan melalui topik lanjutan. Selepas memasang Kit Pembangunan Java, anda boleh berlatih pengaturcaraan dengan mencipta program "Hello, World!" Selepas anda memahami kod, gunakan gesaan arahan untuk menyusun dan menjalankan program, dan "Hello, World!" Pembelajaran Java memulakan perjalanan pengaturcaraan anda, dan apabila penguasaan anda semakin mendalam, anda boleh mencipta aplikasi yang lebih kompleks.