Всем привет! В одном из моих проектов используется что-то вроде частного облака.
Это несколько серверов для хранения данных и несколько бездисковых серверов, отвечающих за виртуализацию.
На днях, кажется, я наконец-то поставил точку в вопросе выжимания максимальной производительности дисковой подсистемы этого решения.
Это было довольно интересно и даже в некоторых моментах весьма неожиданно.
Именно поэтому я хочу поделиться с хабра-сообществом своей историей, которая началась еще в 2008 году, еще до появления «Первого облачного провайдера России» и кампании по бесплатной рассылке счетчиков воды.
Архитектура
Эвиртуальные жесткие диски экспортируются через отдельную гигабитную сеть по протоколу Область действия .Если кратко, то это детище компании Coraid, которая предложила реализовать передачу ATA-команд по сети напрямую.
Спецификация протокола занимает всего десяток страниц! Основная особенность — отсутствие TCP/IP. При передаче данных накладные расходы минимальны, но в качестве платы за простоту маршрутизация невозможна.
Почему именно этот выбор? Если опустить перепечатку официальных источников – в т.ч.
и банальная дешевизна.
Соответственно, в СХД мы использовали обычные SATA-накопители со скоростью 7200 об/мин.
Их недостаток всем известен — низкий IOPS.
RAID10
Самый первый, популярный и очевидный способ решения проблемы скорости произвольного доступа.Мы взяли в руки mdadm, набрали в консоль пару соответствующих команд, установили поверх LVM (мы в итоге собираемся раздавать блочные устройства для виртуальных машин) и прогнали несколько наивных тестов.
Честно говоря, проверять IOPS было страшновато; вариантов решения проблемы, кроме как перейти на SCSI или написать свои костыли, по-прежнему не было.root@storage:~# hdparm -tT /dev/md127 /dev/md127: Timing cached reads: 9636 MB in 2.00 seconds = 4820.51 MB/sec Timing buffered disk reads: 1544 MB in 3.03 seconds = 509.52 MB/sec
Сеть и MTU
Хотя сеть была гигабитной, скорость чтения с бездисковых серверов была немного ниже ожидаемой ~100 МБ/сек.Естественно, виноваты оказались драйвера сетевой карты (привет, Debian).
Использование свежих драйверов с сайта производителя вроде бы частично устранило проблему.
Во всех мануалах по оптимизации скорости AoE первым пунктом стоит установка максимального MTU. На тот момент это было 4200. Сейчас это кажется смешным, но по сравнению со стандартными 1500 скорость линейного чтения реально достигала ~120МиБ/сек, круто! И даже при небольшой нагрузке на дисковую подсистему всеми виртуальными серверами локальные кэши исправляли ситуацию и внутри каждой виртуальной машины скорость линейного чтения сохранялась на уровне не менее 50МиБ/сек.
На самом деле неплохо! Со временем мы поменяли сетевые карты, свитчи и подняли MTU до максимальных 9К.
MySQL еще не прибыл
Да, в одном из проектов MySQL работал круглосуточно и без выходных, как для записи, так и для чтения.
Это выглядело примерно так: Total DISK READ: 506.61 K/s | Total DISK WRITE: 0.00 B/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
30312 be/4 mysql 247.41 K/s 11.78 K/s 0.00 % 11.10 % mysqld
30308 be/4 mysql 113.89 K/s 19.64 K/s 0.00 % 7.30 % mysqld
30306 be/4 mysql 23.56 K/s 23.56 K/s 0.00 % 5.36 % mysqld
30420 be/4 mysql 62.83 K/s 11.78 K/s 0.00 % 5.03 % mysqld
30322 be/4 mysql 23.56 K/s 23.56 K/s 0.00 % 2.58 % mysqld
30445 be/4 mysql 19.64 K/s 19.64 K/s 0.00 % 1.75 % mysqld
30183 be/4 mysql 7.85 K/s 7.85 K/s 0.00 % 1.15 % mysqld
30417 be/4 mysql 7.85 K/s 3.93 K/s 0.00 % 0.36 % mysqld
Безвреден? Как бы то ни было.
Огромный поток мелких запросов, 70% io ожидания на виртуальном сервере, 20% нагрузка на каждый из жестких дисков (по атопу) на СХД и такая печальная картина на остальных виртуальных машинах: root@mail:~# hdparm -tT /dev/xvda
/dev/xvda:
Timing cached reads: 10436 MB in 1.99 seconds = 5239.07 MB/sec
Timing buffered disk reads: 46 MB in 3.07 seconds = 14.99 MB/sec
И это еще быстрее! Зачастую скорость линейного чтения составляла не более 1-2 МиБ/сек.
Думаю, все уже догадались, с чем мы столкнулись.
Низкий IOPS дисков SATA, даже несмотря на RAID10.
Флешкэш
Эти ребята появились как раз вовремя! Это спасение, вот оно! Жизнь налаживается, мы спасемся! Срочная покупка SSD от Intel, включение модуля flashcache и утилит в живой образ серверов хранения, настройка write-back кэша и огонь в глаза.Да, все счетчики на нуле.
Ну а возможности LVM+Flashcache легко погуглить, проблема быстро решилась.
На виртуальном сервере с MySQL loadavg упал с 20 до 10. Линейное чтение на других виртуальных машинах выросло до стабильных 15-20 МБ/сек.
Мы вас не обманули!
Спустя некоторое время я собрал следующую статистику: root@storage:~# dmsetup status cachedev
0 2930294784 flashcache stats:
reads(85485411), writes(379006540)
read hits(12699803), read hit percent(14)
write hits(11805678) write hit percent(3)
dirty write hits(4984319) dirty write hit percent(1)
replacement(144261), write replacement(111410)
write invalidates(2928039), read invalidates(8099007)
pending enqueues(2688311), pending inval(1374832)
metadata dirties(11227058), metadata cleans(11238715)
metadata batch(3317915) metadata ssd writes(19147858)
cleanings(11238715) fallow cleanings(6258765)
no room(27) front merge(1919923) back merge(1058070)
disk reads(72786438), disk writes(374046436) ssd reads(23938518) ssd writes(42752696)
uncached reads(65392976), uncached writes(362807723), uncached IO requeue(13388)
uncached sequential reads(0), uncached sequential writes(0)
pid_adds(0), pid_dels(0), pid_drops(0) pid_expiry(0)
Процент попаданий при чтении: 13, процент попаданий при записи: 3. Огромное количество некэшированных операций чтения/записи.
Получается, что flashcache работал, но не на полную мощность.
Всего виртуальных машин было пару десятков, общий объем виртуальных дисков не превышал терабайта, дисковая активность была небольшой.
Те.
такой низкий процент попаданий в кэш не связан с активностью соседей.
Богоявление!
Смотрю в сотый раз: root@storage:~# dmsetup table cachedev
0 2930294784 flashcache conf:
ssd dev (/dev/sda), disk dev (/dev/md2) cache mode(WRITE_BACK)
capacity(57018M), associativity(512), data block size(4K) metadata block size(4096b)
skip sequential thresh(0K)
total blocks(14596608), cached blocks(3642185), cache percent(24)
dirty blocks(36601), dirty percent(0)
nr_queued(0)
Size Hist: 512:117531108 1024:61124866 1536:83563623 2048:89738119 2560:43968876 3072:51713913 3584:83726471 4096:41667452
Я решил открыть свой любимый Excel LibreOffice Calc:
В основе диаграммы лежит последняя строка — гистограмма распределения запросов по размерам блоков.
Мы все это знаем Жесткие диски обычно работают блоками по 512 байт. Точно так же, как и AoE. Ядро Linux — 4096 байт. Размер блока данных во flaskache также равен 4096. Суммировав количество запросов с размерами блоков, отличными от 4096, мы видим, что полученное число подозрительно совпадает с количеством некэшированных чтений + некэшированных записей из статистики flashcache. Кэшируются только блоки размером 4К! Помните, изначально у нас MTU было 4200? Если вычесть отсюда размер заголовка AoE-пакета, то получим размер блока данных 3584. Это означает, что любой запрос к дисковой подсистеме будет разбит как минимум на 2 AoE-пакета: 3584 байта и 512 байт. Именно это было ясно видно на исходной диаграмме, которую я видел.
Даже на схеме из статьи заметно преобладание пакетов размером 512 байт. И рекомендуемый на каждом углу 9К MTU тоже имеет аналогичную проблему: размер блока данных составляет 8704 байта, то есть 2 блока по 4К и один по 512 байт (именно это и наблюдается на схеме из статьи).
Упс! Решение, я думаю, очевидно для всех.
МТУ 8700
Диаграмма сделана через несколько дней после обновления конфигурации на одной из бездисковых нод. После обновления MTU на остальных ситуация станет еще лучше.
И loadavg на виртуальном сервере с MySQL упал до 3!
Заключение
Не будучи системными администраторами с 20-летним стажем, мы решали проблемы, используя «стандартные» и наиболее популярные подходы, известные сообществу на тот момент. Но в реальном мире всегда есть место несовершенствам, костылям и предположениям.С чем мы собственно и столкнулись.
Вот история.
Теги: #linux #Сетевые технологии #Системное администрирование #SAN #aoe
-
Поиск Облачных Задач. Лекция В Яндексе
19 Oct, 24 -
Спамеры Объявили Третью Мировую Войну
19 Oct, 24 -
Обновление Mozilla Firefox 2.0.0.10
19 Oct, 24