Rumah >pangkalan data >Redis >Apakah pelbagai jenis data dan pengetahuan berkaitan kluster dalam redis?

Apakah pelbagai jenis data dan pengetahuan berkaitan kluster dalam redis?

王林
王林ke hadapan
2023-05-26 21:40:541032semak imbas

Apakah pelbagai jenis data dan pengetahuan berkaitan kluster dalam redis?

Pelbagai jenis data

rentetan Jenisnya ringkas dan mudah, serta menyokong pra-peruntukan ruang, iaitu, lebih banyak ruang akan diperuntukkan setiap kali, jadi rentetan Jika ia menjadi lebih lama lagi, tidak perlu memohon ruang tambahan Sudah tentu, premis adalah bahawa ruang yang tinggal adalah mencukupi. [Cadangan berkaitan: Tutorial video Redis] Jenis

Senarai boleh melaksanakan baris gilir mesej yang mudah, tetapi sila ambil perhatian bahawa mungkin terdapat kehilangan mesej dan ia tidak menyokong mod ACK.

Hash Jadual adalah sedikit seperti pangkalan data hubungan, tetapi apabila jadual hash menjadi lebih besar dan lebih besar, sila berhati-hati untuk mengelakkan menggunakan pernyataan seperti hgetall, kerana meminta sejumlah besar data akan menyebabkan redis Block, jadi saudara di belakang perlu menunggu.

set Jenis koleksi boleh membantu anda melakukan beberapa statistik Contohnya, jika anda ingin mengira pengguna aktif pada hari tertentu, anda boleh terus memasukkan ID pengguna ke dalam koleksi. Koleksi ini menyokong beberapa operasi yang hebat, seperti sdiff Anda boleh mendapatkan perbezaan antara set, dan sunion boleh mendapatkan penyatuan antara set Ia mempunyai banyak fungsi, tetapi anda mesti berhati-hati kerana fungsi hebat datang pada harga dan sumber IO, yang boleh menyebabkan Penyekatan, jadi operasi antara set besar harus digunakan dengan berhati-hati

zset boleh dikatakan sebagai bintang yang paling terang diisih, terdapat banyak senario aplikasi, seperti Suka pengguna xx pertama, baris gilir kelewatan, dsb.

bitmap Kelebihan bitmap ialah menjimatkan ruang, terutamanya apabila melakukan beberapa statistik, seperti mengira bilangan pengguna yang telah log masuk pada hari tertentu dan sama ada pengguna tertentu telah melog masuk. Jika anda tidak menggunakan bitmap, anda mungkin terfikir untuk menggunakan set.

SADD day 1234//签到就添加到集合
SISMEMBER day 1234//判断1234是否签到
SCARD day   //有多少个签到的

set adalah memuaskan dari segi fungsi, tetapi berbanding dengan bitmap, set menggunakan lebih banyak ruang storan Lapisan bawah set terutamanya terdiri daripada koleksi integer atau hashtable hanya boleh digunakan apabila jumlah data sangat kecil. Ia hanya boleh digunakan, biasanya kurang daripada 512 elemen, dan semua elemen mestilah integer Untuk set, data koleksi integer adalah lebih padat, dan pertanyaan itu hanya boleh menjadi carian binari kerumitan masa ialah Ia adalah O(logN), tetapi jadual cincang di sini adalah sama dengan cincang dalam lima jenis data utama redis, kecuali tidak ada nilainya tiada konflik kerana ini adalah satu set , tetapi isu yang berkaitan dengan pengulangan perlu dipertimbangkan. Ok, ia agak jauh. Kita bercakap tentang masalah daftar masuk pengguna Apabila terdapat ramai pengguna, hashtable pasti akan digunakan dalam kes hashtable, sebenarnya, setiap elemen adalah struktur dictEntry >

typedef struct dictEntry {
    // 键
    void *key;
    // 值
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
    } v;
    // 指向下个哈希表节点,形成链表
    struct dictEntry *next;

} dictEntry;

Daripada Apa yang boleh kita lihat dalam struktur ini? Pertama sekali, walaupun nilai kesatuan (tiada nilai) dan seterusnya (tiada konflik) adalah kosong, struktur itu sendiri memerlukan ruang dan kunci Ruang yang diduduki ini adalah nyata, dan jika anda menggunakan bitmap, satu bit sudah cukup. Ia mewakili nombor dan menjimatkan ruang Mari kita lihat cara menyediakan dan mengira bitmap.

SETBIT day 1234 1//签到
GETBIT day 1234//判断1234是否签到
BITCOUNT day//有多少个签到的

bf Ini adalah penapis bloom RedisBloom yang disokong selepas redis4.0, tetapi modul yang sepadan perlu dimuatkan secara berasingan, kami juga boleh melaksanakan bloom kami sendiri berdasarkan perkara di atas Penapis bitmap, tetapi memandangkan redis sudah menyokongnya, RedisBloom boleh mengurangkan masa pembangunan kita. Apa yang dilakukan oleh penapis Bloom. Mari kita lihat penggunaan RedisBloom yang berkaitan.

# 可以通过docker的方式快速拉取镜像来玩耍
docker run -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest
docker exec -it redis-redisbloom bash
redis-cli
# 相关操作
bf.reserve sign 0.001 10000
bf.add sign 99 //99这个用户加入
bf.add exists 99//判断99这个用户是否存在

Oleh kerana penapis Bloom mempunyai salah sangka, semua bf menyokong kadar salah sangka tersuai, 0.001 mewakili kadar salah sangka, 10000 mewakili bilangan elemen yang penapis Bloom boleh simpan, apabila storan sebenar Apabila bilangan elemen melebihi ini nilai, kadar positif palsu akan meningkat.

HyperLogLog boleh digunakan untuk statistik kelebihannya ialah ia memerlukan ruang storan yang sangat sedikit. Ia hanya memerlukan 12KB memori untuk mengira 2^64 elemen ? Sebenarnya, ia terutamanya mengenai statistik kardinaliti, seperti UV Dari segi fungsi, UV boleh disimpan menggunakan set atau cincang, tetapi kelemahannya ialah ia menggunakan storan dan boleh menjadi kunci besar jika anda ingin menjimatkan ruang juga boleh digunakan, 12KB Peta bit spatial hanya boleh mengira 12*1024*8=98304 elemen, manakala HyperLogLog boleh mengira 2^64 elemen Walau bagaimanapun, teknologi yang berkuasa itu sebenarnya mempunyai ralat berdasarkan kebarangkalian, dan ralat standard pengiraan Kadarnya ialah 0.81%. Dalam senario di mana data besar dikira dan keperluan ketepatan tidak begitu tinggi, HyperLogLog masih sangat baik untuk menjimatkan ruang.

PFADD uv 1 2 3 //1 2 3是活跃用户
PFCOUNT uv //统计

GEO 是可以应用在地理位置的业务上,比如微信附近的人或者附近的车辆等等,先来看一下如果没有GEO 这种数据结构,你如何知道你附近的人?首先得上报自己的地理位置信息吧,比如经度 116.397128,纬度 39.916527,此时可以用 string、hash 数据类型存储,但是如果要查找你附近的人,string 和 hash 这种就无能为例了,你不可能每次都要遍历全部的数据来判断,这样太耗时了,当然你也不可能通过 zset 这种数据结构来把经纬度信息当成权重,但是如果我们能把经纬度信息通过某种方式转换成一个数字,然后当成权重好像也可以,这时我们只需通过zrangebyscore key v1 v2也可以找到附近的人。真的需要这么麻烦吗?于是 GEO 出现了,GEO 转换经纬度为数字的方法是“二分区间,区间编码”,这是什么意思呢?以经度为例,它的范围是[-180,180],如果要采用3位编码值,那么就是需要二分3次,二分后落在左边的用0表示,右边的用1表示,以经度是121.48941 来说,第一次是在[0,180]这个区间,因此记1,第二次是在[90,180],因此再记1,第三次是在[90,135],因此记0。纬度也是同样的逻辑,假设此时对应的纬度编码后是010,最后把经纬度合并在一起,需要注意的是经度的每个值在偶数位,纬度的每个值在奇数位。

1 1 0   //经度
 0 1 0  //纬度
------------
101100 //经纬度对应的数值

原理是这样,我们再来看看 redis 如何使用 GEO:

GEOADD location 112.123456 41.112345 99 //上报用户99的地理位置信息
GEORADIUS location  112.123456 41.112345 1 km ASC COUNT 10 //获取附近1KM的人

搞懂集群

生产环境用单实例 redis 的应该比较少,单实例的风险在于:

  • 单点故障即服务故障,没有backup

  • 单实例压力大,又要提供读,又要提供写

于是我们首先想到的就是经典的主从模式,而且往往是一主多从,这是因为大部分应用都是读多写少的情况,我们的主负责更新,从负责提供读,就算我们的主宕机了,我们也可以选择一个从来充当主,这样整个应用依然可以提供服务。

复制过程的细节

当一个 redis 实例首次成为某个主的从的时候,这时主得把数据发给它,也就是 rdb 文件,这个过程 master 是要 fork 一个子进程来处理的,这个子进程会执行 bgsave 把当前的数据重新保存一下,然后准备发给新来的从,bgsave 的本质是读取当前内存中的数据然后保存到 rdb 文件中,这个过程涉及大量的 IO,如果直接在主进程中来处理的话,大概率会阻塞正常的请求,因此使用个子进程是个明智的选择。

