Artikel ini membawakan anda pengetahuan yang berkaitan tentang Redis, yang terutamanya memperkenalkan isu berkaitan kegigihan Ia boleh memperkenalkan mekanisme dan prinsip kegigihan redis dari beberapa aspek .
Pembelajaran yang disyorkan: Tutorial Redis
Artikel ini akan memperkenalkan mekanisme kegigihan Redis dari aspek berikut:
Artikel ini memperkenalkan dua kaedah kegigihan Redis secara terperinci secara keseluruhan, termasuk prinsip kerja, proses kegigihan dan strategi praktikal, serta beberapa pengetahuan teori di belakangnya. Artikel sebelumnya hanya memperkenalkan kegigihan RDB, tetapi kegigihan Redis adalah keseluruhan dan tidak boleh diperkenalkan secara berasingan, jadi ia telah disusun semula.
Redis ialah pangkalan data dalam memori, dan semua data akan disimpan dalam memori Berbanding dengan pangkalan data hubungan tradisional seperti MySQL, Oracle dan SqlServer, yang menyimpan data secara langsung ke cakera keras, Redis. membaca dan menulis Sangat cekap. Walau bagaimanapun, penjimatan dalam ingatan juga mempunyai kelemahan besar Setelah kuasa terputus atau komputer terputus, semua kandungan dalam pangkalan data memori akan hilang. Untuk mengimbangi kekurangan ini, Redis menyediakan fungsi menyimpan data memori kepada fail cakera keras dan memulihkan data melalui fail sandaran, yang merupakan mekanisme kegigihan Redis.
Redis menyokong dua kaedah kegigihan: petikan RDB dan AOF.
Petikan RDB Dalam perkataan rasmi: Penyelesaian kegigihan RDB ialah petikan titik ke masa yang dijana daripada set data anda pada selang masa yang ditentukan. Ia menyimpan petikan memori semua objek data dalam pangkalan data Redis pada masa tertentu dalam fail binari termampat, yang boleh digunakan untuk sandaran, pemindahan dan pemulihan data Redis. Setakat ini, ia masih merupakan penyelesaian sokongan lalai rasmi.
Memandangkan RDB ialah petikan titik dalam masa bagi set data dalam Redis, mari kita fahami secara ringkas bagaimana objek data dalam Redis disimpan dan disusun dalam ingatan.
Secara lalai, terdapat 16 pangkalan data dalam Redis, bernombor dari 0-15 Setiap pangkalan data Redis diwakili oleh objek redisDb
dan redisDb
menggunakan hashtable untuk menyimpan objek K-V. Untuk memudahkan pemahaman, saya mengambil salah satu dbs sebagai contoh untuk melukis gambar rajah skema struktur penyimpanan data dalaman Redis. Gambar titik dalam masa ialah status setiap objek data dalam setiap DB dalam Redis pada masa tertentu Andaikan semua objek data tidak akan berubah pada masa ini di atas Berdasarkan perhubungan struktur data dalam fail, objek data ini dibaca dan ditulis ke fail untuk mencapai kegigihan Redis. Kemudian, apabila Redis dimulakan semula, kandungan fail ini dibaca mengikut peraturan, dan kemudian ditulis ke memori Redis untuk memulihkan kepada keadaan kegigihan.
Sudah tentu, premis ini benar apabila andaian kami di atas adalah benar, jika tidak, kami tidak akan mempunyai cara untuk bermula dalam menghadapi set data yang berubah sepanjang masa. Kami tahu bahawa pemprosesan arahan klien dalam Redis ialah model berbenang tunggal Jika kegigihan diproses sebagai arahan, set data pasti akan berada dalam keadaan statik. Di samping itu, proses anak yang dicipta oleh fungsi fork() yang disediakan oleh sistem pengendalian boleh mendapatkan data memori yang sama seperti proses induk, yang bersamaan dengan mendapatkan salinan data memori selepas garpu selesai, apakah yang perlu; proses ibu bapa lakukan, dan kerja-kerja berterusan negeri diserahkan sahaja kepada proses anak.
Jelas sekali, situasi pertama tidak digalakkan untuk membuat sandaran berterusan akan menyebabkan perkhidmatan Redis tidak tersedia untuk jangka masa yang singkat, yang tidak boleh diterima untuk sistem HA tinggi. Oleh itu, kaedah kedua ialah kaedah praktikal utama kegigihan RDB. Memandangkan data proses induk terus berubah selepas menghentikan proses anak, dan proses anak tidak disegerakkan dengan proses induk, kegigihan RDB tidak dapat menjamin prestasi masa nyata terputus bekalan elektrik atau masa mati selepas kegigihan RDB selesai kehilangan beberapa data; Kekerapan menentukan jumlah data yang hilang. Meningkatkan kekerapan sandaran bermakna proses fork menggunakan lebih banyak sumber CPU dan juga akan membawa kepada I/O cakera yang lebih besar.
Terdapat dua kaedah untuk melengkapkan kegigihan RDB dalam Redis: rdbSave dan rdbSaveBackground (dalam fail kod sumber rdb.c. Mari kita bincangkan secara ringkas tentang perbezaan antara keduanya:
rdbSave: Ia dilaksanakan secara serentak, dan proses kegigihan akan dimulakan serta-merta selepas kaedah dipanggil. Memandangkan Redis ialah model berutas tunggal, ia akan disekat semasa proses kegigihan dan Redis tidak boleh menyediakan perkhidmatan luaran
rdbSaveBackground: dilaksanakan di latar belakang (tak segerak), dan ini kaedah akan menghentikan proses anak Proses kegigihan sebenar dilaksanakan dalam proses anak (memanggil rdbSave), dan proses utama akan terus menyediakan perkhidmatan
Pencetusan kegigihan RDB tidak dapat dielakkan daripada dua kaedah di atas Kaedah pencetus terbahagi kepada manual dan automatik. Pencetusan manual mudah difahami Ini bermakna kami memulakan arahan sandaran kegigihan secara manual ke pelayan Redis melalui klien Redis, dan kemudian pelayan Redis mula melaksanakan proses kegigihan Arahan di sini termasuk simpan dan bgsave. Pencetusan automatik ialah proses kegigihan yang dicetuskan Redis secara automatik apabila syarat pratetap dipenuhi berdasarkan keperluan pengendaliannya sendiri Senario yang dicetuskan secara automatik adalah seperti berikut (dipetik daripada artikel ini):
serverCron The. save m n
peraturan konfigurasi dicetuskan secara automatik;
Apabila nod hamba disalin sepenuhnya, nod induk menghantar fail rdb ke nod hamba untuk melengkapkan operasi penyalinan, dan nod induk akan mula bgsave;
Apabila melaksanakan perintah debug reload
untuk memuatkan semula; arahan shutdown dilaksanakan, bgsave secara automatik dilaksanakan;
Menggabungkan kod sumber dan artikel rujukan, saya telah mengatur proses kegigihan RDB untuk membantu semua orang memahami keseluruhannya, dan kemudian menerangkannya dalam beberapa butiran.
Daripada rajah di atas kita boleh tahu:Kegigihan RDB yang dicetuskan secara automatik ialah strategi kegigihan yang dilaksanakan dalam sub-proses melalui rdbSaveBackground;
Pencetusan manual dicetuskan oleh arahan klien, termasuk perintah save dan bgsave Arahan save diselesaikan dengan memanggil kaedahsimpan peraturan dan semakanrdbSave
Saya mengekstraknya daripada kod dan melihatnya dalam bahasa Cina dan Inggeris:
sepadan, parameter simpan ialah strategi pencetus untuk Redis mencetuskan sandaran automatik,
ialah masa statistik (unit: saat) dan ialah bilangan penulisan yang berlaku dalam masa statistik. redisServer
bermaksud: n menulis dalam m saat akan mencetuskan syot kilat, iaitu sandaran. Berbilang kumpulan parameter simpan boleh dikonfigurasikan untuk memenuhi keperluan sandaran di bawah keadaan yang berbeza. Jika anda perlu mematikan dasar sandaran automatik RDB, anda boleh menggunakan
struct redisServer { /* 省略其他字段 */ /* RDB persistence */ long long dirty; /* Changes to DB from the last save * 上次持久化后修改key的次数 */ struct saveparam *saveparams; /* Save points array for RDB, * 对应配置文件多个save参数 */ int saveparamslen; /* Number of saving points, * save参数的数量 */ time_t lastsave; /* Unix time of last successful save * 上次持久化时间*/ /* 省略其他字段 */ } /* 对应redis.conf中的save参数 */ struct saveparam { time_t seconds; /* 统计时间范围 */ int changes; /* 数据修改次数 */ };
saveparams
redis.conf
Kod pengesanan untuk peraturan simpan RDB adalah seperti berikut: seconds
changes
save m n
Jika tiada latar belakang RDB kegigihan atau replikasi AOF Semasa menulis proses, serverCron akan menilai sama ada operasi kegigihan perlu dilakukan berdasarkan konfigurasi dan status di atas Asas untuk penghakiman adalah sama ada lastsave dan dirty memenuhi salah satu syarat dalam tatasusunan saveparams. Jika syarat dipadankan, kaedah rdbSaveBackground dipanggil untuk melaksanakan proses kegigihan tak segerak. save ""
# 表示900秒(15分钟)内至少有1个key的值发生变化,则执行 save 900 1 # 表示300秒(5分钟)内至少有1个key的值发生变化,则执行 save 300 10 # 表示60秒(1分钟)内至少有10000个key的值发生变化,则执行 save 60 10000 # 该配置将会关闭RDB方式的持久化 save ""
rdbSaveBackground ialah kaedah tambahan untuk kegigihan RDB. . serverCron
int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { /* 省略其他逻辑 */ /* 如果用户请求进行AOF文件重写时,Redis正在执行RDB持久化,Redis会安排在RDB持久化完成后执行AOF文件重写, * 如果aof_rewrite_scheduled为true,说明需要执行用户的请求 */ /* Check if a background saving or AOF rewrite in progress terminated. */ if (hasActiveChildProcess() || ldbPendingChildren()) { run_with_period(1000) receiveChildInfo(); checkChildrenDone(); } else { /* 后台无 saving/rewrite 子进程才会进行,逐个检查每个save规则*/ for (j = 0; j = sp->changes && server.unixtime-server.lastsave > sp->seconds &&(server.unixtime-server.lastbgsave_try > CONFIG_BGSAVE_RETRY_DELAY || server.lastbgsave_status == C_OK)) { serverLog(LL_NOTICE,"%d changes in %d seconds. Saving...", sp->changes, (int)sp->seconds); rdbSaveInfo rsi, *rsiptr; rsiptr = rdbPopulateSaveInfo(&rsi); /* 执行bgsave过程 */ rdbSaveBackground(server.rdb_filename,rsiptr); break; } } /* 省略:Trigger an AOF rewrite if needed. */ } /* 省略其他逻辑 */ }
Jika pemanggil adalah proses ibu bapa, hentikan proses anak, simpan maklumat proses anak dan kembali terus.
Jika pemanggil ialah proses anak, panggil rdbSave untuk melaksanakan logik kegigihan RDB dan keluar dari proses anak selepas kegigihan selesai.
Redis的rdbSave函数是真正进行RDB持久化的函数,流程、细节贼多,整体流程可以总结为:创建并打开临时文件、Redis内存数据写入临时文件、临时文件写入磁盘、临时文件重命名为正式RDB文件、更新持久化状态信息(dirty、lastsave)。其中“Redis内存数据写入临时文件”最为核心和复杂,写入过程直接体现了RDB文件的文件格式,本着一图胜千言的理念,我按照源码流程绘制了下图。 补充说明一下,上图右下角“遍历当前数据库的键值对并写入”这个环节会根据不同类型的Redis数据类型及底层数据结构采用不同的格式写入到RDB文件中,不再展开了。我觉得大家对整个过程有个直观的理解就好,这对于我们理解Redis内部的运作机制大有裨益。
上一节我们知道RDB是一种时间点(point-to-time)快照,适合数据备份及灾难恢复,由于工作原理的“先天性缺陷”无法保证实时性持久化,这对于缓存丢失零容忍的系统来说是个硬伤,于是就有了AOF。
AOF是Append Only File的缩写,它是Redis的完全持久化策略,从1.1版本开始支持;这里的file存储的是引起Redis数据修改的命令集合(比如:set/hset/del等),这些集合按照Redis Server的处理顺序追加到文件中。当重启Redis时,Redis就可以从头读取AOF中的指令并重放,进而恢复关闭前的数据状态。
AOF持久化默认是关闭的,修改redis.conf以下信息并重启,即可开启AOF持久化功能。
# no-关闭,yes-开启,默认no appendonly yes appendfilename appendonly.aof
AOF本质是为了持久化,持久化对象是Redis内每一个key的状态,持久化的目的是为了在Reids发生故障重启后能够恢复至重启前或故障前的状态。相比于RDB,AOF采取的策略是按照执行顺序持久化每一条能够引起Redis中对象状态变更的命令,命令是有序的、有选择的。把aof文件转移至任何一台Redis Server,从头到尾按序重放这些命令即可恢复如初。举个例子:
首先执行指令set number 0
,然后随机调用incr number
、get number
各5次,最后再执行一次get number
,我们得到的结果肯定是5。
因为在这个过程中,能够引起number
状态变更的只有set/incr
类型的指令,并且它们执行的先后顺序是已知的,无论执行多少次get
都不会影响number
的状态。所以,保留所有set/incr
命令并持久化至aof文件即可。按照aof的设计原理,aof文件中的内容应该是这样的(这里是假设,实际为RESP协议):
set number 0 incr number incr number incr number incr number incr number
最本质的原理用“命令重放”四个字就可以概括。但是,考虑实际生产环境的复杂性及操作系统等方面的限制,Redis所要考虑的工作要比这个例子复杂的多:
Redis Server启动后,aof文件一直在追加命令,文件会越来越大。文件越大,Redis重启后恢复耗时越久;文件太大,转移工作就越难;不加管理,可能撑爆硬盘。很显然,需要在合适的时机对文件进行精简。例子中的5条incr指令很明显的可以替换为为一条set
命令,存在很大的压缩空间。
众所周知,文件I/O是操作系统性能的短板,为了提高效率,文件系统设计了一套复杂的缓存机制,Redis操作命令的追加操作只是把数据写入了缓冲区(aof_buf),从缓冲区到写入物理文件在性能与安全之间权衡会有不同的选择。
文件压缩即意味着重写,重写时即可依据已有的aof文件做命令整合,也可以先根据当前Redis内数据的状态做快照,再把存储快照过程中的新增的命令做追加。
aof备份后的文件是为了恢复数据,结合aof文件的格式、完整性等因素,Redis也要设计一套完整的方案做支持。
从流程上来看,AOF的工作原理可以概括为几个步骤:命令追加(append)、文件写入与同步(fsync)、文件重写(rewrite)、重启加载(load),接下来依次了解每个步骤的细节及背后的设计哲学。
命令追加
Apabila fungsi kegigihan AOF dihidupkan, selepas Redis melaksanakan arahan tulis, ia akan menambahkan arahan tulis yang dilaksanakan pada Penghujung penimbal AOF yang diselenggara oleh pelayan Redis. Terdapat hanya operasi tambah satu benang untuk fail AOF, dan tiada operasi yang rumit seperti mencari Tiada risiko kerosakan fail walaupun terdapat gangguan bekalan elektrik atau masa mati. Di samping itu, terdapat banyak faedah menggunakan protokol teks:
Protokol teks mempunyai keserasian yang baik
Protokol teks adalah milik pelanggan; perintah permintaan, bukan pemprosesan sekunder diperlukan, yang menjimatkan overhed pemprosesan semasa penyimpanan dan pemuatan;
Jenis penimbal AOF ialah struktur data yang direka secara bebas oleh Redis
Redis akan menggunakan kaedah yang berbeza (sds
Perlu diambil perhatian bahawa jika penulisan semula AOF sedang dijalankan apabila arahan dilampirkan, arahan ini juga akan dilampirkan pada penimbal tulis semula (catAppendOnlyGenericCommand
). catAppendOnlyExpireAtCommand
aof_rewrite_buffer
Penulisan dan penyegerakan fail AOF tidak boleh dipisahkan daripada sokongan sistem pengendalian Sebelum memulakan pengenalan, kita perlu menambah sedikit pengetahuan tentang Linux I/O penampan. Prestasi I/O cakera keras adalah lemah, dan kelajuan membaca dan menulis fail jauh lebih rendah daripada kelajuan pemprosesan CPU Jika anda menunggu data ditulis ke cakera keras setiap kali anda menulis fail, ia akan merendahkan prestasi keseluruhan sistem pengendalian. Untuk menyelesaikan masalah ini, sistem pengendalian menyediakan mekanisme tulis tertunda untuk meningkatkan prestasi I/O cakera keras.
Pelaksanaan UNIX tradisional mempunyai cache penimbal atau cache halaman dalam kernel, dan kebanyakan I/O cakera berlaku melalui penimbalan. Apabila menulis data ke fail, kernel biasanya menyalin data ke salah satu penimbal terlebih dahulu Jika penimbal belum penuh, ia tidak beratur ke dalam baris gilir keluaran, tetapi menunggu untuk diisi atau apabila kernel memerlukan. hingga Apabila penimbal digunakan semula untuk menyimpan data blok cakera lain, penimbal akan beratur ke dalam baris gilir keluaran, dan kemudian operasi I/O sebenar dilakukan hanya apabila ia mencapai kepala baris gilir. Kaedah keluaran ini dipanggil penulisan tertunda.
Tulisan tertunda mengurangkan bilangan cakera membaca dan menulis, tetapi ia juga mengurangkan kelajuan kemas kini kandungan fail, supaya data yang akan ditulis ke fail tidak ditulis ke cakera untuk satu tempoh masa. Apabila kegagalan sistem berlaku, kelewatan ini boleh menyebabkan kemas kini fail hilang. Untuk memastikan ketekalan sistem fail sebenar pada cakera dan kandungan dalam cache penimbal, sistem UNIX menyediakan tiga fungsi: penyegerakan, fsync dan fdatasync untuk menyediakan sokongan untuk penulisan paksa pada cakera keras. Redis akan memanggil fungsisebelum setiap putaran acara tamat (
akan menulis data dalam penimbal AOF (
) ke penimbal kernel, dan mengikut Konfigurasikan untuk memutuskan strategi yang hendak digunakan untuk menulis data dalam penimbal kernel ke cakera, iaitu, panggil beforeSleep
. Konfigurasi ini mempunyai tiga pilihan flushAppendOnlyFile
, flushAppendOnlyFile
dan aof_buf
Penerangan khusus adalah seperti berikut: appendfsync
fsync()
always
no
sentiasa: Panggil everysec
setiap kali, iaitu yang tertinggi. keselamatan dan prestasi Strategi yang paling teruk.
no: fsync()
tidak akan dipanggil. Prestasi terbaik, keselamatan paling teruk.
everysec: Dipanggil hanya apabila syarat penyegerakan dipenuhi fsync()
. Ini adalah strategi penyegerakan yang disyorkan secara rasmi dan juga merupakan konfigurasi lalai. Ia mengambil kira prestasi dan keselamatan data Secara teori, hanya 1 saat data akan hilang sekiranya sistem ditutup secara tiba-tiba.
fsync()
Nota: Strategi yang diperkenalkan di atas dipengaruhi oleh item konfigurasi
Jika ditetapkan kepada no-appendfsync-on-rewrite
atau ,
yang berterusan di latar belakang menggunakan I/O cakera yang berlebihan, di bawah konfigurasi sistem Linux tertentu, Redis's panggilan ke fsync() mungkin menyekat untuk masa yang lama. Walau bagaimanapun, masalah ini masih belum diselesaikan, kerana operasi tulis segerak akan disekat walaupun semasa melaksanakan appendfsync
dalam urutan yang berbeza. always
everysec
Untuk mengurangkan isu ini, pilihan boleh digunakan untuk menghalang fsync() daripada dipanggil dalam proses utama semasa BGSAVE
atau BGREWRITEAOF
sedang dijalankan. fsync()
BGSAVE
ditetapkan kepada BGREWRITEAOF
bermakna jika proses anak sedang berjalan
. Dalam kes yang paling teruk, ini boleh mengakibatkan 30 saat data cache hilang. yes
BGSAVE
BGREWRITEAOF
appendfsync
Jika sistem anda mempunyai isu kependaman yang diterangkan di atas, tetapkan pilihan ini kepada no
, jika tidak biarkan di
yes
Penulisan semula failno
如前面提到的,Redis长时间运行,命令不断写入AOF,文件会越来越大,不加控制可能影响宿主机的安全。
为了解决AOF文件体积问题,Redis引入了AOF文件重写功能,它会根据Redis内数据对象的最新状态生成新的AOF文件,新旧文件对应的数据状态一致,但是新文件会具有较小的体积。重写既减少了AOF文件对磁盘空间的占用,又可以提高Redis重启时数据恢复的速度。还是下面这个例子,旧文件中的6条命令等同于新文件中的1条命令,压缩效果显而易见。 我们说,AOF文件太大时会触发AOF文件重写,那到底是多大呢?有哪些情况会触发重写操作呢? ** 与RDB方式一样,AOF文件重写既可以手动触发,也会自动触发。手动触发直接调用bgrewriteaof
命令,如果当时无子进程执行会立刻执行,否则安排在子进程结束后执行。自动触发由Redis的周期性方法serverCron
检查在满足一定条件时触发。先了解两个配置项:
auto-aof-rewrite-percentage:代表当前AOF文件大小(aof_current_size)和上一次重写后AOF文件大小(aof_base_size)相比,增长的比例。
auto-aof-rewrite-min-size:表示运行BGREWRITEAOF
时AOF文件占用空间最小值,默认为64MB;
Redis启动时把aof_base_size
初始化为当时aof文件的大小,Redis运行过程中,当AOF文件重写操作完成时,会对其进行更新;aof_current_size
为serverCron
执行时AOF文件的实时大小。当满足以下两个条件时,AOF文件重写就会触发:
增长比例:(aof_current_size - aof_base_size) / aof_base_size > auto-aof-rewrite-percentage 文件大小:aof_current_size > auto-aof-rewrite-min-size
手动触发与自动触发的代码如下,同样在周期性方法serverCron
中:
int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { /* 省略其他逻辑 */ /* 如果用户请求进行AOF文件重写时,Redis正在执行RDB持久化,Redis会安排在RDB持久化完成后执行AOF文件重写, * 如果aof_rewrite_scheduled为true,说明需要执行用户的请求 */ if (!hasActiveChildProcess() && server.aof_rewrite_scheduled) { rewriteAppendOnlyFileBackground(); } /* Check if a background saving or AOF rewrite in progress terminated. */ if (hasActiveChildProcess() || ldbPendingChildren()) { run_with_period(1000) receiveChildInfo(); checkChildrenDone(); } else { /* 省略rdb持久化条件检查 */ /* AOF重写条件检查:aof开启、无子进程运行、增长百分比已设置、当前文件大小超过阈值 */ if (server.aof_state == AOF_ON && !hasActiveChildProcess() && server.aof_rewrite_perc && server.aof_current_size > server.aof_rewrite_min_size) { long long base = server.aof_rewrite_base_size ? server.aof_rewrite_base_size : 1; /* 计算增长百分比 */ long long growth = (server.aof_current_size*100/base) - 100; if (growth >= server.aof_rewrite_perc) { serverLog(LL_NOTICE,"Starting automatic rewriting of AOF on %lld%% growth",growth); rewriteAppendOnlyFileBackground(); } } } /**/ }
AOF文件重写的流程是什么?听说Redis支持混合持久化,对AOF文件重写有什么影响?
从4.0版本开始,Redis在AOF模式中引入了混合持久化方案,即:纯AOF方式、RDB+AOF方式,这一策略由配置参数aof-use-rdb-preamble
(使用RDB作为AOF文件的前半段)控制,默认关闭(no),设置为yes可开启。所以,在AOF重写过程中文件的写入会有两种不同的方式。当aof-use-rdb-preamble
的值是:
no:按照AOF格式写入命令,与4.0前版本无差别;
yes:先按照RDB格式写入数据状态,然后把重写期间AOF缓冲区的内容以AOF格式写入,文件前半部分为RDB格式,后半部分为AOF格式。
结合源码(6.0版本,源码太多这里不贴出,可参考aof.c
)及参考资料,绘制AOF重写(BGREWRITEAOF)流程图: 结合上图,总结一下AOF文件重写的流程:
rewriteAppendOnlyFileBackground开始执行,检查是否有正在进行的AOF重写或RDB持久化子进程:如果有,则退出该流程;如果没有,则继续创建接下来父子进程间数据传输的通信管道。执行fork()操作,成功后父子进程分别执行不同的流程。
记录子进程信息(pid)、时间戳等;
继续响应其他客户端请求;
收集AOF重写期间的命令,追加至aof_rewrite_buffer;
等待并向子进程同步aof_rewrite_buffer的内容;
修改当前进程名称,创建重写所需的临时文件,调用rewriteAppendOnlyFile函数;
根据aof-use-rdb-preamble
配置,以RDB或AOF方式写入前半部分,并同步至硬盘;
从父进程接收增量AOF命令,以AOF方式写入后半部分,并同步至硬盘;
重命名AOF文件,子进程退出。
Redis启动后通过loadDataFromDisk
函数执行数据加载工作。这里需要注意,虽然持久化方式可以选择AOF、RDB或者两者兼用,但是数据加载时必须做出选择,两种方式各自加载一遍就乱套了。
Secara teorinya, kegigihan AOF mempunyai prestasi masa nyata yang lebih baik daripada RDB Apabila kegigihan AOF didayakan, Redis memberi keutamaan kepada AOF apabila memuatkan data. Selain itu, selepas versi Redis 4.0, AOF menyokong kegigihan hibrid, dan keserasian versi perlu dipertimbangkan semasa memuatkan fail AOF. Proses pemuatan data Redis ditunjukkan dalam rajah di bawah: Dalam mod AOF, fail yang dijana dengan menghidupkan mekanisme kegigihan hibrid ialah "pengepala RDB dan ekor AOF" Apabila ia tidak dihidupkan, semua fail yang dihasilkan dalam format AOF. Memandangkan keserasian dua format fail, jika Redis mendapati bahawa fail AOF ialah pengepala RDB, ia akan menggunakan kaedah pemuatan data RDB untuk membaca dan memulihkan separuh pertama dan kemudian menggunakan kaedah AOF untuk membaca dan memulihkan separuh kedua . Memandangkan data yang disimpan dalam format AOF ialah arahan protokol RESP, Redis menggunakan klien pseudo untuk melaksanakan arahan untuk memulihkan data.
Jika masa henti berlaku semasa proses penambahan arahan AOF, arahan RESP AOF mungkin tidak lengkap (dipotong) disebabkan oleh ciri teknikal penulisan tertunda. Apabila menghadapi situasi ini, Redis akan melaksanakan strategi pemprosesan yang berbeza mengikut item konfigurasi aof-load-truncated
. Konfigurasi ini memberitahu Redis untuk membaca fail aof semasa memulakan, dan perkara yang perlu dilakukan jika fail didapati dipotong (tidak lengkap):
ya: muatkan data sebanyak mungkin, dan Beritahu pengguna dalam bentuk log;
tidak: ranap sistem dan melarang permulaan, memerlukan pengguna membaiki fail dan kemudian mulakan semula.
Redis menyediakan dua pilihan kegigihan: RDB menyokong penjanaan syot kilat titik dalam masa untuk set data pada selang masa praktikal tertentu AOF menerima Pelayan Redis Setiap arahan tulis dikekalkan ke log, dan data dipulihkan melalui arahan main semula apabila Redis dimulakan semula. Format log ialah protokol RESP, dan hanya operasi tambah dijalankan pada fail log, jadi tiada risiko kerosakan. Dan apabila fail AOF terlalu besar, fail yang dimampatkan boleh ditulis semula secara automatik.
Sudah tentu, jika anda tidak perlu mengekalkan data, anda juga boleh melumpuhkan fungsi kegigihan Redis, tetapi ini tidak berlaku dalam kebanyakan kes. Malah, kadangkala kita mungkin menggunakan RDB dan AOF pada masa yang sama Perkara yang paling penting ialah kita memahami perbezaan antara kedua-duanya untuk menggunakannya secara munasabah.
Kelebihan RDB
RDB ialah fail binari termampat padat yang mewakili Redis pada masa tertentu Data syot kilat pada titik sangat sesuai untuk senario seperti sandaran dan replikasi penuh.
RDB sangat mesra kepada pemulihan bencana dan pemindahan data boleh dialihkan ke mana-mana tempat yang diperlukan dan dimuat semula.
RDB ialah petikan memori data Redis Kelajuan pemulihan data lebih pantas dan mempunyai prestasi yang lebih tinggi daripada main semula arahan AOF.
Kelemahan RDB
Kaedah RDB tidak boleh mencapai ketekunan masa nyata atau tahap kedua. Oleh kerana proses kegigihan diselesaikan oleh proses anak selepas proses anak bercabang, ingatan proses anak hanyalah gambaran data proses induk pada saat operasi garpu Selepas operasi garpu, proses induk diteruskan untuk berkhidmat kepada dunia luar, dan data dalaman berubah sepanjang masa Data tidak lagi dikemas kini, dan sentiasa terdapat perbezaan antara keduanya, jadi prestasi masa nyata tidak dapat dicapai.
Operasi fork semasa proses kegigihan RDB akan menggandakan penggunaan memori, dan semakin banyak data yang dimiliki oleh proses induk, semakin lama proses fork.
Permintaan Redis yang tinggi mungkin kerap melanggar peraturan simpan, mengakibatkan kekerapan operasi fork yang tidak terkawal dan sandaran berterusan
fail RDB ada Keperluan format fail, versi Redis yang berbeza akan melaraskan format fail, dan terdapat masalah bahawa versi lama tidak serasi dengan versi baharu.
Kelebihan AOF
Kegigihan AOF mempunyai prestasi masa nyata yang lebih baik Kita boleh memilih tiga kaedah berbeza (appendfsync): tidak, Setiap saat , sentiasa, setiap saat sebagai strategi lalai mempunyai prestasi terbaik, dan dalam kes yang melampau, satu saat data mungkin hilang.
Fail AOF hanya mempunyai operasi tambah, tiada carian rumit dan operasi fail lain serta tiada risiko kerosakan. Walaupun data bertulis terakhir dipotong, ia boleh dibaiki dengan mudah menggunakan alat redis-check-aof
Apabila fail AOF menjadi lebih besar, Redis boleh menulis semula secara automatik di latar belakang. Semasa proses penulisan semula, fail lama akan terus ditulis Selepas penulisan semula selesai, fail baharu akan menjadi lebih kecil, dan arahan tambahan semasa proses penulisan semula juga akan dilampirkan pada fail baharu.
Fail AOF mengandungi semua arahan operasi untuk data dalam Redis dengan cara yang mudah difahami dan dihuraikan. Walaupun semua data secara tidak sengaja dibersihkan secara tidak sengaja, selagi fail AOF tidak ditulis semula, kami boleh mendapatkan semula semua data dengan mengalih keluar arahan terakhir.
AOF sudah pun menyokong kegigihan hibrid, saiz fail boleh dikawal dengan berkesan dan kecekapan pemuatan data dipertingkatkan.
Kelemahan AOF
Untuk pengumpulan data yang sama, fail AOF biasanya lebih besar daripada fail RDB
Di bawah strategi fsync tertentu, AOF akan menjadi lebih perlahan daripada RDB. Secara umumnya, prestasi fsync_every_second masih sangat tinggi, dan prestasi fsync_no adalah setanding dengan RDB. Tetapi di bawah tekanan tulis yang besar, RDB boleh memberikan jaminan kependaman rendah yang paling hebat.
Pada AOF, Redis pernah menemui beberapa pepijat jarang yang hampir mustahil ditemui pada RDB. Beberapa arahan khas (seperti BRPOPLPUSH) menyebabkan data yang dimuat semula tidak konsisten dengan itu sebelum pegawai Redis diuji dalam keadaan yang sama, tetapi masalah itu tidak dapat diterbitkan semula.
Setelah memahami prinsip kerja, proses pelaksanaan, kebaikan dan keburukan kedua-dua kaedah kegigihan RDB dan AOF, mari kita fikirkan tentangnya Seterusnya, bagaimana untuk menimbang kebaikan dan keburukan dalam senario sebenar dan menggunakan dua kaedah kegigihan secara munasabah. Jika anda hanya menggunakan Redis sebagai alat caching, semua data boleh dibina semula berdasarkan pangkalan data berterusan Anda boleh mematikan fungsi kegigihan dan melakukan kerja perlindungan seperti pemanasan awal, penembusan cache, pecahan dan salji.
Dalam keadaan biasa, Redis akan mengambil lebih banyak kerja, seperti kunci yang diedarkan, kedudukan, pusat pendaftaran, dll. Fungsi kegigihan akan memainkan peranan yang lebih besar dalam pemulihan bencana dan pemindahan data. Adalah disyorkan untuk mengikuti beberapa prinsip:
Jangan gunakan Redis sebagai pangkalan data Semua data boleh dibina semula secara automatik oleh perkhidmatan aplikasi sebanyak mungkin.
Gunakan Redis versi 4.0 ke atas dan gunakan fungsi kegigihan hibrid AOF RDB.
Rancang dengan munasabah memori maksimum yang diduduki oleh Redis untuk mengelakkan sumber yang tidak mencukupi semasa AOF menulis semula atau menyimpan.
Elakkan menggunakan berbilang kejadian pada satu mesin.
Kebanyakan persekitaran pengeluaran adalah penempatan berkelompok Keupayaan kegigihan boleh didayakan pada hamba untuk membolehkan tuan memberikan perkhidmatan penulisan luaran dengan lebih baik.
Fail sandaran hendaklah dimuat naik secara automatik ke bilik komputer luar tapak atau storan awan untuk menyediakan sandaran bencana.
Melalui analisis di atas, kita semua tahu bahawa syot kilat RDB dan penulisan semula AOF memerlukan garpu , ini operasi heavyweight dan akan menyebabkan penyekatan kepada Redis. Oleh itu, untuk tidak menjejaskan tindak balas proses utama Redis, kita perlu mengurangkan penyekatan sebanyak mungkin.
Kurangkan kekerapan garpu, contohnya, anda boleh mencetuskan RDB secara manual untuk menjana syot kilat dan menulis semula AOF
Kawal penggunaan memori maksimum daripada Redis untuk menghalang Fork mengambil masa terlalu lama; memori. Menyebabkan garpu gagal
Pembelajaran yang disyorkan:
Tutorial pembelajaran RedisAtas ialah kandungan terperinci Penjelasan terperinci tentang prinsip kegigihan teknik klasik Redis. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!