Перейти к содержанию

Конфигурация

Справочник параметров плагина S3R для администратора кластера: где задаётся каждый параметр, его значение по умолчанию, что он задаёт и когда новое значение начинает действовать. Зачем нужны сервисы, к которым относятся параметры, объясняет страница Устройство плагина.

Где задаются параметры

Где задаётся Какие параметры Как изменить
Контекст миграции общие для кластера, подставляются в текст миграций до применения миграций; после этого не изменяются
Конфигурация плагина общие для кластера; значения по умолчанию заданы в манифесте плагина ALTER PLUGIN ... SET
Конфигурация инстанса Picodata, раздел instance.plugin различаются от узла к узлу файл конфигурации инстанса
Переменные окружения различаются от узла к узлу окружение процесса инстанса

Когда применяется новое значение

Команда ALTER PLUGIN ... SET сохраняет значение в кластере. Каждый инстанс применяет изменение вместе с записью журнала Raft, которая его содержит, в том числе когда отставший инстанс получает эту запись в составе снимка.

Сохранённое значение и значение, с которым работает сервис, могут различаться. В таблицах параметров столбец «Применяется» принимает одно из значений:

Значение столбца Что происходит после ALTER PLUGIN ... SET
сразу новое значение действует без перезапуска
сразу, перезапуск эндпоинта новое значение действует сразу; эндпоинт S3 перезапускается на каждом инстансе
при запуске сервиса значение сохраняется, но работающий сервис использует прежнее до своего перезапуска
при первом запуске инстанса значение читается один раз и далее не меняется

При запуске сервиса читаются и далее не меняются только параметры bridge_fibers, bridge_queue и tx_slice_warn_ms сервиса s3r_meta и список дисков s3r_storage.disks. Эндпоинт S3 перезапускают параметры listen, credentials и inline_max сервиса s3r_api. Остальные параметры вступают в силу без перезапуска.

Случаи, когда команда приняла значение, а сервис использует другое:

Параметр Что сохранено Что действует Как узнать
s3r_meta.bridge_fibers, s3r_meta.bridge_queue, s3r_meta.tx_slice_warn_ms новое значение прежнее, до перезапуска сервиса строки журнала, см. Применение параметров s3r_meta
read_timeout_s, write_timeout_s, catalog_timeout_s, равные нулю 0 одна секунда предупреждение <параметр> = 0 is not a timeout
s3r_storage.dirgc_grace_s, равный нулю 0 вычисленный таймаут запись в журнале
s3r_storage.spare_extents, равный нулю 0 1 —
s3r_storage.pg_size_max больше предела группы заданное значение предел 2^16 полос —
s3r_api.inline_max для уже записанных ярусов новое значение классы блоков, записанные при формировании яруса предупреждение inline_max is <N>, and tiers keep the block classes they were recorded with, см. Запись схемы яруса
конфигурация s3r_storage, сохранённая без проверки значение, нарушающее правило сервис продолжает запуск ошибка the stored s3r_storage configuration breaks a rule: ..., см. Проверка значений

Контекст миграции

Параметры контекста миграции задаются до применения миграций и после этого не изменяются: их значения подставляются в текст миграций как фрагменты SQL.

Параметр Тип По умолчанию Что задаёт
storage_tier имя тира default тир Picodata, в котором создаются шардированные таблицы и работает хранилище фрагментов
extent_size размер с единицей: KiB, MiB или GiB нет, параметр обязателен размер экстента для всех дисков кластера, например 1GiB
engine memtx memtx движок таблиц пространства имён
unlogged UNLOGGED или пусто пусто UNLOGGED отключает журнал упреждающей записи (WAL) для таблиц пространства имён

Ограничения значений:

  • extent_size:
    • допустимы значения от 16 МиБ до 2 ГиБ, кратные 4 КиБ; рекомендуемое значение 1GiB;
    • число без единицы отклоняется;
    • без параметра плагин не включается;
    • после того как отформатирован первый диск, значение изменить нельзя: команда ALTER PLUGIN отклоняется.
  • engine: допустимо только memtx, другое значение отклоняется. Проверка бакета при записи читает глобальную таблицу, а Picodata хранит глобальные таблицы только в memtx.
  • unlogged: допустимо только для memtx и только там, где допустима потеря метаданных при перезапуске мастера репликасета.

Сервис s3r_api

Сервис принимает запросы S3. Каждый инстанс с сервисом s3r_api открывает собственный порт и обслуживает запросы к любым данным кластера, поэтому балансировщик нагрузки может направить запрос на любой узел.

Параметр Тип По умолчанию Применяется Что задаёт
listen адрес и порт 127.0.0.1:8000 сразу, перезапуск эндпоинта адрес и порт эндпоинта S3. Применяется, только если в конфигурации Picodata нет раздела слушателя, см. Слушатель s3r_api
inline_max байты 4096 сразу, перезапуск эндпоинта верхняя граница размера объекта со способом хранения inline. Значение больше 65536 (64 КиБ) задавать не рекомендуется: такие объекты читаются медленнее, чем с дисков, см. Что даёт такое устройство. Не больше 262144 (256 КиБ); большее значение отклоняется с ошибкой InlineMaxTooLarge. От значения зависит малый блок яруса, см. Запись схемы яруса
credentials список [] сразу, перезапуск эндпоинта начальный список ключей доступа, только для тенанта 0. Пустой список не отключает аутентификацию
region строка default сразу значение в ответе GetBucketLocation и допустимое значение LocationConstraint при создании бакета
read_timeout_s секунды 30 сразу предельное время запроса на чтение, см. Предельное время запроса
write_timeout_s секунды 30 сразу предельное время записи объекта, см. Предельное время запроса
catalog_timeout_s секунды 360 сразу предельное время изменения каталога, см. Предельное время запроса
api_memory auto или байты auto, то есть четверть памяти, доступной процессу сразу общий предел памяти для содержимого объектов в обрабатываемых запросах, см. Память запросов
diagnostics health, debug или bench health сразу доступная часть пространства /-/, см. Диагностические эндпоинты
control_api true или false false сразу включает консоль и API управления на HTTP-порту Picodata (instance.http_listen), см. API управления
iam объект или null null сразу аутентификация в консоли и API управления: внешний провайдер OpenID Connect либо проверка паролей самим кластером, см. Аутентификация
s3_public_url адрес или null null сразу адрес эндпоинта S3 в том виде, в каком к нему обращается браузер, см. Адрес для заранее подписанных ссылок
grafana_url адрес или null null сразу адрес Grafana для ссылки из консоли; без значения ссылка не показывается

Параметры TLS задаются в конфигурации инстанса Picodata, см. Слушатель s3r_api.

Предельное время запроса

Предельное время отсчитывается от поступления запроса и зависит от операции.

Параметр Какие запросы ограничивает Что не входит в срок
read_timeout_s GetObject, HeadObject, листинги, HeadBucket, чтение подресурсов бакета и объекта, запросы GET к API управления передача тела ответа клиенту
write_timeout_s PutObject, копирование, составная загрузка, удаление объектов, запись подресурсов объекта время, в течение которого S3R ждёт от клиента тело объекта. Чтение XML-тела запросов CompleteMultipartUpload и DeleteObjects в срок входит
catalog_timeout_s создание и удаление бакета, запись и удаление его подресурсов, все запросы к API управления, кроме GET —

Правила:

  • Срок общий для запроса: все его обращения к метаданным, другим инстансам и Raft ограничены этим сроком, а не каждое своим.
  • Исключение — тело ответа GetObject. Общий срок ограничивает чтение первой полосы, а каждая следующая полоса читается не дольше read_timeout_s с момента, когда она понадобилась.
  • Запросы, ограниченные catalog_timeout_s, ожидают подтверждения записи в Raft, поэтому значение по умолчанию совпадает с таймаутом DDL в Picodata.
  • Создание тенанта ограничено собственным сроком в 120 секунд. Когда он истекает, API управления отвечает 202, а создание завершает фоновый процесс tenant.
  • Ноль не является значением этих параметров: вместо него действует одна секунда, а в журнал инстанса записывается предупреждение <параметр> = 0 is not a timeout.

Ответ на запрос, срок которого истёк:

Кто отвечает Ответ
эндпоинт S3 503 SlowDown
эндпоинт S3, срок истёк во время ожидания Raft 503 ServiceUnavailable
API управления, в обоих случаях 503 с кодом Internal

В записи журнала инстанса указана проверка, которая обнаружила истечение срока, а в тексте ответа указан её номер (deadline check N):

Номер На чём истёк срок
1 ожидание свободного файбера в пуле
2 ожидание ответа другого инстанса
3 ожидание подтверждения записи в Raft
4 ожидание применения записи на других инстансах
5 чтение тела запроса
6 ожидание памяти api_memory
7 обмен фрагментами с другим инстансом
8 начало обработки запроса

Память запросов

Параметр api_memory ограничивает память, которую содержимое объектов занимает во всех обрабатываемых запросах. Значение auto выбирает предел автоматически, число задаёт его в байтах. Ноль не является значением: с нулевым пределом не был бы принят ни один запрос.

Ограничения на полный размер тела запроса нет. Запись выполняется потоком: данные кодируются и передаются на диски по мере поступления, и записываемый объект целиком в памяти не накапливается.

Запись:

  • Параметр учитывает буфер приёма и созданные из него фрагменты. Для схемы избыточности k+m это приблизительно объём буфера, умноженный на 1 + (k + m) / k.
  • Тело запроса с заголовком Content-Length принимается в первый буфер приёма такого же размера, но не больше 2 МиБ. Тело без длины принимается в первый буфер размером 256 КиБ.
  • При допуске запрос резервирует 1 МиБ. Когда приходят первые байты тела, резерв увеличивается до учетверённого объёма первого буфера, если в api_memory хватает свободной памяти. Если её не хватает, запрос не ждёт и принимает тело в первый буфер размером 256 КиБ.

Чтение:

  • Тело ответа отдаётся по мере чтения полос. Из api_memory резервируется память под четыре полосы: две читаются заранее, одна отправляется клиенту, ещё одна ждёт отправки.
  • Сжатый объект читается участками по 1 МиБ. Если полоса меньше участка, резерв рассчитывается на четыре участка.
  • Если следующая часть составного объекта читается более крупными полосами, резерв увеличивается без ожидания, а если памяти не хватает, тело ответа обрывается.

Если память не освобождается до истечения предельного времени запроса, запрос завершается ответом 503 SlowDown.

Адрес для заранее подписанных ссылок

Параметр s3_public_url используется для заранее подписанных ссылок:

У тенанта есть собственный FQDN s3_public_url задан Как строится ссылка
нет да по адресу s3_public_url
да да по FQDN тенанта; из s3_public_url берутся схема и порт
да нет https://<FQDN>

Консоль загружает объекты по этому адресу, только если он состоит из:

  • схемы http или https;
  • имени узла из латинских букв, цифр, точек и дефисов либо адреса IPv6 в квадратных скобках;
  • необязательного порта.

Другой адрес инстанс отмечает предупреждением в журнале.

Сервис s3r_meta

Сервис выполняет обращения к таблицам, см. Зачем нужен отдельный сервис для таблиц.

Параметр Тип По умолчанию Применяется Что задаёт
bridge_fibers целое число 16 при запуске сервиса число служебных файберов в каждом из пулов local, routed и background. Пул catalog имеет два файбера независимо от этого значения, см. Пулы файберов
bridge_queue целое число 256 при запуске сервиса глубина очереди каждого файбера пулов local и routed и общей очереди каждого из пулов catalog и background. Это предел для каждой очереди, а не сумма по всем пулам. При заполнении очереди приём новых заданий в этот пул приостанавливается
read_preference leader или any leader сразу, для следующего запроса откуда читаются метаданные, см. таблицу ниже
tx_slice_warn_ms миллисекунды не задан при запуске сервиса время, после которого файбер, работающий без передачи управления другим файберам, отмечается в журнале инстанса сообщением Tarantool fiber has not yielded for more than .... Работа файбера при этом продолжается. Параметр действует на все файберы инстанса, включая файберы самой Picodata. Если параметр не задан, Tarantool не отмечает такие файберы

Значения read_preference:

Значение Кто обслуживает чтение Следствие
leader мастер репликасета успешно записанные данные сразу доступны для чтения
any реплика, получившая запрос, или реплика, которую выбирает Picodata; действует на запросы чтения объектов и списков результат может быть устаревшим, в том числе отозванное разрешение продолжает действовать; см. Чтения возвращают устаревшие данные. Использовать не рекомендуется

Применение параметров s3r_meta

