Faut-il monter avec data = writeback et barrière = 0 sur ext3?

13

Nous avons exécuté un serveur sur une machine virtuelle dans une société d'hébergement et nous venons de nous inscrire pour un hôte dédié (AMD Opteron 3250, 4 cœurs, 8 Go de RAM, 2 x 1 To en RAID logiciel, ext3).

Lors de l'exécution des tests de performances, nous avons remarqué que certaines transitions SQLite (combinaison d'insertions, de suppressions et / ou de mises à jour) prenaient 10 à 15 fois plus longtemps que sur mon MacBook Pro 2010.

Après beaucoup de recherches et de recherches sur Google, nous avons pu examiner les options de montage, qui étaient:

    data=ordered,barrier=1

Nous avons fait quelques essais et obtenu les meilleures performances avec

    data=writeback,barrier=0

Je les ai lus et je comprends les bases de ce qu'ils font, mais je n'ai pas de bon sens / sens pour savoir si c'est une bonne idée pour nous de courir comme ça?

Des questions

La configuration ci-dessus est-elle même raisonnable à considérer pour un service hébergé?

Si nous avons eu une panne de courant ou un crash dur, nous pourrions nous retrouver avec des données perdues ou des fichiers corrompus. Si nous prenions des instantanés de la base de données toutes les 15 minutes, cela pourrait atténuer la situation, mais la base de données pourrait ne pas être synchronisée lorsque l'instantané est pris. Comment devrions-nous (pouvons-nous?) Garantir l'intégrité d'un tel instantané?

Y a-t-il d'autres options que nous devrions envisager?

Merci

