- name: osd_network type: string or array of strings type_ru: строка или массив строк info: | Network mask of public OSD network(s) (IPv4 or IPv6). Each OSD listens to all addresses of UP + RUNNING interfaces matching one of these networks, on the same port. Port is auto-selected except if [bind_port](osd.en.md#bind_port) is explicitly specified. Bind address(es) may also be overridden manually by specifying [bind_address](osd.en.md#bind_address). If OSD networks are not specified at all, OSD just listens to a wildcard address (0.0.0.0). info_ru: | Маски подсетей (IPv4 или IPv6) публичной сети или сетей OSD. Каждый OSD слушает один и тот же порт на всех адресах поднятых (UP + RUNNING) сетевых интерфейсов, соответствующих одной из указанных сетей. Порт выбирается автоматически, если только [bind_port](osd.ru.md#bind_port) не задан явно. Адреса для подключений можно также переопределить явно, задав [bind_address](osd.ru.md#bind_address). Если сети OSD не заданы вообще, OSD слушает все адреса (0.0.0.0). - name: osd_cluster_network type: string or array of strings type_ru: строка или массив строк info: | Network mask of separate network(s) (IPv4 or IPv6) to use for OSD cluster connections. I.e. OSDs will always attempt to use these networks to connect to other OSDs, while clients will attempt to use networks from [osd_network](#osd_network). info_ru: | Маски подсетей (IPv4 или IPv6) отдельной кластерной сети или сетей OSD. То есть, OSD будут всегда стараться использовать эти сети для соединений с другими OSD, а клиенты будут стараться использовать сети из [osd_network](#osd_network). - name: use_rdma type: bool default: true info: | Try to use RDMA through libibverbs for communication if it's available. Disable if you don't want Vitastor to use RDMA. TCP-only clients can also talk to an RDMA-enabled cluster, so disabling RDMA may be needed if clients have RDMA devices, but they are not connected to the cluster. `use_rdma` works with RoCEv1/RoCEv2 networks, but not with iWARP and, maybe, with some Infiniband configurations which require RDMA-CM. Consider `use_rdmacm` for such networks. info_ru: | Попробовать использовать RDMA через libibverbs для связи при наличии доступных устройств. Отключите, если вы не хотите, чтобы Vitastor использовал RDMA. TCP-клиенты также могут работать с RDMA-кластером, так что отключать RDMA может быть нужно, только если у клиентов есть RDMA-устройства, но они не имеют соединения с кластером Vitastor. `use_rdma` работает с RoCEv1/RoCEv2 сетями, но не работает с iWARP и может не работать с частью конфигураций Infiniband, требующих RDMA-CM. Рассмотрите включение `use_rdmacm` для таких сетей. - name: use_rdmacm type: bool default: true info: | Use an alternative implementation of RDMA through RDMA-CM (Connection Manager). Works with all RDMA networks: Infiniband, iWARP and RoCEv1/RoCEv2, and even allows to disable TCP and run only with RDMA. OSDs always use random port numbers for RDMA-CM listeners, different from their TCP ports. `use_rdma` is automatically disabled when `use_rdmacm` is enabled. info_ru: | Использовать альтернативную реализацию RDMA на основе RDMA-CM (Connection Manager). Работает со всеми типами RDMA-сетей: Infiniband, iWARP и RoCEv1/RoCEv2, и даже позволяет полностью отключить TCP и работать только на RDMA. OSD используют случайные номера портов для ожидания соединений через RDMA-CM, отличающиеся от их TCP-портов. Также при включении `use_rdmacm` автоматически отключается опция `use_rdma`. - name: disable_tcp type: bool default: true info: | Fully disable TCP and only use RDMA-CM for OSD communication. info_ru: | Полностью отключить TCP и использовать только RDMA-CM для соединений с OSD. - name: rdma_device type: string info: | RDMA device name to use for Vitastor OSD communications (for example, "rocep5s0f0"). If not specified, Vitastor will try to find an RoCE device matching [osd_network](osd.en.md#osd_network), preferring RoCEv2, or choose the first available RDMA device if no RoCE devices are found or if `osd_network` is not specified. Auto-selection is also unsupported with old libibverbs < v32, like in Debian 10 Buster or CentOS 7. Vitastor supports all adapters, even ones without ODP support, like Mellanox ConnectX-3 and non-Mellanox cards. Versions up to Vitastor 1.2.0 required ODP which is only present in Mellanox ConnectX >= 4. See also [rdma_odp](#rdma_odp). Run `ibv_devinfo -v` as root to list available RDMA devices and their features. Remember that you also have to configure your network switches if you use RoCE/RoCEv2, otherwise you may experience unstable performance. Refer to the manual of your network vendor for details about setting up the switch for RoCEv2 correctly. Usually it means setting up Lossless Ethernet with PFC (Priority Flow Control) and ECN (Explicit Congestion Notification). info_ru: | Название RDMA-устройства для связи с Vitastor OSD (например, "rocep5s0f0"). Если не указано, Vitastor попробует найти RoCE-устройство, соответствующее [osd_network](osd.en.md#osd_network), предпочитая RoCEv2, или выбрать первое попавшееся RDMA-устройство, если RoCE-устройств нет или если сеть `osd_network` не задана. Также автовыбор не поддерживается со старыми версиями библиотеки libibverbs < v32, например в Debian 10 Buster или CentOS 7. Vitastor поддерживает все модели адаптеров, включая те, у которых нет поддержки ODP, то есть вы можете использовать RDMA с ConnectX-3 и картами производства не Mellanox. Версии Vitastor до 1.2.0 включительно требовали ODP, который есть только на Mellanox ConnectX 4 и более новых. См. также [rdma_odp](#rdma_odp). Запустите `ibv_devinfo -v` от имени суперпользователя, чтобы посмотреть список доступных RDMA-устройств, их параметры и возможности. Обратите внимание, что если вы используете RoCE/RoCEv2, вам также необходимо правильно настроить для него коммутаторы, иначе вы можете столкнуться с нестабильной производительностью. Подробную информацию о настройке коммутатора для RoCEv2 ищите в документации производителя. Обычно это подразумевает настройку сети без потерь на основе PFC (Priority Flow Control) и ECN (Explicit Congestion Notification). - name: rdma_port_num type: int info: | RDMA device port number to use. Only for devices that have more than 1 port. See `phys_port_cnt` in `ibv_devinfo -v` output to determine how many ports your device has. Not relevant for RDMA-CM (use_rdmacm). info_ru: | Номер порта RDMA-устройства, который следует использовать. Имеет смысл только для устройств, у которых более 1 порта. Чтобы узнать, сколько портов у вашего адаптера, посмотрите `phys_port_cnt` в выводе команды `ibv_devinfo -v`. Опция неприменима к RDMA-CM (use_rdmacm). - name: rdma_gid_index type: int info: | Global address identifier index of the RDMA device to use. Different GID indexes may correspond to different protocols like RoCEv1, RoCEv2 and iWARP. Search for "GID" in `ibv_devinfo -v` output to determine which GID index you need. If not specified, Vitastor will try to auto-select a RoCEv2 IPv4 GID, then RoCEv2 IPv6 GID, then RoCEv1 IPv4 GID, then RoCEv1 IPv6 GID, then IB GID. GID auto-selection is unsupported with libibverbs < v32. A correct rdma_gid_index for RoCEv2 is usually 1 (IPv6) or 3 (IPv4). Not relevant for RDMA-CM (use_rdmacm). info_ru: | Номер глобального идентификатора адреса RDMA-устройства, который следует использовать. Разным gid_index могут соответствовать разные протоколы связи: RoCEv1, RoCEv2, iWARP. Чтобы понять, какой нужен вам - смотрите строчки со словом "GID" в выводе команды `ibv_devinfo -v`. Если не указан, Vitastor попробует автоматически выбрать сначала GID, соответствующий RoCEv2 IPv4, потом RoCEv2 IPv6, потом RoCEv1 IPv4, потом RoCEv1 IPv6, потом IB. Авто-выбор GID не поддерживается со старыми версиями libibverbs < v32. Правильный rdma_gid_index для RoCEv2, как правило, 1 (IPv6) или 3 (IPv4). Опция неприменима к RDMA-CM (use_rdmacm). - name: rdma_mtu type: int info: | RDMA Path MTU to use. Must be 1024, 2048 or 4096. Default is to use the RDMA device's MTU. info_ru: | Максимальная единица передачи (Path MTU) для RDMA. Должно быть равно 1024, 2048 или 4096. По умолчанию используется значение MTU RDMA-устройства. - name: rdma_max_sge type: int default: 128 info: | Maximum number of scatter/gather entries to use for RDMA. OSDs negotiate the actual value when establishing connection anyway, so it's usually not required to change this parameter. info_ru: | Максимальное число записей разделения/сборки (scatter/gather) для RDMA. OSD в любом случае согласовывают реальное значение при установке соединения, так что менять этот параметр обычно не нужно. - name: rdma_max_msg type: int default: 132096 info: Maximum size of a single RDMA send or receive operation in bytes. info_ru: Максимальный размер одной RDMA-операции отправки или приёма. - name: rdma_max_recv type: int default: 16 info: | Maximum number of RDMA receive buffers per connection (RDMA requires preallocated buffers to receive data). Each buffer is `rdma_max_msg` bytes in size. So this setting directly affects memory usage: a single Vitastor RDMA client uses `rdma_max_recv * rdma_max_msg * OSD_COUNT` bytes of memory. Default is roughly 2 MB * number of OSDs. info_ru: | Максимальное число буферов для RDMA-приёма данных на одно соединение (RDMA требует заранее выделенных буферов для приёма данных). Каждый буфер имеет размер `rdma_max_msg` байт. Таким образом, настройка прямо влияет на потребление памяти - один Vitastor-клиент с RDMA использует `rdma_max_recv * rdma_max_msg * ЧИСЛО_OSD` байт памяти, по умолчанию - примерно 2 МБ * число OSD. - name: rdma_max_send type: int default: 8 info: | Maximum number of outstanding RDMA send operations per connection. Should be less than `rdma_max_recv` so the receiving side doesn't run out of buffers. Doesn't affect memory usage - additional memory isn't allocated for send operations. info_ru: | Максимальное число RDMA-операций отправки, отправляемых в очередь одного соединения. Желательно, чтобы оно было меньше `rdma_max_recv`, чтобы у принимающей стороны в процессе работы не заканчивались буферы на приём. Не влияет на потребление памяти - дополнительная память на операции отправки не выделяется. - name: rdma_odp type: bool default: false online: false info: | Use RDMA with On-Demand Paging. ODP is currently only available on Mellanox ConnectX-4 and newer adapters. ODP allows to not register memory explicitly for RDMA adapter to be able to use it. This, in turn, allows to skip memory copying during sending. One would think this should improve performance, but **in reality** RDMA performance with ODP is **drastically** worse. Example 3-node cluster with 8 NVMe in each node and 2*25 GBit/s ConnectX-6 RDMA network without ODP pushes 3950000 read iops, but only 239000 iops with ODP... This happens because Mellanox ODP implementation seems to be based on message retransmissions when the adapter doesn't know about the buffer yet - it likely uses standard "RNR retransmissions" (RNR = receiver not ready) which is generally slow in RDMA/RoCE networks. Here's a presentation about it from ISPASS-2021 conference: https://tkygtr6.github.io/pub/ISPASS21_slides.pdf ODP support is retained in the code just in case a good ODP implementation appears one day. info_ru: | Использовать RDMA с On-Demand Paging. ODP - функция, доступная пока что исключительно на адаптерах Mellanox ConnectX-4 и более новых. ODP позволяет не регистрировать память для её использования RDMA-картой. Благодаря этому можно не копировать данные при отправке их в сеть и, казалось бы, это должно улучшать производительность - но **по факту** получается так, что производительность только ухудшается, причём сильно. Пример - на 3-узловом кластере с 8 NVMe в каждом узле и сетью 2*25 Гбит/с на чтение с RDMA без ODP удаётся снять 3950000 iops, а с ODP - всего 239000 iops... Это происходит из-за того, что реализация ODP у Mellanox неоптимальная и основана на повторной передаче сообщений, когда карте не известен буфер - вероятно, на стандартных "RNR retransmission" (RNR = receiver not ready). А данные повторные передачи в RDMA/RoCE - всегда очень медленная штука. Презентация на эту тему с конференции ISPASS-2021: https://tkygtr6.github.io/pub/ISPASS21_slides.pdf Возможность использования ODP сохранена в коде на случай, если вдруг в один прекрасный день появится хорошая реализация ODP. - name: peer_connect_interval type: sec min: 1 default: 5 online: true info: Interval before attempting to reconnect to an unavailable OSD. info_ru: Время ожидания перед повторной попыткой соединиться с недоступным OSD. - name: peer_connect_timeout type: sec min: 1 default: 5 online: true info: Timeout for OSD connection attempts. info_ru: Максимальное время ожидания попытки соединения с OSD. - name: osd_idle_timeout type: sec min: 1 default: 5 online: true info: | OSD connection inactivity time after which clients and other OSDs send keepalive requests to check state of the connection. info_ru: | Время неактивности соединения с OSD, после которого клиенты или другие OSD посылают запрос проверки состояния соединения. - name: osd_ping_timeout type: sec min: 1 default: 5 online: true info: | Maximum time to wait for OSD keepalive responses. If an OSD doesn't respond within this time, the connection to it is dropped and a reconnection attempt is scheduled. info_ru: | Максимальное время ожидания ответа на запрос проверки состояния соединения. Если OSD не отвечает за это время, соединение отключается и производится повторная попытка соединения. - name: max_etcd_attempts type: int default: 5 online: true info: | Maximum number of attempts for etcd requests which can't be retried indefinitely. info_ru: | Максимальное число попыток выполнения запросов к etcd для тех запросов, которые нельзя повторять бесконечно. - name: etcd_quick_timeout type: ms default: 1000 online: true info: | Timeout for etcd requests which should complete quickly, like lease refresh. info_ru: | Максимальное время выполнения запросов к etcd, которые должны завершаться быстро, таких, как обновление резервации (lease). - name: etcd_slow_timeout type: ms default: 5000 online: true info: Timeout for etcd requests which are allowed to wait for some time. info_ru: | Максимальное время выполнения запросов к etcd, для которых не обязательно гарантировать быстрое выполнение. - name: etcd_keepalive_timeout type: sec default: max(30, etcd_report_interval*2) online: true info: | Timeout for etcd connection HTTP Keep-Alive. Should be higher than etcd_report_interval to guarantee that keepalive actually works. info_ru: | Таймаут для HTTP Keep-Alive в соединениях к etcd. Должен быть больше, чем etcd_report_interval, чтобы keepalive гарантированно работал. - name: etcd_ws_keepalive_interval type: sec default: 5 online: true info: | etcd websocket ping interval required to keep the connection alive and detect disconnections quickly. info_ru: | Интервал проверки живости вебсокет-подключений к etcd. - name: etcd_min_reload_interval type: ms default: 1000 online: true info: | Minimum interval for full etcd state reload. Introduced to prevent excessive load on etcd during outages when etcd can't keep up with event streams and cancels them. info_ru: | Минимальный интервал полной перезагрузки состояния из etcd. Добавлено для предотвращения избыточной нагрузки на etcd во время отказов, когда etcd не успевает рассылать потоки событий и отменяет их. - name: tcp_header_buffer_size type: int default: 65536 info: | Size of the buffer used to read data using an additional copy. Vitastor packet headers are 128 bytes, payload is always at least 4 KB, so it is usually beneficial to try to read multiple packets at once even though it requires to copy the data an additional time. The rest of each packet is received without an additional copy. You can try to play with this parameter and see how it affects random iops and linear bandwidth if you want. info_ru: | Размер буфера для чтения данных с дополнительным копированием. Пакеты Vitastor содержат 128-байтные заголовки, за которыми следуют данные размером от 4 КБ и для мелких операций ввода-вывода обычно выгодно за 1 вызов читать сразу несколько пакетов, даже не смотря на то, что это требует лишний раз скопировать данные. Часть каждого пакета за пределами значения данного параметра читается без дополнительного копирования. Вы можете попробовать поменять этот параметр и посмотреть, как он влияет на производительность случайного и линейного доступа. - name: min_zerocopy_send_size type: int default: 32768 info: | OSDs and clients will attempt to use io_uring-based zero-copy TCP send for buffers larger than this number of bytes. Zero-copy send with io_uring is supported since Linux kernel version 6.1. Support is auto-detected and disabled automatically when not available. It can also be disabled explicitly by setting this parameter to a negative value. ⚠️ Warning! Zero-copy send performance may vary greatly from CPU to CPU and from one kernel version to another. Generally, it tends to only make benefit with larger messages. With smaller messages (say, 4 KB), it may actually be slower. 32 KB is enough for almost all CPUs, but even smaller values are optimal for some of them. For example, 4 KB is OK for EPYC Milan/Genoa and 12 KB is OK for Xeon Ice Lake (but verify it yourself please). Verification instructions: 1. Add `iommu=pt` into your Linux kernel command line and reboot. 2. Upgrade your kernel. For example, it's very important to use 6.11+ with recent AMD EPYCs. 3. Run some tests with the [send-zerocopy liburing example](https://github.com/axboe/liburing/blob/master/examples/send-zerocopy.c) to find the minimal message size for which zero-copy is optimal. Use `./send-zerocopy tcp -4 -R` at the server side and `time ./send-zerocopy tcp -4 -b 0 -s BUFFER_SIZE -D SERVER_IP` at the client side with `-z 0` (no zero-copy) and `-z 1` (zero-copy), and compare MB/s and used CPU time (user+system). info_ru: | OSD и клиенты будут пробовать использовать TCP-отправку без копирования (zero-copy) на основе io_uring для буферов, больших, чем это число байт. Отправка без копирования поддерживается в io_uring, начиная с версии ядра Linux 6.1. Наличие поддержки проверяется автоматически и zero-copy отключается, когда поддержки нет. Также её можно отключить явно, установив данный параметр в отрицательное значение. ⚠️ Внимание! Производительность данной функции может сильно отличаться на разных процессорах и на разных версиях ядра Linux. В целом, zero-copy обычно быстрее с большими сообщениями, а с мелкими (например, 4 КБ) zero-copy может быть даже медленнее. 32 КБ достаточно почти для всех процессоров, но для каких-то можно использовать даже меньшие значения. Например, для EPYC Milan/Genoa подходит 4 КБ, а для Xeon Ice Lake - 12 КБ (но, пожалуйста, перепроверьте это сами). Инструкция по проверке: 1. Добавьте `iommu=pt` в командную строку загрузки вашего ядра Linux и перезагрузитесь. 2. Обновите ядро. Например, для AMD EPYC очень важно использовать версию 6.11+. 3. Позапускайте тесты с помощью [send-zerocopy из примеров liburing](https://github.com/axboe/liburing/blob/master/examples/send-zerocopy.c), чтобы найти минимальный размер сообщения, для которого zero-copy отправка оптимальна. Запускайте `./send-zerocopy tcp -4 -R` на стороне сервера и `time ./send-zerocopy tcp -4 -b 0 -s РАЗМЕР_БУФЕРА -D АДРЕС_СЕРВЕРА` на стороне клиента с опцией `-z 0` (обычная отправка) и `-z 1` (отправка без копирования), и сравнивайте скорость в МБ/с и занятое процессорное время (user+system). - name: use_sync_send_recv type: bool default: false info: | If true, synchronous send/recv syscalls are used instead of io_uring for socket communication. Useless for OSDs because they require io_uring anyway, but may be required for clients with old kernel versions. info_ru: | Если установлено в истину, то вместо io_uring для передачи данных по сети будут использоваться обычные синхронные системные вызовы send/recv. Для OSD это бессмысленно, так как OSD в любом случае нуждается в io_uring, но, в принципе, это может применяться для клиентов со старыми версиями ядра.