Maison > Article > base de données > Comment obtenir une récupération et une persistance rapides sans craindre les temps d'arrêt dans Redis
Comment obtenir une récupération et une persistance rapides sans craindre les temps d'arrêt dans Redis ? L’article suivant vous guidera à travers cela, j’espère qu’il vous sera utile !
C'est bien d'être indépendant, et c'est bien de s'intégrer dans le cercle. La clé est de déterminer quel genre de vie vous voulez et quel prix vous êtes prêt à payer pour cela.
Nous utilisons généralement Redis comme cache pour améliorer les performances de réponse en lecture. Une fois Redis en panne, toutes les données de la mémoire seront perdues si nous accédons directement à la base de données et qu'une grande quantité de trafic atteint MySQL, cela peut causer des problèmes plus graves. problèmes. [Recommandations associées : Tutoriel vidéo Redis]
De plus, les performances de lecture lente de la base de données vers Redis seront inévitablement plus rapides que celles de l'obtention de Redis, ce qui entraînera également un ralentissement de la réponse.
Afin d'obtenir une récupération rapide sans crainte de temps d'arrêt, Redis a conçu deux fonctionnalités majeures, à savoir le journal AOF (Append Only FIle) et l'instantané RDB.
Lors de l'apprentissage d'une technologie, on n'entre généralement en contact qu'avec des points techniques épars, sans établir dans son esprit un cadre de connaissances et un système d'architecture complets, et sans une vision systématique. Ce sera très difficile, et il semblera que vous puissiez le faire au premier coup d’œil, mais ensuite vous l’oublierez et vous serez confus.
Suivez "Code Byte" pour bien comprendre Redis et maîtriser en profondeur les principes de base et les compétences pratiques de Redis. Construisez un cadre de connaissances complet et apprenez à organiser l’ensemble du système de connaissances dans une perspective globale.
Cet article est hardcore, je vous suggère de le sauvegarder, de l'aimer, de vous calmer et de le lire, je pense que vous y gagnerez beaucoup.
Dans l'article précédent, nous avons analysé la structure de données de base, le modèle IO, le modèle de thread de Redis et utilisé un codage de données approprié en fonction de différentes données. Comprenez profondément les raisons pour lesquelles c'est si rapide !
Cet article se concentrera sur les points suivants :
Les points de connaissances impliqués sont comme indiqué sur la figure :
Le panorama peut être étendu autour de deux dimensions, qui sont :
Dimensions de l'application : utilisation du cache, clustering Application et utilisation intelligente des structures de données
Dimensions du système : peuvent être classées en trois niveaux élevés
Les chapitres de la série Redis tournent autour de la carte mentale suivante. Cette fois, explorons les secrets du mécanisme de haute performance et de persistance de Redis.
Ayez une vue panoramique et maîtrisez la vue système.
La vue système est en fait cruciale. Dans une certaine mesure, lors de la résolution de problèmes, avoir la vue système signifie que vous pouvez localiser et résoudre les problèmes de manière organisée.
65 Frère : Redis est en panne pour certaines raisons, ce qui entraînera l'arrivée de tout le trafic sur le backend MySQL. J'ai redémarré Redis immédiatement, mais ses données existent. Pourquoi y a-t-il toujours. aucune donnée en mémoire après le redémarrage ? Comment éviter la perte de données après le redémarrage ?
65 Ne vous inquiétez pas, "Code Byte" vous guidera étape par étape pour comprendre comment récupérer rapidement après un crash de Redis.
Les données Redis sont stockées en mémoire Est-il possible d'envisager d'écrire les données en mémoire sur le disque ? Lorsque Redis redémarre, les données enregistrées sur le disque sont rapidement restaurées dans la mémoire, afin que les services normaux puissent être fournis après le redémarrage.
65 Frère : J'ai pensé à une solution. Chaque fois qu'une opération "d'écriture" est effectuée pour faire fonctionner la mémoire, elle est écrite sur le disque en même temps
Cette solution a un problème fatal : chaque instruction d'écriture. écrit non seulement dans la mémoire mais aussi sur le disque. Les performances sont trop lentes par rapport à la mémoire, ce qui entraînera une réduction considérable des performances de Redis.
65 Frère : Alors, comment éviter ce problème d'écriture simultanée ?
Nous utilisons généralement Redis comme cache, donc même si Redis ne sauvegarde pas toutes les données, elles peuvent toujours être obtenues via la base de données, donc Redis ne sauvegardera pas toutes les données. La persistance des données Redis utilise "l'instantané de données RDB". Obtenez une récupération rapide après un temps d’arrêt.
65 Brother : Alors, qu'est-ce qu'un instantané de mémoire RDB ?
Pendant que Redis exécute la commande "write", les données de la mémoire continueront de changer. Ce que l'on appelle l'instantané de mémoire fait référence aux données d'état des données dans la mémoire Redis à un moment donné.
C'est comme si le temps était figé à un certain moment. Lorsque nous prenons des photos, nous pouvons enregistrer complètement le moment à un certain moment grâce aux photos.
Redis est similaire à ceci, il prend les données à un certain moment sous la forme d'un fichier et les écrit sur le disque. Ce fichier d'instantané est appelé RDB file RDB est l'abréviation de Redis DataBase.
Redis exécute régulièrement des instantanés de mémoire RDB, de sorte qu'il n'est pas nécessaire d'écrire sur le disque à chaque fois que la commande "write" est exécutée. Il ne doit être écrit sur le disque que lorsque l'instantané de mémoire est exécuté. Cela garantit non seulement qu'il est rapide mais pas cassé, mais il atteint également la durabilité et peut récupérer rapidement après un temps d'arrêt.
Lors de la récupération de données, lisez le fichier RDB directement dans la mémoire pour terminer la récupération.
65 Frère : De quelles données prenez-vous des instantanés ? Ou à quelle fréquence prendre des instantanés ? Cela affectera l'efficacité d'exécution de l'instantané.
65 C’est super, je commence à réfléchir à l’efficacité des données. Dans l'article précédent, nous avons appris que son modèle monothread détermine que nous devons éviter autant que possible les opérations qui bloquent le thread principal et éviter que la génération de fichiers RDB ne bloque le thread principal.
Redis fournit deux instructions pour générer des fichiers RDB :
fork
; > Un processus enfant est utilisé pour écrire le fichier RDB. La persistance de l'instantané est entièrement gérée par le processus enfant. Le processus parent continue de traiter les demandes des clients et de générer la configuration par défaut du fichier RDB. fork
产生一个子进程用于写入 RDB 文件,快照持久化完全交给子进程来处理,父进程继续处理客户端请求,生成 RDB 文件的默认配置。65 哥:那在对内存数据做「快照」的时候,内存数据还能修改么?也就是写指令能否正常处理?
首先我们要明确一点,避免阻塞和 RDB 文件生成期间能处理写操作不是一回事。虽然主线程没有阻塞,到那时为了保证快照的数据的一致性,只能处理读操作,不能修改正在执行快照的数据。
很明显,为了生成 RDB 而暂停写操作,Redis 是不答应的。
65 哥:那 Redis 如何实现一边处理写请求,同时生成 RDB 文件呢?
Redis 使用操作系统的多进程写时复制技术 COW(Copy On Write) 来实现快照持久化,这个机制很有意思,也很少人知道。多进程 COW 也是鉴定程序员知识广度的一个重要指标。
Redis 在持久化时会调用 glibc 的函数fork
产生一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端请求。
子进程刚刚产生时,它和父进程共享内存里面的代码段和数据段。这时你可以将父子进程想像成一个连体婴儿,共享身体。
这是 Linux 操作系统的机制,为了节约内存资源,所以尽可能让它们共享起来。在进程分离的一瞬间,内存的增长几乎没有明显变化。
bgsave
子进程可以共享主线程的所有内存数据,读取主线程的数据并写入到 RDB 文件。
在执行 SAVE
命令或者BGSAVE
命令创建一个新的 RDB 文件时,程序会对数据库中的键进行检查,已过期的键不会被保存到新创建的 RDB 文件中。
当主线程执行写指令修改数据的时候,这个数据就会复制一份副本, bgsave
65 Brother : Lors de la prise d'un « instantané » des données de la mémoire, les données de la mémoire peuvent-elles encore être modifiées ? Autrement dit, la commande d’écriture peut-elle être traitée normalement ?
Tout d'abord, nous devons préciser queéviter le blocage et être capable de gérer les opérations d'écriture lors de la génération de fichiers RDB ne sont pas la même chose. Bien que le thread principal ne soit pas bloqué, afin d'assurer la cohérence des données du snapshot, il ne peut traiter que les opérations de lecture et ne peut pas modifier les données du snapshot en cours d'exécution.
Évidemment, Redis ne permet pas de suspendre les opérations d'écriture afin de générer du RDB.65 Brother : Comment Redis peut-il traiter les requêtes d'écriture et générer des fichiers RDB en même temps ?Redis utilise la
fork
pour générer un processus enfant pendant la persistance. La persistance de l'instantané est entièrement gérée par le processus enfant et le processus parent continue de traiter les demandes des clients. bgsave
Le processus enfant peut partager toutes les données mémoire du thread principal, lire les données du thread principal et les écrire dans le fichier RDB. Lors de l'exécution de la commande SAVE
ou de la commande BGSAVE
pour créer un nouveau fichier RDB, le programme vérifiera les clés dans la base de données et les clés expirées ne seront pas enregistrées dans dans le fichier RDB nouvellement créé.
bgsave
Le sous-processus lit les données de copie et les écrit dans le fichier RDB, donc le le thread principal peut modifier directement les données originales.
Cela garantit non seulement l'intégrité de l'instantané, mais permet également au thread principal de modifier les données en même temps, évitant ainsi tout impact sur les activités normales.
En supposant que le journal AOF enregistre toutes les séquences d'instructions modifiées depuis la création de l'instance Redis, alors la structure des données de la mémoire de l'instance Redis actuelle peut être restaurée en exécutant séquentiellement toutes les instructions sur une instance Redis vide, c'est-à-dire l'état « relecture » .
Write Ahead Log (WAL) : Avant d'écrire réellement des données, les données modifiées sont écrites dans le fichier journal, de sorte que la reprise après échec soit garantie.
Par exemple, le redo log dans le moteur de stockage MySQL Innodb est un journal de données qui enregistre les modifications avant de modifier réellement les données, le journal des modifications est enregistré et les données modifiées sont exécutées.
Journal post-écriture : Exécutez d'abord la demande de commande « écriture », écrivez les données dans la mémoire, puis enregistrez le journal.
Lorsque Redis reçoit la commande "set key MageByte" pour écrire des données en mémoire, Redis écrira le fichier AOF au format suivant.
65 Brother : Pourquoi Redis utilise-t-il la journalisation post-écriture ?
Les journaux de post-écriture évitent une surcharge de vérification supplémentaire et ne nécessitent pas de vérification de la syntaxe des commandes exécutées. Si vous utilisez la journalisation à écriture anticipée, vous devez d'abord vérifier si la syntaxe est correcte. Sinon, le journal enregistrera des commandes incorrectes et une erreur se produira lors de l'utilisation de la récupération du journal.
De plus, le log est enregistré après écriture, ne bloquera pas l'exécution de la commande "write" en cours.
65 Frère : Alors avec AOF, c'est infaillible ?
Garçon idiot, ce n'est pas si simple. Si Redis vient de terminer l'exécution de la commande et plante avant d'enregistrer le journal, les données liées à la commande risquent d'être perdues.
De plus, AOF évite le blocage de la commande en cours, mais peut entraîner un risque de blocage pour la commande suivante. Le journal AOF est exécuté par le thread principal. Pendant le processus d'écriture du journal sur le disque, si la pression du disque est élevée, l'écriture sur le disque sera très lente, provoquant le blocage des instructions « d'écriture » ultérieures.
Avez-vous remarqué que ces deux problèmes sont liés à l'écriture sur le disque ? Si vous pouvez raisonnablement contrôler le moment de l'écriture du journal AOF sur le disque après l'exécution de la commande "write", le problème sera résolu.
Afin d'améliorer l'efficacité de l'écriture du fichier, lorsque l'utilisateur appelle la fonction write
pour écrire des données dans le fichier, le système d'exploitation enregistre généralement temporairement les données écrites dans une mémoire. tampon, les données du tampon ne sont pas réellement écrites sur le disque tant que l'espace du tampon n'est pas rempli ou que la limite de temps spécifiée n'est pas dépassée. write
函数,将一些数据写入到文件的时候,操作系统通常会将写入数据暂时保存在一个内存缓冲区里面,等到缓冲区的空间被填满、或者超过了指定的时限之后,才真正地将缓冲区中的数据写入到磁盘里面。
这种做法虽然提高了效率,但也为写入数据带来了安全问题,因为如果计算机发生停机,那么保存在内存缓冲区里面的写入数据将会丢失。
为此,系统提供了fsync
和fdatasync
两个同步函数,它们可以强制让操作系统立即将缓冲区中的数据写入到硬盘里面,从而确保写入数据的安全性。
Redis 提供的 AOF 配置项appendfsync
写回策略直接决定 AOF 持久化功能的效率和安全性。
aof_buf
缓冲区中的内容刷写到 AOF 文件。没有两全其美的策略,我们需要在性能和可靠性上做一个取舍。
always
同步写回可以做到数据不丢失,但是每个「写」指令都需要写入磁盘,性能最差。
everysec
每秒写回,避免了同步写回的性能开销,发生宕机可能有一秒位写入磁盘的数据丢失,在性能和可靠性之间做了折中。
no
À cet effet, le système fournit deux fonctions de synchronisation,
🎜La stratégie de réécriture de l'élément de configuration AOFfsync
etfdatasync
, qui peuvent forcer le système d'exploitation à écrire immédiatement les données du tampon sur le disque dur, Assurer ainsi la sécurité des données écrites.appendfsync
fournie par Redis détermine directement l'efficacité et la sécurité de la fonction de persistance AOF. 🎜🎜🎜🎜always🎜 : Réécriture synchrone, le contenu du tamponaof_buf
sera vidé dans le fichier AOF immédiatement après l'exécution de la commande d'écriture. 🎜🎜🎜everysec🎜 : réécrivez chaque seconde. Une fois la commande d'écriture exécutée, le journal sera uniquement écrit dans le tampon du fichier AOF et le contenu du tampon sera synchronisé avec le disque toutes les secondes. 🎜🎜🎜non : 🎜 Contrôlé par le système d'exploitation, une fois l'exécution de l'écriture terminée, le journal est écrit dans la mémoire tampon du fichier AOF et le système d'exploitation décide quand le vider sur le disque. 🎜🎜🎜Il n'y a pas de stratégie du meilleur des deux mondes, nous devons faire un compromis entre performances et fiabilité. 🎜🎜toujours
L'écriture synchrone peut empêcher la perte de données, mais chaque commande « écriture » doit être écrite sur le disque, qui a les pires performances. 🎜🎜everysec
réécrit toutes les secondes, évitant ainsi la surcharge de performances de l'écriture synchrone. En cas de temps d'arrêt, les données écrites sur le disque peuvent être perdues pendant une seconde, ce qui constitue un compromis entre performances et fiabilité. 🎜🎜no
Contrôle du système d'exploitation, après avoir exécuté la commande d'écriture, écrivez dans le tampon du fichier AOF pour exécuter les commandes "d'écriture" suivantes. Les performances sont les meilleures, mais beaucoup de données peuvent être perdues. 🎜🎜🎜65 Frère : Alors comment dois-je choisir une stratégie ? 🎜
Nous pouvons choisir la stratégie de réécriture en fonction des exigences du système en matière de hautes performances et de haute fiabilité. En résumé : si vous souhaitez obtenir des performances élevées, choisissez la stratégie Non ; si vous souhaitez obtenir une garantie de fiabilité élevée, choisissez la stratégie Toujours ; si vous autorisez une légère perte de données mais souhaitez que les performances soient fortement affectées, choisissez alors la stratégie Everysec. .
Avantages : Le journal n'est enregistré qu'après une exécution réussie, évitant ainsi la surcharge de vérification de la syntaxe des instructions. Dans le même temps, la commande « écriture » en cours ne sera pas bloquée.
Inconvénients : Étant donné qu'AOF enregistre le contenu de chaque instruction, veuillez consulter le format de journal ci-dessus pour le format spécifique. Chaque commande doit être exécutée pendant la récupération après erreur. Si le fichier journal est trop volumineux, l'ensemble du processus de récupération sera très lent.
De plus, le système de fichiers impose également des restrictions sur la taille des fichiers. Les fichiers trop volumineux ne peuvent pas être enregistrés. À mesure que le fichier devient plus volumineux, l'efficacité de l'ajout diminue également.
65 Frère : Que dois-je faire si le fichier journal AOF est trop volumineux ?
Le journal de pré-écriture AOF enregistre chaque opération de commande "écriture". Cela n'entraînera pas de perte de performances comme l'instantané complet de RDB, mais la vitesse d'exécution n'est pas aussi rapide que celle de RDB. En même temps, des fichiers journaux trop volumineux entraîneront également des problèmes de performances pour un vrai homme comme Redis qui veut seulement être rapide. il ne peut absolument pas tolérer les problèmes causés par des bûches trop volumineuses.
Ainsi, Redis a conçu un "mécanisme de réécriture AOF". Redis fournit la commande bgrewriteaof
pour affiner le journal AOF.
Le principe est d'ouvrir un sous-processus pour parcourir la mémoire et de la convertir en une série d'instructions d'opération Redis, qui sont sérialisées dans un nouveau fichier journal AOF. Une fois la sérialisation terminée, le journal AOF incrémentiel généré pendant l'opération est ajouté au nouveau fichier journal AOF. Une fois l'ajout terminé, l'ancien fichier journal AOF est immédiatement remplacé et le travail d'amincissement est terminé.
65 Brother : Pourquoi le mécanisme de réécriture AOF peut-il réduire les fichiers journaux ?
Le mécanisme de réécriture a la fonction "plusieurs à un", qui transforme plusieurs instructions de l'ancien journal en une seule instruction après réécriture.
Comme indiqué ci-dessous :
Trois instructions LPUSH, une est générée après réécriture par AOF. Pour les scènes qui ont été modifiées plusieurs fois, l'effet de réduction est plus évident.
65 Brother : Après la réécriture, le journal AOF est devenu plus petit, et finalement le journal des opérations des dernières données de l'ensemble de la base de données a été vidé sur le disque. La réécriture bloquera-t-elle le fil principal ?
"Brother Ma" a mentionné ci-dessus que le journal AOF est réécrit par le thread principal. Le processus de réécriture AOF est en fait complété par le sous-processus d'arrière-plan bgrewriteaof pour éviter de bloquer le thread principal.
Le processus de réécriture
est différent du journal AOF réécrit par le thread principal. Le processus de réécriture est complété par le sous-processus en arrière-plan bgrewriteaof. Cela permet également d'éviter de bloquer le thread principal et d'entraîner une baisse des performances de la base de données. diminuer.
En général, il y a deux journaux au total, une copie de données en mémoire, qui sont l'ancien journal AOF, le nouveau journal de réécriture AOF et la copie de données Redis.
Redis enregistrera les opérations de commande "écriture" reçues pendant le processus de réécriture dans l'ancien tampon AOF et le tampon de réécriture AOF en même temps, de sorte que le journal de réécriture enregistre également les dernières opérations. Une fois que tous les enregistrements d'opérations des données copiées ont été réécrits, les dernières opérations enregistrées dans le tampon de réécriture seront également écrites dans le nouveau fichier AOF.
Chaque fois qu'AOF est réécrit, Redis effectuera d'abord une copie de mémoire pour parcourir les données afin de générer des enregistrements de réécriture ; utiliser deux journaux pour garantir que pendant le processus de réécriture, les données nouvellement écrites ne seront pas perdues et que les données seront cohérentes. .
65 Brother : AOF rewrite a également un journal de réécriture Pourquoi ne partage-t-il pas le journal en utilisant AOF lui-même ?
C'est une bonne question pour les deux raisons suivantes :
L'une des raisons est que lorsque les processus parent et enfant écrivent le même fichier, une concurrence se produira inévitablement. Le contrôle de la concurrence signifie que cela affectera les performances du processus parent. .
Si le processus de réécriture AOF échoue, le fichier AOF d'origine équivaut à être contaminé et ne peut pas être restauré et utilisé. Par conséquent, Redis AOF réécrit un nouveau fichier si la réécriture échoue, supprimez simplement le fichier directement. Cela n'affectera pas le fichier AOF d'origine. Une fois la réécriture terminée, remplacez simplement l'ancien fichier.
Lors du redémarrage de Redis, nous utilisons rarement rdb pour restaurer l'état de la mémoire car beaucoup de données seront perdues. Nous utilisons généralement la relecture des journaux AOF, mais les performances de la relecture des journaux AOF sont beaucoup plus lentes que celles de RDB, donc lorsque l'instance Redis est volumineuse, le démarrage prend beaucoup de temps.
Redis 4.0 apporte une nouvelle option de persistance pour résoudre ce problème - Persistance hybride. Stockez le contenu du fichier rdb avec le fichier journal AOF incrémentiel. Le journal AOF ici n'est plus le journal complet, mais le journal AOF incrémentiel qui s'est produit pendant la période allant du début de la persistance à la fin de la persistance. Habituellement, cette partie du journal AOF est très petite.
Ainsi, lorsque Redis redémarre, vous pouvez d'abord charger le contenu rdb, puis relire le journal AOF incrémentiel, qui peut remplacer complètement la relecture complète du fichier AOF précédente, et l'efficacité du redémarrage est grandement améliorée.
Ainsi, les instantanés de mémoire RDB sont exécutés à une fréquence légèrement plus lente, en utilisant la journalisation AOF pour enregistrer toutes les opérations « d'écriture » survenues pendant les deux instantanés RDB.
De cette façon, les instantanés n'ont pas besoin d'être exécutés fréquemment. En même temps, comme AOF n'a besoin que d'enregistrer les instructions « d'écriture » qui se produisent entre deux instantanés, il n'a pas besoin d'enregistrer toutes les opérations pour éviter une taille de fichier excessive. .
Redis a conçu bgsave et copy-on-write pour éviter autant que possible l'impact sur les instructions de lecture et d'écriture lors de l'exécution d'un instantané. Des instantanés fréquents exerceront une pression sur le disque et un fork bloquera le thread principal.
Redis a conçu deux fonctionnalités majeures pour permettre une récupération rapide après un temps d'arrêt sans perte de données.
Pour éviter que le journal ne soit trop volumineux, un mécanisme de réécriture AOF est fourni. Selon le dernier état des données de la base de données, l'opération d'écriture des données est générée en tant que nouveau journal et s'effectue en arrière-plan sans bloquer le thread principal. .
L'intégration d'AOF et de RDB fournit une nouvelle stratégie de persistance et un modèle de journal hybride dans Redis 4.0. Lorsque Redis redémarre, vous pouvez d'abord charger le contenu rdb, puis relire le journal AOF incrémentiel, qui peut remplacer complètement la relecture complète du fichier AOF précédente, et l'efficacité du redémarrage est grandement améliorée.
Enfin, concernant le choix de l'AOF et du RDB, "Code Byte" propose trois suggestions :
Restez à l'écoute...
Adresse originale : https://juejin.cn/post/6961735998547951653
Auteur : Code Brother Byte
Pour plus de connaissances liées à la programmation, veuillez visiter : Vidéo de programmation ! !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!