ServerAdmin.ru
31.6K subscribers
841 photos
57 videos
23 files
2.99K links
Авторская информация о системном администрировании.

Информация о рекламе: @srv_admin_reklama_bot
Автор: @zeroxzed

Второй канал: @srv_admin_live
Сайт: serveradmin.ru

Ресурс включён в перечень Роскомнадзора
Download Telegram
В Proxmox существуют различные настройки кэширования дисков виртуальных машин. По умолчанию стоит режим Default (No cache). Считается, что это оптимальный вариант для виртуальной машины общего назначения. Хост данные не кэширует вообще. Гостевая система работает с виртуальным диском как-будто напрямую с физическим в режиме writeback. Она понимает, когда устройство хранения еще не записало данные, но поместило в очередь на запись. Так что виртуалка будет ожидать окончания реальной записи перед сбросом своего дискового кэша, для того, чтобы не было повреждения данных.

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

cache=writeback - хост использует свой кэш и при чтении, и при записи, диск виртуалки тоже работает в режиме writeback. Гостевая система будет получать команду о том, что запись завершена после помещения данных в кэш хоста, а не реальной записи на устройство хранения. Теоретически, это вариант с максимальным быстродействием дисков виртуальных машин. Но в случае каких-то проблем с питанием, хостом, очень велик шанс потери данных.

cache=directsync - хост не использует кэширование вообще, диск виртулаки работает в режиме writethrough, то есть всегда ждёт реальной записи данных на устройство хранения. Максимально надежный вариант сохранности данных. Очевидно, что скорость записи будет минимальной в этом режиме работы дисков.

