MariaDB vs MongoDB : Rafales d’écriture — Qui survit aux pics sans craquer

Cet article vous a aidé ?

Votre système est calme. Les graphiques sont ennuyeux. Puis le marketing « lâche » quelque chose, un partenaire relance sans retenue, ou un cron se dit qu’il est temps de réindexer l’univers. Le trafic d’écriture monte en flèche. La latence suit. Soudain, vous découvrez ce que fait réellement votre base de données quand elle est effrayée.

Ceci n’est pas une guerre de religion entre SQL et NoSQL. C’est un guide de survie pour les rafales d’écriture : ce que MariaDB (InnoDB) et MongoDB (WiredTiger) font sous pression, où ils échouent, comment diagnostiquer rapidement le goulot, et quelles modifications déplacent réellement l’aiguille en production.

Ce qu’est vraiment une rafale d’écriture (et pourquoi ça fait mal)

Une rafale d’écriture n’est pas « un QPS élevé ». C’est un désaccord entre la demande d’écriture entrante et l’étape la plus lente et durable du chemin d’écriture. Cette étape peut être la latence de vidage disque, la sérialisation du journal, la contention de verrous, les accusés de réception de réplication ou le checkpointing.

Sous une charge stable, MariaDB et MongoDB peuvent sembler héroïques. Sous rafales, l’illusion s’effondre parce que les deux moteurs finissent par atteindre un mur où ils doivent soit :

  • Appliquer une rétro-pression (les clients attendent ; les files augmentent ; la latence en queue explose),
  • Abandonner la durabilité (accuser réception avant une persistance sûre),
  • Ou tomber (OOM, disque plein, spirale de retard des réplicas, épuisement de threads).

Quand vous demandez « qui survit aux pics », la vraie question est : qui échoue de manière prévisible, et qui vous donne suffisamment de leviers pour échouer en sécurité — sans transformer le canal d’incident en podcast en direct.

Faits intéressants et contexte historique

  • MariaDB a été créée après qu’Oracle a acquis Sun (et donc MySQL), poussée par des préoccupations de gouvernance et de licence plus que par la seule performance.
  • MongoDB a popularisé un modèle de document favorable aux développeurs à une époque où le sharding des bases relationnelles restait principalement « un projet de week-end et un regret futur ».
  • InnoDB (le moteur de stockage par défaut de MariaDB) centre la durabilité autour d’un journal de redo et d’un vidage en arrière-plan — les écritures ne sont pas « juste des écritures », ce sont des écritures de journal plus des flushs de pages ultérieurs.
  • WiredTiger de MongoDB utilise un journal d’écriture anticipée (write-ahead log) et des checkpoints ; le comportement en rafale dépend souvent du rythme des checkpoints et de la pression sur le cache.
  • Le group commit a rendu les bases transactionnelles bien meilleures en rafales en mutualisant les coûts d’un fsync entre plusieurs transactions.
  • Les write concerns de MongoDB (w:1, majority, journaling) sont essentiellement un tableau de commande entre « rapide » et « durable de manière prouvable », et votre choix importe davantage lors des pics.
  • Le délai de réplication n’est pas seulement « un problème de réplique » ; il peut rétroagir sur les primaires lorsque les clients exigent des accusés de majorité.
  • L’adoption du NVMe a changé la forme des goulots : avec des appareils à IOPS élevés, le CPU, la contention et la sérialisation du journal peuvent devenir le facteur limitant plus tôt.
  • Le réseau cloud a fait de « temps d’accusé d’écriture » un problème de systèmes distribués : les écritures majority peuvent être limitées par la latence du votant le plus lent, pas par le CPU du primaire.

MariaDB face aux rafales : la réalité InnoDB

Le chemin d’écriture qui compte

Sous InnoDB, une écriture transactionnelle typique implique :

  1. Modifier des pages dans le buffer pool (mémoire) et les marquer comme dirty.
  2. Ajouter des enregistrements de redo au tampon de redo log.
  3. Au commit, assurer que le redo est durable selon innodb_flush_log_at_trx_commit.
  4. Plus tard, vider les pages dirty vers les fichiers de données en arrière-plan.

Pendant les rafales, trois choses dominent :

  • La latence de durabilité du redo log (coût du fsync et sérialisation du journal).
  • L’accumulation de pages dirty (remplissage du buffer pool, puis flush forcés).
  • La contention (verrous de ligne, maintenance des index secondaires, pages chaudes, et parfois verrous de métadonnées).

Comment MariaDB « survit » à une rafale

MariaDB a tendance à survivre aux rafales si :

  • Votre stockage a une latence fsync prévisible (pas seulement des IOPS élevés).
  • Votre redo log est dimensionné et configuré pour éviter une « pression de flush » constante.
  • Vous évitez des index secondaires pathologiques sur des tables fortement écrites.
  • Vous acceptez que la durabilité stricte coûte quelque chose, et vous ajustez plutôt que de faire comme si c’était gratuit.

Le mode de défaillance de MariaDB en rafale est généralement une explosion de latence, pas un crash immédiat — sauf si vous le poussez vers le swap, remplissez le disque, ou laissez la réplication/la gestion des connexions spiraler.