Параметры bridge_fibers, bridge_queue и tx_slice_warn_ms применяются при запуске сервиса s3r_meta. Команда ALTER PLUGIN ... SET сохраняет новое значение, но работающий сервис продолжает использовать прежнее.

Новое значение вступает в силу одним из способов:

  • после перезапуска инстанса;
  • после команд ALTER PLUGIN s3r <версия> DISABLE и затем ENABLE. Этот способ останавливает все сервисы плагина на всех инстансах.

Строки журнала инстанса, по которым видно, какое значение действует:

Событие Строка журнала
изменены bridge_fibers или bridge_queue s3r_meta: bridge_fibers N and bridge_queue M apply when the service starts again
изменён tx_slice_warn_ms s3r_meta: tx_slice_warn_ms ... applies when the service starts again
сервис запущен s3r_meta started: N fibers in each of the local, routed and background pools, 2 in catalog, queue M per fiber or shared queue
сервис запущен с заданным tx_slice_warn_ms every fiber now warns after N ms without a yield

Пулы файберов

Обращения к метаданным выполняются в потоке TX в одном из четырёх пулов файберов. Имя пула администратор видит в метке pool метрик. Пул выбирает место вызова:

Пул Что выполняет
local чтение и изменение метаданных, которые не выходят за пределы инстанса
routed операции запросов S3, которые обращаются к другим инстансам, например чтение строки объекта из другого репликасета и листинг
catalog изменения каталога по запросам S3, которые проходят через Raft: создание и удаление бакета и запись его подресурсов
background шаги фоновых процессов

Пулы local и routed обрабатывают обращения запросов S3 к метаданным со стороны среды выполнения Tokio.

Значение catalog метки pool обозначает этот пул, а не фоновый процесс catalog.

Обращение, стоящее в очереди любого пула, не выполняется в двух случаях:

  • срок запроса истёк, пока обращение ждало свободного файбера: запрос получает ответ 503 SlowDown;
  • клиент закрыл соединение.

Сервис s3r_storage

Сервис хранит фрагменты на дисках и обменивается ими с другими инстансами. Адрес обмена фрагментами различается на каждом узле, поэтому он задаётся в конфигурации Picodata, см. Слушатель s3r_storage.

Параметр Тип По умолчанию Применяется Что задаёт
disks список [] при первом запуске инстанса список директорий хранилища фрагментов с необязательными поддоменом отказа, ярусом и ёмкостью. После регистрации первого диска в кластере изменение отклоняется, см. Переменные окружения
erasure список [] сразу; схему яруса с группами изменить нельзя схема избыточности каждого яруса с дисками, см. Схема избыточности яруса
tiers список [] сразу; записанную привязку изменить нельзя карта классов хранения S3, см. Карта классов
write_tolerance целое число 1 сразу число фрагментов, которые запись вправе оставить недописанными, см. Кворум записи
refill_after_s секунды 2 сразу таймаут, после которого освободившаяся позиция блока группы снова выдаётся под запись
dirgc_grace_s auto или секунды auto сразу таймаут перед проверкой опустевшей директории. Значение auto означает max(2, 2 × write_timeout_s), то есть 60 секунд при значениях по умолчанию
mpu_abort_incomplete_after_s секунды или off 604800 сразу возраст, после которого незавершённая составная загрузка прерывается. Значение off останавливает фоновый процесс
pg_size_max объём или null null для групп, созданных позже наибольший объём данных объектов в одной группе размещения. Значение null означает 2^16 полос, то есть 128 ГиБ при полосе 2 МиБ
spare_extents целое число 1 сразу число экстентов каждого класса, которые активная группа держит занятыми на каждом участнике впереди заполняемого. Чем их больше, тем дольше группа принимает записи при недоступном участнике. Значение 0 действует как 1

Особенности значений:

  • refill_after_s и dirgc_grace_s задают границы корректности, а не периоды опроса. Каждый из них задаёт, сколько нужно подождать, чтобы отличить незавершённую работу от несделанной.
  • Нулевое значение refill_after_s выдаёт освободившуюся позицию блока сразу и допустимо только в испытательном контуре.
  • Ноль в dirgc_grace_s значением не является: он записывается в журнал, и применяется вычисленный таймаут.
  • pg_size_max: 2^16 полос — предел адресации группы, константа формата. Большее значение сводится к этому пределу. Предел записывается в строку группы при её создании, поэтому изменение касается только групп, созданных позже.