NeilB
la source
De nombreux facteurs sont impliqués. Vous attendez-vous à de nombreux crashs durs? Avez-vous un onduleur (ou quelque chose d'équivalent) connecté à votre machine hébergée? Avez-vous effectué des analyses comparatives avec d'autres systèmes de fichiers (par exemple ext4, XFS, etc.)? Pouvez-vous contrôler ((dé) activer) le cache du disque dur? Comment avez-vous configuré votre RAID logiciel? Votre disque dur est-il correctement aligné (si vous avez des blocs 4K)?
Huygens
Nous n'attendons pas beaucoup de crashs durs. Nous n'avons pas d'UPS. La spécification de la machine était une norme "standard" de la société d'hébergement, donc: nous n'avons pas comparé les autres fs, ext3 est ce que nous avons obtenu. Je ne sais pas sur le cache du disque dur, examinera cela, et de même pour l'alignement RAID et disque dur. Merci.
NeilB
Une autre question que j'ai oubliée est la valeur de l'histoire que vous pouvez vous permettre de perdre? Ou vous ne pouvez vous permettre aucune perte? Remarque: SQLite prend en charge l'instantané, ou en d'autres termes la sauvegarde d'une base de données en cours d'exécution. sqlite.org/backup.html
Huygens
Quelle est votre version du noyau? Les obstacles sont honorés par md depuis la 2.6.33, pas dans la version précédente du noyau.
Huygens
uname -r signale "2.6.32-220.2.1.el6.x86_64". Qu'est-ce que "md"? Si les barrières ne sont pas respectées dans cette version du noyau, pourquoi ai-je constaté une amélioration des performances lors de la désactivation des barrières?
NeilB

Réponses:

15

Premier conseil
Si vous ne pouvez pas vous permettre de perdre des données (je veux dire une fois qu'un utilisateur a entré de nouvelles données, si cela ne peut pas être perdu dans les secondes à venir) et parce que vous n'avez pas quelque chose comme un onduleur, alors je ne supprimerais pas la barrière d'écriture, je ne passerais pas non plus en écriture différée.

Suppression des barrières d'écriture
Si vous supprimez la barrière d'écriture, en cas de panne ou de panne de courant, le système de fichiers devra effectuer un fsck pour réparer la structure du disque (notez que même avec la barrière activée, la plupart des systèmes de fichiers de journalisation feraient même un fsck mais la rediffusion du journal aurait dû être suffisante). Lors de la suppression de la barrière d'écriture, il est conseillé de supprimer si possible la mise en cache du disque (au niveau du matériel), cela permet de minimiser le risque. Vous devriez cependant évaluer l'impact d'un tel changement. Vous pouvez essayer cette commande (si votre matériel la prend en charge) hdparm -W0 /dev/<your HDD>.
Notez que ext3 utilise 2 barrières pour le changement de métadonnées, alors que ext4 n'en utilise qu'une lors de l'utilisation de l'option de montage journal_async_commit.

Bien que Ted T'so ait expliqué pourquoi quelques altérations de données se sont produites dans les premiers jours de ext3 (les barrières étaient désactivées par défaut jusqu'au noyau 3.1 ), le journal est placé de manière à ce que, à moins qu'un bouclage de journal ne se produise (le journal est un journal cyclique) les données sont écrites sur le disque dans un ordre sûr - le journal d'abord, les données ensuite - même avec le disque dur prend en charge la réorganisation des écritures.
Fondamentalement, il serait malchanceux qu'un plantage du système ou une perte d'alimentation se produise lors de l'enroulement du journal. Cependant, vous devez garder data=ordered. Essayez de comparer avec data=ordered,barrier=0en plus.

Si vous pouvez vous permettre de perdre quelques secondes de données, vous pouvez activer les deux options data=writeback,barrier=0mais essayer également d'expérimenter avec le commit=<nrsec>paramètre. Consultez le manuel de ce paramètre ici . Fondamentalement, vous donnez un nombre de secondes qui est une période pendant laquelle le système de fichiers ext3 synchronisera ses données et métadonnées.
Vous pouvez également essayer de jouer et de comparer certains ajustables du noyau concernant les pages sales (celles qui doivent être écrites sur le disque), il y a un bon article ici qui explique tout sur ces ajustables et comment jouer avec.

Résumé concernant les barrières
Vous devriez comparer quelques autres combinaisons de paramètres ajustables:

  1. Utiliser data=writeback,barrier=0en conjonction avechdparm -W0 /dev/<your HDD>
  2. Utilisation data=ordered,barrier=0
  3. Utiliser data=writeback,barrier=0en conjonction avec l'autre option de montage commit=<nrsec>et essayer différentes valeurs pour nrsec
  4. Utilisez l'option 3. et essayez de régler davantage au niveau du noyau en ce qui concerne les pages sales.
  5. Utilisez le coffre-fort data=ordered,barrier=1, mais essayez d'autres paramètres ajustables: en particulier l' ascenseur du système de fichiers (CFQ, Deadline ou Noop) et leurs paramètres ajustables respectifs.

Envisager de passer à ext4 et de le comparer
Comme dit ext4, il faut moins de barrière que ext3 pour une écriture. En outre, ext4 prend en charge les extensions qui, pour les fichiers volumineux, peuvent apporter de meilleures performances. C'est donc une solution à explorer, d'autant plus qu'il est facile de migrer d'un ext3 vers un ext4 sans réinstaller: documentation officielle ; Je l'ai fait sur un seul système mais en utilisant ce guide Debian . Ext4 est vraiment stable depuis le noyau 2.6.32, il est donc sûr de l'utiliser en production.

Dernière considération
Cette réponse est loin d'être complète, mais elle vous donne suffisamment de matériel pour commencer à enquêter. Cela dépend tellement des exigences (au niveau de l'utilisateur ou du système) qu'il est difficile d'avoir une réponse simple, désolé.

