Sembilan Emas dan Sepuluh Perak akan datang tidak lama lagi Artikel ini akan berkongsi dengan anda 20 soalan temuduga klasik Redis Saya harap ia akan membantu anda.
Redis, nama penuh bahasa Inggeris ialah Pelayan Kamus Jauh (perkhidmatan kamus jauh), ialah sumber terbuka yang ditulis dalam bahasa ANSI C, menyokong rangkaian, boleh berasaskan memori dan jenis Log yang berterusan, pangkalan data Nilai Kunci dan menyediakan API dalam berbilang bahasa. [Cadangan berkaitan: Tutorial video Redis]
Berbeza daripada pangkalan data MySQL, data Redis disimpan dalam ingatan. Kelajuan baca dan tulisnya sangat pantas dan boleh mengendalikan lebih daripada 100,000 operasi baca dan tulis sesaat. Oleh itu, redis digunakan secara meluas dalam cache Selain itu, Redis juga sering digunakan untuk kunci yang diedarkan. Selain itu, Redis menyokong urus niaga, ketekunan, skrip LUA, acara didorong LRU dan pelbagai penyelesaian kluster.
Kebanyakan rakan tahu bahawa Redis mempunyai lima jenis asas berikut:
Ia juga mempunyai tiga jenis struktur data khas
set key value
, get key
, dsb.int(8字节长整型)/embstr(小于等于39字节字符串)/raw(大于39个字节字符串)
Rentetan bahasa C dilaksanakan oleh char[]
dan Redis menggunakan SDS (rentetan dinamik ringkas) Enkapsulasi , kod sumber sds adalah seperti berikut:
struct sdshdr{ unsigned int len; // 标记buf的长度 unsigned int free; //标记buf中未使用的元素个数 char buf[]; // 存放元素的坑 }
Rajah struktur SDS adalah seperti berikut:
Mengapa Redis memilih SDS struktur, manakala C Bukankah bahasa ibunda char[]
sedap?
Sebagai contoh, dalam SDS, kerumitan masa O(1) boleh digunakan untuk mendapatkan panjang rentetan manakala untuk rentetan C, keseluruhan rentetan perlu dilalui dan masa kerumitan ialah O(n)
hset key field value
, hget key field
ziplist(压缩列表)
, hashtable(哈希表)
Perbandingan antara jenis rentetan dan cincang adalah seperti berikut:
lpush key value [value ...]
, lrange key start end
Gambar untuk memahami sisipan dan pop timbul jenis senarai:
Senario aplikasi senarai rujuk perkara berikut: < . 🎜>lpush brpop=Baris Gilir Mesej (Baris Baris Mesej)
- Tetapkan (Set)
Set tertib (zset)
- Pengenalan: Jenis set juga digunakan untuk menyimpan berbilang elemen rentetan, tetapi elemen pendua tidak dibenarkan
- Contoh penggunaan mudah:
sadd key element [element ...]
,smembers key
- Dalaman pengekodan:
intset(整数集合)
,hashtable(哈希表)
- Nota: smembers, lrange, dan hgetall adalah perintah yang agak berat Jika terdapat terlalu banyak elemen, terdapat kemungkinan untuk menyekat Redis menggunakan sscan.
Senario aplikasi: Teg pengguna, menjana nombor rawak untuk loteri, keperluan sosial.Pengenalan: Koleksi rentetan yang diisih dan elemen tidak boleh diulang Contoh format mudah:
2.2 Tiga jenis data khas Redis- ,
Pengekodan dalaman asas:zadd key score member [score member ...]
zrank key member
- ,
Senario aplikasi: kedudukan, keperluan sosial (seperti kesukaan pengguna).ziplist(压缩列表)
skiplist(跳跃表)
Geo: diperkenalkan oleh Redis 3.2, penentududukan lokasi geografi, digunakan untuk menyimpan maklumat lokasi geografi dan menyimpan maklumat Laksanakan operasi. HyperLogLog: Struktur data yang digunakan untuk algoritma statistik kardinaliti, seperti UV untuk tapak web statistik. Bitmaps: Gunakan satu bit untuk memetakan status elemen Dalam Redis, lapisan bawahnya adalah berdasarkan jenis rentetan Anda boleh menukar peta bit menjadi tatasusunan dalam bit
3. Mengapa Redis begitu pantas? 3.1 Pelaksanaan berdasarkan storan memoriKita semua tahu bahawa membaca dan menulis memori adalah lebih pantas daripada pangkalan data Redis data disimpan dalam pangkalan data MySQL pada cakera, menghapuskan penggunaan I/O cakera. 3.2 Struktur data yang cekap Kami tahu bahawa untuk meningkatkan kecekapan, indeks Mysql memilih struktur data B-tree. Malah, struktur data yang munasabah boleh menjadikan aplikasi/program anda lebih pantas. Mari kita lihat struktur data & gambar rajah pengekodan dalaman Redis: rentetan dinamik ringkas SDSPemprosesan panjang rentetan: Redis memperoleh panjang rentetan, kerumitan masa ialah O(1), manakala dalam bahasa C, ia perlu dilalui dari awal, kerumitannya ialah O(n);Pra-peruntukan ruang : Lebih kerap rentetan diubah suai, lebih kerap peruntukan memori akan digunakan, yang akan menggunakan prestasi pengubahsuaian SDS dan pengembangan ruang akan memperuntukkan ruang yang tidak digunakan tambahan, mengurangkan kehilangan prestasi. Lazy space release: Apabila SDS dipendekkan, bukannya mengitar semula lebihan ruang memori, lebihan ruang direkodkan secara percuma Jika terdapat perubahan seterusnya, ruang yang direkodkan secara percuma akan digunakan terus untuk mengurangkan peruntukan. Keselamatan binari: Redis boleh menyimpan beberapa data binari, rentetan yang ditemui dalam bahasa C '
Apakah pemultipleksan I/O?< . benang tunggal untuk mengendalikan berbilang permintaan sambungan dengan cekap, dan Redis menggunakan epoll sebagai pelaksanaan teknologi pemultipleksan I/O. Selain itu, model pemprosesan acara Redis sendiri menukar sambungan, membaca, menulis dan menutup dalam epoll kepada acara, tanpa membuang terlalu banyak masa pada rangkaian I/O.
- String: Jika nombor disimpan, pengekodan jenis int digunakan jika bukan nombor disimpan, rentetan yang kurang daripada atau sama dengan 39 bait adalah embstr jika lebih besar daripada 39 bait pengekodan digunakan.
- Senarai: Jika bilangan elemen dalam senarai kurang daripada 512, dan nilai setiap elemen dalam senarai kurang daripada 64 bait (lalai), gunakan pengekodan ziplist, jika tidak gunakan pengekodan senarai terpaut
- Cincang: Ha Jika bilangan elemen jenis cincang kurang daripada 512 dan semua nilai kurang daripada 64 bait, gunakan pengekodan senarai zip, jika tidak gunakan pengekodan jadual cincang.
- Set: Jika elemen dalam set adalah semua integer dan bilangan elemen kurang daripada 512, gunakan pengekodan inset, jika tidak gunakan pengekodan hashtable.
- Zset: Apabila bilangan elemen dalam set tersusun kurang daripada 128 dan nilai setiap elemen adalah kurang daripada 64 bait, pengekodan senarai zip digunakan, jika tidak, pengekodan skiplist digunakan
I/O: Rangkaian I/O
Berbilang: Berbilang sambungan rangkaian
Guna Semula: Guna semula urutan yang sama. Pemultipleksan IO sebenarnya ialah model IO segerak, yang melaksanakan urutan yang boleh memantau berbilang pemegang fail apabila pemegang fail sedia, ia boleh memberitahu aplikasi untuk melaksanakan operasi baca dan tulis yang sepadan; sudah siap, aplikasi akan disekat dan CPU akan diserahkan.Model benang tunggalRedis ialah model benang tunggal dan benang tunggal mengelakkan penukaran konteks dan persaingan yang tidak perlu untuk penggunaan Kunci CPU. Tepat kerana ia adalah satu utas, jika arahan tertentu dilaksanakan terlalu lama (seperti arahan hgetall), ia akan menyebabkan penyekatan. Redis ialah pangkalan data untuk senario pelaksanaan pantas. , jadi arahan seperti smembers, lrange, hgetall, dsb. hendaklah digunakan dengan berhati-hati. Redis 6.0 memperkenalkan multi-threading untuk mempercepatkan, dan pelaksanaan perintah dan operasi memorinya masih dalam satu utas.
3.5 Mekanisme Memori MayaRedis secara langsung membina mekanisme VM sendiri. Ia tidak memanggil fungsi sistem seperti sistem biasa, yang membuang masa tertentu untuk bergerak dan meminta.
Apakah mekanisme ingatan maya Redis?
- Mekanisme memori maya menukar sementara data yang jarang diakses (data sejuk) dari memori ke cakera, dengan itu membebaskan ruang memori yang berharga untuk data lain yang perlu diakses (data panas). ). Fungsi VM boleh merealisasikan pemisahan data panas dan sejuk, supaya data panas masih dalam ingatan dan data sejuk disimpan ke cakera. Ini boleh mengelakkan masalah kelajuan capaian perlahan yang disebabkan oleh memori yang tidak mencukupi.
4. Apakah pecahan cache, penembusan cache dan runtuhan cache?
4.1 Masalah penembusan cache
Mari kita lihat cara biasa untuk menggunakan cache: apabila permintaan baca datang, semak cache dahulu Jika cache terkena, ia akan kembali secara langsung; jika cache terlepas, Hanya semak pangkalan data, kemas kini nilai pangkalan data kepada cache, dan kemudian kembali.
Penembusan cache: merujuk kepada pertanyaan data yang tidak mesti wujud Oleh kerana cache terlepas, ia perlu disoal dari pangkalan data data tidak dapat ditemui, Tanpa menulis ke cache, ini akan menyebabkan data yang tidak wujud akan ditanya dalam pangkalan data setiap kali ia diminta, yang akan memberi tekanan kepada pangkalan data.Ringkasnya, apabila permintaan baca diakses, baik cache mahupun pangkalan data tidak mempunyai nilai tertentu, yang akan menyebabkan setiap permintaan pertanyaan untuk nilai ini menembusi ke dalam pangkalan data penembusan.
Penembusan cache secara amnya disebabkan oleh situasi berikut:Reka bentuk perniagaan yang tidak munasabah, contohnya, kebanyakan pengguna tidak mendayakan Guard, tetapi setiap permintaan yang anda buat pergi ke cache dan menyemak sama ada id pengguna tertentu dikawal.
Ralat perniagaan/operasi dan penyelenggaraan/pembangunan, seperti data cache dan pangkalan data dipadamkan secara tidak sengaja.
Serangan permintaan tidak sah oleh penggodam
, sebagai contoh, penggodam sengaja mereka-reka sebilangan besar permintaan haram untuk membaca data perniagaan yang tidak wujud.
- Bagaimana untuk mengelakkan penembusan cache?
Secara amnya terdapat tiga kaedah.
- 1 Jika ia adalah permintaan yang tidak sah, kami akan mengesahkan parameter di pintu masuk API dan menapis nilai yang tidak sah.
- 2 Jika pangkalan data pertanyaan kosong, kami boleh menetapkan nilai nol atau nilai lalai untuk cache. Walau bagaimanapun, jika permintaan tulis masuk, cache perlu dikemas kini untuk memastikan konsistensi cache Pada masa yang sama, masa tamat tempoh yang sesuai akhirnya ditetapkan untuk cache. (Biasa digunakan dalam perniagaan, mudah dan berkesan)
- 3 Gunakan penapis Bloom untuk menentukan dengan cepat sama ada data wujud. Iaitu, apabila permintaan pertanyaan masuk, ia terlebih dahulu menilai sama ada nilai itu wujud melalui penapis Bloom, dan kemudian terus menyemak sama ada nilai itu wujud.
Prinsip penapis Bloom: Ia terdiri daripada tatasusunan peta bit dengan nilai awal 0 dan fungsi cincang N. Lakukan algoritma cincang N pada kunci untuk mendapatkan nilai N Hash nilai N ini dalam tatasusunan bit dan tetapkannya kepada 1. Kemudian apabila menyemak, jika kedudukan khusus ini semuanya 1, maka Penapisan Bloom Pelayan menentukan bahawa kunci itu wujud. .
4.2 Masalah larian salji cache
Larian salji cache: merujuk kepada masa tamat tempoh kumpulan besar data dalam cache dan jumlah data pertanyaan adalah besar, dan semua permintaan diakses secara terus Pangkalan Data, menyebabkan tekanan yang berlebihan pada pangkalan data atau bahkan menurunkan mesin.
- Cache snowfall secara amnya disebabkan oleh sejumlah besar data yang luput pada masa yang sama Atas sebab ini, ia boleh diselesaikan dengan menetapkan masa tamat tempoh secara sama rata, iaitu, menjadikan masa tamat tempoh agak diskret. . Contohnya, gunakan nilai tetap yang lebih besar dan nilai rawak yang lebih kecil, 5 jam, 0 hingga 1800 saat.
- Kegagalan redis juga boleh menyebabkan salji cache. Ini memerlukan pembinaan kluster ketersediaan tinggi Redis.
4.3 Masalah pecahan cache
Pecahan cache: merujuk kepada apabila kunci tempat liputan tamat tempoh pada masa tertentu dan tepat pada masa ini, Kunci ini mempunyai sejumlah besar permintaan serentak, jadi sejumlah besar permintaan mencapai db.
Pecahan cache kelihatan agak serupa Malah, perbezaan di antara mereka ialah salji cache bermakna bahawa pangkalan data berada di bawah tekanan yang berlebihan atau bahkan pecahan Cache hanyalah sejumlah besar permintaan serentak ke pangkalan data DB tahap. Ia boleh dianggap bahawa pecahan ialah subset cache salji. Sesetengah artikel percaya bahawa perbezaan antara kedua-duanya ialah pecahan ditujukan kepada cache kunci panas tertentu, manakala Xuebeng disasarkan pada banyak kunci.
Terdapat dua penyelesaian:
- 1 Gunakan skema kunci mutex . Apabila cache gagal, daripada memuatkan data db serta-merta, anda mula-mula menggunakan beberapa perintah operasi atom dengan pulangan yang berjaya, seperti (Redis's setnx) untuk beroperasi Apabila berjaya, muatkan data pangkalan data db dan sediakan cache. Jika tidak, cuba dapatkan cache sekali lagi.
- 2. "Tidak pernah tamat tempoh" bermakna masa tamat tempoh tidak ditetapkan, tetapi apabila data tempat liputan hampir tamat tempoh, urutan tak segerak mengemas kini dan menetapkan masa tamat tempoh.
5. Apakah masalah kunci panas dan cara menyelesaikan masalah kunci panas
Apakah kunci panas? Di Redis, kami memanggil kekunci dengan kekerapan akses tinggi sebagai kekunci panas.
Jika permintaan kunci tempat liputan dihantar kepada hos pelayan, disebabkan volum permintaan yang sangat besar, ia mungkin menyebabkan sumber hos tidak mencukupi atau bahkan masa henti, sekali gus menjejaskan perkhidmatan biasa.
Bagaimanakah Kunci tempat liputan dijana? Terdapat dua sebab utama:
- Data yang digunakan oleh pengguna jauh lebih besar daripada data yang dihasilkan, seperti jualan kilat, berita hangat dan senario lain di mana terdapat lebih banyak bacaan dan kurang penulisan.
- Pembahagian permintaan adalah tertumpu, yang melebihi prestasi pelayan Redi tunggal Contohnya, jika kunci nama tetap dan Hash jatuh ke dalam pelayan yang sama, jumlah akses segera adalah besar, melebihi kesesakan mesin. , dan menyebabkan masalah kunci panas.
Jadi bagaimana untuk mengenal pasti kunci panas dalam pembangunan harian?
Peluasan gugusan Redis: tambah salinan serpihan untuk mengimbangi trafik baca; , cache tempatan JVM, mengurangkan permintaan baca Redis.
- Tentukan kekunci panas yang berdasarkan pengalaman;
- Pelaporan statistik pelanggan;
Bagaimana untuk menyelesaikan masalah kunci panas?, anda boleh menetapkan masa tamat tempoh untuknya, seperti6. Strategi tamat tempoh Redis dan strategi penghapusan ingatan
Kami berada dalam- 6.1 Strategi tamat tempoh Redis
. Tentukan bahawa kunci ini akan tamat tempoh selepas 60 saat Bagaimana redis mengendalikannya selepas 60 saat? Mari kita perkenalkan beberapa strategi tamat tempoh dahulu:
Tamat tempoh masa
Setiap kunci dengan masa tamat tempoh perlu mencipta pemasa dan kunci akan dikosongkan serta-merta apabila masa tamat tempoh dicapai. . Strategi ini boleh mengosongkan data yang telah tamat tempoh serta-merta dan sangat mesra memori walau bagaimanapun, ia akan menduduki sejumlah besar sumber CPU untuk memproses data yang telah tamat tempoh, sekali gus menjejaskan masa tindak balas cache dan pemprosesan.
Tamat tempoh malas
Hanya apabila kunci diakses, ia akan dinilai sama ada kunci telah tamat tempoh, dan ia akan dikosongkan jika ia tamat tempoh. Strategi ini boleh menjimatkan sumber CPU ke tahap maksimum, tetapi ia sangat tidak mesra memori. Dalam kes yang melampau, sebilangan besar kunci yang telah tamat tempoh mungkin tidak dapat diakses semula, oleh itu tidak dibersihkan dan menduduki sejumlah besar memori.
Tamat tempoh secara tetap
Setiap masa tertentu, bilangan kunci tertentu dalam kamus tamat tempoh bilangan pangkalan data tertentu akan diimbas dan kunci tamat tempoh akan dikosongkan. Strategi ini adalah kompromi antara dua yang pertama. Dengan melaraskan selang masa imbasan berjadual dan penggunaan masa terhad bagi setiap imbasan, keseimbangan optimum antara CPU dan sumber memori boleh dicapai dalam keadaan yang berbeza.
Kamus tamat tempoh akan menyimpan data masa tamat tempoh semua kunci dengan masa tamat tempoh yang ditetapkan, dengan kunci ialah penunjuk kepada kunci dalam ruang kunci dan nilai ialah cap masa UNIX bagi kunci dengan ketepatan milisaat masa. Ruang kekunci merujuk kepada semua kekunci yang disimpan dalam kelompok Redis.
Redis menggunakan kedua-dua tamat tempoh malas dan tamat tempoh berkala dua strategi tamat tempoh.
- Andaikan bahawa Redis pada masa ini menyimpan 300,000 kekunci, dan kesemuanya mempunyai masa tamat tempoh yang ditetapkan Jika anda menyemak semua kekunci setiap 100ms, beban CPU akan menjadi sangat tinggi, dan akhirnya ia mungkin hang.
- Oleh itu, redis menggunakan tamat tempoh biasa dan secara rawak memilih bilangan kunci tertentu untuk menyemak dan memadam setiap 100ms.
- Namun, pada akhirnya, mungkin terdapat banyak kunci tamat tempoh yang belum dipadamkan. Pada masa ini, redis menggunakan pemadaman malas. Apabila anda mendapat kunci, redis akan menyemaknya Jika kunci mempunyai masa tamat tempoh yang ditetapkan dan telah tamat tempoh, ia akan dipadamkan pada masa ini.
Namun, jika pemadaman biasa terlepas banyak kunci tamat tempoh, maka pemadaman malas tidak akan digunakan. Terdapat banyak kunci tamat tempoh terkumpul dalam memori, yang secara langsung akan menyebabkan memori meletup. Atau kadangkala, apabila volum perniagaan meningkat, kekunci redis banyak digunakan, memori tidak mencukupi, dan lelaki operasi dan penyelenggaraan terlupa untuk meningkatkan ingatan. Bolehkah redis menutup telefon seperti ini? Tidak! Redis menggunakan 8 strategi penghapusan memori untuk melindungi dirinya~
6.2 Strategi penghapusan memori Redis
CachingSenarai kedudukan
- volatile-lru: Apabila memori tidak mencukupi untuk menampung data yang baru ditulis, tetapkan ia daripada Gunakan algoritma LRU (Paling Kurang Digunakan) untuk kunci yang telah tamat tempoh; Lakukan penyingkiran.
- volatile-lfu: Baru ditambahkan dalam versi 4.0, apabila memori tidak mencukupi untuk menampung data yang baru ditulis, algoritma LFU digunakan untuk memadamkan kunci antara kunci yang telah tamat tempoh.
- allkeys-lfu: Baharu dalam versi 4.0, apabila memori tidak mencukupi untuk menampung data yang baru ditulis, algoritma LFU digunakan untuk menghapuskan daripada semua kunci; ingatan tidak mencukupi Apabila menampung data yang baru ditulis, data disingkirkan secara rawak daripada kunci dengan set masa tamat tempoh;.
- allkeys-random: Apabila memori tidak mencukupi untuk menampung data yang baru ditulis, data disingkirkan secara rawak daripada semua kekunci.
- volatile-ttl: Apabila memori tidak mencukupi untuk menampung data yang baru ditulis, kunci dengan set masa tamat tempoh akan dihapuskan mengikut masa tamat tempoh, dan lebih awal tarikh tamat tempoh akan dihapuskan terlebih dahulu;
- noeviction: Dasar lalai, apabila memori tidak mencukupi untuk menampung data yang baru ditulis, operasi tulis baharu akan melaporkan ralat.
- 7 Mari kita bincangkan tentang senario aplikasi biasa Redis
7.2 Kedudukan Aplikasi Internet hari ini mempunyai pelbagai kedudukan, seperti kedudukan jualan bulanan tapak web e-dagang, kedudukan hadiah APP sosial, dan kedudukan undian bagi program mini dan seterusnya. Jenis data
- Aplikasi balas<. 🎜>
Sesi DikongsiKunci TeragihRangkaian SosialBaris Gilir MesejOperasi Bit- Caching 7.1
- Apabila kita menyebut redis, kita secara semula jadi memikirkan cache laman web sederhana dan besar di dalam dan luar negara tidak dapat dipisahkan daripada cache. Penggunaan cache yang munasabah, seperti caching data hotspot, bukan sahaja dapat meningkatkan kelajuan akses laman web, tetapi juga mengurangkan tekanan pada pangkalan data DB. Selain itu, berbanding dengan memcached, Redis juga menyediakan struktur data yang kaya, dan menyediakan mekanisme kegigihan seperti RDB dan AOF, yang merupakan antara yang paling kuat.
yang disediakan oleh Redis boleh melaksanakan penarafan kompleks ini.
Sebagai contoh, jika pengguna memuat naik video setiap hari, senarai kedudukan suka boleh direka seperti ini:
- 1.用户Jay上传一个视频,获得6个赞,可以酱紫:
zadd user:ranking:2021-03-03 Jay 3Salin selepas log masuk
- 过了一段时间,再获得一个赞,可以这样:
zincrby user:ranking:2021-03-03 Jay 1Salin selepas log masuk
- 如果某个用户John作弊,需要删除该用户:
zrem user:ranking:2021-03-03 JohnSalin selepas log masuk
- 展示获取赞数最多的3个用户
zrevrangebyrank user:ranking:2021-03-03 0 2Salin selepas log masuk7.3 计数器应用
各大网站、APP应用经常需要计数器的功能,如短视频的播放数、电商网站的浏览数。这些播放数、浏览数一般要求实时的,每一次播放和浏览都要做加1的操作,如果并发量很大对于传统关系型数据的性能是一种挑战。Redis天然支持计数功能而且计数的性能也非常好,可以说是计数器系统的重要选择。
7.4 共享Session
如果一个分布式Web服务将用户的Session信息保存在各自服务器,用户刷新一次可能就需要重新登录了,这样显然有问题。实际上,可以使用Redis将用户的Session进行集中管理,每次用户更新或者查询登录信息都直接从Redis中集中获取。
7.5 分布式锁
几乎每个互联网公司中都使用了分布式部署,分布式服务下,就会遇到对同一个资源的并发访问的技术难题,如秒杀、下单减库存等场景。
- 用synchronize或者reentrantlock本地锁肯定是不行的。
- 如果是并发量不大话,使用数据库的悲观锁、乐观锁来实现没啥问题。
- 但是在并发量高的场合中,利用数据库锁来控制资源的并发访问,会影响数据库的性能。
- 实际上,可以用Redis的setnx来实现分布式的锁。
7.6 社交网络
赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等是社交网站的必备功能,由于社交网站访问量通常比较大,而且传统的关系型数据不太适保存 这种类型的数据,Redis提供的数据结构可以相对比较容易地实现这些功能。
7.7 消息队列
消息队列是大型网站必用中间件,如ActiveMQ、RabbitMQ、Kafka等流行的消息队列中间件,主要用于业务解耦、流量削峰及异步处理实时性低的业务。Redis提供了发布/订阅及阻塞队列功能,能实现一个简单的消息队列系统。另外,这个不能和专业的消息中间件相比。
7.8 位操作
用于数据量上亿的场景下,例如几亿用户系统的签到,去重登录次数统计,某用户是否在线状态等等。腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,能怎么做?千万别说给每个用户建立一个key,然后挨个记(你可以算一下需要的内存会很恐怖,而且这种类似的需求很多。这里要用到位操作——使用setbit、getbit、bitcount命令。原理是:redis内构建一个足够长的数组,每个数组元素只能是0和1两个值,然后这个数组的下标index用来表示用户id(必须是数字哈),那么很显然,这个几亿长的大数组就能通过下标和元素值(0和1)来构建一个记忆系统。
8. Redis 的持久化机制有哪些?优缺点说说
Redis是基于内存的非关系型K-V数据库,既然它是基于内存的,如果Redis服务器挂了,数据就会丢失。为了避免数据丢失了,Redis提供了持久化,即把数据保存到磁盘。
Redis提供了RDB和AOF两种持久化机制,它持久化文件加载流程如下:
8.1 RDB
RDB,就是把内存数据以快照的形式保存到磁盘上。
什么是快照?可以这样理解,给当前时刻的数据,拍一张照片,然后保存下来。
RDB持久化,是指在指定的时间间隔内,执行指定次数的写操作,将内存中的数据集快照写入磁盘中,它是Redis默认的持久化方式。执行完操作后,在指定目录下会生成一个
dump.rdb
文件,Redis 重启的时候,通过加载dump.rdb
文件来恢复数据。RDB触发机制主要有以下几种:RDB 的优点
- 适合大规模的数据恢复场景,如备份,全量复制等
RDB缺点
- Tiada cara untuk mencapai kegigihan masa nyata/kegigihan peringkat kedua.
- Versi lama dan baharu mempunyai isu keserasian format RDB
AOF
AOF (tambah fail sahaja) Kegigihan, dalam bentuk log Rekod setiap operasi tulis, tambahkannya pada fail, dan kemudian laksana semula arahan dalam fail AOF untuk memulihkan data apabila dimulakan semula. Ia terutamanya menyelesaikan masalah masa nyata kegigihan data. Ia tidak didayakan secara lalai.
Aliran kerja AOF adalah seperti berikut:
Kelebihan AOF
- Ketekalan data dan Integriti yang lebih tinggi
Kelemahan AOF
- Semakin banyak kandungan rekod AOF, semakin besar fail dan semakin perlahan pemulihan data.
9. Bagaimana untuk mencapai ketersediaan Redis yang tinggi?
Apabila kami menggunakan Redis dalam projek, kami pasti tidak akan menggunakan perkhidmatan Redis sebagai satu titik. Kerana apabila penggunaan satu titik menurun, ia tidak lagi tersedia. Untuk mencapai ketersediaan tinggi, amalan biasa ialah menyalin berbilang salinan pangkalan data dan menggunakannya pada pelayan yang berbeza Jika salah satu daripadanya gagal, ia boleh terus menyediakan perkhidmatan. Terdapat tiga mod penggunaan untuk Redis mencapai ketersediaan tinggi: mod master-slave, mod sentinel dan mod cluster.
9.1 Mod Master-slave
Dalam mod master-slave, Redis menggunakan berbilang mesin, dengan nod induk yang bertanggungjawab untuk operasi baca dan tulis dan nod hamba yang bertanggungjawab untuk operasi baca sahaja. Data nod hamba berasal daripada nod induk Prinsip pelaksanaan ialah mekanisme replikasi induk-hamba
Replikasi induk-hamba termasuk replikasi penuh dan replikasi tambahan. Secara amnya, apabila hamba mula menyambung kepada tuan buat kali pertama, atau ia dianggap sebagai kali pertama menyambung, salinan penuh digunakan proses salinan penuh adalah seperti berikut:
- 1.hamba menghantar arahan penyegerakan kepada tuan.
- 2. Selepas induk menerima arahan SYNC, ia melaksanakan perintah bgsave untuk menjana fail RDB penuh.
- 3. Induk menggunakan penimbal untuk merekod semua arahan tulis semasa penjanaan syot kilat RDB.
- 4. Selepas master melaksanakan bgsave, ia menghantar fail snapshot RDB kepada semua hamba.
- 5. Selepas menerima fail petikan RDB, hamba memuatkan dan menghuraikan petikan yang diterima.
- 6. Induk menggunakan penimbal untuk merekod semua arahan bertulis yang dijana semasa penyegerakan RDB.
- 7 Selepas syot kilat induk dihantar, ia mula menghantar arahan tulis dalam penimbal kepada hamba
- 8 penimbal
Selepas redis versi 2.8, psync telah digunakan untuk menggantikan penyegerakan, kerana arahan penyegerakan menggunakan sumber sistem dan psync lebih cekap.
Selepas hamba disegerakkan sepenuhnya dengan tuan, jika data pada tuan dikemas kini semula, replikasi tambahan akan dicetuskan.
Apabila data bertambah atau berkurang pada nod induk, fungsi
replicationFeedSalves()
akan dicetuskan. Setiap arahan yang kemudiannya dipanggil pada nod Induk akan menggunakanreplicationFeedSlaves()
untuk menyegerakkan ke nod Hamba. Sebelum melaksanakan fungsi ini, nod induk akan menentukan sama ada arahan yang dilaksanakan oleh pengguna mempunyai kemas kini data Jika terdapat kemas kini data dan nod hamba tidak kosong, fungsi ini akan dilaksanakan. Fungsi fungsi ini adalah untuk: menghantar arahan yang dilaksanakan oleh pengguna kepada semua nod hamba dan biarkan nod hamba melaksanakannya. Prosesnya adalah seperti berikut:9.2 Mod Sentinel
Dalam mod induk-hamba, apabila nod induk tidak dapat menyediakan perkhidmatan kerana kegagalan, ia adalah perlu untuk mempromosikan nod hamba secara manual kepada nod induk, dan juga memberitahu bahagian aplikasi untuk mengemas kini alamat nod induk. Jelas sekali, kaedah pengendalian kerosakan ini tidak boleh diterima dalam kebanyakan senario perniagaan. Redis telah secara rasmi menyediakan seni bina Redis Sentinel sejak 2.8 untuk menyelesaikan masalah ini.
Mod Sentinel, sistem Sentinel yang terdiri daripada satu atau lebih tika Sentinel, yang boleh memantau semua nod induk dan nod hamba Redis, dan memasuki keadaan luar talian apabila nod induk dipantau , secara automatik meningkatkan nod hamba di bawah pelayan induk luar talian kepada nod induk baharu . Walau bagaimanapun, jika proses sentinel memantau nod Redis, masalah mungkin berlaku (Masalah titik tunggal Oleh itu, berbilang sentinel boleh digunakan untuk memantau nod Redis, dan akan ada komunikasi berterusan antara setiap sentinel.
Ringkasnya, mod sentinel mempunyai tiga fungsi:
Apakah proses failover itu?
- Hantar arahan dan tunggu pelayan Redis (termasuk pelayan induk dan pelayan hamba) untuk mengembalikan Pantau status berjalannya;
- Sentinel mengesan bahawa nod induk dimatikan, dan akan bertukar secara automatik daripada nod hamba kepada nod induk, dan kemudian memberitahu nod hamba yang lain melalui penerbitan dan langgan mod, ubah suai fail konfigurasi dan biarkan mereka menukar hos;
Andainya pelayan utama tidak berfungsi dan Sentinel 1 mengesan keputusan ini terlebih dahulu Sistem tidak akan melaksanakan proses failover dengan serta-merta luar talian. Apabila pengawal berikutnya juga mengesan bahawa pelayan utama tidak tersedia dan bilangannya mencapai nilai tertentu, undian akan diadakan antara pengawal Keputusan undian akan dimulakan oleh seorang pengawal untuk melakukan operasi failover. Selepas suis berjaya, setiap pengawal akan menggunakan mod terbitkan-langganan untuk menukar pelayan hamba yang dipantaunya kepada hos Proses ini dipanggil objektif luar talian. Dengan cara ini semuanya telus kepada pelanggan.
Mod kerja Sentinel adalah seperti berikut:
Setiap Sentinel menghantar mesej kepada Master, Slave dan contoh Sentinel lain yang diketahuinya sekali setiap saat Perintah PING.
Jika masa sejak balasan terakhir yang sah kepada arahan PING melebihi nilai yang ditentukan oleh pilihan turun-selepas milisaat, kejadian itu akan ditandakan secara subjektif di luar talian oleh Sentinel.
Jika Master ditandakan sebagai subjektif luar talian, semua Sentinel yang memantau Master mesti mengesahkan sekali sesaat bahawa Master memang telah memasuki keadaan luar talian subjektif.
Apabila bilangan Sentinel yang mencukupi (lebih daripada atau sama dengan nilai yang dinyatakan dalam fail konfigurasi) mengesahkan bahawa Master memang telah memasuki keadaan luar talian subjektif dalam julat masa yang ditentukan, Sarjana akan ditandakan sebagai objektif luar talian.
Dalam keadaan biasa, setiap Sentinel akan menghantar arahan INFO kepada semua Master dan Slaves yang diketahuinya sekali setiap 10 saat.
Apabila Master ditandakan sebagai luar talian secara objektif oleh Sentinel, kekerapan Sentinel menghantar arahan INFO kepada semua hamba Master luar talian akan ditukar daripada sekali setiap 10 saat kepada sekali setiap saat
Jika tidak cukup Sentinel untuk bersetuju bahawa Master berada di luar talian, status luar talian objektif Master akan dialih keluar jika Master mengembalikan jawapan yang sah kepada arahan PING Sentinel, subjektif Master status luar talian akan dialih keluar Status akan dialih keluar.
9.3 Mod Kluster
Mod Sentinel adalah berdasarkan mod induk-hamba dan menyedari pemisahan baca dan tulis Ia juga boleh bertukar secara automatik dan ketersediaan sistem lebih tinggi. Walau bagaimanapun, data yang disimpan dalam setiap nod adalah sama, yang membazirkan memori dan tidak mudah untuk dikembangkan dalam talian. Oleh itu, gugusan Kluster wujud. Ia telah ditambahkan dalam Redis 3.0 dan melaksanakan storan teragih Redis. Bahagikan data, yang bermaksud simpan kandungan berbeza pada setiap nod Redis untuk menyelesaikan masalah pengembangan dalam talian. Selain itu, ia juga menyediakan keupayaan replikasi dan failover.
Komunikasi nod kelompok KlusterKluster Redis terdiri daripada berbilang nodBagaimanakah setiap nod berkomunikasi antara satu sama lain? Melalui protokol Gosip!
Kluster Redis berkomunikasi melalui protokol Gossip Nod bertukar maklumat secara berterusan termasuk kegagalan nod, sambungan nod baharu, maklumat pertukaran nod induk, maklumat slot, dsb. Mesej gosip yang biasa digunakan terbahagi kepada empat jenis: ping, pong, meet, dan fail.Khususnya, setiap nod berkomunikasi dengan nod lain melaluimesej jumpa: Maklumkan nod baharu untuk menyertai. Pengirim mesej memberitahu penerima untuk menyertai kluster semasa Selepas komunikasi mesej bertemu selesai seperti biasa, nod penerima akan menyertai kluster dan melakukan pertukaran mesej ping dan pong secara berkala. Mesej ping: Mesej yang paling kerap ditukar dalam kluster Setiap nod dalam kluster menghantar mesej ping ke berbilang nod lain setiap saat, yang digunakan untuk mengesan sama ada nod berada dalam talian dan bertukar maklumat status antara satu sama lain. . mesej pong: Apabila menerima mesej ping atau meet, ia akan membalas kepada penghantar sebagai mesej respons untuk mengesahkan komunikasi biasa mesej itu. Mesej pong secara dalaman merangkum data statusnya sendiri. Nod juga boleh menyiarkan mesej pongnya sendiri kepada kluster untuk memberitahu seluruh kluster untuk mengemas kini statusnya sendiri. mesej gagal: Apabila nod menentukan bahawa nod lain dalam kluster berada di luar talian, ia akan menyiarkan mesej gagal ke kluster Selepas menerima mesej gagal, nod lain akan mengemas kini nod yang sepadan kepada keadaan luar talian.
bas kluster (bas kluster). Semasa berkomunikasi, gunakan nombor port khas, iaitu nombor port perkhidmatan luaran ditambah 10000. Sebagai contoh, jika nombor port nod ialah 6379, maka nombor port yang digunakan untuk berkomunikasi dengan nod lain ialah 16379. Komunikasi antara nod menggunakan protokol binari khas.
Algoritma Slot CincangMemandangkan ia adalah storan teragih, adakah algoritma yang diedarkan digunakan oleh kelompok KlusterCincang Konsisten? Tidak, tetapi Algoritma slot Hash Slot.
Algoritma slotSeluruh pangkalan data dibahagikan kepada 16384 slot (slot). Peta hash yang digunakan juga agak mudah Ia menggunakan algoritma CRC16 untuk mengira nilai 16-bit, dan kemudian modulo 16384. Setiap kunci dalam pangkalan data adalah milik salah satu daripada 16384 slot ini dan setiap nod dalam kelompok boleh mengendalikan 16384 slot ini.
Setiap nod dalam gugusan bertanggungjawab untuk sebahagian daripada slot cincang Contohnya, gugusan semasa mempunyai nod A, B dan C, dan bilangan slot cincang pada setiap nod = 16384/3, maka terdapat:
- Nod A bertanggungjawab untuk slot cincang 0~5460
- Nod B bertanggungjawab untuk slot cincang 5461~10922
- Nod C bertanggungjawab untuk slot cincang 10923~16383
Kluster Kluster Redis
Dalam kluster Kluster Redis, adalah perlu untuk memastikan bahawa nod yang sepadan dengan slot 16384 berfungsi seperti biasa , slot yang dipertanggungjawabkan juga akan gagal, dan keseluruhan kluster tidak akan berfungsi.
Oleh itu, untuk memastikan ketersediaan tinggi, kluster Kluster memperkenalkan replikasi induk-hamba, dan satu nod induk sepadan dengan satu atau lebih nod hamba. Apabila nod induk lain melakukan ping ke nod induk A, jika lebih separuh daripada nod induk berkomunikasi dengan A tamat masa, maka nod induk A dianggap turun. Jika nod induk turun, nod hamba akan didayakan.
Pada setiap nod Redis, terdapat dua perkara, satu ialah slot dan julat nilainya ialah 016383. Yang lain ialah kluster, yang boleh difahami sebagai pemalam pengurusan kluster. Apabila kunci yang kami akses tiba, Redis akan memperoleh nilai 16-bit berdasarkan algoritma CRC16, dan kemudian mengambil hasil modulo 16384. Setiap kunci dalam Jiangzi sepadan dengan slot cincang bernombor antara 016383 Gunakan nilai ini untuk mencari nod yang sepadan dengan slot yang sepadan, dan kemudian secara automatik melompat ke nod yang sepadan untuk beroperasi.
Walaupun data disimpan secara berasingan pada nod yang berbeza, kepada pelanggan, keseluruhan kluster dilihat secara keseluruhan. Pelanggan menyambung ke mana-mana nod dan kelihatan sama seperti mengendalikan satu contoh Redis. Apabila kunci yang dikendalikan oleh klien tidak diberikan kepada nod yang betul, Redis akan mengembalikan arahan pengalihan dan akhirnya menunjuk ke nod yang betul Ini sedikit seperti lompatan 302 halaman penyemak imbas.
Failover
Kluster Redis mencapai ketersediaan tinggi Apabila nod dalam kluster gagal, failover digunakan untuk memastikan Kluster menyediakan. perkhidmatan luar biasanya.
Kluster redis menyedari penemuan kesalahan melalui mesej ping/pong. Persekitaran ini termasuk subjektif luar talian dan objektif luar talian.
Subjektif luar talian: Nod berpendapat bahawa nod lain tidak tersedia, iaitu, keadaan luar talian ini bukan penentuan kesalahan terakhir dan hanya boleh mewakili pendapat satu nod wujud Salah menilai keadaan.
Objektif luar talian: menunjukkan bahawa nod benar-benar luar talian dalam kelompok percaya bahawa nod itu tidak tersedia, dengan itu mencapai keputusan . Jika nod induk yang memegang slot gagal, failover perlu dilakukan untuk nod.
- Jika nod A menandakan nod B sebagai luar talian secara subjektif, selepas satu tempoh masa, nod A menghantar status nod B ke nod lain melalui mesej Apabila nod C menerima mesej dan menghuraikan badan mesej , jika status pfail nod B ditemui, proses luar talian objektif akan dicetuskan
- Apabila nod induk berada di luar talian, kelompok Redis Cluster akan mengira undian nod induk yang memegang slot untuk melihat sama ada bilangan undian mencecah Separuh, apabila statistik laporan luar talian melebihi separuh, ia akan ditandakan sebagai status Objektif Luar Talian.
Prosesnya adalah seperti berikut:
Pemulihan kerosakan: Selepas kesalahan ditemui, jika nod luar talian adalah nod induk, maka Anda perlu memilih salah satu nod hambanya untuk menggantikannya bagi memastikan ketersediaan kluster yang tinggi. Prosesnya adalah seperti berikut:
10. Adakah anda pernah menggunakan kunci edaran Redis? Apakah perkara yang perlu diberi perhatian?
- Semakan kelayakan: Semak sama ada nod hamba mempunyai syarat untuk menggantikan nod induk yang gagal.
- Sediakan masa pilihan raya: Selepas semakan kelayakan diluluskan, kemas kini masa untuk mencetuskan pilihan raya kesalahan.
- Mulakan pilihan raya: Apabila tiba masa pilihan raya yang salah, jalankan pilihan raya.
- Pengundian pilihan raya: Hanya nod induk yang memegang slot mempunyai undian Jika undian mencukupi (lebih daripada separuh) dikumpulkan daripada nod hamba, penggantian operasi nod induk. < dicetuskan 🎜>
Kunci teragih ialah pelaksanaan kunci yang mengawal proses berbeza dalam sistem teragih untuk mengakses sumber dikongsi bersama. Senario perniagaan seperti membuat pesanan jualan kilat, mengambil sampul merah, dll. semuanya memerlukan penggunaan kunci yang diedarkan Redis sering digunakan sebagai kunci yang diedarkan dalam projek kami.
选了Redis分布式锁的几种实现方法,大家来讨论下,看有没有啥问题哈。
- 命令setnx + expire分开写
- setnx + value值是过期时间
- set的扩展命令(set ex px nx)
- set ex px nx + 校验唯一随机值,再删除
10.1 命令setnx + expire分开写
if(jedis.setnx(key,lock_value) == 1){ //加锁 expire(key,100); //设置过期时间 try { do something //业务请求 }catch(){ } finally { jedis.del(key); //释放锁 } }Salin selepas log masuk如果执行完
setnx
加锁,正要执行expire设置过期时间时,进程crash掉或者要重启维护了,那这个锁就“长生不老”了,别的线程永远获取不到锁啦,所以分布式锁不能这么实现。10.2 setnx + value值是过期时间
long expires = System.currentTimeMillis() + expireTime; //系统时间+设置的过期时间 String expiresStr = String.valueOf(expires); // 如果当前锁不存在,返回加锁成功 if (jedis.setnx(key, expiresStr) == 1) { return true; } // 如果锁已经存在,获取锁的过期时间 String currentValueStr = jedis.get(key); // 如果获取到的过期时间,小于系统当前时间,表示已经过期 if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) { // 锁已过期,获取上一个锁的过期时间,并设置现在锁的过期时间(不了解redis的getSet命令的小伙伴,可以去官网看下哈) String oldValueStr = jedis.getSet(key_resource_id, expiresStr); if (oldValueStr != null && oldValueStr.equals(currentValueStr)) { // 考虑多线程并发的情况,只有一个线程的设置值和当前值相同,它才可以加锁 return true; } } //其他情况,均返回加锁失败 return false; }Salin selepas log masuk笔者看过有开发小伙伴是这么实现分布式锁的,但是这种方案也有这些缺点:
- 过期时间是客户端自己生成的,分布式环境下,每个客户端的时间必须同步。
- 没有保存持有者的唯一标识,可能被别的客户端释放/解锁。
- 锁过期的时候,并发多个客户端同时请求过来,都执行了
jedis.getSet()
,最终只能有一个客户端加锁成功,但是该客户端锁的过期时间,可能被别的客户端覆盖。10.3: set的扩展命令(set ex px nx)(注意可能存在的问题)
if(jedis.set(key, lock_value, "NX", "EX", 100s) == 1){ //加锁 try { do something //业务处理 }catch(){ } finally { jedis.del(key); //释放锁 } }Salin selepas log masuk这个方案可能存在这样的问题:
- 锁过期释放了,业务还没执行完。
- 锁被别的线程误删。
10.4 set ex px nx + 校验唯一随机值,再删除
if(jedis.set(key, uni_request_id, "NX", "EX", 100s) == 1){ //加锁 try { do something //业务处理 }catch(){ } finally { //判断是不是当前线程加的锁,是才释放 if (uni_request_id.equals(jedis.get(key))) { jedis.del(key); //释放锁 } } }Salin selepas log masuk在这里,判断当前线程加的锁和释放锁是不是一个原子操作。如果调用jedis.del()释放锁的时候,可能这把锁已经不属于当前客户端,会解除他人加的锁。
一般也是用lua脚本代替。lua脚本如下:
if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end;Salin selepas log masuk这种方式比较不错了,一般情况下,已经可以使用这种实现方式。但是存在锁过期释放了,业务还没执行完的问题(实际上,估算个业务处理的时间,一般没啥问题了)。
11. 使用过Redisson嘛?说说它的原理
分布式锁可能存在锁过期释放,业务没执行完的问题。有些小伙伴认为,稍微把锁过期时间设置长一些就可以啦。其实我们设想一下,是否可以给获得锁的线程,开启一个定时守护线程,每隔一段时间检查锁是否还存在,存在则对锁的过期时间延长,防止锁过期提前释放。
当前开源框架Redisson就解决了这个分布式锁问题。我们一起来看下Redisson底层原理是怎样的吧:
只要线程一加锁成功,就会启动一个
watch dog
看门狗,它是一个后台线程,会每隔10秒检查一下,如果线程1还持有锁,那么就会不断的延长锁key的生存时间。因此,Redisson就是使用Redisson解决了锁过期释放,业务没执行完问题。12. 什么是Redlock算法
Redis一般都是集群部署的,假设数据在主从同步过程,主节点挂了,Redis分布式锁可能会有哪些问题呢?一起来看些这个流程图:
如果线程一在Redis的master节点上拿到了锁,但是加锁的key还没同步到slave节点。恰好这时,master节点发生故障,一个slave节点就会升级为master节点。线程二就可以获取同个key的锁啦,但线程一也已经拿到锁了,锁的安全性就没了。
为了解决这个问题,Redis作者 antirez提出一种高级的分布式锁算法:Redlock。Redlock核心思想是这样的:
搞多个Redis master部署,以保证它们不会同时宕掉。并且这些master节点是完全相互独立的,相互之间不存在数据同步。同时,需要确保在这多个master实例上,是与在Redis单实例,使用相同方法来获取和释放锁。
我们假设当前有5个Redis master节点,在5台服务器上面运行这些Redis实例。
RedLock的实现步骤:如下
- 1. Dapatkan masa semasa dalam milisaat.
- 2. Minta kunci daripada 5 nod induk mengikut urutan. Pelanggan menetapkan sambungan rangkaian dan tamat masa tindak balas, dan tamat masa hendaklah kurang daripada masa tamat tempoh kunci. (Dengan mengandaikan bahawa masa tamat tempoh kunci automatik ialah 10 saat, masa tamat masa biasanya antara 5-50 milisaat. Mari kita anggap bahawa masa tamat masa ialah 50ms). Jika masa tamat, langkau nod induk dan cuba nod induk seterusnya secepat mungkin.
- 3. Pelanggan menggunakan masa semasa tolak masa mula untuk memperoleh kunci (iaitu masa yang direkodkan dalam langkah 1) untuk mendapatkan masa yang digunakan untuk memperoleh kunci. Kunci akan berjaya diperoleh jika dan hanya jika lebih daripada separuh (N/2 1, di sini 5/2 1 = 3 nod) nod induk Redis telah memperoleh kunci, dan masa penggunaan kurang daripada masa tamat tempoh kunci. (Seperti yang ditunjukkan dalam gambar di atas, 10s>30ms 40ms 50ms 4m0s 50ms)
- Jika kunci diperoleh, masa berkesan sebenar kunci berubah, dan masa yang digunakan untuk mendapatkan kunci perlu ditolak.
- Jika pemerolehan kunci gagal (kunci tidak diperoleh pada sekurang-kurangnya N/2 1 kejadian induk, atau masa pemerolehan kunci telah melebihi masa efektif), pelanggan mesti membuka kunci pada semua nod induk (walaupun jika beberapa Nod induk tidak berjaya dikunci sama sekali dan perlu dibuka untuk mengelakkan beberapa ikan daripada tergelincir melalui jaring).
Langkah yang dipermudahkan ialah:
- Minta kunci daripada 5 nod induk mengikut urutan
- Penghakiman berdasarkan tamat masa yang ditetapkan untuk melangkau nod induk?
- Jika lebih daripada atau sama dengan tiga nod berjaya dikunci, dan masa penggunaan kurang daripada tempoh sah kunci, ia boleh dianggap bahawa kunci itu berjaya.
- Jika memperoleh kunci gagal, buka kuncinya!
13 Jadual lompat Redis
- Jadual lompat ialah salah satu pelaksanaan asas bagi set zset yang dipesan
- Jadual langkau menyokong carian nod dengan purata O(logN) dan kerumitan O(N) kes terburuk, dan juga boleh memproses nod dalam kelompok melalui operasi berjujukan.
- Pelaksanaan jadual langkau terdiri daripada dua struktur: zskiplist dan zskiplistNode, di mana zskiplist digunakan untuk menyimpan maklumat jadual langkau (seperti nod pengepala, nod ekor, panjang) dan zskiplistNode digunakan untuk Mewakili nod jadual langkau.
- Senarai langkau adalah berdasarkan senarai terpaut, menambah indeks berbilang peringkat untuk meningkatkan kecekapan carian.
14 Bagaimana MySQL dan Redis memastikan konsistensi penulisan dua kali
- Cache tertunda pemadaman dua kali
- Padam mekanisme percubaan semula cache
- Baca biglog dan padam cache secara tak segerak
14.1 Menangguhkan pemadaman dua kali?
Apakah pemadaman berganda tertunda? Carta alir adalah seperti berikut:
Padam cache dahulu
kemudian kemas kini pangkalan data
Tidur sebentar (contohnya, 1 saat) dan padamkan cache sekali lagi.
Berapa lama biasanya masa untuk tidur seketika? Adakah mereka semua 1 saat?
Masa tidur ini = masa yang diperlukan untuk membaca data logik perniagaan ialah beberapa ratus milisaat. Untuk memastikan permintaan baca tamat, permintaan tulis boleh memadamkan data kotor cache yang mungkin dibawa oleh permintaan baca.
Penyelesaian ini tidak buruk Hanya semasa tempoh tidur (contohnya, hanya 1 saat), mungkin terdapat data yang kotor dan perniagaan umum akan menerimanya. Tetapi bagaimana jika Memadamkan cache gagal untuk kali kedua? Data cache dan pangkalan data mungkin masih tidak konsisten, bukan? Bagaimana pula dengan menetapkan masa tamat tempoh semula jadi untuk Kunci dan membiarkannya tamat tempoh secara automatik? Adakah perniagaan perlu menerima ketidakkonsistenan data dalam tempoh tamat tempoh? Atau adakah penyelesaian lain yang lebih baik?
14.2 Mekanisme percubaan semula pemadaman cache
Disebabkan oleh pemadaman dua kali tertunda, langkah kedua memadam cache mungkin gagal, mengakibatkan ketidakkonsistenan data. Anda boleh menggunakan penyelesaian ini untuk mengoptimumkan: jika pemadaman gagal, padamkannya beberapa kali lagi untuk memastikan pemadaman cache berjaya~ Jadi anda boleh memperkenalkan mekanisme percubaan semula cache pemadaman
Tulis permintaan untuk mengemas kini pangkalan data
Pemadaman cache gagal atas sebab tertentu
Letakkan kunci yang gagal dipadamkan ke dalam baris gilir mesej
Gunakan mesej daripada baris gilir mesej dan dapatkan kunci untuk dipadamkan
Cuba semula padamkan operasi cache
14.3 Membaca biglog memadamkan cache secara tidak segerak
Mekanisme cache pemadaman cuba semula tidak mengapa, tetapi ia akan menyebabkan banyak pencerobohan kod perniagaan. Malah, ia juga boleh dioptimumkan seperti ini: menghapuskan kunci secara tidak segerak melalui binlog pangkalan data.
Ambil mysql sebagai contoh
- Anda boleh menggunakan saluran Alibaba untuk mengumpul log binlog dan menghantarnya ke baris gilir MQ
- Kemudian sahkan dan proses mesej kemas kini ini melalui mekanisme ACK, padamkan cache dan pastikan ketekalan cache data
15 Mengapakah Redis bertukar kepada berbilang benang selepas 6.0?
- Sebelum Redis 6.0, apabila Redis memproses permintaan pelanggan, termasuk soket membaca, menghurai, melaksanakan, menulis soket, dsb., semuanya diproses oleh urutan utama bersiri. dipanggil "benang tunggal".
- Mengapa anda tidak menggunakan multi-threading sebelum Redis 6.0? Apabila menggunakan Redis, hampir tiada situasi di mana CPU menjadi hambatan terutamanya oleh memori dan rangkaian. Sebagai contoh, pada sistem Linux biasa, Redis boleh mengendalikan 1 juta permintaan sesaat dengan menggunakan saluran paip, jadi jika aplikasi terutamanya menggunakan arahan O(N) atau O(log(N)), ia tidak akan mengambil banyak CPU.
Penggunaan redis berbilang benang tidak bermakna ia meninggalkan sepenuhnya benang tunggal Redis masih menggunakan model berbenang tunggal untuk memproses permintaan pelanggan Ia hanya menggunakan berbilang benang untuk mengendalikan pembacaan data dan penulisan dan penghuraian protokol Untuk melaksanakan arahan, ia masih menggunakan berulir Tunggal.
Tujuan ini adalah kerana kesesakan prestasi redis adalah IO rangkaian dan bukannya CPU Menggunakan multi-threading boleh meningkatkan kecekapan membaca dan menulis IO, dengan itu meningkatkan prestasi keseluruhan redis.
16 Mari kita bincangkan tentang mekanisme transaksi Redis
Redis melaksanakan mekanisme transaksi melalui satu set perintah seperti MULTI, EXEC dan WATCH. Urus niaga menyokong pelaksanaan berbilang arahan pada satu masa, dan semua arahan dalam urus niaga akan bersiri. Semasa proses pelaksanaan transaksi, arahan dalam baris gilir akan dilaksanakan secara bersiri mengikut tertib, dan permintaan arahan yang dikemukakan oleh pelanggan lain tidak akan dimasukkan ke dalam urutan perintah pelaksanaan transaksi.
Ringkasnya, transaksi Redis ialah pelaksanaan berurutan, sekali dan eksklusif bagi siri perintah dalam baris gilir.
Proses pelaksanaan transaksi Redis adalah seperti berikut:Mulakan transaksi (MULTI)
- Arahan perintah
- Laksanakan transaksi (EXEC), batalkan transaksi (BUANG)
17. Cara menangani konflik Hash dalam Redis
Redis ialah pangkalan data dalam memori K-V, yang menggunakan cincang global untuk menyimpan semua pasangan nilai kunci. Jadual cincang ini terdiri daripada berbilang baldi cincang Elemen entri dalam baldi cincang menyimpan kunci dan penunjuk nilai, di mana *kunci menunjuk ke kunci sebenar dan *nilai menunjuk kepada nilai sebenar .
Kelajuan carian jadual hash sangat pantas, agak serupa dengan HashMap dalam Java, yang membolehkan kami mencari pasangan nilai kunci dengan cepat dalam kerumitan masa O(1). Mula-mula, hitung nilai cincang melalui kunci, cari lokasi baldi cincang yang sepadan, kemudian cari entri dan cari data yang sepadan dalam entri.
Apakah perlanggaran cincang?
Konflik cincang: Nilai cincang yang sama dikira melalui kunci yang berbeza, menghasilkan baldi cincang yang sama.
Untuk menyelesaikan konflik cincang, Redis menggunakan pencincangan rantai. Pencincangan berantai bermakna berbilang elemen dalam baldi cincang yang sama disimpan dalam senarai terpaut, dan ia disambungkan secara bergilir menggunakan penunjuk.
Sesetengah pembaca mungkin masih mempunyai soalan: elemen pada rantaian konflik cincang hanya boleh dicari satu demi satu melalui penunjuk dan kemudian dikendalikan. Apabila banyak data dimasukkan ke dalam jadual cincang, lebih banyak konflik akan berlaku, lebih lama senarai pautan konflik dan kecekapan pertanyaan akan dikurangkan.
Untuk mengekalkan kecekapan, Redis akan melakukan operasi rehash pada jadual cincang, yang bermaksud menambah baldi cincang dan mengurangkan konflik. Untuk menjadikan rehash lebih cekap, Redis juga menggunakan dua jadual cincang global secara lalai, satu untuk kegunaan semasa, dipanggil jadual cincang utama, dan satu untuk pengembangan, dipanggil jadual cincang sandaran .
18 Semasa penjanaan RDB, bolehkah Redis mengendalikan permintaan tulis pada masa yang sama?
Ya, Redis menyediakan dua arahan untuk menjana RDB iaitu simpan dan bgsave.
- Jika ia adalah arahan simpan, ia akan menyekat kerana ia dilaksanakan oleh utas utama.
- Jika ia adalah arahan bgsave, ia menghentikan proses kanak-kanak untuk menulis fail RDB Kegigihan syot kilat dikendalikan sepenuhnya oleh proses anak, dan proses induk boleh terus memproses permintaan pelanggan.
19. Apakah protokol yang digunakan di bahagian bawah Redis
RESP, nama penuh bahasa Inggeris ialah Redis Serialization Protocol, iaitu protokol bersiri yang direka khas untuk redis ini sebenarnya Ia telah pun muncul dalam redis versi 1.2, tetapi hanya dalam redis2.0 yang akhirnya menjadi standard protokol komunikasi redis.
RESP terutamanya mempunyai kelebihan pelaksanaan yang mudah, kelajuan penghuraian yang pantas dan kebolehbacaan yang baik.
20. Bloom Filter
Untuk menangani masalah cache penetrasi, kita boleh menggunakan Bloom Filter. Apakah penapis mekar?
Penapis Bloom ialah struktur data yang menggunakan ruang yang sangat sedikit. Ia terdiri daripada vektor perduaan panjang dan satu set fungsi pemetaan Hash Ia digunakan untuk mendapatkan semula sama ada elemen berada dalam satu set, ruang Kecekapan dan masa pertanyaan adalah lebih baik daripada algoritma umum Kelemahannya ialah terdapat kadar salah pengecaman dan kesukaran pemadaman tertentu.
Apakah prinsip penapis Bloom? Andaikan kita mempunyai set A, dan terdapat n elemen dalam A. Menggunakan fungsi k pencincangan , setiap elemen dalam A dipetakan ke kedudukan berbeza dalam tatasusunan B dengan panjang bit, dan nombor perduaan pada kedudukan ini Kedua-duanya ditetapkan kepada 1 . Jika elemen yang hendak disemak dipetakan oleh fungsi cincang k ini dan didapati bahawa nombor perduaan dalam kedudukan knya semuanya 1, elemen ini berkemungkinan tergolong dalam set A. Jika tidak, Mesti tidak tergolong dalam set A.
Mari kita lihat contoh mudah bahawa set A mempunyai 3 elemen, iaitu {d1, d2, d3}. Terdapat 1 fungsi hash iaitu Hash1. Sekarang petakan setiap elemen A kepada tatasusunan B dengan panjang 16 bit.
Kami kini memetakan d1. Dengan mengandaikan Hash1 (d1) = 2, kami menukar grid dengan subskrip 2 dalam tatasusunan B kepada 1, seperti berikut:
Kami kini memetakan d2, dengan mengandaikan Hash1(d2) = 5, kami juga menukar grid dengan subskrip 5 dalam tatasusunan B kepada 1, seperti berikut:
Kemudian kami memetakan d3 juga dengan mengandaikan bahawa Hash1 (d3) juga sama dengan 2, ia juga menetapkan subskrip kepada 2 Grid markah 1:
<.>Oleh itu, kita perlu mengesahkan sama ada sesuatu elemen dn berada dalam set A. Kita hanya perlu mengira subskrip indeks yang diperolehi oleh Hash1 (dn) Selagi ia adalah 0, ia bermakna elemen ini tidak dalam set A Jika Subskrip indeks ialah 1? Kemudian elemen mungkin menjadi elemen dalam A. Kerana anda lihat, nilai subskrip yang diperoleh oleh d1 dan d3 mungkin kedua-duanya adalah 1, atau ia mungkin dipetakan oleh nombor lain Penapis Bloom mempunyai kelemahan ini: akan terdapat cincangan Palsu. positif yang disebabkan oleh perlanggaran , terdapat ralat dalam penghakiman.
Bagaimana untuk mengurangkan ralat ini?
- Bina lebih banyak pemetaan fungsi cincang untuk mengurangkan kebarangkalian perlanggaran cincang
- Pada masa yang sama, meningkatkan panjang bit tatasusunan B boleh meningkatkan julat data yang dijana oleh cincang fungsi, dan juga Ia boleh mengurangkan kebarangkalian perlanggaran cincang
Kami menambah satu lagi fungsi Hash2Peta cincang, dengan andaian Hash2(d1)=6, Hash2(d3)=8, mereka tidak Tiada konflik, seperti berikut:
Walaupun terdapat ralat, kami dapati bahawa penapis Bloom tidak menyimpan data lengkap , ia hanya Kedudukan dikira menggunakan satu siri fungsi peta cincang dan kemudian vektor binari diisi. Jika bilangan besar, penapis Bloom boleh menjimatkan banyak ruang storan melalui kadar ralat yang sangat kecil, yang agak menjimatkan kos.
Pada masa ini terdapat perpustakaan sumber terbuka yang melaksanakan penapis Bloom sewajarnya, seperti Pustaka kelas Guava Google, perpustakaan kelas Algebird Twitter, yang boleh diakses dengan mudah, atau berdasarkan perpustakaan Redis sendiri Ia adalah juga mungkin untuk Bitmaps melaksanakan reka bentuknya sendiri.
Untuk lebih banyak pengetahuan berkaitan pengaturcaraan, sila lawati: Video Pengaturcaraan! !
Atas ialah kandungan terperinci Ringkasan dan perkongsian 20 soalan wawancara klasik tentang Redis (dengan analisis jawapan). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!