Skip to content

Latest commit

 

History

History
148 lines (110 loc) · 8.27 KB

rbd-qemu.rst

File metadata and controls

148 lines (110 loc) · 8.27 KB

RBD, Qemu и discard

И Ceph (RBD) и Qemu умеют в discard/trim/unmap. Это означает, что гостевая ОС может отправить соответствующий запрос к хранилищу, чтобы сообщить что данные не нужны. Исходно это было предназначено для SSD-дисков с целью оптимизации wear-leveling (выравнивание износа). В RBD это позволяет удалить ненужные данные из кластера и тем самым уменьшить бекфиллинг, размеры снапшотов и др.

Мы знаем, что RBD виртуально делит диски на куски по 4 МБ (по-умолчанию). Каждый кусок -- это один объект Rados. Соответственно, дискард может либо удалить целиком один объект (если он не нужен), либо сократить размер (вплоть до нуля). Что он не может -- так это продискардить середину объекта или начало. Он мог бы просто заполнить нулями, но нет. Появляется ошибка, правда, не фатальная. В API RBD нет функции для выяснения размера чанка. Поэтому Qemu не может догадаться какие дискарды можно отправлять в librbd, а какие закончатся ошибкой. В документации про это ничего не сказано.

Есть костыль для ceph.conf -- параметр rbd_skip_partial_discard. Однако:

В связи с чем, лучше проинструктировать Qemu чтобы она сообщила в гостевую об имеющемся выравнивании в 4 МБ. Тогда ядро гостевой ОС не будет отправлять дискарды которые невозможно выполнить в RBD.

К сожалению, libvirt напрямую не может указать это для каждого диска персонально. Но есть костыль:

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  <qemu:commandline>
    <qemu:arg value='-global'/>
    <qemu:arg value='scsi-hd.discard_granularity=4194304'/>
  </qemu:commandline>
  ...
  <disk type='network' device='disk'>
     <!--
         detect_zeroes='on'
         https://libvirt.org/formatdomain.html:

         NB enabling the detection is a compute intensive operation,
         but can save file space and/or time on slow media.

         А ещё это может повлиять на бенчмарки в стиле dd if=/dev/zero ...
         fio использует случайный паттерн.
      -->
     <driver name='qemu' type='raw' cache='writeback' discard='unmap'/>
     ...
  </disk>
</domain>

Important

xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0' крайне важен. Без этой строки <qemu:commandline> будет проигнорирован. Проверить можно повторно отредактировав описание ВЫКЛЮЧЕНОЙ виртуальной машины virsh edit some-domain

Данный фрагмент будет работать только для virtio-scsi. Для IDE аналогично, но мне неизвестно как :).

(Пример по ссылке http://docs.ceph.com/docs/master/rbd/qemu-rbd похоже что устарел и не работает)

Для справки есть ещё такие параметры:

  • logical_block_size
  • physical_block_size
  • min_io_size
  • opt_io_size

Important

Discard будет работать только для виртуальных дисковых интерфейсов IDE и virtio-scsi. Не путайте virtio и virtio-scsi -- это два совершенно разных интерфейса. virtio устарел и более не развивается. В гостевой ОС virtio-scsi выглядит как /dev/sd*, а virtio как /dev/vd*.

Их всех можно посмотреть командой lsblk в гостевой ОС чтобы удостовериться, что виртуальная машина настроена правильно (DISC-GRAN равен размеру чанка в RBD):

$ lsblk -D
NAME   DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda           0        4M       1G         0
├─sda1  4176896        4M       1G         0
├─sda2  3145728        4M       1G         0
└─sda3  3145728        4M       1G         0

$ lsblk -t
NAME   ALIGNMENT MIN-IO OPT-IO PHY-SEC LOG-SEC ROTA SCHED    RQ-SIZE  RA WSAME
sda            0    512      0     512     512    1 deadline     128 128    2G
├─sda1         0    512      0     512     512    1 deadline     128 128    2G
├─sda2         0    512      0     512     512    1 deadline     128 128    2G
└─sda3         0    512      0     512     512    1 deadline     128 128    2G

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

Linux

  • fstrim -v -a. Вручную, либо по расписанию (раз в неделю). Рекомендуется. не уверен, но в Ubuntu, по-моему, работает из коробки.
  • Опции для SWAP-разделов. TODO: расписать какие именно. Есть первичный дискард перед подключением, есть включение дискарда во время работы.
  • Есть опции при монтировании различных ФС чтобы выполняли discard для данных которые стали ненужными (после удаления файлов)
  • Команда blkdiscard для очистки всего устройства либо раздела или тома LVM.

Warning

Говорят, что опции монтирования и аналогичные опции для SWAP-раздела понижают производительность. С другой стороны, массивный fstrim по расписанию может дать непредвиденные проседания IO в гостевой ОС.

Windows

TODO: всё работает из коробки как-то само собой. На старых версиях можно включить через реестр. Как посмотреть ? Как форсировано прочистить ?

Настоятельно рекомендуется установить дополнения в гостевую ОС:

Иначе придётся довольствоваться только IDE, а это сильно меньшая производительность.

RBD, Qemu и rotational

Для более оптимальной работы приложений внутри гостевой ОС можно пометить диск как non-rotational. По-умолчанию, он rotational.

Коммит, который это добавляет: https://github.com/qemu/qemu/commit/070f80095ad5b1143b50d2faffd2b1a84292e00d

Такая возможность есть, начиная с qemu 2.11 и выше. Настраивается аналогично discard_granularity. Нужно выставить scsi-hd.rotation_rate=1 и scsi-block.rotation_rate=1 (на всякий случай)