cache=unsafe - как я понял, это то же самое, что и writeback, только гостевая система вообще не сбрасывает свой дисковый кэш (doesn't flush data, fastest and unsafest). Я до конца не понял смысл этого режима.

Рассказанное выше мой пересказ официальной статьи в wiki по этой теме - https://pve.proxmox.com/wiki/Performance_Tweaks#Disk_Cache Полезно выбирать подходящие режимы под конкретную ситуацию, а не использовать всё время дефолт. Можно лишние 10-20% производительности получить на ровном месте.

И еще важное дополнение. Режимы работы нужно выбирать не только исходя из назначения вирутальной машины, но и в соответствии с параметрами самого storage. К примеру, если storage это локальный raid контроллер со своим кэшем и батарейкой, очевидно, что кэширование гипервизора здесь не нужно. А если обычный mdadm, то можно попробовать включить.

Я такие записи обычно держу в закладках. Особенно это касается настройки рейд контроллеров, которые не так часто выполняешь. Каждый раз начинаю вспоминать, какой режим кэширования выбрать. Там примерно то же самое, то и тут.

#proxmox
👍7
Тема тестирования производительности диска непростая. Если есть время и чёткая задача, то с помощью fio и продолжительного времени на тесты, можно добиться стабильного результата. А если хочется быстро оценить работу диска и сравнить результат, то возникают вопросы даже с самым простым тестом на последовательную запись.

Я попытался немного разобраться с этой темой и сделал ряд тестов в виртуальных машинах. Основные сложности тут следующие:

1️⃣ Если просто писать данные на диск с уровня операционной системы Linux, то она будет их кэшировать, пока у неё достаточно оперативной памяти для этого. Если не учитывать этот момент, то результаты будут разными в зависимости от объёма оперативной памяти и размера записываемых данных.

2️⃣ Если речь идёт о виртуальных машинах, то там есть слой кэширования гипервизора.

3️⃣ Если используется аппаратный рейд контроллер, то там есть свой слой кэширования, плюс запись в несколько потоков может идти быстрее, чем в один.

На практике это выглядит так. Берём виртуальную машину на Proxmox с 1G оперативной памяти и виртуальным диском без кэширования. Пробуем тесты на запись с помощью dd и разных флагов:

# dd if=/dev/zero of=/tempfile bs=1M count=512
259 MB/s

# dd if=/dev/zero of=/tempfile bs=1M count=2000
247 MB/s

# dd if=/dev/zero of=/tempfile bs=1M count=2000 oflag=direct
240 MB/s

# dd if=/dev/zero of=/tempfile bs=1M count=2000 oflag=dsync
123 MB/s

# dd if=/dev/zero of=/tempfile bs=1M count=2000 oflag=sync
123 MB/s

Используются флаги:

▪️direct - прямая запись в обход файлового кэша и синхронизации
▪️dsync - запись данных с синхронизацией каждого блока, то есть ждём подтверждение диска об успешной записи
▪️sync - запись данных и метаданных с синхронизацией

Результаты меня удивили. Я всегда был уверен, что запись dd по умолчанию будет вестись в кэш ОС, если хватает оперативной памяти. Я провёл много тестов на разных виртуалках, в разных гипервизорах, с разным количеством памяти в VM. И везде запись нулей из /dev/zero на диск в кэш не попадала. Из-за большого количества тестов глаз замылился, и я не мог понять, в чём причина. Подумал уже, что по дефолту dd работает с флагом direct, но это не так.

Причина вот в чём. Если файл /tempfile уже существует, то запись ведётся напрямую, а если отсутствует и оперативы достаточно, то в кэш. Проверяем:

# dd if=/dev/zero of=/tempfile bs=1M count=200
231 MB/s
# rm /tempfile
# dd if=/dev/zero of=/tempfile bs=1M count=200
635 MB/s

Если взять ещё меньше файл, то скорость будет ещё больше:

# rm /tempfile
# dd if=/dev/zero of=/tempfile bs=1M count=100
1.6 GB/s

Если вы будете писать с помощью dd обычный файл, который полностью помещается в оперативную память, то тоже при первичной записи файл попадёт в кэш:

# dd if=/tempfile of=/tempfile2 bs=1M count=128
910 MB/s

Всё было записано в кэш. Скорость диска мы вообще не увидели. Для тестирования линейной скорости записи на диск обязательно используйте флаг direct или sync. Значения вы получите разные в зависимости от флага, но они точно будут без использования кэша ОС.

А теперь я включу кэширование диска (Write back) на уровне гипервизора и выполню тесты с direct:

# dd if=/dev/zero of=/tempfile bs=1M count=2000 oflag=direct
1.0 GB/s

Скорость нереальная, так как файл не влезает в оперативку. Работает кэширование с уровня гипервизора, так что из VM измерить реальную скорость невозможно. Как зачастую невозможно и на арендованных VDS.

Интересная тема. Пару часов проковырялся с тестами, документацией, статьями. Забыл упомянуть, что погонял тесты с помощью sysbench, используя те же размеры блока и их количества. Результаты полностью совпадают с dd.

❗️Если при тестах диска вы видите очень большой разброс в значениях, у вас 100% где-то что-то залетает в кэш. Я не раз слышал от знакомых и читателей замечания по этому поводу. Люди получают сильно разные результаты тестов и не понимают, как их интерпретировать. Могут из-за этого ошибочно посчитать одно хранилище или формат диска быстрее другого.

#linux #disk
2👍92👎4
Пока была возможность, решил проверить, какой штраф на дисковые операции накладывает виртуализация в Proxmox. В моей работе чаще всего именно дисковая подсистема является узким местом серверов. CPU обычно хватает, память сейчас недорога и легко расширяется. С дисками проблем больше всего.

Взял тестовый сервер Proxmox, в котором есть железный RAID контроллер без кэша и собранный RAID10 из 4-х HDD. Воткнул туда дополнительно обычный SSD AMD Radeon R5 R5SL480G 480ГБ. RAID10 подключил как обычный LVM storage, а SSD как LVM-Thin.

Нарезал там LV для хоста:

# lvcreate -V 10G -n test_ssd --thinpool SSD-RADEON/SSD-RADEON
# lvcreate -L 10G -n test_raid10 raid10

Сделал фс ext4 и смонтировал:

# mkfs.ext4 /dev/SSD-RADEON/test_ssd
# mkfs.ext4 /dev/raid10/test_raid10
# mount /dev/SSD-RADEON/test_ssd /mnt/SSD-RADEON
# mount /dev/raid10/test_raid10 /mnt/raid10

Прогнал серию из 10-ти тестов для каждого хранилища с помощью dd:

# dd if=/dev/zero of=/mnt/raid10/tempfile bs=1M count=2000 oflag=direct
# dd if=/dev/zero of=/mnt/SSD-RADEON/tempfile bs=1M count=2000 oflag=direct

Далее взял fio и прогнал тесты с его помощью:

Линейное чтение: 
# fio -ioengine=libaio -direct=1 -invalidate=1 -name=test -bs=1M -iodepth=32 -rw=read -runtime=30 -filename=/dev/raid10/test_raid10

Линейная запись: 
# fio -ioengine=libaio -direct=1 -invalidate=1 -name=test -bs=1M -iodepth=32 -rw=write -runtime=30 -filename=/dev/raid10/test_raid10

Пиковые IOPS случайной записи: 
# fio -ioengine=libaio -direct=1 -invalidate=1 -name=test -bs=4k -iodepth=128 -rw=randwrite -runtime=30 -filename=/dev/raid10/test_raid10

Так для обоих дисков. С dd сделал по 10 тестов, с fio по 5. Потом создал VM на Debian 12, создал для неё такие же диски, выбрав параметры:

▪️Device: SCSI
▪️Cache: Default (No cache)
▪️IO thread: yes
▪️Async IO: Default (io_uring)

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

Разброс в производительности не более 9%. А если точно, то разница между хостом и VM только в одном тесте на запись была 9%, в остальных случаях 2-6%. Немного удивило то, что в паре тестов в VM результаты были выше на 2%, чем на хосте. Я несколько раз перепроверял, но ситуация воспроизводилась снова. Не знаю, с чем это может быть связано.

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

#proxmox #disk #perfomance
2👍126👎4
Завершу тему с тестированием дисков информацией про кэширование в Proxmox VE. У него стандартный набор режимов, которые будут плюс-минус такие же и у рейд контроллеров. Сделаю в формате небольшой шпаргалки, а подробности с картинками есть в документации.

▪️None - режим по умолчанию. Если не хочется разбираться в этой теме, то можете оставлять этот режим и не заморачиваться. Он универсален для сервера общего назначения. Гипервизор никак не вмешивается в операции ввода-вывода. VM работает как-будто напрямую с хранилищем. Может отправлять данные в очередь хранилища на запись, либо дожидаться реальной записи.

▪️Writethrough - операции записи VM идут напрямую в хранилище, как и в режиме none. В этом режиме добавляется кэш гипервизора, который используется только для чтения. То есть мы получаем такую же надёжность записи, как и в none, но добавляется кэш на операции чтения. Если у вас сервер отдаёт много статики, то можете включить этот режим.

Железный рейд контроллер без батарейки обычно работает в таком же режиме.

▪️Directsync - кэширование гипервизора не используется вообще, как в none. Отличие этого режима в том, что мы заставляем VM работать с хранилищем только в режиме реальной записи с подтверждением. То есть виртуалка не использует очередь хранилища. Затрудняюсь придумать пример, где это реально надо. Никогда не использовал этот режим.

▪️Writeback - операции записи и чтения кэшируются гипервизором. VM будет получать подтверждения о записи, когда данные попадут в кэш гипервизора, а не хранилища. Это существенно увеличивает быстродействие дисков VM. Особенно если у гипервизора много свободной оперативной памяти для кэша. Если будет сбой сервера и данные из кэша хоста не успеют записаться, то мы получим потерю информации с разными последствиями для системы. Она скорее всего выживет, но если там работала СУБД, то база может оказаться битой.

Если у вас настроен UPS, сервер корректно завершает работу в случае пропадания питания, и в целом стабильно работает, без проблем и аварийных завершений, то можно использовать этот режим для всех виртуальных машин. Железный рейд контроллер с батарейкой обычно работает в этом же режиме.

▪️Writeback (unsafe) - то же самое, что Writeback, но с одним отличием. В режиме Writeback гостевая VM может отправить команду на запись данных в реальное хранилище, а не кэш гипервизора. У неё есть возможность принудительно поддерживать консистентность данных. В режиме unsafe команда на запись в хранилище всё равно перехватывается кэшем хоста. Это обеспечивает максимальное быстродействие VM и максимальную ненадёжность сохранности данных. Я этот режим использую на тестовых гипервизорах.

❗️Все эти режимы имеют смысл при использовании типа диска RAW. Например, при использовании LVM Storage или обычных raw файлов с хранением в директории хоста. Во всех остальных случаях (qcow2, zfs) кэширование лучше не трогать и оставлять его в режиме none. Также следует аккуратно менять режимы при использовании raid контроллера с батарейкой, встроенной памятью и включенным кэшированием. Будет неочевидно, какой режим выбрать - тот или иной кэш гипервизора или самого контроллера, либо их обоих. Надо тестировать на своей нагрузке. Я в таких случаях оставляю кэш контроллера и не использую кэш гипервизора. Просто интуитивно так делаю. Как лучше, я не знаю.

🔹Если заметка вам полезна, не забудьте 👍 и забрать в закладки.

#proxmox #disk
5👍151👎1
Посмотрел очень интересное видео про снижение задержек в SSD дисках. Там и по теории прошлись, но в основном по практике. По шагам рассказали, что пробовали сделать, какие параметры ОС и софта меняли и к чему это приводило.

Как в Айри.рф сократили SSD-задержки в 61 раз

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

У автора стал тормозить классический веб стек под Nginx. Увеличились как задержки на отдачу обычной статики пользователю из кэша, доходили до 1-2 секунд, так и динамические запросы мимо кэша. Было не понятно, с чем это связано. Использовались одиночные SSD диски Samsung Evo без рейда, файловая система ext4 поверх LVM разделов.

Начали разбор ситуации с выделения метрик и утилит для отслеживания отклика дисков:

◽️системный i/o wait
◽️метрики disk timings (статистика от Prometheus)
◽️утилиты ioping / iostat / iotop
◽️HTTP response time

Эти данные ничего не прояснили и не подсказали, куда в итоге надо смотреть и что делать. Далее начали анализировать очередь на запись операционной системы. На практике это никак не помогло понять, где возникают дисковые задержки.

Между приложением и диском есть несколько звеньев: буфер nginx, буфер ОС, очередь на запись. Каждый из этих этапов может добавлять задержку. Проанализировать всё это - нетривиальная задача.

Пробовали следующие изменения:

● асинхронные потоки в nginx через параметр aio threads = default; результат: снижение задержек на 5-10%;
● уменьшение очереди на запись ОС:
vm_dirty_expire_centisecs=1
vm_dirty_writeback_centisecs=1
не дало заметных улучшений
● изменение планировщика с cfq на deadline не принесло значимых изменений
● отключение журналирования через монтирование в fstab с параметром noatime снизило на 10% задержки.
● перенос логов nginx на внешние хранилища и отключение или перенос других системных логов еще уменьшили задержки на 10%.

Для дальнейшего анализа производительности сервиса решили привязаться к метрикам nginx для запросов, которые проходят мима кэша: nginx_time_request и nginx_upstream_header_time. Анализ этих метрик позволил оценить производительность сервиса в целом: лучше он стал работать или нет. Я, кстати, тоже включаю метрику request_time для веб серверов, где требуется оценка производительности. Можно почитать об этом в моей статье Мониторинг производительности бэкенда с помощью ELK Stack.

Что в итоге помогло больше всего?

🔹Отключение полностью журналирования на серверах с кэшем, который можно без последствий потерять
🔹Включение Trim по расписанию примерно тогда, когда объём диска предположительно полностью перезаписан. В данном случае это происходило примерно через неделю работы. Этот интервал и использовали. Я раз в сутки обычно ставлю на своих виртуалках.
🔹Использование tmpfs там, где это возможно. Уменьшает нагрузку на запись, увеличивает срок жизни SSD, работает только на небольших объёмах данных, которые можно потерять.

Каждый из этих шагов дал примерно в 2-3 раза снижение задержек. И в сумме получился заметный прирост для всего сервиса. Плюс, оптимизировали немного само приложение. И в итоге всё заработало в десятки раз быстрее.

❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.

#perfomance #disk
2👍164👎2