web-dev-qa-db-fra.com

Comment purger les caches d'E / S disque sous Linux?

Je dois le faire pour une analyse comparative plus prévisible.

50
taw

On dirait que vous voulez la commande sync ou la fonction sync () .

Si vous souhaitez vider le cache du disque: echo 3 | Sudo tee /proc/sys/vm/drop_caches

55
Chris Dennett

Vous pouvez le faire comme ceci:

# sync # (move data, modified through FS -> HDD cache) + flush HDD cache
# echo 3 > /proc/sys/vm/drop_caches # (slab + pagecache) -> HDD (https://www.kernel.org/doc/Documentation/sysctl/vm.txt)
# blockdev --flushbufs /dev/sda
# hdparm -F /dev/sda

# NEXT COMMAND IS NOT FOR BENCHMARKING:
# should be run before unplug, flushes everything possible guaranteed.
# echo 1 > /sys/block/sdX/device/delete

Vous pouvez utiliser strace pour voir qu'il s'agit de trois appels système différents

En outre, il peut être souhaitable de désactiver le cache du disque dur à l'aide de hdparm, vous ne savez pas ce que vous comparez.

De toute façon, vous ne pouvez pas empêcher le disque dur de mettre en cache les derniers 64/32/16 Mo de données récemment utilisées. Afin de tuer ce cache, il suffit d'écrire une certaine quantité de zéros (et de vider) + de lire un endroit sans rapport avec le disque dur. Cela est nécessaire car le cache peut être divisé en partie lecture et partie écriture. Après cela, vous pouvez comparer le disque dur.

35
socketpair

Purge du cache disque: echo 3 | Sudo tee /proc/sys/vm/drop_caches

Documentation de commande: https://www.kernel.org/doc/Documentation/sysctl/vm.txt

Si vous y écrivez, le noyau supprimera de la mémoire les caches, les dentiers et les inodes propres, ce qui rendra cette mémoire libre.

Pour libérer la pagecache:

echo 1 > /proc/sys/vm/drop_caches

Pour libérer des dentiers et des inodes:

echo 2 > /proc/sys/vm/drop_caches

Pour libérer la pagecache, les dentiers et les inodes:

echo 3 > /proc/sys/vm/drop_caches

Comme il s'agit d'une opération non destructive et que les objets sales ne sont pas libérables, l'utilisateur doit d'abord exécuter la "synchronisation" afin de s'assurer que tous les objets mis en cache sont libérés.

21
Piotr Jurkiewicz

Réponse courte et assez bonne: (copier-coller convivial)

DISK=/dev/sdX # <===ADJUST THIS===
sync
echo 3 > /proc/sys/vm/drop_caches
blockdev --flushbufs $DISK
hdparm -F $DISK

Explication:

sync: Depuis la page de manuel: vidage des tampons du système de fichiers. Forcer les blocs modifiés sur le disque, mettre à jour le super bloc.

echo 3 > /proc/sys/vm/drop_cache: à partir des documents du noya cela entraînera le noyau à supprimer des caches propres

blockdev --flushbufs /dev/sda: à partir de la page de manuel: appeler le périphérique de bloc ioctls [pour] vider les tampons.

hdparm -F /dev/sda: à partir de la page de manuel: Vider le tampon du cache d'écriture sur le lecteur (les anciens lecteurs peuvent ne pas implémenter cela)

Bien que les commandes blockdev et hdparm se ressemblent selon ne réponse ci-dessus , elles émettent différents ioctls au périphérique.

Longue façon probablement meilleure:

(Je suppose que vous avez formaté le disque mais vous pouvez adapter ces commandes si vous souhaitez écrire directement sur le disque)

Exécutez ceci une seule fois avant le 1er benchmark:

MOUNT=/mnt/test # <===ADJUST THIS===
# create a file with psuedo-random data. We will read it
# to fill the read cache of the HDD with garbage
dd if=/dev/urandom of=$MOUNT/temp-hddread.tmp bs=64M count=16

Exécutez cela chaque fois que vous souhaitez vider les caches:

DISK=/dev/sdX # <===ADJUST THIS===
MOUNT=/mnt/test # <===AND THIS===
# create a file with psuedo-random data to fill the write cache
# of the disk with garbage. Delete it afterwards it's not useful anymore
dd if=/dev/urandom of=$MOUNT/temp-hddwrite.tmp bs=64M count=16
rm $MOUNT/temp-hddwrite.tmp
# see short good enough answer above
sync
echo 3 > /proc/sys/vm/drop_caches
blockdev --flushbufs $DISK
hdparm -F $DISK
# read the file with pseudo-random data to fill any read-cache
# the disk may have with garbage
dd if=$MOUNT/temp-hddread.tmp of=/dev/null

Exécutez cela lorsque vous avez terminé.

MOUNT=/mnt/test # <===ADJUST THIS===
# delete the temporary file with pseudo-random data
rm $MOUNT/temp-hddread.tmp

Explication:

Le disque aura probablement un cache H/W. Certains disques, de par leur conception ou en raison de bogues, peuvent ne pas vider leur cache lorsque vous exécutez les commandes blockdev et hdparm. Pour compenser, nous écrivons et lisons des sauts de données pseudo-aléatoires pour remplir ces caches afin que toutes les données mises en cache leur soient supprimées. La quantité de données dont vous avez besoin pour remplir le cache dépend de sa taille. Dans les commandes ci-dessus, j'utilise dd pour lire/écrire 16 * 64 Mo = 1024 Mo, ajustez les arguments si votre disque dur peut avoir un cache plus important (les fiches techniques et l'expérimentation sont votre ami et cela ne fait pas de mal de spécifier des valeurs supérieures à la taille réelle du cache). J'utilise/dev/urandom comme source de données aléatoires car c'est rapide et nous ne nous soucions pas de vrai aléatoire (nous ne nous soucions que d'une entropie élevée parce que le firmware du disque mai utiliser la compression avant de stocker les données dans le cache). Je crée /mnt/test/temp-hddread.tmp depuis le début et l'utilise chaque fois que je veux lire suffisamment de données aléatoires. Je crée et supprime /mnt/test/temp-hddwrite.tmp chaque fois que je veux écrire suffisamment de données aléatoires.

Crédits

J'ai écrit cette réponse sur la base des meilleures parties des réponses existantes.

8
ndemou

Le démontage et le remontage du disque sous test réinitialisera tous les caches et tampons.

2
Phil