- 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: 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, но, в
    принципе, это может применяться для клиентов со старыми версиями ядра.
- name: use_rdma
  type: bool
  default: true
  info: |
    Try to use RDMA 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.
  info_ru: |
    Пытаться использовать RDMA для связи при наличии доступных устройств.
    Отключите, если вы не хотите, чтобы Vitastor использовал RDMA.
    TCP-клиенты также могут работать с RDMA-кластером, так что отключать
    RDMA может быть нужно только если у клиентов есть RDMA-устройства,
    но они не имеют соединения с кластером Vitastor.
- name: rdma_device
  type: string
  info: |
    RDMA device name to use for Vitastor OSD communications (for example,
    "rocep5s0f0"). Now 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 поддерживает все модели адаптеров, включая те, у которых
    нет поддержки 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
  default: 1
  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.
  info_ru: |
    Номер порта RDMA-устройства, который следует использовать. Имеет смысл
    только для устройств, у которых более 1 порта. Чтобы узнать, сколько портов
    у вашего адаптера, посмотрите `phys_port_cnt` в выводе команды
    `ibv_devinfo -v`.
- name: rdma_gid_index
  type: int
  default: 0
  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.

    **IMPORTANT:** If you want to use RoCEv2 (as recommended) then the correct
    rdma_gid_index is usually 1 (IPv6) or 3 (IPv4).
  info_ru: |
    Номер глобального идентификатора адреса RDMA-устройства, который следует
    использовать. Разным gid_index могут соответствовать разные протоколы связи:
    RoCEv1, RoCEv2, iWARP. Чтобы понять, какой нужен вам - смотрите строчки со
    словом "GID" в выводе команды `ibv_devinfo -v`.

    **ВАЖНО:** Если вы хотите использовать RoCEv2 (как мы и рекомендуем), то
    правильный rdma_gid_index, как правило, 1 (IPv6) или 3 (IPv4).
- name: rdma_mtu
  type: int
  default: 4096
  info: |
    RDMA Path MTU to use. Must be 1024, 2048 or 4096. There is usually no
    sense to change it from the default 4096.
  info_ru: |
    Максимальная единица передачи (Path MTU) для RDMA. Должно быть равно 1024,
    2048 или 4096. Обычно нет смысла менять значение по умолчанию, равное 4096.
- 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: 30
  online: true
  info: |
    etcd websocket ping interval required to keep the connection alive and
    detect disconnections quickly.
  info_ru: |
    Интервал проверки живости вебсокет-подключений к etcd.
