Rumah  >  Artikel  >  pangkalan data  >  Bagaimana kunci edaran Redis menghalang kerosakan cache

Bagaimana kunci edaran Redis menghalang kerosakan cache

王林
王林ke hadapan
2023-06-03 19:04:371289semak imbas

Pecahan 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:

Bagaimana kunci edaran Redis menghalang kerosakan cache

Penyelesaian: Pertanyaan DB ditambah kunci teragih.

Situasi tidak berkunci

Sebelum menyelesaikan masalah, lihat dahulu kod dan operasi yang tidak diproses.

Soal kod butiran produk berdasarkan ID produk

Bagaimana kunci edaran Redis menghalang kerosakan cache

Kosongkan cache Redis dan buka 5 urutan untuk ujian akses serentak. Kod ujian adalah seperti berikut :

Bagaimana kunci edaran Redis menghalang kerosakan cache


Kami menjangkakan bahawa DB hanya akan disoal sekali dan empat pertanyaan seterusnya akan diambil daripada cache Redis, tetapi keputusannya ialah:
Bagaimana kunci edaran Redis menghalang kerosakan cache
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

Bagaimana kunci edaran Redis menghalang kerosakan cache

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:

Bagaimana kunci edaran Redis menghalang kerosakan cache

Atas ialah kandungan terperinci Bagaimana kunci edaran Redis menghalang kerosakan cache. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam