Pull to refresh

Flashcache: первый опыт

Reading time6 min
Views9K
Дисковая подсистема зачастую является узким местом в производительности серверов, заставляя компании вкладывать значительные средства в быстрые диски и специализированные решения. В настоящее время всё больше набирают популярность твердотельные SSD-накопители, но они всё ещё слишком дороги по сравнению с традиционными жёсткими дисками. Тем не менее, существуют технологии, разработанные для того, чтобы сочетать скорость SSD с объёмом HDD. Это технологии кэширования, когда объём дискового кэша на SSD составляет гигабайты, а не мегабайты кэша HDD или контроллера.

Одна из таких технологий — flashcache, разработанная в Facebook для использования со своими базами данных, и которая теперь распространяется с открытым исходным кодом. Я уже давно присматривался к ней. Наконец, подвернулась возможность протестировать её, когда я решил поставить в домашний компьютер SSD-накопитель в качестве системного диска.

И, прежде чем ставить SSD в домашний комп, я подключил его к серверу, который как раз оказался свободным для тестирования. Далее я опишу процесс установки flashcache на ОС CentOS 6.3 и приведу результаты некоторых тестов.

Имеется сервер с 4 SATA-дисками Western Digital Caviar Black WD1002FAEX, объединёнными в программный RAID10, 2 процессорами Xeon E5-2620 и 8 ГБ оперативной памяти. Выбор твердотельного накопителя пал на OCZ Vertex-3 объёмом 90 ГБ. SSD подключён к 6-гигабитному порту SATA, жёсткие диски — к 3-гигабитным портам. Диск SSD определился как /dev/sda.

Для экспериментов я оставил неразмеченной большую область дискового пространства, на RAID-устройстве /dev/md3, в котором создал группу томов LVM с именем vg1, и логический том LVM размером 100ГБ с именем lv1:

# lvcreate -L 100G -n lv1 vg1
# mkfs -t ext4 /dev/vg1/lv1


На этом томе я и тестировал flashcache.

Установка flashcache


С недавних пор установка flashcache стала элементарной: в репозитории elrepo теперь есть бинарные пакеты. До этого было необходимо компилировать утилиты и модуль ядра из исходников.
Подключим репозиторий elrepo:

# rpm -Uvh http://elrepo.reloumirrors.net/elrepo/el6/x86_64/RPMS/elrepo-release-6-4.el6.elrepo.noarch.rpm


Flashcache состоит из модуля ядра и управляющих утилит. Вся установка сводится к одной кодманде:

# yum -y install kmod-flashcache flashcache-utils


Flashcache может работать в одном из трёх режимов:

  • writethrough — в кэше сохраняются операции чтения и записи, запись на диск производится незамедлительно. В этом режиме гарантируется целостность данных.
  • writearound — аналогично предыдущему, за исключением того, что в кэше сохраняются только операции чтения.
  • writeback — самый быстрый режим, поскольку в кэше сохраняются операции чтения и записи, но на диск данные сбрасываются в фоновом режиме, через некоторое время. Этот режим не столь безопасен с точки зрения сохранности целостности данных, так как есть риск того, что данные не будут записаны на диск при внезапном сбое сервера или потере питания.


Для управления в комплекте идут три утилиты: flashcache_create, flashcache_load и flashcache_destroy. Первая служит для создания кэширующего устройства, две другие нужны для работы только в режиме writeback для загрузки существующего кэширующего устройства и для его удаления соответственно.

flashcache_create имеет следующие основные параметры:
  • -p — режим кэширования. Обязательный параметр. Может принимать значения thru, around и back для включения режимов writethrough, writearound и writeback соответственно.
  • -s — размер кэша. Если этот параметр не указан, под кэш будет использоваться весь SSD-диск.
  • -b — размер блока. По умолчанию — 4КБ. Оптимально для большинства случаев использования.


Создадим кэш.

# flashcache_create -p thru cachedev /dev/sda /dev/vg1/lv1
cachedev cachedev, ssd_devname /dev/sda, disk_devname /dev/vg1/lv1 cache mode WRITE_THROUGH
block_size 8, cache_size 0
Flashcache metadata will use 335MB of your 7842MB main memory


Эта команда создаёт кэширующее устройство с именем cachedev, работающее в режиме writethrough на SSD /dev/sda для блочного устройства /dev/vg1/lv1.

В результате должно появиться устройство /dev/mapper/cachedev, а команда dmsetup status должна отобразить статистику по различным операциям с кэшем:

# dmsetup status
vg1-lv1: 0 209715200 linear
cachedev: 0 3463845888 flashcache stats:
        reads(142), writes(0)
        read hits(50), read hit percent(35)
        write hits(0) write hit percent(0)
        replacement(0), write replacement(0)
        write invalidates(0), read invalidates(0)
        pending enqueues(0), pending inval(0)
        no room(0)
        disk reads(92), disk writes(0) ssd reads(50) ssd writes(92)
        uncached reads(0), uncached writes(0), uncached IO requeue(0)
        uncached sequential reads(0), uncached sequential writes(0)
        pid_adds(0), pid_dels(0), pid_drops(0) pid_expiry(0)


Теперь можно монтировать раздел и начинать тестирование. Следует обратить внимание на момент, что монтировать нужно не сам раздел, а кэширующее устройство:

# mount /dev/mapper/cachedev /lv1/


Вот и всё: теперь дисковые операции в директории /lv1/ будут кэшироваться на SSD.

Опишу один нюанс, который может быть полезен при работе не с отдельным томом LVM, а с группой томов. Кэш можно создать на блочном устройстве, содержащем группу LVM, в моём случае — это /dev/md3:

# flashcache_create -p thru cachedev /dev/sda /dev/md3


Но для того, чтобы всё заработало, необходимо изменить настройки конфигурации LVM, отвечающие за поиск томов. Для этого в файле /etc/lvm/lvm.conf установить фильтр:
filter = [ "r/md3/" ]
либо ограничить поиск LVM только по директории /dev/mapper:
scan = [ "/dev/mapper" ]

После сохранения изменений нужно сообщить об этом подсистеме LVM:

# vgchange -ay


Тестирование


Я провёл три вида тестов:

  • тестирование утилитой iozone в различных режимах кэширования;
  • последовательное чтение командой dd в 1 и 4 потока;
  • чтение набора файлов различного размера, взятых из бэкапов реальных сайтов.


Тестирование iozone

Утилита есть в репозитории rpmforge.

# rpm -Uvh http://apt.sw.be/redhat/el6/en/x86_64/rpmforge/RPMS/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm
# yum -y install iozone


Тест запускался следующим образом:

# cd /lv1/
# iozone -a -i0 -i1 -i2 -s8G -r64k


iozone

Диаграмма показывает небольшую потерю производительности при включенном кэше при операциях последовательной записи и чтения, однако в операциях случайного чтения даёт многократный прирост производительности. Режим writeback уходит в отрыв также и на операциях записи.

Тестирование dd

Тест последовательного чтения запускался следующими командами.
В один поток:

# dd if=/dev/vg1/lv1 of=/dev/null bs=1M count=1024 iflag=direct


В 4 потока:

# dd if=/dev/vg1/lv1 of=/dev/null bs=1M count=1024 iflag=direct skip=1024 & dd if=/dev/vg1/lv1 of=/dev/null bs=1M count=1024 iflag=direct skip=2048 & dd if=/dev/vg1/lv1 of=/dev/null bs=1M count=1024 iflag=direct skip=3072 & dd if=/dev/vg1/lv1 of=/dev/null bs=1M count=1024 iflag=direct skip=4096


Перед каждым запуском выполнялась команда для очистки кэша RAM:

# echo 3 > /proc/sys/vm/drop_caches


dd

Кэшированное многопоточное чтение демонстрирует скорость, близкую к максимальной скорости SSD-накопителя, однако при первом запуске скорость ниже, чем без кэша. Это, скорее всего, связано с тем, что наряду с отдачей потока данных системе приходится записывать информацию на твердотельный накопитель. Однако, при повторном запуске вся информация уже записана на SSD и отдаётся с максимальной скоростью.

Тест чтения различных файлов

Напоследок, небольшой тест времени чтения большого количества файлов различных размеров. Я взял несколько десятков реальных сайтов из резервных копий, распаковал их в директорию /lv1/sites/. Суммарный объём файлов составил около 20 ГБ, а количество — порядка 760 тысяч.

# cd /lv1/sites/
# echo 3 > /proc/sys/vm/drop_caches
# time find . -type f -print0 | xargs -0 cat >/dev/null


Последняя команда ищет в текущей директории все файлы, и прочитывает их, засекая при этом время общего выполнения.

sites

На диаграмме видим ожидаемую потерю производительности «в первом чтении», которая составила порядка 25%, зато при повторном запуске команда выполнилась более, чем в 3 раза, быстрее по сравнению с операцией без кэша.

Отключение кэша


Перед удалением кэширующего устройства необходимо размонтировать раздел:

# umount /lv1/


Либо, если вы работали с группой томов, то отключить LVM:

# vgchange -an


Затем удаляем кэш:

# dmsetup remove cachedev


Заключение


Я не коснулся тонких настроек flashcache, которые можно регулировать с помощью sysctl. Среди них выбор алгоритма записи в кэш FIFO или LRU, порог кэширования при последовательном доступе и др. Думаю, что с помощью этих настроек можно выжать ещё немного прироста производительности, если адаптировать их под нужные условия работы.

Технология показала себя наилучшим образом преимущественно в операциях случайного чтения, продемонстрировав многократный прирост производительности. А ведь в реальных условиях на серверах чаще всего используются именно случайные операции ввода-вывода. Поэтому, путём минимальных капиталовложений появилась возможность сочетать скорость твердотельных накопителей с объёмом традиционных жёстких дисков, а наличие пакетов в репозиториях делает установку простой и быстрой.

При подготовке статьи я использовал официальную документацию от разработчиков, с которой можно ознакомиться здесь.

На этом всё. Надеюсь, эта информация окажется кому-нибудь полезной. Буду рад комментариям, замечаниям и рекомендациям. Особенно интересно было бы узнать опыт использования flashcache на боевых серверах, и, в частности, нюансы использования в режиме writeback.
Tags:
Hubs:
Total votes 22: ↑22 and ↓0+22
Comments18

Articles