Skip to content

Latest commit

 

History

History
122 lines (97 loc) · 9.13 KB

CalculationRAM.md

File metadata and controls

122 lines (97 loc) · 9.13 KB

Примерный расчет расходуемой сервисом оперативной памяти.

В памяти хранятся следующие объекты:

  • Объект Map с операциями, которые еще выполняются;
  • Объект Map с преагрегатами (внутри каждого преагрегата присутствует список операций с текущим состоянием);
  • Объект Map с конфигурационной информацией по сервисам;
  • Объкет Map с последними агрегатами для каждого сервиса.

Рассчитаем гипотетическое количество потребляемой памяти для каждой Map'ы.

#####1. Объем памяти, который может потреблять Map'a с операциями, которые еще выполняются.

Данная структура состоит из ключа (ID сервиса - строка) и значения - Map'ы с операциями, где в качестве ключа выступает ID операции (строка), а в качестве значения объект, содержащий ID сервиса, ID операции, время начала и время окончания операции, а так же признак ошибки. Таком образом предположим, что Fault Detector будут использовать 10 сервисов, и нагрузка на каждый будет в среднем 100 уникальных операций в минуту, которые равномерно поступают в систему. Стоит понимать что для одной операции будет 2 внешних вызова - во время начала и завершения операции. Интересующий временной интервал (далее ВИ) 10 минут, а ожидаемое время выполнения 6 минут.

Таким образом максимально за 10 минут в 10 сервисах будет находится 10000 объектов, содержаших информацию о операциях. Сам объект ServiceEvent содержит следующие поля:

  • String serviceId;
  • String operationId;
  • long startTime;
  • long endTime;
  • boolean error.

Начнем со строк. Класс String содержит следующие поля:

  • final char value[];
  • final int offset;
  • final int count;
  • int hash.

Подсчитаем размер:

  • Заголовок -> 8 байт
  • Поля int -> 4 байта * 3 == 12 байт
  • Ссылочная переменная на объект массива -> 4 байта

Итого после выравнивания для кратности 16-ти: 32 байта.

Так как строка содержит ссылку на массив символов, то, по сути, мы имеем дело с двумя разными объектами — объектом класса String и самим массивом, который хранит строку, а это еще 12 байт на сам объект массива + 2 байта на каждый символ строки. Ну и, конечно же, не забываем добавлять выравнивание для кратности 16 байтам (для 32-ух разрядной системы 8).

Таким образом объект String serviceId = "hellgate_service.adapter_availability.110" будет занимать следующее количество памяти.

Для "new String()":

  • Заголовок: 8 байт
  • Поля int: 4 байта * 3 == 12 байт
  • Ссылочная переменная на объект массива: 4 байта
  • Выравнивание для кратности 16: 8 байт Итого: 32 байта

Для "new char[41]":

  • Заголовок: 8 байт + 4 байта на длину массива == 12 байт
  • Примитивы char: 2 байта * 41 == 82 байт
  • Выравнивание для кратности 16: 4 байт Итого: 96 байта

В итоге new String("hellgate_service.adapter_availability.110") == 128 байт.

Для примера возьмем operationId = "hellgate_operation.adapter_availability.1CmOAov8Ls8", то есть 51 символ. Это означает, что объект String согласно расчетам будет равен 160-ти байтам.

Примитив типа long занимает 8 байт, а boolean 1 байт. Таким образом размер одного объекта ServiceEvent будет расчитываться из следующих параметров:

  • String serviceId = 128 байт;
  • String operationId = 160 байта;
  • long startTime = 8 байт;
  • long endTime = 8 байт;
  • boolean error = 1 байт;
  • Заголовок: 8 байт.

Итого: 313 байт + 7 байт для выравнивания = 320 байт на каждый объект ServiceEvent. Также минимум 4 байта на ссылку на объект в Map'e. Таким образом минимальный размер оперативной памяти, который понадобится на хранение 10000 элементов будет равен 3 240 000 байт или 3,09 мегабайта.

Если же закладываться на предполагаемую нагрузку хотя бы а 50 операций в секунду, то для 10 сервисов в худшем случае будет храниться 300000 операций. Это 97 200 000 байт или 92,7 мегабайт. Ожидаемо, что с увеличением ВИ и количества сервисов в худшем случае можно упереться в размер RAM. Подобная маловероятна в обычной работе, так как подсчитываются преагрегаты, а успешные/сбойные операции сразу удаляются, но возможна при одновременном сбое всех сервисов.

#####2. Объем памяти, который может потреблять Map'a с преагрегатами

Объект Map с преагрегатами похож на описанную ранее Map'y с операциями, поэтому перейду сразу к основному - объекту ServicePreAggregates. Он содержит следующие поля:

  • String serviceId = 128 байт;
  • String timeMark = 72 байт;
  • long aggregationTime = 8 байт;
  • Set operationsSet = 4 байта на ссылку на сам объект + 4 байта на ссылку на объект String в самом Set'e, а также по 160 байт на запись, так как там будет находится operationId
  • int operationsCount = 4 байт;
  • int runningOperationsCount = 4 байт;
  • Set overtimeOperationsSet = 4 байта на ссылку на сам объект + 4 байта на ссылку на объект String в самом Set'e, а также по 160 байт на запись, так как там будет находится operationId
  • int overtimeOperationsCount = 4 байт;
  • int errorOperationsCount = 4 байт;
  • int successOperationsCount = 4 байт;
  • Заголовок: 8 байт.

Итого минимально объект занимает 236 байт + 4 байта выравнивание = 240. Так же по 4 байта в качестве ссылки в Map'e. Минимальный размер агрегата = 1 секунда. таким образом за 10 минут для 10 сервисов будет 6000 агрегатов, что выразится в 1 440 000 байт или 1,37 мб.

Дополнительно в объекте присутствуют поля, в которых содержится список конкретный операций в рамках одной преагрегации согласно настройкам от hellgate. Предположим, что преагрегация будет равна 5 секундам. В таком случае максимально в 2 Set'ах будет храниться 500 операций или 80 кб, что является крайне малым.

#####3. Объем памяти, который может потреблять Map'ы с конфигурацией и агрегатами.

Для каждого сервиса существует строго 1 агрегат и строго 1 конфигурация. Размер данных структур в сравнении со структурами представленными ранее является ничтожным и не требует рассчета.