Rumah > Artikel > pangkalan data > Cara menggunakan strategi dan transaksi penghapusan cache Redis untuk melaksanakan penguncian optimistik
Algoritma LRU (Paling kurang digunakan, paling kurang digunakan baru-baru ini) adalah berdasarkan sejarah capaian rekod data Untuk menghapuskan data, idea terasnya ialah "jika data telah diakses baru-baru ini, kebarangkalian untuk diakses pada masa hadapan juga lebih tinggi."
Pelaksanaan yang paling biasa ialah menggunakan senarai terpaut untuk menyimpan data cache Algoritma terperinci dilaksanakan seperti berikut:
Data baharu dimasukkan ke dalam kepala senarai yang dipautkan; kepala senarai terpaut;
Apabila senarai terpaut penuh, data di hujung senarai terpaut dibuang.
Tajuk Redis Strategi penghapusan cache
Tetapkan cache maksimum
Dalam redis, pengguna dibenarkan untuk menetapkan memori maksimum saiz memori Lalainya ialah 0. Cache maksimum tidak dinyatakan data ditambah, Melebihi memori maksimum akan menyebabkan redis ranap, jadi ia mesti ditetapkan.Apabila saiz set data memori redis meningkat kepada saiz tertentu, strategi penyingkiran data akan dilaksanakan. Strategi penghapusankonfigurasi strategi penghapusan redis: maxmemory-policy voltile-lru, menyokong konfigurasi panas
redis menyediakan 6 jenis data Strategi penghapusan:
volatile-lru:
volatile-ttl:
rawak meruap:
allkeys-lru:
allkeys-random:
tiada enviction (pengusiran) ):
Transaksi Redis
Arahan individu Redis adalah atom, jadi di sini anda perlu memastikan objek transaksi ialah set arahan.
Redis menyerikan set arahan dan memastikan pelaksanaan set arahan yang berterusan dan tidak terganggu dalam transaksi yang sama
Redis tidak menyokong Roll pemulangan operasi. Perintah transaksi
MULTI
multi
EXECLaksanakan semua arahan beratur sebelum ini dalam transaksi dan kemudian pulihkan keadaan sambungan biasa
Sintaks:exec
BUANGMengosongkan semua perintah yang sebelum ini beratur dalam transaksi, kemudian memulihkan status sambungan biasa.
Sintaks:discard
TONTONApabila [urus niaga perlu dilaksanakan secara bersyarat], gunakan arahan ini untuk menukar kekunci [ yang diberikan ditetapkan untuk dipantau] status.
Sintaks:watch key [key…]
Nota: Gunakan arahan ini untuk melaksanakan penguncian optimistik Redis.
UNWATCHKosongkan semua kekunci yang dipantau sebelum ini untuk transaksi
Sintaks: rreeeIlustrasi arahan:
Demo transaksi:
unwatch
Redis tidak menyokong rollback transaksi (mengapa)Transaksi Terbesar kegagalan adalah disebabkan oleh ralat sintaks atau ralat jenis kedua-dua ralat ini boleh diramalkan semasa peringkat pembangunan Redis mengabaikan pemulangan transaksi atas sebab prestasi.
Kunci optimistik adalah berdasarkan idea CAS (Banding Dan Tukar) (bandingkan dan gantikan Ia tidak saling eksklusif dan tidak akan menyebabkan kunci menunggu dan menggunakan sumber, tetapi ia perlu diulang cuba semula, tetapi juga kerana mekanisme cuba semula, ia boleh bertindak balas dengan lebih cepat. Oleh itu, kita boleh menggunakan redis untuk
melaksanakan penguncian optimistik. Idea khusus adalah seperti berikut:Gunakan fungsi jam tangan redis untuk memantau nilai status redisKey ini
Dapatkan nilai redisKey
Buat transaksi redis
Berikan nilai kunci ini +1
然后去执行这个事务,如果key的值被修改过则回滚,key不加1
public void watch() { try { String watchKeys = "watchKeys"; //初始值 value=1 jedis.set(watchKeys, 1); //监听key为watchKeys的值 jedis.watch(watchkeys); //开启事务 Transaction tx = jedis.multi(); //watchKeys自增加一 tx.incr(watchKeys); //执行事务,如果其他线程对watchKeys中的value进行修改,则该事务将不会执行 //通过redis事务以及watch命令实现乐观锁 List<Object> exec = tx.exec(); if (exec == null) { System.out.println("事务未执行"); } else { System.out.println("事务成功执行,watchKeys的value成功修改"); } } catch (Exception e) { e.printStackTrace(); } finally { jedis.close(); } }
public class RedisLock { public static void main(String[] arg) { //库存key String redisKey = "stock"; ExecutorService executorService = Executors.newFixedThreadPool(20); try { Jedis jedis = new RedisProperties.Jedis("127.0.0.1", 6378); // 可以被秒杀的库存的初始值,库存总共20个 jedis.set(redisKey, "0"); jedis.close(); } catch (Exception e) { e.printStackTrace(); } for (int i = 0; i < 1000; i++) { executorService.execute(() -> { Jedis jedis1 = new Jedis("127.0.0.1", 6378); try { jedis1.watch(redisKey); String redisValue = jedis1.get(redisKey); int valInteger = Integer.valueOf(redisValue); String userInfo = UUID.randomUUID().toString(); // 没有秒完 if (valInteger < 20) { Transaction tx = jedis1.multi(); tx.incr(redisKey); List list = tx.exec(); // 秒成功 失败返回空list而不是空 if (list != null && list.size() > 0) { System.out.println("用户:" + userInfo + ",秒杀成 功!当前成功人数:" + (valInteger + 1)); } // 版本变化,被别人抢了。 else { System.out.println("用户:" + userInfo + ",秒杀失 败"); } } // 秒完了 else { System.out.println("已经有20人秒杀成功,秒杀结束"); } } catch (Exception e) { e.printStackTrace(); } finally { jedis1.close(); } }); } executorService.shutdown(); } }
Atas ialah kandungan terperinci Cara menggunakan strategi dan transaksi penghapusan cache Redis untuk melaksanakan penguncian optimistik. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!