Надежные коллекции и память Azure Service Fabric

Скажем, я запускаю кластер Service Fabric на 5 виртуальных машинах класса D1 (1 ядро, 3,5 ГБ, 50 ГБ SSD). и что я запускаю 2 надежных сервиса в этом кластере, один без гражданства и один из них. Предположим, что цель реплики равна 3.

  • Как рассчитать, сколько можно хранить мои надежные коллекции?

  • Скажем, я добавляю одну или несколько служб с сохранением состояния. Поскольку я действительно не знаю, как инфраструктура распределяет службы, мне нужно принять наиболее консервативный подход и предположить, что node может запускать все мои службы с состоянием на одном node и что их накопительная память должна быть ниже ОЗУ доступно на одной машине?

Ответ 1

TL;DR - Оценка ожидаемой мощности кластера - это отчасти искусство, отчасти наука. Скорее всего, вы можете получить хорошую нижнюю границу, которую сможете продвинуть выше, но по большей части развертывание, запуск и сбор данных в условиях вашей рабочей нагрузки - лучший способ ответить на этот вопрос.

1) Как правило, коллекции на данном компьютере ограничены объемом доступной памяти или объемом доступного дискового пространства на узле, в зависимости от того, что меньше. Сегодня мы храним все данные в коллекциях в памяти и сохраняем их на диске. Таким образом, максимальный объем, который могут храниться вашими коллекциями в кластере, обычно равен (объем доступной памяти в кластере)/(размер набора целевой реплики).

Обратите внимание, что "Доступная память" - это то, что осталось от другого кода, работающего на машинах, включая ОС. В приведенном выше примере, хотя вы работаете не со всеми узлами, вы сможете получить только 3 из них. Таким образом, (нереально) предполагая, что из-за этих других факторов происходит дополнительная нагрузка, равная 0, можно ожидать, что вы сможете разместить около 3,5 ГБ данных в этой реплике с отслеживанием состояния до того, как у вас не хватит памяти на узлах, на которых он работал. В кластере по-прежнему оставалось бы 2 узла.

Давайте возьмем другой пример. Допустим, он примерно такой же, как в приведенном выше примере, за исключением того, что в этом случае вы настраиваете службу с сохранением состояния для разделения. Допустим, вы выбрали количество разделов 5. Итак, теперь на каждом узле у вас есть первичная реплика и 2 вторичные реплики из других разделов. В этом случае каждый раздел может содержать максимум около 1,16 ГБ состояния, но теперь в целом вы можете упаковать 5,83 ГБ состояния в кластер (поскольку все узлы теперь могут использоваться полностью). Кстати, просто чтобы доказать математическую работу, (3,5 ГБ памяти на узел * 5 узлов в кластере) [17,5]/(размер набора целевой реплики 3) = 5,83.

Во всех этих примерах мы также предполагали, что потребление памяти для всех разделов и всех реплик одинаково. Часто оказывается, что это не так (по крайней мере, временно) - некоторым разделам может потребоваться больше или меньше работы, что приводит к неравномерному потреблению ресурсов. Мы также предположили, что вторичные всегда были такими же, как первичные. В случае количества штатов, вероятно, будет справедливо предположить, что они будут отслеживаться достаточно равномерно, хотя для других ресурсов это может не произойти (просто что-то нужно иметь в виду). В случае неравномерного потребления это действительно поможет остальной части управления ресурсами кластера Service Fabric, поскольку мы можем узнать о потреблении различных реплик и эффективно упаковать их в кластер, чтобы использовать доступное пространство. Автоматическая отчетность о потреблении ресурсов, связанных с состоянием в коллекциях, находится на нашем радаре, и мы хотим что-то сделать, поэтому в будущем это будет автоматически, но сегодня вы должны будете сообщать об этом потреблении самостоятельно.

2) По умолчанию мы будем балансировать услуги в соответствии с метриками по умолчанию (подробнее о метриках здесь). Таким образом, по умолчанию разные реплики этих двух разных сервисов могут оказаться на компьютере, но в вашем примере вы получите 4 узла с 1 репликой из сервиса на нем, а затем 1 узел с двумя репликами из двух разные услуги. Это означает, что каждая служба (каждая с 1 разделом в соответствии с вашим примером) сможет потреблять только 1,75 ГБ памяти в каждой службе, в общей сложности 3,5 ГБ в кластере. Это опять-таки меньше, чем общая доступная память кластера, поскольку есть некоторые части узлов, которые вы не используете.

Обратите внимание, что это максимально возможное потребление, и предполагается, что потребление не входит в само обслуживание. Принимать это как максимум не рекомендуется. Вы захотите уменьшить его по нескольким причинам, но наиболее практическая причина заключается в том, чтобы при наличии обновлений и сбоев существовала достаточная доступная емкость в кластере. В качестве примера предположим, что у вас есть 5 доменов обновления и 5 доменов сбоя. Теперь допустим, что в узлах сбойных узлов происходит сбой, когда в домене обновлений происходит обновление. Это означает, что (чуть менее) 40% емкости вашего кластера может быть потеряно в любое время, и вы, вероятно, захотите, чтобы на оставшихся узлах оставалось достаточно места для продолжения работы. Это означает, что если ваш кластер ранее мог содержать 5,83 ГБ состояния (по нашим предыдущим расчетам), в действительности вы, вероятно, не захотите добавлять в него более 3,5 ГБ состояния, так как при большем количестве эта служба не сможет чтобы вернуться к 100% работоспособности (учтите также, что мы не создаем замещающие реплики немедленно, поэтому узлы должны быть недоступны для вашего ReplicaRestartWaitDuration, прежде чем вы столкнулись с этим делом). В этой статье рассматривается множество дополнительной информации о показателях, емкости, буферизованной емкости (которую можно использовать для обеспечения свободного места на узлах для случаев сбоя) и доменах сбоя и обновления.

Есть некоторые другие вещи, которые практически ограничат количество состояния, которое вы сможете хранить. Вы хотите сделать несколько вещей:

  • Оцените размер ваших данных. Вы можете заранее оценить, насколько велики ваши данные, рассчитав размер каждого поля, которое содержат ваши объекты. Обязательно примите во внимание 64-битные ссылки. Это даст вам нижнюю границу отправной точки.
  • Хранение накладных расходов. Каждый объект, который вы храните в коллекции, будет иметь некоторые накладные расходы для хранения этого объекта. В надежных коллекциях, в зависимости от коллекции и операций, выполняемых в данный момент (копирование, перечисления, обновления и т.д.), Эти издержки могут варьироваться от 100 до 700 байтов на элемент (строку), хранящиеся в коллекциях. Знайте также, что мы всегда ищем способы уменьшить количество накладных расходов, которые мы вводим.

Мы также настоятельно рекомендуем запускать ваш сервис в течение определенного периода времени и измерять фактическое потребление ресурсов с помощью счетчиков производительности. Моделирование какой-то реальной рабочей нагрузки, а затем измерение фактического использования метрик, которые вас интересуют, будут вам весьма полезны. Причина, по которой мы рекомендуем это, в частности, заключается в том, что вы сможете увидеть потребление от таких вещей, как, например, куча объектов CLR, в которые ваши объекты помещаются, как часто работает GC, утечки или другие подобные вещи, которые влияют на количество. памяти вы можете реально использовать.

Я знаю, что это был длинный ответ, но я надеюсь, что вы найдете его полезным и полным.