Dm-cache

Aus Thomas-Krenn-Wiki
Zur Navigation springen Zur Suche springen
Hinweis: Bitte beachten Sie, dass dieser Artikel / diese Kategorie sich entweder auf ältere Software/Hardware Komponenten bezieht oder aus sonstigen Gründen nicht mehr gewartet wird.
Diese Seite wird nicht mehr aktualisiert und ist rein zu Referenzzwecken noch hier im Archiv abrufbar.

dm_cache ist ein Cache-Target des Linux Device-Mappers. Die SSD-Caching-Software hielt mit Kernel-Version 3.9 Einzug in den Linux Kernel.[1] Mit dem Cache Target lässt sich ein schnelles Medium (z.B. eine SSD) als Cache für ein langsameres Medium (z.B. eine Festplatte) einrichten. Wie Datenblöcke in und vom Cache migriert werden kann über sogenannte Policies konfiguriert werden.[2]

Zum Caching müssen bei dm-cache insgesamt 3 Devices (eines für Metadaten, eines für den Cache und eines für die zu cachenden Daten) vorhanden sein.[3] Diese Devices müssen nicht speziell formatiert werden, daher ist es möglich bestehende Filesysteme nachträglich durch Caching zu beschleunigen. Im folgenden Beispiel-Setup sind Metadaten und Cache auf dem selben physischen Device untergebracht. Dies kann durch entsprechende Partitionierung oder beispielsweise durch ein Logical Volume (vgl. LVM Grundlagen) erreicht werden.

Hinweis: Aufgrund möglicher Beschränkungen unseres Setups war der Performancegewinn beim Einsatz von dm-cache geringer als erwartet.

Berechnung der Größe der Metadaten

Damit die Partition für die Metadaten nicht zu groß oder zu klein wird kann vorab die ungefähre Größe der Metadaten anhand der Größe des Cache-Devices berechnet werden.[4] Folgende Formel wird dazu verwendet:

4 MB + ( 16 bytes + nr_blocks )

Wir wählen eine Cache-Block-Size von 256 KB (262144 bytes).
Mit Hilfe von

  sudo blockdev --getsize64 /dev/sde #The cache device

erhalten wir die Größe des Devices in Byte. Im Beispiel 2147483648.
Nun setzen wir in die Formel ein (alle Werte in Byte):

4194304 + (16 * 2147483648 / 262144) = 4325376 (4,125MB)

Um sicher zu gehen, dass der Platz ausreicht, wird auf 5MB gerundet.

Caching Device partitionieren

Mit den Ergebnissen der Berechnung kann das Caching-Device formatiert werden. Im Beispiel wird zur Partitionierung das Kommandozeilenwerkzeug fdisk verwendet:

sudo fdisk /dev/sde

  Command (m for help): n
  Partition type:
     p   primary (0 primary, 0 extended, 4 free)
     e   extended 
  Select (default p): p
  Partition number (1-4, default 1): 
  Using default value 1
  First sector (2048-4194303, default 2048): 
  Using default value 2048
  Last sector, +sectors or +size{K,M,G} (2048-4194303, default 4194303): +5M

  Command (m for help): n
  Partition type:
     p   primary (1 primary, 0 extended, 3 free)
     e   extended
  Select (default p): p
  Partition number (1-4, default 2): 
  Using default value 2
  First sector (12288-4194303, default 12288): 
  Using default value 12288
  Last sector, +sectors or +size{K,M,G} (12288-4194303, default 4194303): 
  Using default value 4194303

  Command (m for help): v
  Remaining 2047 unallocated 512-byte sectors

  Command (m for help): w
  The partition table has been altered!

  Calling ioctl() to re-read partition table.
  Syncing disks.

Das Cache-Device wird damit in 2 Partitionen aufgeteilt - Metadaten (5MB) sowie das restliche Device als Cache.

Optional Daten-Device formatieren

Achtung: Dieser Schritt ist nur notwendig, wenn sich auf dem Daten-Device noch kein Dateisystem befindet, wenn das Device bereits formatiert ist kann dieser Schritt übersprungen werden

  sudo mkfs.ext4 /dev/sdd #The data device

Caching Einrichten

Für die Erstellung des Caches benötigen wir noch die Größe des Daten-Devices in Sektoren.

  sudo blockdev --getsz /dev/sdd #The data device

Im Beispiel liefert dieser Befehl 8388608 zurück.
Folgender Befehl richtet den Cache ein:

  sudo dmsetup create device_name --table '0 8388608 cache /dev/sde1 /dev/sde2 /dev/sdd 512 1 writeback default 0'
                                           │    │              │         │         │     │  │     │        │    └─Anzahl der Policy Argumente 
                                           │    │              │         │         │     │  │     │        └──────Verwendete Caching Policy
                                           │    │              │         │         │     │  │     └───────────────Feature-Argument:(Write-Cache (writeback oder writethrough))
                                           │    │              │         │         │     │  └─────────────────────Anzahl der Feature-Argumente
                                           │    │              │         │         │     └────────────────────────Blockgröße in Sektoren (256KB = 512*512Byte)
                                           │    │              │         │         └──────────────────────────────Daten-Device
                                           │    │              │         └────────────────────────────────────────Cache-Device
                                           │    │              └──────────────────────────────────────────────────Metadaten-Device
                                           │    └─────────────────────────────────────────────────────────────────Letzter Sektor des Devices
                                           └──────────────────────────────────────────────────────────────────────Erster Sektor des Devices