那 fork 的子进程在 bgsave 过程中如果有新的变更请求会怎么办?

严格来说子进程出来的一瞬间,要保存的数据应该就是当时那个点的快照数据,所以是直接把当时的内存再复制一份吗?不复制的话,如果这期间又有变更改怎么办?其实这要说到写实复制(COW)机制,首先从表象上来看内存是一整块空间,其实这不太好维护,因此操作系统会把内存分成一小块一小块的,也就是内存分页管理,一页的大小一般是4K、8K或者16K等等,redis 的数据都是分布在这些页面上的,出于效率问题,fork 出来的子进程是和主进程是共享同一块的内存的,并不会复制内存,如果这期间主进程有数据变更,那么为了区分,这时最快捷的做法就是把对应的数据页重新复制一下,然后主的变更就在这个新的数据页上修改,并不会修改来的数据页,这样就保证了子进程处理的还是当时的快照。

以上说的变更是从快照的角度来考虑的,如果从数据的一致性来说,当快照的 rdb 被从库应用之后,这期间的变更该如何同步给从库?答案是缓冲区,这个缓冲区叫做 replication buffer,主库在收到需要同步的命令之后,会把期间的变更都先保存在这个缓冲区中,这样在把 rdb 发给从库之后,紧接着会再把 replication buffer 的数据也发给从库,最终主从就保持了一致。

replication buffer不是万能的补给剂

我们来看看 replication buffer 持续写入的时间有多长。

  • 我们知道主从同步的时候,主库会执行 fork 来让子进程完成相应地工作,因此子进程从开始执行 bgsave 到执行完毕这期间,变更是要写入 replication buffer 的。

  • rdb 生成好之后,需要把它发送给从库,这个网络传输是不是也需要耗点时间,这期间也是要写入 replication buffer 的。

  • Selepas menerima rdb, perpustakaan hamba perlu menggunakan rdb pada memori Dalam tempoh ini, perpustakaan hamba disekat dan tidak dapat menyediakan perkhidmatan, jadi penimbal replikasi juga perlu ditulis semasa. tempoh ini.

Memandangkan penimbal replikasi adalah penimbal, saiznya terhad Jika salah satu daripada tiga langkah di atas mengambil masa yang lama, ia akan menyebabkan penimbal replikasi berkembang dengan cepat (dengan syarat Terdapat. adalah penulisan biasa), apabila penimbal replikasi melebihi had, sambungan antara perpustakaan utama dan perpustakaan hamba akan diputuskan sambungan Selepas pemotongan, jika perpustakaan hamba disambungkan semula, replikasi akan dimulakan semula, dan kemudian proses panjang yang sama. Oleh itu, saiz penimbal replikasi masih sangat kritikal Secara amnya, ia perlu dinilai secara menyeluruh berdasarkan faktor seperti kelajuan menulis, jumlah penulisan sesaat, dan kelajuan penghantaran rangkaian.

Apakah yang perlu saya lakukan jika rangkaian pangkalan data hamba tidak baik dan pangkalan data induk terputus sambungan?

Biasanya, selagi sambungan antara tuan dan hamba diwujudkan, perubahan seterusnya kepada pangkalan data induk boleh dihantar terus ke pangkalan data hamba untuk main balik terus daripada pangkalan data hamba, tetapi kami tidak dapat menjamin bahawa persekitaran rangkaian adalah 100% lancar, jadi isu pemotongan antara pangkalan data hamba dan pangkalan data induk juga mesti dipertimbangkan.

Seharusnya sebelum redis2.8, selagi pangkalan data hamba diputuskan, walaupun hanya untuk masa yang singkat, apabila pangkalan data hamba disambungkan semula kemudian, pangkalan data utama secara langsung akan berfungsi penuh penyegerakan tanpa berfikir. Dalam versi 2.8 dan lebih baru, replikasi tambahan disokong Prinsip replikasi tambahan ialah mesti ada penimbal untuk menyimpan rekod perubahan ini dipanggil repl_backlog_buffer Penimbal ini secara logiknya ditimpa dari awal apabila penuh, jadi ada juga had saiz. Apabila perpustakaan hamba menyambung semula, perpustakaan hamba akan memberitahu perpustakaan utama: "Saya telah menyalin ke lokasi xx Selepas perpustakaan utama menerima mesej daripada perpustakaan hamba, ia mula menyemak sama ada data di lokasi xx masih." dalam repl_backlog_buffer Jika ya, , hantarkan sahaja data selepas xx ke pustaka hamba Jika tiada, tiada apa yang boleh anda lakukan dan anda hanya boleh melakukan penyegerakan penuh.

Memerlukan pengurus

