Artikel ini akan berkongsi dengan anda 20 isu Redis yang mesti anda ketahui dan kuasai saya harap ia akan membantu anda.
Redis (Remote Dictionary Server
) ialah pangkalan data nilai kunci bukan perhubungan berprestasi tinggi yang ditulis dalam bahasa C. Tidak seperti pangkalan data tradisional, data Redis disimpan dalam ingatan, jadi kelajuan baca dan tulis sangat pantas, dan ia digunakan secara meluas dalam caching. Redis boleh menulis data ke cakera, memastikan keselamatan data dan bukan kehilangan, dan operasi Redis adalah atom. [Cadangan berkaitan: Tutorial video Redis]
Berdasarkan operasi memori, kelajuan membaca dan menulis memori adalah pantas.
Redis adalah satu-benang untuk mengelakkan penukaran benang overhed dan isu persaingan berbilang benang. Satu utas bermaksud permintaan rangkaian diproses oleh satu utas, iaitu satu utas mengendalikan semua permintaan rangkaian Redis mempunyai lebih daripada satu utas semasa berjalan Contohnya, proses kegigihan data akan memulakan satu lagi utas.
Menyokong berbilang jenis data , termasuk String, Hash, Senarai, Set, ZSet, dsb.
Sokongan kegigihan. Redis menyokong dua mekanisme kegigihan, RDB dan AOF Fungsi kegigihan dapat mengelakkan masalah kehilangan data dengan berkesan.
Sokong transaksi . Semua operasi Redis adalah atom, dan Redis juga menyokong pelaksanaan atom selepas menggabungkan beberapa operasi.
Menyokong replikasi tuan-hamba. Nod induk akan menyegerakkan data secara automatik ke nod hamba, membenarkan pemisahan baca dan tulis.
Cache data hotspot untuk melegakan tekanan pada pangkalan data.
Menggunakan operasi autokenaikan atom Redis, anda boleh merealisasikan fungsi kaunter, seperti mengira bilangan suka pengguna, bilangan lawatan pengguna, dll.
Baris gilir mesej ringkas, anda boleh menggunakan mod terbitan/langganan Redis sendiri atau Senarai untuk melaksanakan baris gilir mesej ringkas dan melaksanakan operasi tak segerak.
Penghad kelajuan boleh digunakan untuk mengehadkan kekerapan pengguna mengakses antara muka tertentu Contohnya, senario jualan kilat digunakan untuk menghalang pengguna daripada tekanan yang tidak perlu disebabkan oleh klik pantas.
Hubungan rakan menggunakan beberapa arahan pengumpulan, seperti persimpangan, kesatuan, perbezaan, dll., untuk merealisasikan fungsi seperti rakan bersama dan hobi biasa.
Redis hanya menggunakan teras tunggal, manakala Memcached boleh menggunakan berbilang teras.
MemCached mempunyai struktur data tunggal dan hanya digunakan untuk cache data, manakala Redis menyokong berbilang jenis data.
MemCached tidak menyokong kegigihan data dan data akan hilang selepas dimulakan semula. Redis menyokong kegigihan data.
Redis menyediakan mekanisme penyegerakan induk-hamba dan keupayaan penggunaan kelompok, yang boleh menyediakan perkhidmatan ketersediaan tinggi. Memcached tidak menyediakan mod kluster asli dan perlu bergantung pada klien untuk menulis data ke dalam serpihan dalam kluster.
Redis jauh lebih pantas daripada Memcached.
Redis menggunakan model penggunaan semula IO berbilang saluran berutas tunggal dan Memcached menggunakan model IO tidak menyekat berbilang benang.
Jenis data asas:
1 String: Jenis data yang paling biasa digunakan boleh berupa rentetan atau nombor. Atau binari, tetapi nilai maksimum tidak boleh melebihi 512MB.
2. Hash: Hash ialah koleksi pasangan nilai kunci.
3. Set: Set tidak tertib dengan penduaan. Set menyediakan kaedah seperti persimpangan dan kesatuan, yang amat sesuai untuk merealisasikan fungsi seperti rakan bersama dan perhatian bersama.
4. Senarai: Koleksi tersusun dan boleh berulang, lapisan bawah dilaksanakan dengan bergantung pada senarai berganda.
5. Set Susun(ZSet): Set Tempahan. Parameter score
dikekalkan secara dalaman untuk pelaksanaan. Sesuai untuk senario seperti kedudukan dan baris gilir mesej berwajaran.
Jenis data khas:
1 Bitmap: bitmap, yang boleh dianggap sebagai tatasusunan dalam unit bit tatasusunan Setiap unit hanya boleh menyimpan 0 atau 1. Subskrip tatasusunan dipanggil offset dalam Bitmap. Panjang Bitmap tiada kaitan dengan bilangan elemen dalam koleksi, tetapi berkaitan dengan had atas kardinaliti.
2, Hyperloglog. HyperLogLog ialah algoritma yang digunakan untuk statistik kardinaliti ialah apabila bilangan atau isipadu elemen input sangat besar, ruang yang diperlukan untuk mengira kardinaliti sentiasa tetap dan sangat kecil. Senario penggunaan biasa adalah mengira pelawat unik.
3. Geospatial: Terutamanya digunakan untuk menyimpan maklumat lokasi geografi dan beroperasi pada maklumat yang disimpan Ia boleh digunakan untuk senario seperti kedudukan dan orang berdekatan.
Prinsip transaksi ialah menghantar beberapa perintah dalam skop transaksi kepada Redis, dan kemudian biarkan Redis melaksanakan perintah ini mengikut turutan.
Kitaran hayat transaksi:
Gunakan MULTI
untuk membuka urus niaga; arahan untuk operasi ini akan dimasukkan ke dalam baris gilir, dan arahan ini sebenarnya tidak akan dilaksanakan;
EXEC
, pemantauan akan dibatalkan secara automatik.
first:0>MULTI "OK" first:0>set a 1 "QUEUED" first:0>set b 2 3 4 "QUEUED" first:0>set c 6 "QUEUED" first:0>EXEC 1) "OK" 2) "OK" 3) "OK" 4) "ERR syntax error" 5) "OK" 6) "OK" 7) "OK"
Sebagai contoh, dalam kod di atas:
menghidupkan pemantauan WATCH
iniEXEC
first:0>watch name "OK" first:0>set name 1 "OK" first:0>MULTI "OK" first:0>set name 2 "QUEUED" first:0>set gender 1 "QUEUED" first:0>EXEC (nil) first:0>get gender (nil)
Nilai
watch name
dan menetapkan nilai name
dan key
dalam transaksi aname
untuk melakukan transaksi name
gender
Gunakan EXEC
, dan semua kunci pemantauan akan dibatalkan. get gender
untuk mengelakkan kehilangan data memori yang disebabkan oleh masa henti perkhidmatan. UNWATCH
WATCH
Redis menyokong dua kaedah kegigihan, satu kaedah key
dan satu lagi kaedah
yang terakhir akan merekodkan arahan selepas setiap pelaksanaan perintah . Umumnya gabungan kedua-duanya digunakan.
Mod RDBRDB
AOF
ialah penyelesaian kegigihan lalai Redis. Apabila RDB berterusan, data dalam memori akan ditulis pada cakera dan fail akan dijana dalam direktori yang ditentukan. Redis restart akan memuatkan data pemulihan fail.
RDB
dump.rdb
dump.rdb
Jalankan perintah
Proses induk Redis menentukan sama ada terdapat proses anak yang melaksanakan bgsave
dalam
akan kembali secara langsung.
Proses induk menjalankan operasiBGSAVE
dan proses induk akan disekat semasa operasi garpu. BGSAVE
, dan fork
Apabila proses anak selesai menulis semua data, ia akan menggantikan fail RDB lama fork
Apabila Redis bermula, ia akan membaca fail syot kilat RDB dan memuatkan data daripada cakera keras ke dalam memori. Melalui kegigihan RDB, setelah Redis keluar secara tidak normal, data yang berubah sejak kegigihan terakhir akan hilang. Cara mencetuskan kegigihan RDB: 手动触发:用户执行SAVE
或BGSAVE
命令。SAVE
命令执行快照的过程会阻塞所有客户端的请求,应避免在生产环境使用此命令。BGSAVE
命令可以在后台异步进行快照操作,快照的同时服务器还可以继续响应客户端的请求,因此需要手动执行快照时推荐使用BGSAVE
命令。
被动触发:
SAVE 100 10
,100秒内至少有10个键被修改则进行快照。BGSAVE
生成 RDB 文件并发送给从节点。shutdown
命令时,如果没有开启 AOF 持久化功能则自动执行·BGSAVE·。优点:
Redis 加载 RDB 恢复数据远远快于 AOF 的方式。
使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 Redis 的高性能。
缺点:
RDB方式数据无法做到实时持久化。因为BGSAVE
每次运行都要执行fork
操作创建子进程,属于重量级操作,频繁执行成本比较高。
RDB 文件使用特定二进制格式保存,Redis 版本升级过程中有多个格式的 RDB 版本,存在老版本 Redis 无法兼容新版 RDB 格式的问题。
AOF(append only file)持久化:以独立日志的方式记录每次写命令,Redis重启时会重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,AOF 是Redis持久化的主流方式。
默认情况下Redis没有开启AOF方式的持久化,可以通过appendonly
参数启用:appendonly yes
。开启AOF方式持久化后每执行一条写命令,Redis就会将该命令写进aof_buf
缓冲区,AOF缓冲区根据对应的策略向硬盘做同步操作。
默认情况下系统每30秒会执行一次同步操作。为了防止缓冲区数据丢失,可以在Redis写入AOF文件后主动要求系统将缓冲区数据同步到硬盘上。可以通过appendfsync
参数设置同步的时机。
appendfsync always //每次写入aof文件都会执行同步,最安全最慢,不建议配置 appendfsync everysec //既保证性能也保证安全,建议配置 appendfsync no //由操作系统决定何时进行同步操作
接下来看一下 AOF 持久化执行流程:
所有的写入命令会追加到 AOP 缓冲区中。
AOF 缓冲区根据对应的策略向硬盘同步。
随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩文件体积的目的。AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程。
当 Redis 服务器重启时,可以加载 AOF 文件进行数据恢复。
优点:
AOF可以更好的保护数据不丢失,可以配置 AOF 每秒执行一次fsync
操作,如果Redis进程挂掉,最多丢失1秒的数据。
AOF以append-only
的模式写入,所以没有磁盘寻址的开销,写入性能非常高。
缺点:
对于同一份文件AOF文件比RDB数据快照要大。
数据恢复比较慢。
Redis的复制功能是支持多个数据库之间的数据同步。主数据库可以进行读写操作,当主数据库的数据发生变化时会自动将数据同步到从数据库。从数据库一般是只读的,它会接收主数据库同步过来的数据。一个主数据库可以有多个从数据库,而一个从数据库只能有一个主数据库。
//启动Redis实例作为主数据库 redis-server //启动另一个实例作为从数据库 redis-server --port 6380 --slaveof 127.0.0.1 6379 slaveof 127.0.0.1 6379 //停止接收其他数据库的同步并转化为主数据库 SLAVEOF NO ONE
主从复制的原理?
当启动一个从节点时,它会发送一个 PSYNC
命令给主节点;
如果是从节点初次连接到主节点,那么会触发一次全量复制。此时主节点会启动一个后台线程,开始生成一份 RDB
快照文件;
同时还会将从客户端 client 新收到的所有写命令缓存在内存中。RDB
文件生成完毕后, 主节点会将RDB
文件发送给从节点,从节点会先将RDB
文件写入本地磁盘,然后再从本地磁盘加载到内存中;
Kemudian nod induk akan menghantar arahan tulis yang dicache dalam memori ke nod hamba, dan nod hamba akan menyegerakkan data; nod hamba berada di antara nod hamba dan nod induk Jika rangkaian gagal dan sambungan terputus, ia akan menyambung semula secara automatik Selepas sambungan, nod induk hanya akan menyegerakkan sebahagian daripada data yang hilang ke nod hamba.
Sentinel
Cara ia berfungsi
Setiap berkomunikasi sekali sesaat kepada
yang diketahuinya 🎜 >,Sentinel
. Master
Slave
Jika masa sejak balasan terakhir yang sah kepada perintah Sentinel
melebihi nilai yang ditentukan, kejadian itu akan ditandakan sebagai luar talian secara subjektif oleh PING
. PING
ditandakan sebagai subjektif di luar talian, semua Sentine
yang memantau ini Master
Master
Apabila bilangan yang mencukupi Sentinel
(lebih besar daripada atau sama dengan nilai yang dinyatakan dalam fail konfigurasi) mengesahkan bahawa Master
sememangnya telah memasuki keadaan luar talian subjektif dalam julat masa yang ditentukan, maka Sentinel
telah berada di luar talian, status luar talian objektif Master
akan ditarik balik. Jika Master
mengembalikan balasan yang sah kepada perintah Sentinel
Master
, status luar talian subjektif Master
akan dialih keluar. Master
Sentinel
Nod sentinel akan memilih ketua sentinel untuk bertanggungjawab terhadap failover. PING
Master
Ketua sentinel akan memilih nod hamba dengan prestasi yang baik untuk menjadi nod induk baharu, dan kemudian memberitahu nod hamba lain untuk mengemas kini maklumat nod induk. Kluster Redis menggunakan
pembahagian slot mayaSemua kekunci dipetakan kepada 0~16383 slot integer mengikut fungsi cincangan Setiap nod bertanggungjawab untuk mengekalkan sebahagian daripada slot dan nilai kunci dipetakan oleh data slot.
Bagaimanakah slot cincang dipetakan kepada tika Redis?
Gunakan algoritma
untuk pasangan nilai kunci untuk mengira hasilkey
dan ambil baki hasil hingga 16384, Nilai yang diperoleh mewakili slot cincang yang sepadan crc16
key
menyokong pengembangan dinamik kapasiti
data disimpan dan diedarkan dalam berbilang nod mengikutslot
key
pada nod yang sama Fungsi transaksi tidak boleh digunakan apabila berbilang key
diedarkan pada berbeza nod. key
, sebagai butiran minimum pembahagian data, tidak boleh memetakan objek nilai kunci yang besar seperti hash
, list
, dsb. ke nod yang berbeza. 1. Pemadaman pasif (malas) . Apabila mengakses kunci, jika didapati bahawa kunci telah tamat tempoh, kunci akan dipadamkan.
2. Padam secara aktif (secara kerap) . Kekunci bersih dengan kerap. Setiap pembersihan akan melintasi semua DB dalam urutan, mengeluarkan 20 kekunci secara rawak dari db, dan memadamnya jika ia tamat tempoh, kemudian teruskan membersihkan db ini, jika tidak, mula membersihkan db seterusnya.
3. Bersihkan apabila ingatan tidak mencukupi. Redis mempunyai had memori maksimum Memori maksimum boleh ditetapkan melalui parameter maxmemory Apabila memori yang digunakan melebihi memori maksimum yang ditetapkan, memori mesti dikeluarkan Apabila memori dilepaskan, memori akan dibersihkan mengikut strategi penghapusan yang dikonfigurasikan.
Apabila memori Redis melebihi memori maksimum yang dibenarkan, Redis akan mencetuskan strategi penghapusan memori dan memadamkan beberapa data yang jarang digunakan untuk memastikan operasi normal pelayan Redis.
Redisv4.0 menyediakan 6 strategi penghapusan data :
Least Recently Used
), digunakan baru-baru ini. Gunakan algoritma LRU untuk mengalih keluar kunci dengan masa tamat tempoh ditetapkanSelepas Redisv4.0, dua jenis berikut telah ditambahkan:
Strategi penghapusan memori boleh diubah suai melalui fail konfigurasi Item konfigurasi yang sepadan ialah maxmemory-policy
dan konfigurasi lalai ialah noeviction
.
1. Padamkan cache dahulu dan kemudian kemas kini pangkalan data
Apabila melakukan operasi kemas kini, padamkan cache dahulu dan kemudian kemas kini pangkalan data apabila permintaan berikutnya dibaca semula , data akan dibaca daripada pangkalan data Selepas membaca, data baharu dikemas kini ke cache.
Masalah sedia ada: Selepas memadamkan data cache dan sebelum mengemas kini pangkalan data, jika terdapat permintaan baca baharu dalam tempoh masa ini, data lama akan dibaca daripada pangkalan data dan ditulis semula ke dalam cache, menyebabkan ketidakkonsistenan lagi. Dan semua bacaan seterusnya adalah data lama.
2. Kemas kini pangkalan data dahulu dan kemudian padamkan cache
Apabila melakukan operasi kemas kini, kemas kini MySQL dahulu Selepas berjaya, padamkan cache, dan kemudian tambah data baharu kepada permintaan baca seterusnya.
Masalah sedia ada: Dalam tempoh antara mengemas kini MySQL dan memadam cache, permintaan membaca data cache lama Walau bagaimanapun, apabila kemas kini pangkalan data selesai, ia akan menjadi konsisten dan kesannya akan agak kecil.
3. Cache kemas kini tak segerak
Selepas operasi kemas kini pangkalan data selesai, cache tidak dikendalikan secara langsung, tetapi arahan operasi dirangkumkan ke dalam mesej dan dibuang ke dalam baris gilir mesej, dan kemudian Redis sendiri menggunakan dan mengemas kini data, dan baris gilir mesej boleh memastikan konsistensi urutan operasi data dan memastikan bahawa data dalam sistem cache adalah normal.
Penembusan cache, avalanche cache, pecahan cache [penjelasan terperinci] Pecahan cache Redis, penembusan, konsep dan penyelesaian avalanche
Penembusan cache merujuk kepada pertanyaan data yang tidak wujud Memandangkan cache ditulis secara pasif apabila terdapat kesilapan, jika data tidak ditemui daripada DB, ia tidak akan ditulis kepada. cache. Ini akan menyebabkan data yang tidak wujud akan ditanya dalam DB setiap kali ia diminta, kehilangan makna caching. Apabila trafik sesak, DB mungkin tergantung.
Cache nilai kosong dan tidak akan menyemak pangkalan data.
采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap
中,查询不存在的数据会被这个bitmap
拦截掉,从而避免了对DB
的查询压力。
布隆过滤器的原理:当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。查询时,将元素通过散列函数映射之后会得到k个点,如果这些点有任何一个0,则被检元素一定不在,直接返回;如果都是1,则查询元素很可能存在,就会去查询Redis和数据库。
缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重挂掉。
解决方法:在原有的失效时间基础上增加一个随机值,使得过期时间分散一些。
缓存击穿:大量的请求同时查询一个 key 时,此时这个 key 正好失效了,就会导致大量的请求都落到数据库。缓存击穿是查询缓存中失效的 key,而缓存穿透是查询不存在的 key。
解决方法:加分布式锁,第一个请求的线程可以拿到锁,拿到锁的线程查询到了数据之后设置缓存,其他的线程获取锁失败会等待50ms然后重新到缓存取数据,这样便可以避免大量的请求落到数据库。
public String get(String key) { String value = redis.get(key); if (value == null) { //缓存值过期 String unique_key = systemId + ":" + key; //设置30s的超时 if (redis.set(unique_key, 1, 'NX', 'PX', 30000) == 1) { //设置成功 value = db.get(key); redis.set(key, value, expire_secs); redis.del(unique_key); } else { //其他线程已经到数据库取值并回写到缓存了,可以重试获取缓存值 sleep(50); get(key); //重试 } } else { return value; } }
redis客户端执行一条命令分4个过程:发送命令、命令排队、命令执行、返回结果。使用pipeline
可以批量请求,批量返回结果,执行速度比逐条执行要快。
使用pipeline
组装的命令个数不能太多,不然数据量过大,增加客户端的等待时间,还可能造成网络阻塞,可以将大量命令的拆分多个小的pipeline
命令完成。
原生批命令(mset和mget)与pipeline
对比:
原生批命令是原子性,pipeline
是非原子性。pipeline命令中途异常退出,之前执行成功的命令不会回滚。
原生批命令只有一个命令,但pipeline
支持多命令。
Redis 通过 LUA 脚本创建具有原子性的命令:当lua脚本命令正在运行的时候,不会有其他脚本或 Redis 命令被执行,实现组合命令的原子操作。
在Redis中执行Lua脚本有两种方法:eval
和evalsha
。eval
命令使用内置的 Lua 解释器,对 Lua 脚本进行求值。
//第一个参数是lua脚本,第二个参数是键名参数个数,剩下的是键名参数和附加参数 > eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second 1) "key1" 2) "key2" 3) "first" 4) "second"
lua脚本作用
1、Lua脚本在Redis中是原子执行的,执行过程中间不会插入其他命令。
2、Lua脚本可以将多条命令一次性打包,有效地减少网络开销。
应用场景
举例:限制接口访问频率。
在Redis维护一个接口访问次数的键值对,key
是接口名称,value
是访问次数。每次访问接口时,会执行以下操作:
aop
拦截接口的请求,对接口请求进行计数,每次进来一个请求,相应的接口访问次数count
加1,存入redis。count=1
,并设置过期时间。因为这里set()
和expire()
组合操作不是原子操作,所以引入lua
脚本,实现原子操作,避免并发访问问题。private String buildLuaScript() { return "local c" + "\nc = redis.call('get',KEYS[1])" + "\nif c and tonumber(c) > tonumber(ARGV[1]) then" + "\nreturn c;" + "\nend" + "\nc = redis.call('incr',KEYS[1])" + "\nif tonumber(c) == 1 then" + "\nredis.call('expire',KEYS[1],ARGV[2])" + "\nend" + "\nreturn c;"; } String luaScript = buildLuaScript(); RedisScript<Number> redisScript = new DefaultRedisScript<>(luaScript, Number.class); Number count = redisTemplate.execute(redisScript, keys, limit.count(), limit.period());
PS:这种接口限流的实现方式比较简单,问题也比较多,一般不会使用,接口限流用的比较多的是令牌桶算法和漏桶算法。
更多编程相关知识,请访问:编程入门!!
Atas ialah kandungan terperinci 20 soalan yang mesti dikuasai dalam Redis, datang dan kumpulkan! !. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!