Das erstellte Device ist danch unter /dev/mapper/device_name verfügbar und kann gemountet werden.

Verwendung

Das erstellte, gecachte Device /dev/mapper/device_name ist ein herkömmliches Block-Device:

sudo mount /dev/mapper/dmcache_test /mnt

Beachten sie, dass das Device beim Reboot verloren geht. Für die automatischer Erstellung der Devices können Start- bzw. Unmount-Skripte verwenden werden. Beispiel-Skripte für Upstart und Systemd, die ein sicheres Entfernen und wieder Einhängen bei einem Reboot sicherstellen, finden sich unter:

Testen und Monitoring

Der Device-Mapper stellt über dmsetup status den aktuellen Status des Caches zur Verfügung.

  sudo dmsetup status /dev/mapper/dmcache_test

Beispielausgabe:

    0 8388608 cache 34/1280 1781667 761103 200117 225373 0 0 3567 1 1 writethrough 2 migration_threshold 2048 4 random_threshold 4 sequential_threshold 512
                      │        │       │      │      │   │ │   │  │ │      │       │          │            │  │       └──────────└───────────└───────────└─<policy args>*
                      │        │       │      │      │   │ │   │  │ │      │       │          │            │  └─<#policy args>
                      │        │       │      │      │   │ │   │  │ │      │       │          └────────────└─<core args>*
                      │        │       │      │      │   │ │   │  │ │      │       └─<#core args>
                      │        │       │      │      │   │ │   │  │ │      └─<feature args>*
                      │        │       │      │      │   │ │   │  │ └─<#feature args>
                      │        │       │      │      │   │ │   │  └─<#dirty>
                      │        │       │      │      │   │ │   └─<#blocks in cache>
                      │        │       │      │      │   │ └─<#promotions>
                      │        │       │      │      │   └─<#demotions>
                      │        │       │      │      └─<#write misses>
                      │        │       │      └─<#write hits> 
                      │        │       └─<#read misses>
                      │        └─<#read hits>
                      └─<#used metadata blocks>/<#total metadata blocks>

Die Erklärung der Variablen wird in der Kernel-Dokumentation kurz erläutert:[3]

#used metadata blocks    : Number of metadata blocks used
#total metadata blocks   : Total number of metadata blocks
#read hits               : Number of times a READ bio has been mapped to the cache
#read misses             : Number of times a READ bio has been mapped to the origin
#write hits              : Number of times a WRITE bio has been mapped to the cache
#write misses            : Number of times a WRITE bio has been mapped to the origin
#demotions               : Number of times a block has been removed from the cache
#promotions              : Number of times a block has been moved to the cache
#blocks in cache         : Number of blocks resident in the cache
#dirty                   : Number of blocks in the cache that differ from the origin
#feature args            : Number of feature args to follow
feature args             : 'writethrough' (optional)
#core args               : Number of core arguments (must be even)
core args                : Key/value pairs for tuning the core e.g. migration_threshold
#policy args             : Number of policy arguments to follow (must be even)
policy args              : Key/value pairs e.g. 'sequential_threshold 1024

Caching beenden

Beim Beenden des Caches müssen alle Daten aus dem Cache auf das Daten-Device geschrieben werden. Folgenden Befehle werden dabei verwendet:

  dmsetup suspend device_name
  dmsetup reload device_name --table '0 8388608 cache /dev/sde1 /dev/sde2 /dev/sdd 512 0 cleaner 0'
  dmsetup resume device_name
  dmsetup wait device_name

Danach sind alle Daten vom Cache auf das Daten-Device geschrieben worden und der Cache wird entfernt:

  dmsetup suspend device_name
  dmsetup clear device_name
  dmsetup remove device_name

Einzelnachweise

  1. Heise Kernel-Log – Was 3.9 bringt (heise.de)
  2. Device-Mapper Cache Policies (git.kernel.org)
  3. 3,0 3,1 Device Mapper Cache (git.kernel.org)
  4. dm-cache Mailing list - cache target (redhat.com/archives/dm-devel)

Das könnte Sie auch interessieren

HA Cluster mit Linux Container basierend auf Heartbeat, Pacemaker, DRBD und LXC
IRQ 16: nobody cared Problem beim Einsatz von mehreren NVIDIA Grafikkarten beheben
Max-hw-sectors-kb bei MegaRAID Controllern anpassen