Схема избыточности яруса

Параметр erasure — список записей, по одной на ярус. Ярус объявляет одну схему.

Поле По умолчанию Что задаёт
k нет число фрагментов данных, не меньше 1
m нет число фрагментов чётности, не меньше 1
stripe_size 2 МиБ размер полосы
tier standard ярус
scrub_period_s 1209600, то есть 14 дней период проверки целостности данных яруса в секундах, см. Контроль целостности

Правила:

  • k + m не больше 64;
  • k = 1 означает репликацию в m + 1 копиях. Например, {"k":1,"m":2} хранит содержимое в трёх копиях на дисках различных доменов отказа. Число копий содержимого не зависит от параметра replication_factor тира Picodata;
  • scrub_period_s можно менять и у яруса с данными. Ярус без записи получает период по умолчанию.

Пример объявления схемы избыточности:

ALTER PLUGIN s3r 2.2.0 SET
  s3r_storage.erasure = '[{"k":8,"m":4,"stripe_size":"1MiB"}]';

Как выбрать схему, описано в разделе Выбор схемы избыточности яруса.

Карта классов

Параметр tiers — список пар {name, class}: ярус и его класс хранения S3. Порядок списка — от наиболее частого к наиболее редкому доступу. Пустая карта означает ярус standard с классом STANDARD.

Необязательное поле compress включает сжатие объектов, записываемых в ярус операцией PutObject, см. Сжатие.

Правила привязки ярусов к классам описаны в разделе Классы хранения S3 и ярусы.

Проверка значений

Команда ALTER PLUGIN ... SET, изменяющая параметры s3r_storage, проверяет новое значение до сохранения. Она отклоняется целиком, ничего не сохранив, если:

  • ярус объявляет две схемы, либо k или m равно нулю;
  • у инстанса в ярусе 2 × (k + m) дисков или больше: владелец пишет в одну группу яруса за раз, и лишние диски простаивали бы;
  • меняется или удаляется схема избыточности яруса, в котором уже есть группы размещения. Чтобы изменить схему данных, их переносят в новый ярус через карту классов;
  • меняется disks, когда в кластере уже зарегистрирован хотя бы один диск. Диски добавляются и удаляются действиями API управления, см. Действия с дисками;
  • в схеме указан ярус, которого нет в карте классов tiers;
  • карта классов tiers содержит класс, которого нет в S3, либо меняет записанную привязку яруса к классу или порядок ярусов.

Ярус, у которого есть диски, но нет схемы, командой не отклоняется: схему можно объявить и после включения плагина, а начальное формирование её дождётся.

Когда проверка не выполняется

Проверку выполняет инстанс, на котором выполняется команда, по таблицам кластера. При включении плагина и при обновлении Picodata проверку не вызывает. Поэтому сервис s3r_storage повторяет её при запуске. Если сохранённая конфигурация нарушает правило, сервис записывает в журнал ошибку the stored s3r_storage configuration breaks a rule: ... и продолжает запуск.

Запись схемы яруса

Схема и классы блоков яруса записываются в столбец tiers таблицы s3r_cluster один раз:

  • при переходе кластера к формированию первых групп;
  • для яруса, появившегося позже, — когда проверка этого яруса проходит, см. Группы размещения.

Запись не перезаписывается. Диски, владельцы групп и API управления читают её, а не конфигурацию.

Классы блоков зависят от схемы, размера полосы и значения s3r_api.inline_max на момент записи. Поэтому изменённое значение inline_max не меняет классы блоков уже записанных ярусов и действует только на ярусы, записанные позже. Инстанс, который ведёт формирование, выводит в журнал предупреждение, в котором названы ярусы с другим записанным значением:

inline_max is <N>, and tiers keep the block classes they were recorded with: <ярус> at <значение>, ...

Каждая группа, кроме того, хранит k, m и размер полосы (столбец stripe_bytes) в своей строке таблицы s3r_pg. Чтение и запись берут геометрию оттуда.

Конфигурация Picodata

Часть параметров плагина задаётся в конфигурации инстанса Picodata:

