
Une courte histoire sur fio et etcd
Les performances du cluster etcd dépendent largement des performances de son stockage. etcd exporte certaines métriques vers Prometheus pour fournir les informations nécessaires sur les performances de stockage. Par exemple, la métrique wal_fsync_duration_seconds. La documentation pour etcd dit : pour que le stockage soit considéré comme assez rapide, le 99e centile de cette métrique doit être inférieur à 10 ms. Si vous prévoyez d'exécuter le cluster etcd sur des machines Linux et que vous souhaitez évaluer si votre stockage est suffisamment rapide (comme les SSD), vous pouvez utiliser fio , un outil populaire pour tester les opérations d'E / S. Exécutez la commande suivante, où test-data est le répertoire sous le point de montage de stockage:
fio --rw=write --ioengine=sync --fdatasync=1 --directory=test-data --size=22m --bs=2300 --name=mytest
Il vous suffit d'examiner les résultats et de vérifier que le 99e centile de la durée fdatasync est inférieur à 10 ms. Si oui, vous disposez d'un stockage assez rapide. Voici un exemple des résultats:
sync (usec): min=534, max=15766, avg=1273.08, stdev=1084.70 sync percentiles (usec): | 1.00th=[ 553], 5.00th=[ 578], 10.00th=[ 594], 20.00th=[ 627], | 30.00th=[ 709], 40.00th=[ 750], 50.00th=[ 783], 60.00th=[ 1549], | 70.00th=[ 1729], 80.00th=[ 1991], 90.00th=[ 2180], 95.00th=[ 2278], | 99.00th=[ 2376], 99.50th=[ 9634], 99.90th=[15795], 99.95th=[15795], | 99.99th=[15795]
Remarques
- Nous avons configuré les options --size et --bs pour notre scénario spécifique. Pour obtenir un résultat utile de fio, entrez vos valeurs. Où les obtenir? Découvrez comment nous avons appris à configurer fio .
- Pendant les tests, la charge d'E / S entière provient de fio. Dans un scénario réel, il est probable que d'autres demandes d'écriture parviennent au référentiel, à l'exception de celles liées à wal_fsync_duration_seconds. Une charge supplémentaire augmentera la valeur de wal_fsync_duration_seconds. Donc, si le 99e centile a presque atteint 10 ms, votre stockage n'aura pas assez de vitesse.
- Prenez la version fio pas inférieure à 3,5 (les précédentes ne montrent pas les centiles de la durée fdatasync).
- Ci-dessus n'est qu'un extrait des résultats de fio.
Une longue histoire sur fio et etcd
Qu'est-ce que WAL dans etcd
Les bases de données utilisent généralement des journaux d'écriture anticipée ; etcd l'utilise aussi. Ici, nous ne discuterons pas en détail du journal d'écriture anticipée (WAL). Nous avons seulement besoin de savoir que chaque membre du cluster etcd le maintient dans un stockage persistant. etcd écrit chaque opération de paire clé-valeur (par exemple, la mise à jour) dans le WAL avant de les appliquer au référentiel. Si entre les instantanés l'un des membres de stockage se bloque et redémarre, il peut récupérer localement les transactions du dernier instantané en utilisant le contenu WAL.
Lorsqu'un client ajoute une clé à un magasin de paires clé-valeur ou met à jour la valeur d'une clé existante, etcd enregistre cette opération dans le WAL, qui est un fichier normal dans un stockage persistant. Avant de continuer, etcd DOIT être complètement sûr que l'écriture dans le WAL a vraiment eu lieu. Sous Linux, un seul appel système d' écriture n'est pas suffisant pour cela, car l'écriture sur le stockage physique peut être retardée. Par exemple, Linux peut stocker un enregistrement WAL dans un cache de la mémoire du noyau pendant un certain temps (par exemple, un cache de page). Et pour que les données soient écrites avec précision dans le stockage persistant, vous avez besoin de l'appel système fdatasync après l'écriture, et etcd l'utilise simplement (comme vous pouvez le voir dans strace , où 8 est le descripteur de fichier WAL):
21:23:09.894875 lseek(8, 0, SEEK_CUR) = 12808 <0.000012> 21:23:09.894911 write(8, ".\0\0\0\0\0\0\202\10\2\20\361\223\255\266\6\32$\10\0\20\10\30\26\"\34\"\r\n\3fo"..., 2296) = 2296 <0.000130> 21:23:09.895041 fdatasync(8) = 0 <0.008314>
Malheureusement, l'écriture sur un stockage persistant ne se fait pas instantanément. Si l'appel fdatasync est lent, les performances du système etcd chutent. La documentation pour etcd indique que le référentiel est considéré comme assez rapide si dans le 99e centile des appels fdatasync, il faut moins de 10 ms pour écrire dans le fichier WAL. Il existe d'autres mesures utiles pour le stockage, mais dans cet article, nous ne parlons que de cette mesure.
Évaluer le stockage avec fio
Si vous devez évaluer si votre référentiel est adapté à etcd, utilisez fio, un outil de test de charge d'E / S très populaire. Il ne faut pas oublier que les opérations sur disque peuvent être très différentes: synchrones et asynchrones, de nombreuses classes d'appels système, etc. Par conséquent, fio est très difficile à utiliser. Il a de nombreux paramètres et différentes combinaisons de leurs valeurs produisent des charges de travail d'E / S complètement différentes. Pour obtenir des nombres adéquats pour etcd, vous devez vous assurer que la charge d'enregistrement de test de fio est aussi proche que possible de la charge réelle de etcd lors de l'écriture de fichiers WAL.
Par conséquent, fio doit au moins créer une charge sous la forme d'une série d'opérations d'écriture séquentielles dans le fichier, chaque enregistrement sera composé d'un appel système d' écriture suivi d'un appel système fdatasync. Pour les opérations d'écriture séquentielle, fio a besoin de l'option --rw = write. Pour que fio utilise l'appel système d'écriture plutôt que pwrite lors de l'enregistrement, il convient de spécifier le paramètre --ioengine = sync. Enfin, pour que fdatasync soit appelé après chaque entrée, vous devez ajouter le paramètre --fdatasync = 1. Les deux autres options de cet exemple (--size et --bs) sont spécifiques au scénario. Dans la section suivante, nous vous montrerons comment les configurer.
Pourquoi Fio et comment nous avons appris à le configurer
Dans cet article, nous décrivons le cas réel. Nous avions un cluster Kubernetes v1.13, que nous avons contrôlé à l'aide de Prometheus. etcd v3.2.24 était hébergé sur un SSD. Les métriques Etcd ont montré des latences trop élevées pour fdatasync, même lorsque le cluster ne faisait rien. Les mesures étaient étranges et nous ne savions vraiment pas ce qu'elles signifiaient. Le cluster était composé de machines virtuelles, il fallait comprendre quel était le problème: dans les SSD physiques ou dans la couche de virtualisation. De plus, nous avons souvent apporté des modifications à la configuration matérielle et logicielle, et nous avions besoin d'un moyen d'évaluer leurs résultats. Nous pourrions exécuter etcd dans chaque configuration et regarder les métriques de Prometheus, mais c'est trop gênant. Nous recherchions un moyen assez simple d'évaluer une configuration spécifique. Nous voulions vérifier si nous comprenions correctement les métriques Prometheus de etcd.
Mais pour cela, il fallait résoudre deux problèmes. Tout d'abord, à quoi ressemble la charge d'E / S créée par etcd lors de l'écriture dans le WAL? Quels appels système sont utilisés? Quelle est la taille des enregistrements? Deuxièmement, si nous répondons à ces questions, comment reproduire une charge de travail similaire avec fio? N'oubliez pas que fio est un outil très flexible avec de nombreuses options. Nous avons résolu les deux problèmes avec une seule approche - en utilisant les commandes lsof et strace . lsof affiche tous les descripteurs de fichiers utilisés par le processus et ses fichiers associés. Et avec strace, vous pouvez étudier un processus déjà en cours ou démarrer un processus et l'étudier. strace affiche tous les appels système du processus étudié (et de ses processus enfants). Ce dernier est très important, car etcd adopte simplement une approche similaire.
Tout d'abord, nous avons utilisé strace pour apprendre le serveur etcd pour Kubernetes lorsqu'il n'y avait pas de charge sur le cluster. Nous avons vu que presque tous les enregistrements WAL avaient à peu près la même taille: 2200-2400 octets. Par conséquent, dans la commande au début de la publication, nous avons spécifié le paramètre --bs = 2300 (bs signifie la taille en octets pour chaque entrée fio). Notez que la taille de l'entrée etcd dépend de la version de etcd, de la livraison, des valeurs des paramètres, etc., et affecte la durée de fdatasync. Si vous avez un scénario similaire, examinez vos processus etcd avec strace pour connaître les nombres exacts.
Ensuite, pour avoir une bonne idée des actions dans le système de fichiers etcd, nous l'avons démarré avec strace et avec les options -ffttT. Nous avons donc essayé d'étudier les processus enfants et d'écrire la sortie de chacun d'eux dans un fichier séparé, et d'obtenir également des rapports détaillés sur le début et la durée de chaque appel système. Nous avons utilisé lsof pour confirmer notre analyse de la sortie strace et voir quel descripteur de fichier a été utilisé dans quel but. Donc, avec Strace, nous avons obtenu les résultats ci-dessus. Les statistiques sur le temps de synchronisation ont confirmé que l'indicateur wal_fsync_duration_seconds de etcd correspond aux appels fdatasync avec des descripteurs de fichier WAL.
Nous avons étudié la documentation de fio et sélectionné les options de notre script afin que fio génère une charge similaire à etcd. Nous avons également vérifié les appels système et leur durée en exécutant fio à partir de strace, similaire à etcd.
Nous avons soigneusement sélectionné la valeur du paramètre --size, qui représente la charge d'E / S entière de fio. Dans notre cas, il s'agit du nombre total d'octets écrits dans le stockage. Il s'est avéré être directement proportionnel au nombre d'appels système en écriture (et fdatasync). Pour une valeur bs spécifique, le nombre d'appels à fdatasync = size / bs. Puisque nous étions intéressés par le centile, nous aurions dû avoir suffisamment d'échantillons pour la fiabilité, et nous avons calculé que 10 ^ 4 nous suffiraient (nous obtenons 22 mégaoctets). Si --size est plus petit, des valeurs aberrantes peuvent se produire (par exemple, plusieurs appels fdatasync fonctionnent plus longtemps que d'habitude et affectent le 99e centile).
Essayez-le vous-même
Nous avons montré comment utiliser fio et savoir si le stockage a une vitesse suffisante pour des performances élevées, etc. Vous pouvez maintenant l'essayer en pratique par vous-même, en utilisant, par exemple, des machines virtuelles avec stockage SSD dans IBM Cloud .