Huygens
la source
Merci - beaucoup de choses utiles là-bas. J'avais déjà lu le doc ext3 sur kernel.org, et essayé de changer de commit, mais je n'avais pas de sens pour ce qui était une grande valeur. Réglé sur 15 plutôt que 5 secondes, je n'ai vu aucun changement. Je ferai un peu plus d'analyse comparative pour couvrir les permutations que vous avez suggérées. Merci encore.
NeilB
C'était une bonne idée d'essayer d'augmenter le temps de validation tout en conservant les valeurs par défaut sûres! Il est possible que SQLite soit le rinçage / synchronisation qui pourrait expliquer pourquoi vous n'avez mesuré aucun changement de performances à l'aide de l'option de validation.
Huygens
@NeilB vient de tomber sur ces articles: 1. sqlite.org/draft/lockingv3.html y chercher ext3. Cela donne une explication peut-être plus facile (ou simplifiée) de ce que j'ai essayé d'aborder dans ma réponse. 2. sqlite.1065341.n5.nabble.com/… vous pouvez essayer de conserver les valeurs par défaut ext3 sécurisées (ordonné + barrière) mais supprimer la synchronisation dans SQLite. Je mettrai prochainement à jour ma réponse concernant ce deuxième aspect.
Huygens
Merci pour ceux-là. Je suis sur le point de travailler sur toutes les permutations et d'exécuter des tests de performances avec eux à leur tour. Au début, j'ai essayé de désactiver la synchronisation dans SQLite et j'ai obtenu de bonnes performances. Je dois d'abord écrire du code pour rassembler une plage de données pour différentes combinaisons d'opérations d'écriture. Je posterai un résumé ici, mais si vous voulez plus de détails, je suis neil chez bowers dot com.
NeilB
10

Attention: il peut y avoir des inexactitudes ci-dessous. J'ai appris beaucoup de choses au fur et à mesure, alors prenez-le avec une pincée de sel. C'est assez long, mais vous pouvez simplement lire les paramètres avec lesquels nous jouions, puis passer à la conclusion à la fin.

Il existe un certain nombre de couches où vous pouvez vous soucier des performances d'écriture SQLite:

différents niveaux de réflexion sur la performance

Nous avons examiné ceux mis en évidence en gras. Les paramètres particuliers étaient

  • Cache d'écriture sur disque. Les disques modernes ont un cache RAM qui est utilisé pour optimiser les écritures de disque par rapport au disque en rotation. Lorsque cette option est activée, les données peuvent être écrites dans des blocs désordonnés, donc en cas de panne, vous pouvez vous retrouver avec un fichier partiellement écrit. Vérifiez le paramètre avec hdparm -W / dev / ... et réglez-le avec hdparm -W1 / dev / ... (pour l'activer et -W0 pour le désactiver).
  • barrière = (0 | 1). Beaucoup de commentaires en ligne disant "si vous exécutez avec barrière = 0, alors la mise en cache d'écriture sur disque n'est pas activée". Vous pouvez trouver une discussion sur les obstacles à http://lwn.net/Articles/283161/
  • data = (journal | ordonné | écriture différée). Consultez http://www.linuxtopia.org/HowToGuides/ext3JournalingFilesystem.html pour une description de ces options.
  • commit = N. Indique à ext3 de synchroniser toutes les données et métadonnées toutes les N secondes (par défaut 5).
  • Pragma SQLite synchrone = ON | DE. Lorsqu'il est activé, SQLite s'assurera qu'une transaction est «écrite sur le disque» avant de continuer. Si vous désactivez cette option, les autres paramètres sont essentiellement hors de propos.
  • SQLite pragma cache_size. Contrôle la quantité de mémoire que SQLite utilisera pour son cache en mémoire. J'ai essayé deux tailles: une où la base de données entière tiendrait dans le cache, et une où le cache était la moitié de la taille maximale de la base de données.

En savoir plus sur les options ext3 dans la documentation ext3 .

J'ai effectué des tests de performances sur un certain nombre de combinaisons de ces paramètres. L'ID est un numéro de scénario, mentionné ci-dessous.

scénarios que j'ai essayés

J'ai commencé par exécuter la configuration par défaut sur ma machine en tant que scénario 1. Le scénario 2 est ce que je suppose être le "plus sûr", puis j'ai essayé différentes combinaisons, le cas échéant / à l'invite. C'est probablement plus facile à comprendre avec la carte que j'ai fini par utiliser:

carte reliant les scénarios aux paramètres

J'ai écrit un script de test qui a exécuté de nombreuses transactions, avec des insertions, des mises à jour et des suppressions, le tout sur des tables avec INTEGER uniquement, TEXT uniquement (avec la colonne id) ou mixtes. Je l'ai exécuté plusieurs fois sur chacune des configurations ci-dessus:

graphique montrant les horaires des scénarios

Les deux derniers scénarios sont # 6 et # 17, qui ont "pragma synchronous = off", si peu surprenant qu'ils étaient les plus rapides. Le prochain groupe de trois est # 7, # 11 et # 19. Ces trois sont surlignés en bleu sur la "carte de configuration" ci-dessus. Fondamentalement, la configuration est le cache d'écriture sur disque activé, la barrière = 0 et les données définies sur autre chose que «journal». Changer le commit entre 5 secondes (# 7) et 60 secondes (# 11) semble faire peu de différence. Sur ces tests, il ne semblait pas y avoir beaucoup de différence entre data = commandé et data = réécriture, ce qui m'a surpris.

Le test de mise à jour mixte est le pic du milieu. Il existe un groupe de scénarios qui sont plus clairement plus lents sur ce test. Ce sont tous ceux avec data = journal . Sinon, il n'y a pas grand-chose entre les autres scénarios.

J'ai eu un autre test de synchronisation, qui a fait un mélange plus hétérogène d'insertions, de mises à jour et de suppressions sur les différentes combinaisons de types. Cela a pris beaucoup plus de temps, c'est pourquoi je ne l'ai pas inclus dans l'intrigue ci-dessus:

types mixtes et insérer / mettre à jour / supprimer

Ici, vous pouvez voir que la configuration d'écriture différée (# 19) est un peu plus lente que celles commandées (# 7 et # 11). Je m'attendais à ce que l'écriture différée soit légèrement plus rapide, mais cela dépend peut-être de vos modèles d'écriture, ou peut-être que je n'ai pas encore assez lu sur ext3 :-)

Les différents scénarios étaient quelque peu représentatifs des opérations effectuées par notre application. Après avoir sélectionné une liste restreinte de scénarios, nous avons effectué des tests de synchronisation avec certaines de nos suites de tests automatisées. Ils étaient conformes aux résultats ci-dessus.

Conclusion

  • Le paramètre commit semblait faire peu de différence, donc nous le laissons à 5 secondes.
  • Nous allons avec le cache d'écriture sur disque, barrière = 0 et données = ordonnées . J'ai lu certaines choses en ligne qui pensaient que c'était une mauvaise configuration, et d'autres qui semblaient penser que cela devrait être la valeur par défaut dans de nombreuses situations. Je suppose que le plus important est que vous preniez une décision éclairée, sachant quels compromis vous faites.
  • Nous n'allons pas utiliser le pragma synchrone dans SQLite.
  • La définition du pragma SQLite cache_size pour que la base de données tienne en mémoire améliore les performances de certaines opérations, comme nous nous y attendions.
  • La configuration ci-dessus signifie que nous prenons un peu plus de risques. Nous utiliserons l' API de sauvegarde SQLite pour minimiser le risque de défaillance du disque lors d'une écriture partielle: prendre un instantané toutes les N minutes et conserver le dernier M autour. J'ai testé cette API lors de l'exécution de tests de performances, et cela nous a donné confiance pour aller dans cette direction.
  • Si nous voulions encore plus, nous pourrions envisager de nettoyer le noyau, mais nous avons suffisamment amélioré les choses sans y aller.

Merci à @Huygens pour divers conseils et conseils.

NeilB
la source