Pevný disk se SSD cache na Linuxu

Možností nastavení je v současné době několik:

  • konfigurací DM
  • aktivací v LVM
  • použitím speciálních modulů, např. EnhanceIO

Konfigurace DM

Tato konfigurace vyžaduje použití tří existujících oblastí. První představuje pomalé zařízení, tj. HDD, druhé cache, tj. SSD, a třetí obsahuje metadata, která popisují jaké bloky jsou cachovány. Metadata obsahují kromě provozních statistik i údaje o tom, zda jsou dané bloky uloženy na HDD, resp. zda vyžadují provedení zápisu na HDD. Tato oblast je proto kritická a měla by být provozována na spolehlivém zařízení.

Jedna z možných konfigurací může před HDD disk (/dev/md3) přeřazovat část SSD disku (/dev/md4), přičemž jeho začátek použije pro metadata. Určení konkrétních parametrů vychází z kapacit disků a může být následující:
dmsetup create ssd-metadata --table '0 32024 linear /dev/md4 0'
dmsetup create ssd-blocks --table '0 390427752 linear /dev/md4 32024'
dmsetup create raid-cached --table '0 3515581440 cache /dev/mapper/ssd-metadata /dev/mapper/ssd-blocks /dev/md3 512 1 writeback default 0'

Tyto operace je nutné provést při zavádění systému, což lze už snadno zrealizovat například pomocí RC-scriptu:
#!/bin/sh
#
# System startup script for DM-setup.
#
#
### BEGIN INIT INFO
# Provides:       dmsetup
# Required-Start: $syslog $local_fs $network
# Required-Stop:  $syslog $local_fs $network
# Default-Start:  3 5
# Default-Stop:   0 1 2 4 6
# Description:    lg-dmsetup
### END INIT INFO
### BEGIN CHKCONFIG INFO
# chkconfig:      2345 12 88
# description:    Dmsetup - disk manager setup for disk array
### END CHKCONFIG INFO

# Return values according to LSB for all commands except status:
# 0 - success
# 1 - generic or unspecified error
# 2 - invalid or excess argument(s)
# 3 - unimplemented feature (e.g. "reload")
# 4 - insufficient privilege
# 5 - program is not installed
# 6 - program is not configured
# 7 - program is not running
#

if [ -e /lib/lsb/init-functions ]; then
    # Debian, RHEL, Fedora, SLES and openSUSE.
    SYSTEMD_NO_WRAP="true"
    . /lib/lsb/init-functions
else
    # Slackware (Gentoo has these functions).
log_success_msg() {
    echo "$@"
}
log_failure_msg() {
    echo "$@"
}
fi

PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin

[ -x "$(which dmsetup)" ] || exit 5

if [ ! -e /lib/lsb/init-functions ]; then
    # Slackware and Gentoo.
start_daemon() {
    start_lg_dmsetup
}
killproc() {
    echo "lg_dmsetup cannot be killed"
}
fi

start_lg_dmsetup() {
    dmsetup create ssd-metadata --table '0 32024 linear /dev/md4 0'
    dmsetup create ssd-blocks --table '0 390427752 linear /dev/md4 32024'
    dmsetup create raid-cached --table '0 3515581440 cache /dev/mapper/ssd-metadata /dev/mapper/ssd-blocks /dev/md3 512 1 writeback default 0'
}

stop_lg_dmsetup() {
    echo "lg_dmsetup cannot be stopped"
}

rc=0
case "$1" in
    start)
        ## Start the service.
        echo -n "Loading and configuring lg_dmsetup"
        start_lg_dmsetup
        rc=$?
        ;;
    stop)
        ## Stop the service.
        echo -n "Stopping lg_dmsetup"
        stop_lg_dmsetup
        rc=$?
        ;;
    restart)
        ## Stop and restart the service if the service is already running,
        ## otherwise start the service.
        echo -n "Restarting lg_dmsetup"
        stop_lg_dmsetup && start_lg_dmsetup
        rc=$?
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
        exit 2
        ;;
esac

if [ $rc = 0 ]; then
    log_success_msg
else
    log_failure_msg
fi

exit $rc

Získání parametrů a iniciální aktivace vyžaduje zvláštní postup. Nesmí zapomenout především na vyčištění oblasti s metadaty, což by mohlo jinak vést k nepredikovatelným výsledkům.

Zjistíme velikost v blocích používané SSD oblasti:
blockdev --getsize64 /dev/md4
# ...velikost SSD svazku
echo '199915405312 / 512' | bc -l
# ...velikost v blocich - musi byt cele cislo bez desetinne tecky (390459776)

Oblast s metadaty vyžaduje 4MB hlavičku a na každý cachovaný blok 16 bytů. Cachovaný blok může být například o velikosti 256kB, takže dostáváme:
echo '4194304 + (16 * 199915405312 / 262144)' | bc
# ...planovana velikost metadat
echo '16396172 / 512' | bc -l
# ...v blocich, zaokrouhluje se nahoru (32024)

Rozřízneme disk na oblast s metadaty a samotnou cache
# oblast pro metadata na zacatku disku
dmsetup create ssd-metadata --table '0 32024 linear /dev/md4 0'
# oblast pro data, v blocich
echo '390459776 - 32024' | bc
dmsetup create ssd-blocks --table '0 390427752 linear /dev/md4 32024'

Nyní musíme vyčistit oblast s metadaty:
# vycisteni inicialni cache - datovy svazek pak zustane v puvodnim stavu
dd if=/dev/zero of=/dev/mapper/ssd-metadata

A nakonec svážeme cache s vlastním datovým prostorem, přičemž si nejprve zjistíme jeho velikost:
# prirazeni md4 k md3
blockdev --getsize64 /dev/md3
# ...velikost datoveho svazku
echo '1799977697280 / 512' | bc
# ...v blocich (3515581440)

Samotnou vazbu, včetně volby typu cache, provedeme už jen závěrečným povelem pro DM:
dmsetup create raid-cached --table '0 3515581440 cache /dev/mapper/ssd-metadata /dev/mapper/ssd-blocks /dev/md3 512 1 writeback default 0'

-- LeoGalambos - 05 Aug 2016
Topic revision: r1 - 05 Aug 2016, LeoGalambos
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback