Rumah >pangkalan data >Redis >Bagaimana kunci edaran Redis menghalang kerosakan cache
Perbezaan daripada penembusan cache ialah pecahan cache merujuk kepada data panas yang tiada dalam cache tetapi wujud dalam pangkalan data.
Contohnya: berita hangat di halaman utama, data panas dengan jumlah lawatan serentak yang sangat besar, jika cache tamat tempoh, pelayan akan menanyakan DB Pada masa ini, jika sejumlah besar pertanyaan serentak dibuat kepada DB, DB mungkin terharu serta-merta.
Lukis rajah ringkas, seperti ditunjukkan di bawah:
Penyelesaian: Pertanyaan DB ditambah kunci teragih.
Sebelum menyelesaikan masalah, lihat dahulu kod dan operasi yang tidak diproses.
Soal kod butiran produk berdasarkan ID produk
Kosongkan cache Redis dan buka 5 urutan untuk ujian akses serentak. Kod ujian adalah seperti berikut :
Kami menjangkakan bahawa DB hanya akan disoal sekali dan empat pertanyaan seterusnya akan diambil daripada cache Redis, tetapi keputusannya ialah:
Tiada kunci yang diedarkan, dan hasilnya dijangkakan, bekas itu memberi tekanan yang tinggi pada DB.
Jika ia adalah pelayan tunggal, gunakan sahaja kunci penyegerakan Java secara terus
Malangnya, biasanya selepas Pelanggan akan gunakan kluster, dan kunci penyegerakan Java tidak boleh melaksanakan kunci teragih.
Kunci edaran Redis menyelesaikan pecahan cache
Kunci terbina dalam Java hanya boleh digunakan pada satu mesin dan tidak boleh diedarkan Anda boleh menggunakan Redis untuk mencapainya. Kunci yang diedarkan.
Kod selepas menambah kunci yang diedarkan
//根据ID查询商品 @GetMapping("/{id}") public R id(@PathVariable String id){ //先查Redis缓存 Object o = redisTemplate.opsForValue().get(id); if (o != null) { //命中缓存 System.err.println("id:"+id+",命中redis缓存..."); return R.success(o); } //缓存未命中 查询数据库 String lockKey = "lock" + id; //加锁,10s后过期 for (;;) { if (redisTemplate.opsForValue().setIfAbsent(lockKey, System.currentTimeMillis(), 10L, TimeUnit.SECONDS)) { //加锁成功的线程,再次检查 o = redisTemplate.opsForValue().get(id); if (o != null) { //命中缓存 System.err.println("Thread:" + Thread.currentThread().getName() + ",id:"+id+",命中redis缓存..."); //释放锁 redisTemplate.delete(lockKey); return R.success(o); } //仍未命中 System.err.println("Thread:" + Thread.currentThread().getName() + ",id:" + id + ",查询DB..."); Goods goods = goodsMapper.selectById(id); //结果存入Redis redisTemplate.opsForValue().set(id, goods); //释放锁 redisTemplate.delete(lockKey); return R.success(goods); } //竞争不到锁,暂时让出CPU资源 Thread.yield(); } }
Mulakan 5 urutan untuk akses serentak Hasilnya adalah seperti berikut:
Atas ialah kandungan terperinci Bagaimana kunci edaran Redis menghalang kerosakan cache. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!