instance:
  failure_domain:
    dc: msk
    rack: r3
  plugin:
    s3r:
      service:
        s3r_api:
          listener:
            enabled: true
            listen: "0.0.0.0:8443"
            tls:
              enabled: true
              cert_file: /etc/s3r/server.pem
              key_file:  /etc/s3r/server.key
              ca_file:   /etc/s3r/clients-ca.pem
        s3r_storage:
          listener:
            enabled: true
            listen: "0.0.0.0:8700"
            advertise: "node3.example.net:8700"

Домен отказа инстанса

Домен отказа инстанса задаётся параметром instance.failure_domain.

Компонент Что задаёт Правило
dc площадку; группа размещения не выходит за границу площадки кластер с несколькими площадками объявляет dc на каждом инстансе, кластер с одной площадкой — ни на одном
остальные какие инстансы отказывают вместе S3R считает два инстанса одним доменом отказа, только если совпадают все компоненты, кроме dc. Инстансы, домены отказа которых совпадают хотя бы в одном компоненте, Picodata не объединяет в один репликасет

Объяснение и примеры — в разделах Домен отказа, Схема избыточности и Домен отказа диска.

Слушатель s3r_api

Слушатель s3r_api задаёт адрес эндпоинта S3 и его сертификат.

Параметр Что задаёт
listener.enabled явное значение false отключает эндпоинт S3; запасной адрес в этом случае не применяется
listener.listen адрес и порт эндпоинта S3
listener.tls.cert_file, listener.tls.key_file сертификат эндпоинта S3 и его ключ
listener.tls.ca_file включает двустороннюю аутентификацию TLS (mTLS): клиент без сертификата отклоняется на этапе рукопожатия

Адрес эндпоинта S3 выбирается в таком порядке:

  1. Раздел listener конфигурации инстанса.
  2. Если раздела listener нет — переменная окружения S3R_API_LISTEN.
  3. Если нет и её — параметр s3r_api.listen.

Слушатель s3r_storage

Внимание

Инстанс, на котором заданы диски и не задан слушатель s3r_storage, не запускается. Иначе инстанс опубликовал бы диски, недоступные остальным узлам кластера, и при этом выглядел бы исправным.

Слушатель s3r_storage задаёт адрес обмена фрагментами. Объявленный адрес (advertise) Picodata публикует в таблице _pico_peer_address, и по этой таблице узлы находят друг друга. Собственного реестра узлов плагин не ведёт.

Переменные окружения

Переменная Назначение
S3R_DISKS список дисков инстанса для первого запуска; перекрывает параметр s3r_storage.disks
S3R_API_LISTEN адрес эндпоинта S3; применяется, только если в конфигурации Picodata нет раздела слушателя
S3R_WORKER_THREADS верхняя граница пула рабочих потоков Tokio

S3R_DISKS

Список дисков через запятую. Диск описывается полями через двоеточие:

путь[:КЛЮЧ=ЗНАЧЕНИЕ]*[:ёмкость]

Пример: /mnt/d0:hba=a,/mnt/d1:hba=b:tier=hdd:4TiB.

Поле Что задаёт
со знаком =, ключ tier ярус: метка администратора из символов [a-z0-9_-], по умолчанию standard
со знаком =, другой ключ свойство диска; такие свойства образуют поддомен отказа
без знака = ёмкость. Её можно не указывать, только если в директорию диска смонтирована отдельная файловая система, см. Ёмкость диска

Если у диска указано второе числовое поле, диск не монтируется и в журнал выводится ошибка.

Когда какой способ применять:

  • параметр s3r_storage.disks описывает установку, в которой на всех узлах одинаковые устройства смонтированы по одинаковым путям;
  • если пути различаются, например из-за нескольких инстансов на одном узле, диски задаются переменной S3R_DISKS.

Список читается один раз, при первом запуске сервиса s3r_storage на инстансе, и проверяется по правилам шага 3 установки, см. Конфигурация инстансов. После регистрации дисков переменная не читается, и её изменение ни на что не влияет. Хватает ли дисков и доменов отказа для схемы избыточности каждого яруса, показывает /-/ready до завершения начального формирования.

S3R_WORKER_THREADS

Переменная нужна на узлах с несколькими инстансами. Без неё каждый инстанс определяет размер пула по всей машине, и на узле с четырьмя инстансами рабочих потоков запускается вчетверо больше, чем процессорных ядер. Если ресурсы инстансов ограничены средствами cgroup, переменная не требуется: функция available_parallelism() учитывает квоту.