Les réglages InnoDB qui comptent réellement pendant les pics

  • innodb_flush_log_at_trx_commit : 1 est le plus sûr ; 2 est courant pour un meilleur débit ; 0 équivaut à « j’espère que le courant ne sautera jamais ».
  • sync_binlog : si vous utilisez le binlog (réplication), c’est l’autre moitié de la durabilité. Le régler à 1 est sûr et peut être coûteux.
  • innodb_log_file_size et innodb_log_files_in_group : des logs plus gros lissent les rafales ; trop petits forcent des flushs agressifs.
  • innodb_io_capacity et innodb_io_capacity_max : si trop bas, les pages dirty s’accumulent ; trop haut, vous pouvez affamer l’E/S de premier plan.
  • innodb_buffer_pool_size : suffisamment de mémoire évite que les lectures ne combattent les écritures ; trop peut masquer des problèmes jusqu’à ce que les checkpoints frappent comme un camion.
  • innodb_flush_method=O_DIRECT : réduit souvent les problèmes de double mise en mémoire tampon sur Linux.

Rétro-pression dans MariaDB : principalement implicite

MariaDB ne vous donne pas un simple curseur « profondeur de file ». La rétro-pression se manifeste par :

  • La latence de commit qui augmente (fsync du redo).
  • Des threads en attente de verrous ou d’E/S.
  • La réplication qui prend du retard (si les écritures produisent aussi du binlog et que les réplicas n’arrivent pas à suivre).

Quand MariaDB a des problèmes, il ressemble souvent à « la base est up, mais rien ne se termine ». C’est toujours une forme de miséricorde. Votre appli peut expirer. Vous pouvez réduire la charge. Vous pouvez agir.

MongoDB face aux rafales : la réalité WiredTiger

Le chemin d’écriture qui compte

Le comportement d’écriture de MongoDB dépend fortement du write concern et de la journalisation, mais le chemin habituel est :

  1. L’écriture arrive sur le primaire et met à jour des structures en mémoire (cache WiredTiger).
  2. Le journal (write-ahead log) est ajouté ; la durabilité dépend de la journalisation et des intervalles de commit.
  3. La réplication envoie les opérations aux secondaires via l’oplog ; le write concern majority attend les votants.
  4. Les checkpoints flushent périodiquement les données sur disque, produisant des pics d’E/S.

Comment MongoDB « survit » à une rafale

MongoDB survit aux rafales d’écriture lorsque :

  • Votre disque peut absorber la journalisation + l’E/S des checkpoints sans pics fsync à longue traîne.
  • Vous n’êtes pas tellement sollicité que le cache WiredTiger évince constamment des pages dirty.
  • Votre topologie de réplication peut suivre les accusés majority (ou vous êtes prêt à relaxer le write concern pendant les rafales).
  • Vos documents et index sont conçus pour la localité d’écriture (ou au moins ne sont pas conçus pour la saboter).

Le mode de défaillance le plus néfaste de MongoDB en rafale est le retard de réplication + write concern majority + disque lent. Cette combinaison transforme une rafale en un verrouillage distribué auto-infligé.

Les réglages et comportements WiredTiger qui apparaissent pendant les pics

  • Write concern : w:1 vs majority, et j:true. C’est le tableau de commande latence vs durabilité.
  • Checkpointing : les checkpoints créent des pics d’E/S périodiques ; si le système est déjà tendu, les checkpoints peuvent amplifier le comportement de blocage.
  • Pression sur le cache : quand le cache est plein, l’éviction devient le régulateur caché du débit d’écriture.
  • Taille de l’oplog : trop petite et les secondaires décrochent ; trop grande et les temps de récupération, le stockage et le profil I/O changent.
  • Amplification d’écriture par les index : chaque index secondaire est du travail supplémentaire. MongoDB n’est pas exempté par la physique.

Rétro-pression dans MongoDB : plus explicite, mais facile à mal interpréter

MongoDB peut appliquer une rétro-pression quand il n’arrive pas à tenir la journalisation/les checkpoints ou quand la réplication ne peut satisfaire le write concern assez rapidement. En pratique, vous verrez :

  • Mises en file d’attente dans le driver, puis expirations.
  • Augmentation de l’activité « WT cache eviction ».
  • Le retard de réplication de l’oplog qui grandit jusqu’à provoquer des élections, des rollbacks ou une obsolescence des lectures préjudiciable au business.

Le piège : les équipes interprètent « MongoDB accepte les écritures rapidement » comme « MongoDB est durable rapidement ». Sous rafales, ce sont deux phrases différentes.

Qui « survit » aux pics : un tableau de décision défendable

Si vous avez besoin de garanties transactionnelles strictes pendant les rafales

Privilégiez MariaDB lorsque vous avez besoin d’intégrité transactionnelle multi-lignes, de contraintes complexes et de sémantiques prévisibles pendant les rafales. Le comportement d’InnoDB est bien connu : le coût du commit dépend de la durabilité du journal et de la contention, pas du mystère.

MongoDB peut être durable et cohérent, oui. Mais une fois que vous exigez majority et la journalisation, vous entrez en territoire de latence distribuée. Sous pics, ce territoire devient rapidement coûteux.

Si vous avez besoin d’un schéma flexible et pouvez tolérer d’ajuster le write concern

Privilégiez MongoDB lorsque le modèle document est réellement votre modèle de données (et non « on ne voulait pas concevoir de tables »), et que vous pouvez choisir explicitement les niveaux de durabilité pendant les rafales.

L’avantage opérationnel de MongoDB : pour certains workloads il est plus simple de sharder horizontalement et de maintenir le flux d’écritures — à condition d’être discipliné sur les clés et les index.

Si vos pics sont de l’ingestion par rafales et les lectures sont secondaires

Les deux peuvent ingérer. La différence est là où ils paient :

  • MariaDB paie au commit (fsync redo/binlog), puis plus tard via les flushs si vous dépassez les limites de pages dirty.
  • MongoDB paie via la journalisation et les checkpoints, et potentiellement via le retard de réplication quand le write concern est strict.

Si vous ne pouvez vous permettre qu’une chose fiable : latence prévisible

Je suis opinionné ici : choisissez le système dont le mode de défaillance vous pouvez opérationnaliser.

  • MariaDB a tendance à se dégrader en « lent mais correct » quand il est configuré raisonnablement.
  • MongoDB peut se dégrader en « rapide mais pas là où vous pensez que la vérité est » si vous avez été lâche avec le write concern, la santé de la réplication ou le disque.

Blague #1 : Une rafale d’écriture, c’est juste vos utilisateurs lançant un test de charge que vous n’avez pas budgété.

La citation à coller au tableau de bord

L’espoir n’est pas une stratégie. — General Gordon R. Sullivan

Cette phrase survit parce que c’est la chose la plus vraie jamais dite sur les écritures en production.

Manuel de diagnostic rapide

Vous avez 10 minutes avant que quelqu’un ne propose « ajoutez juste plus de pods ». Voici ce qu’il faut vérifier d’abord, ensuite, et enfin — pour identifier le vrai goulot au lieu de traiter les symptômes.

Première étape : est-ce la latence de vidage disque, ou le CPU/les verrous ?

  • Vérifiez l’utilisation disque et l’await : si await est élevé et l’utilisation bloquée, vous êtes limité par l’E/S.
  • Vérifiez le steal CPU et la saturation : si le CPU est saturé ou vous êtes throttle, vous êtes limité par le calcul.
  • Vérifiez les attentes de verrous : si des threads attendent des verrous, les graphiques d’E/S peuvent mentir.

Deuxième étape : la configuration de durabilité force-t-elle des sync à chaque écriture ?

  • MariaDB : innodb_flush_log_at_trx_commit, sync_binlog, format du binlog, regroupement des commits.
  • MongoDB : write concern (w, j), comportement des intervalles de commit, attentes majority.

Troisième étape : la réplication est-elle le limiteur caché ?

  • MariaDB : réplicas appliquant le binlog lentement, paramètres semi-sync, ou stockage réseau lent sur les réplicas.
  • MongoDB : secondaires en retard, élections, write concern majority attendant un nœud malade.

Quatrième étape : checkpointing/flush trop agressif (ou trop tard) ?

  • MariaDB : pourcentage de pages dirty, pression sur le redo log, paramètres de flush en arrière-plan.
  • MongoDB : taux d’éviction du cache WiredTiger, durées de checkpoint, pression sur le journal.

Cinquième étape : les index et le schéma sont-ils la vraie taxe ?

Les rafales exposent l’amplification d’écriture. Un schéma qui « fonctionnait bien » à 1k writes/s peut imploser à 20k writes/s car chaque écriture touche trop d’index, trop de clés chaudes, ou trop de structures secondaires.

Tâches pratiques : commandes, sorties, et décisions

Voici les tâches que j’exécute réellement quand une rafale frappe. Chaque item inclut la commande, une sortie d’exemple, ce que cela signifie, et la décision que vous prenez. Pas d’héroïsme, juste des recettes.

1) Linux : confirmer la saturation disque et la latence

cr0x@server:~$ iostat -x 1 5
Linux 6.5.0 (db01)  12/30/2025  _x86_64_  (8 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.10    0.00    6.20   18.40    0.00   63.30

Device            r/s     w/s   rMB/s   wMB/s  avgrq-sz  avgqu-sz   await  r_await  w_await  svctm  %util
nvme0n1         110.0  4200.0    3.2   180.5     87.1      35.2    8.4      1.9      8.6   0.23  99.2

Ce que cela signifie : %util proche de 100 et un avgqu-sz élevé montrent une file profonde. L’attente d’écriture est d’environ 8.6ms. Sous rafales, cela devient souvent 20–100ms, et les bases commencent à expirer.

Décision : Si l’await augmente avec la charge, vous êtes lié par l’E/S. Réduisez la fréquence des fsync (prudemment), regroupez les commits, ou migrez vers un stockage plus rapide/moins contendu.

2) Linux : vérifier les pressions d’attente (CPU/mémoire/E/S)

cr0x@server:~$ cat /proc/pressure/io
some avg10=12.45 avg60=8.21 avg300=2.14 total=9382211
full avg10=4.10 avg60=2.01 avg300=0.50 total=1923112

Ce que cela signifie : Le noyau vous dit que des tâches sont bloquées en attente d’E/S. « full » indique des périodes où aucune tâche ne pouvait progresser à cause de l’I/O.

Décision : Traitez-le d’abord comme un goulot plateforme. Le tuning de la base ne battra pas une pile de stockage saturée.

3) Linux : vérifier l’espace système de fichiers et les inodes

cr0x@server:~$ df -h /var/lib/mysql /var/lib/mongodb
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme0n1p2  1.8T  1.6T  120G  94% /
/dev/nvme1n1p1  1.8T  1.2T  560G  69% /data

Ce que cela signifie : 94% utilisé frôle les falaises de performance et les erreurs opérationnelles. Certains systèmes de fichiers se comportent mal quand ils sont presque pleins ; les bases se comportent mal quand elles ne peuvent pas étendre des fichiers.

Décision : Si une rafale d’écriture est en cours et que vous êtes au-dessus d’environ 90%, priorisez la libération d’espace ou l’ajout de capacité avant de chasser les plans de requête.

4) MariaDB : voir ce que le serveur pense se passer en ce moment

cr0x@server:~$ mysql -e "SHOW FULL PROCESSLIST\G" | head -n 40
*************************** 1. row ***************************
     Id: 4312
   User: app
   Host: 10.10.2.14:51132
     db: prod
Command: Query
   Time: 12
  State: Waiting for redo log flush
   Info: COMMIT
*************************** 2. row ***************************
     Id: 4321
   User: app
   Host: 10.10.2.18:51410
     db: prod
Command: Query
   Time: 8
  State: Updating
   Info: INSERT INTO events ...

Ce que cela signifie : « Waiting for redo log flush » est un signal clignotant : les commits sont bloqués par la durabilité du journal. C’est la douleur classique des rafales d’écriture.

Décision : Examinez la latence fsync, le dimensionnement du redo log, et les paramètres de durabilité. N’ajoutez pas d’index maintenant ; vous êtes en train de vous noyer dans le coût des flushs.

5) MariaDB : confirmer les paramètres de durabilité (les vrais)

cr0x@server:~$ mysql -e "SHOW VARIABLES WHERE Variable_name IN ('innodb_flush_log_at_trx_commit','sync_binlog','binlog_format')"
+-------------------------------+-------+
| Variable_name                 | Value |
+-------------------------------+-------+
| binlog_format                 | ROW   |
| innodb_flush_log_at_trx_commit| 1     |
| sync_binlog                   | 1     |
+-------------------------------+-------+

Ce que cela signifie : C’est le territoire de « sécurité maximale » : fsync du redo à chaque commit, fsync du binlog à chaque commit. Sous rafales, cela peut se transformer en brasier de latence de commit à moins que votre stockage ne soit excellent.

Décision : Si l’entreprise peut tolérer une petite fenêtre de perte en cas de coupure de courant, envisagez innodb_flush_log_at_trx_commit=2 et/ou sync_binlog=100 pour une ingestion rafaleuse — après une revue de risque délibérée.

6) MariaDB : inspecter les pages dirty InnoDB et la pression de flush

cr0x@server:~$ mysql -e "SHOW ENGINE INNODB STATUS\G" | egrep -i "Modified db pages|Log sequence number|Log flushed up to|pages flushed" -n | head
121:Log sequence number          98422341122
122:Log flushed up to            98422338816
401:Modified db pages            812345
405:Pages flushed up to          255112233

Ce que cela signifie : Un grand nombre de pages modifiées indique une accumulation de pages dirty. Si « Log flushed up to » est en retard sur le LSN pendant une rafale, les commits font la queue derrière le fsync.

Décision : Si les pages dirty restent élevées et que le flush ne suit pas, ajustez les paramètres d’I/O capacity et la taille du redo log. Si le fsync est lent, réparez d’abord le stockage.

7) MariaDB : détecter les points chauds de contention de verrous

cr0x@server:~$ mysql -e "SELECT * FROM information_schema.INNODB_LOCK_WAITS\G" | head -n 60
*************************** 1. row ***************************
requesting_trx_id: 123456789
requested_lock_id: 123456789:45:3:12
blocking_trx_id: 123456700
blocking_lock_id: 123456700:45:3:12

Ce que cela signifie : Des transactions attendent d’autres transactions. Pendant les rafales, une ligne chaude ou une page d’index chaude peut sérialiser le débit.

Décision : Si les attentes de verrous corrèlent avec les pics, corrigez les schémas d’accès (clés de sharding, partitionnement, éviter les compteurs chauds) plutôt que de tuner le fsync.

8) MariaDB : vérifier le taux de succès du buffer pool et la contention lecture/écriture

cr0x@server:~$ mysql -e "SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%'; SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';"
+---------------------------------------+-----------+
| Variable_name                         | Value     |
+---------------------------------------+-----------+
| Innodb_buffer_pool_read_requests      | 982341122 |
| Innodb_buffer_pool_reads              | 8123411   |
+---------------------------------------+-----------+
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| Innodb_buffer_pool_pages_dirty | 81234 |
+--------------------------------+-------+

Ce que cela signifie : Si les lectures physiques augmentent pendant une rafale d’écriture, votre buffer pool peut être trop petit ou vous thrash. Les pages dirty importent aussi : trop de pages déclenchent des tempêtes de flushing.

Décision : Si les lectures augmentent avec les écritures, ajoutez de la mémoire ou réduisez la pression de lecture (cache, changements de requêtes). Si les pages dirty sont élevées, ajustez le flushing et la taille du journal.

9) MongoDB : vérifier la santé du replica set et le retard

cr0x@server:~$ mongosh --quiet --eval 'rs.status().members.map(m=>({name:m.name,state:m.stateStr,health:m.health,lagSeconds:(m.optimeDate?Math.round((new Date()-m.optimeDate)/1000):null)}))'
[
  { name: 'mongo01:27017', state: 'PRIMARY', health: 1, lagSeconds: 0 },
  { name: 'mongo02:27017', state: 'SECONDARY', health: 1, lagSeconds: 6 },
  { name: 'mongo03:27017', state: 'SECONDARY', health: 1, lagSeconds: 84 }
]

Ce que cela signifie : Un secondaire accuse 84 secondes de retard. Si les clients utilisent w:"majority", ce retard peut ajouter directement de la latence (ou des expirations) selon le vote et les exigences de write concern.

Décision : Si des accusés majority sont requis, réparez le nœud en retard (disque, CPU, réseau) ou retirez-le temporairement du quorum de vote, avec contrôle de changement.

10) MongoDB : confirmer le write concern utilisé par l’application

cr0x@server:~$ mongosh --quiet --eval 'db.getMongo().getWriteConcern()'
{ w: 'majority', wtimeout: 0 }

Ce que cela signifie : Majority writes. Parfait pour la correction ; sous rafales, vous dépendez maintenant de la santé de la réplication et de la latence inter-nœuds.

Décision : Pendant des ingestions planifiées, envisagez un write concern différent seulement si les données peuvent être reconstruites et que le risque est documenté. Sinon, dimensionnez le replica set et le stockage pour répondre à l’exigence.

11) MongoDB : vérifier la pression du cache WiredTiger et le churn d’éviction

cr0x@server:~$ mongosh --quiet --eval 'var s=db.serverStatus().wiredTiger.cache; ({ "bytes currently in cache": s["bytes currently in the cache"], "tracked dirty bytes": s["tracked dirty bytes in the cache"], "pages evicted": s["pages evicted"] })'
{
  "bytes currently in cache": 29192355840,
  "tracked dirty bytes": 9423123456,
  "pages evicted": 182341122
}

Ce que cela signifie : Des octets dirty élevés et une éviction rapide signifient souvent que le moteur passe des cycles à pousser des données dirty, ce qui peut limiter les écritures et amplifier les blocages de checkpoint.

Décision : Si l’éviction est intense pendant les rafales, revoyez la taille du cache, la taille des documents/index, et le débit disque. N’ajoutez pas simplement de la RAM sans vérifier le comportement des checkpoints.

12) MongoDB : inspecter les opérations en cours pour symptômes de verrou/E/S

cr0x@server:~$ mongosh --quiet --eval 'db.currentOp({active:true,secs_running:{$gte:2}}).inprog.slice(0,3).map(o=>({opid:o.opid,secs:o.secs_running,ns:o.ns,desc:o.desc,waitingForLock:o.waitingForLock,locks:o.locks}))'
[
  {
    opid: 18231,
    secs: 9,
    ns: 'prod.events',
    desc: 'conn31291',
    waitingForLock: false,
    locks: { Global: 'w' }
  },
  {
    opid: 18247,
    secs: 5,
    ns: 'prod.events',
    desc: 'conn31340',
    waitingForLock: false,
    locks: { Global: 'w' }
  }
]

Ce que cela signifie : Des écritures longue durée peuvent indiquer des blocages d’E/S downstream, de la contention d’index ou une pression de journalisation. Les versions modernes de MongoDB ont des verrous finement granuleux, mais un verrou global peut encore apparaître dans les agrégations.

Décision : Si des opérations durent sans attendre de verrou, suspectez la latence du stockage ou des problèmes de checkpoint/journal. Correliez avec les métriques disque.

13) Linux : confirmer que vous n’êtes pas bridé par des cgroups

cr0x@server:~$ systemctl show mariadb -p CPUQuota -p MemoryMax
CPUQuota=50%
MemoryMax=8589934592

Ce que cela signifie : Vous avez donné à la base moitié d’un CPU et 8GB de RAM en espérant qu’elle encaisse des rafales. Audacieux.

Décision : Retirez les throttles artificiels pour les services stateful, ou concevez-les explicitement avec un contrôle d’admission et une mise en file.

14) Linux : vérifier l’activité de swap (le tueur silencieux)

cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 4  2  524288 112340  8204 3124000  40  120   210  1820  980 2200 22  7 48 23  0

Ce que cela signifie : Swap in/out pendant les rafales transforme le « stockage rapide » en « lente misère ». Les latences de la base deviennent non bornées.

Décision : Réduisez la pression mémoire (buffers, taille du cache), corrigez les workloads co-localisés, ou migrez la base vers un hôte qui ne traite pas la RAM comme optionnelle.

Trois mini-histoires d’entreprise (comment ça foire en vrai)

Mini-histoire n°1 : L’incident causé par une mauvaise hypothèse

Une entreprise SaaS de taille moyenne utilisait MongoDB pour l’ingestion d’événements. Le modèle de données avait du sens : les événements étaient des documents, le schéma évoluait chaque semaine, et le sharding était prévu. Ils avaient un replica set avec trois membres répartis sur des zones et se trouvaient plutôt mûrs.

Puis un système partenaire a commencé à relancer sur des 500 sans jitter. Les écritures ont grimpé, et le CPU du primaire est resté raisonnable. L’équipe a supposé « MongoDB tient bien les hauts débits », parce que ça avait été le cas auparavant. La latence a quand même augmenté, puis l’appli a commencé à expirer sur les écritures avec w:"majority". Le responsable d’incident a regardé les graphiques du primaire et n’a vu que quelque chose qui semblait « occupé », pas catastrophique.

La mauvaise hypothèse était subtile : ils pensaient que le write concern majority signifiait « deux sur trois, toujours rapide ». En réalité, un secondaire était dégradé depuis des semaines — encore assez sain pour voter, mais trop lent pour suivre. Sous la rafale, il a encore pris du retard. Les accusés majority dépendaient maintenant du votant le plus lent capable de rattraper son retard assez souvent pour acquitter de nouvelles opérations.

Ils ont stabilisé la situation en déclassant le secondaire dégradé (et en le réintégrant après réparation), réduisant ainsi le comportement de quorum d’ack. La solution long terme était opérationnelle : surveiller le retard de réplication avec des alertes qui déclenchent avant la crise, et ne pas laisser un votant malade rester dans le quorum pour des raisons de commodité.

Ils n’ont pas « sur-dimensionné » l’incident. Ils ont retiré l’hypothèse erronée que la santé de la topologie est optionnelle pendant les rafales. Ce n’est pas le cas.

Mini-histoire n°2 : L’optimisation qui s’est retournée contre eux

Une plateforme e‑commerce utilisait MariaDB pour les commandes et l’inventaire. Ils prévoyaient des pics d’écriture pendant les lancements, alors ils optimisèrent pour la vitesse : buffer pool plus grand, paramètres de threads agressifs, et innodb_flush_log_at_trx_commit=2 pour réduire la pression des fsync. Ça a fonctionné. La latence de commit a chuté. Tout le monde a célébré.

Puis le retournement : la même équipe a aussi augmenté la concurrence côté application pour « utiliser la nouvelle marge », et ils ont ajouté quelques index secondaires pour soutenir de nouveaux tableaux de bord. Lors de la rafale suivante, les transactions se sont accumulées derrière des verrous sur des lignes d’inventaire et des pages d’index secondaires chaudes. En même temps, les pages dirty se sont accumulées rapidement. Quand le système a dû finalement flusher agressivement, l’I/O a explosé, la latence est devenue non linéaire, et les retries de l’application l’ont transformée en tempête.

L’optimisation n’était pas mauvaise en soi. L’erreur était de penser qu’un seul réglage était une montée en capacité. En rendant les commits moins coûteux, ils ont encouragé plus d’écritures concurrentes sur les mêmes points chauds, amplifiant la contention et la pression de flushing en arrière-plan.

La correction fut de l’ingénierie terre-à-terre : supprimer un index de tableau de bord qui pénalisait le chemin d’écriture, sharder/partitionner les mises à jour d’inventaire les plus chaudes, et implémenter une limitation côté client pour que les retries ne deviennent pas de la charge. Ce n’est qu’ensuite que leur tuning de durabilité a produit des gains stables.

Mini-histoire n°3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Une société « fintech-ish » (du genre qui dit « fintech » mais vend surtout des abonnements) utilisait MariaDB pour les transactions et MongoDB pour les événements d’audit. Ils vivaient dans un monde de contrôles de conformité et de questions gênantes, donc ils étaient allergiques au « mettez ça à 0 ».

Ils faisaient aussi quelque chose de non sexy : un « exercice de rafale » mensuel. Pas un benchmark synthétique en labo — une augmentation de charge contrôlée en staging avec des volumes de données proches de la production et la même classe de stockage. Ils s’exerçaient à l’échec : retard de réplication, injection de latence disque, bascule primaire. Quelqu’un se plaignait toujours que c’était chronophage. Quelqu’un d’autre trouvait toujours quelque chose d’important.

Un mois, l’exercice révéla qu’un nouveau secondaire MongoDB dans une zone différente avait une latence fsync pire. Les majority semblaient corrects au trafic normal et devenaient problématiques seulement quand le débit doublait. Ils l’ont corrigé avant la campagne réelle en déplaçant le nœud vers une meilleure couche de stockage et en ajustant le vote pour que le membre lent ne dicte pas la latence d’ack.

Pendant la rafale réelle quelques semaines plus tard, les deux bases ont tourné chaud mais stable. L’équipe n’avait pas l’air brillante. Elle avait l’air ennuyeuse. C’est le but.

Erreurs courantes : symptômes → cause racine → correction

1) Symptom : les commits stagnent, beaucoup de threads « Waiting for redo log flush » (MariaDB)

Cause racine : la latence du fsync ou la sérialisation du redo log devient le goulot ; un journal trop petit augmente la pression.

Correction : Passez à un stockage à latence plus faible ; augmentez la taille du redo log ; validez innodb_flush_log_at_trx_commit et sync_binlog par rapport aux besoins de durabilité business ; assurez-vous que binlog et redo sont sur un stockage raisonnable.

2) Symptom : pics soudains de latence d’écriture toutes les quelques minutes (MongoDB)

Cause racine : cycles de checkpoint/journal provoquant des rafales périodiques d’E/S ; aggravé par la pression du cache.

Correction : Assurez un débit disque et une faible latence tail ; réduisez l’amplification d’écriture (index, taille des docs) ; assurez-vous que le cache WiredTiger ne prive pas le cache page de l’OS ; revoyez le comportement des checkpoints dans les métriques.

3) Symptom : les écritures MongoDB expirent seulement quand on utilise majority

Cause racine : un secondaire votant est en retard ou lent ; majority ack inclut désormais un chemin lent.

Correction : réparer/remplacer le secondaire lent ; envisager d’ajuster les membres votants ; corriger le réseau et la cohérence du stockage entre nœuds ; augmenter l’oplog si les secondaires décrochent.

4) Symptom : le CPU de MariaDB est correct, mais le QPS s’effondre

Cause racine : contention de verrous (lignes chaudes, gap locks, transactions longues) ou attente I/O ; les graphiques CPU sont trompeurs.

Correction : identifier les attentes de verrous ; réduire la portée des transactions ; éviter les compteurs chauds ; changer l’isolation ou le pattern d’accès ; ajouter des index appropriés seulement s’ils réduisent le temps de verrou (pas juste « pour les lectures »).

5) Symptom : les deux bases ralentissent « au hasard » pendant les rafales dans des VM

Cause racine : voisins bruyants et contention de stockage ; latence fsync variable ; steal CPU.

Correction : isoler le stockage ; volumes dédiés ; mesurer la tail latency de fsync ; vérifier le steal CPU ; arrêter de co-localiser des workloads batch avec la base.

6) Symptom : la rafale provoque une tempête de retries puis tout meurt

Cause racine : retries clients sans backoff ; la base devient le limiteur ; les timeouts amplifient la charge.

Correction : backoff exponentiel avec jitter ; coupe-circuit ; contrôle d’admission côté serveur ; limiter la concurrence ; retourner 429/503 intentionnellement plutôt que de laisser les timeouts provoquer une cascade.

7) Symptom : « On a monté les IOPS disque mais c’est toujours lent »

Cause racine : vous êtes limité par la sérialisation (mutex de journal, shard unique chaud), le CPU, ou la latence de réplication réseau, pas par les IOPS bruts.

Correction : mesurer où le temps est passé (fsync, verrous, ack de réplication) ; réduire les points chauds ; sharder/partitionner pour répartir les écritures ; vérifier que vous avez bien réduit la latence tail et pas seulement augmenté le débit de pointe.

Listes de contrôle / plan pas à pas

Pas à pas : préparer MariaDB pour des rafales d’écriture prévisibles

  1. Mesurer la latence tail du fsync sur la classe de volume réelle utilisée pour redo/binlog. Si le p99 est mauvais, arrêtez-vous et corrigez le stockage d’abord.
  2. Définir la durabilité intentionnellement : décider de innodb_flush_log_at_trx_commit et sync_binlog avec une déclaration de risque écrite.
  3. Redimensionner correctement les redo logs pour lisser les rafales et réduire la pression de flush.
  4. Auditer les index secondaires sur les tables fortement écrites. Supprimez les index de vanité. Conservez ceux qui évitent des scans complets qui verrouillent trop.
  5. Contrôler la taille des transactions : de petits commits sont plus faciles à regrouper et à répliquer ; de grosses transactions créent des tempêtes de verrous et de flush.
  6. Planifier la rétro-pression : définir des timeouts raisonnables, limiter la concurrence applicative, implémenter des retries avec jitter.
  7. Répétition de réplication : confirmer que les réplicas peuvent appliquer au taux de rafale ; sinon les réplicas deviennent votre problème de temps de récupération.

Pas à pas : préparer MongoDB pour des rafales d’écriture prévisibles

  1. Définir le write concern par workload (pas selon l’humeur). Écritures critiques : majority+journal. Télémétrie reconstruisible : peut-être moins, avec garde-fous.
  2. Surveiller le retard de réplication et les élections comme s’il s’agissait d’un SLO de première classe. En rafales, ça l’est.
  3. Valider le stockage pour la journalisation et les checkpoints : la faible latence tail vaut mieux que des IOPS de gros chiffre.
  4. Choisir des shard keys pour la distribution d’écriture si vous shardez. Les shards chauds transforment « distribué » en « douleur mono‑nœud avec étapes supplémentaires ».
  5. Discipline d’index : chaque index est une taxe sur votre budget d’écriture. Conservez ceux qui servent de vraies requêtes.
  6. Capacité pour cache + éviction : surveillez les octets dirty et le churn d’éviction ; évitez de tourner constamment à la limite.
  7. Timeouts et politiques de retry du driver : configurez-les consciemment ; ne laissez pas le driver « vous aider » à créer une tempête de retries.

Blague #2 : Les bases de données ne « gèrent » pas les pics. Elles négocient avec eux, et le contrat est écrit en millisecondes.

FAQ

1) Lequel est plus rapide en écriture : MariaDB ou MongoDB ?

Aucun ne « gagne » universellement. MongoDB peut ingérer rapidement avec un write concern relâché et une bonne shard key. MariaDB peut ingérer rapidement avec group commit et des index raisonnables. Sous durabilité stricte, les deux sont limités par la latence tail du fsync et l’amplification d’écriture.

2) Quelle est la raison la plus fréquente pour laquelle MariaDB fond pendant des rafales d’écriture ?

Le coût de la durabilité des commits (fsync redo/binlog) plus la pression de flush due aux pages dirty, souvent aggravés par trop d’index secondaires ou de la contention de lignes chaudes.

3) Quelle est la raison la plus fréquente pour laquelle MongoDB fond pendant des rafales d’écriture ?

Le retard de réplication combiné au write concern majority, ou des pics I/O de checkpoint/journal quand le disque ne peut pas maintenir une faible latence tail.

4) Puis-je « juste scaler horizontalement » pour survivre aux rafales ?

Parfois. Le sharding MongoDB peut répartir les écritures si vous choisissez une clé qui distribue. MariaDB peut scaler via du sharding côté application ou des solutions de clustering, mais les configurations multi‑writer ont leurs propres contraintes. L’échelle horizontale est un projet de conception, pas un bouton.

5) Est-il acceptable de désactiver la durabilité pour les rafales ?

Seulement si les données sont reconstruisables et que vous avez une procédure documentée et testée. Sinon vous échangez un incident immédiat contre un incident d’intégrité des données plus coûteux et moins pardonnable.

6) Dois-je mettre les redo logs / le journal sur des disques séparés ?

La séparation peut aider si la contention est le problème et que vous avez une isolation réelle (pas deux partitions sur le même périphérique sous-jacent). Souvent, la meilleure victoire est d’avoir moins de dispositifs, plus rapides et plus prévisibles plutôt que des agencements compliqués.

7) Quel est le meilleur indicateur unique pour survivre aux rafales ?

La latence tail des écritures durables. Pas la moyenne. Pas le débit de pointe. Si la latence p99 du commit/journal se dégrade, tout en amont commence aussi à mal se comporter.

8) « Plus de RAM » résout-il les problèmes d’écriture en rafale ?

Parfois, ça les recule. Pour MariaDB, un buffer pool plus grand réduit la contention lecture et peut lisser les écritures, mais il peut aussi permettre à plus de pages dirty de s’accumuler. Pour MongoDB, plus de cache réduit le churn, mais les checkpoints et la journalisation frappent toujours le disque. La RAM aide ; elle ne supprime pas la physique.

9) Qu’en est-il de Galera (MariaDB) vs replica sets MongoDB pour les rafales ?

Les systèmes multi‑maître quasi‑synchrone peuvent réduire une partie de la douleur de basculement mais peuvent aussi amplifier la latence d’écriture parce que la coordination devient partie intégrante de chaque commit. En rafales, le surcoût de coordination n’est pas votre ami sauf si c’est soigneusement conçu.

10) Comment choisir si mon workload a des « exigences futures inconnues » ?

Si vous avez besoin de contraintes relationnelles et de transactions complexes, commencez par MariaDB et ajoutez un store de documents là où il convient. Si votre domaine est vraiment centré document et que vous êtes engagé dans la conception des shards et la discipline du write concern, MongoDB peut être une forme opérationnelle plus simple.

Conclusion : prochaines étapes exécutables

Les rafales d’écriture ne récompensent pas l’optimisme. Elles récompensent les systèmes avec une latence d’écriture durable prévisible, une conception disciplinée du schéma/index, et une rétro-pression qui ne se transforme pas en ouragan de retries.

  • Choisissez votre posture de durabilité (paramètres de commit MariaDB / write concern MongoDB) et documentez-la comme politique.
  • Mesurez la latence tail du fsync/journal sur votre stockage réel. Si elle est incohérente, corrigez la plateforme avant de toucher aux plans de requête.
  • Organisez un exercice de rafale mensuel : retard de réplication, checkpoints, bascules, et comportement de retry côté client.
  • Implémentez du shedding de charge : limitez la concurrence, ajoutez des retries jittered, et cessez de prétendre que les timeouts sont une stratégie.
  • Réduisez l’amplification d’écriture : auditez les index, évitez les clés chaudes, et maintenez les transactions petites et ennuyeuses.

Si vous voulez un seul enseignement : MariaDB a tendance à échouer lentement et bruyamment ; MongoDB a tendance à échouer selon la topologie. Concevez pour le mode de panne que vous pouvez gérer à 2h du matin, pas pour le benchmark dont vous vous vantez à 14h.

← Précédent
Journalisation VPN pour bureaux : suivre les connexions et détecter les clients non autorisés
Suivant →
3dfx : l’ascension et le déclin d’une légende du jeu vidéo

Laisser un commentaire