Dalam mod tuan-hamba, jika perpustakaan induk ditutup, kita boleh menaik taraf perpustakaan hamba kepada perpustakaan induk, tetapi proses ini adalah manual Ya, operasi manual tidak boleh meminimumkan kerugian Satu set pengurusan automatik dan mekanisme pilihan raya masih diperlukan. Ia hanya bertanggungjawab untuk menguruskan semua kejadian redis Pengawal akan berkomunikasi dengan setiap redis pada selang masa yang tetap (operasi ping setiap kejadian redis boleh menyatakan kedudukannya selagi ia bertindak balas dalam masa yang ditetapkan). Sudah tentu, Sentinel itu sendiri mungkin terputus atau rangkaian tidak tersedia, jadi secara amnya Sentinel juga akan membina gugusan Sentinel Sebaik-baiknya mempunyai bilangan gugusan ganjil, seperti 3 atau 5. Tujuan nombor ganjil ialah. terutamanya untuk pilihan raya (Minoriti mematuhi majoriti). Apabila sentinel gagal menerima pong tepat pada masanya selepas memulakan ping, tika redis akan ditandakan di luar talian Pada masa ini, sentinel lain juga akan menentukan semasa Adakah sentinel ini benar-benar di luar talian? Apabila kebanyakan pengawal menentukan bahawa redis ini berada di luar talian, mereka akan menendangnya keluar dari kluster Jika ia adalah pangkalan data hamba yang berada di luar talian, maka tidak mengapa pangkalan data perlu mencetuskan pilihan raya, pilihan raya bukan pilihan raya buta Ia mestilah memilih yang paling sesuai untuk dijadikan pangkalan data utama yang baharu. Perpustakaan yang paling sesuai untuk dijadikan perpustakaan utama biasanya ditentukan mengikut keutamaan berikut:

    Berat Setiap perpustakaan hamba sebenarnya boleh menetapkan pemberat dengan kehendak yang lebih tinggi Keutamaan diberikan kepada kemajuan penyalinan
  • Kemajuan penyalinan dari setiap pangkalan data hamba mungkin berbeza yang mempunyai jurang data terkecil antara pangkalan data semasa dan pangkalan data utama lebih disukai
  • ID perkhidmatan Sebenarnya, setiap instance redis mempunyai ID sendiri Jika syarat di atas adalah sama, maka perpustakaan dengan ID terkecil akan dipilih untuk dijadikan perpustakaan utama
Skala mendatar yang lebih kukuh

Mod tuan-hamba menyelesaikan masalah satu titik kegagalan Pada masa yang sama, bacaan -teknologi pemisahan tulis menjadikan sokongan aplikasi lebih kuat Mod pengawal secara automatik boleh mengawasi kelompok dan merealisasikan pemilihan automatik, keupayaan untuk menghapuskan nod yang rosak.

Biasanya, apabila tekanan membaca meningkat, kita boleh menambah perpustakaan hamba untuk mengurangkannya. Tetapi bagaimana jika tekanan terhadap perpustakaan utama sangat tinggi? Ini membawa kita kepada teknologi

sharding

yang akan kita bincangkan seterusnya. Kita hanya perlu memotong perpustakaan utama kepada beberapa bahagian dan menggunakannya ke mesin yang berbeza. Sharding ini ialah konsep slot dalam redis, redis akan membahagikannya kepada 0~16383 secara lalai, iaitu sejumlah 16384 slot, dan kemudian membahagikan slot ini sama rata ke dalam setiap nod sharding memainkan peranan mengimbangi beban. Slot yang mana setiap kunci harus diperuntukkan. Perkara utama ialah menggunakan CRC16 dahulu untuk mendapatkan nombor 16-bit, dan kemudian menggunakan modulo 16384 nombor ini:

crc16(key)%16384

然后客户端会缓存槽信息,这样每当一个 key 到来时,只要通过计算就知道该发给哪个实例来处理来了。但是客户端缓存的槽信息并不是一成不变的,比如在增加实例的时候,这时候会导致重新分片,那么原来客户端缓存的信息就会不准确,一般这时候会发生两个常见的错误,严格来说也不是错误,更像一种信息,一个叫做MOVED,一个叫做ASK。moved的意思就说,原来是实例A负责的数据,现在被迁移到了实例B,MOVED 代表的是迁移完成的,但是 ASK 代表的是正在迁移过程中,比如原来是实例A负责的部分数据,现在被迁移到了实例B,剩下的还在等待迁移中,当数据迁移完毕之后 ASK 就会变成 MOVED,然后客户端收到 MOVED 信息之后就会再次更新下本地缓存,这样下次就不会出现这两个错误了。

Atas ialah kandungan terperinci Apakah pelbagai jenis data dan pengetahuan berkaitan kluster dalam redis?. 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