В классе поточных алгоритмов имеется подкласс, решающий задачу поиска тяжелых элементов (heavy hitters). В общем виде эта задача формулируется как «выявление во входящем потоке наиболее часто повторяющихся событий и измерение их интенсивности». В данной публикации сотрудника компании Qrator Labs Артема janatem Шворина предлагается эффективный алгоритм для решения этой задачи.
Введение
Алгоритмы нахождения тяжелых элементов помогают решать задачи, такие как борьба с перегрузкой сети, выявление сетевых аномалий и атак, управление динамической маршрутизацией. Например, известный веб-сервер NGINX позволяет ограничивать интенсивность запросов к определённому ресурсу, и для того, чтобы это делать, интенсивность должна быть измерена количественно.
В этой публикации мы хотим показать читателю ещё один подход к измерению интенсивности потока событий при наличии множества разных (не идентичных) потоков событий. Пусть задано множество типов событий. Требуется оценивать, насколько часто происходит событие данного типа, и обращать внимание на случаи, когда событие одного типа повторяется «слишком часто».
Важной характеристикой данного инструмента является его высокая эффективность, чтобы он не стал узким местом во всей системе анализа и фильтрации трафика. Речь в этом случае идет о том, чтобы обрабатывать одно событие за несколько десятков тактов центрального процессора современных компьютеров.
Помимо собственно измерения интенсивности требуется выделять типы событий, которые случаются наиболее часто. Их интенсивность нужно измерять более точно, в то время как редкие типы событий большой роли не играют, и оценивать их интенсивность не обязательно с высокой точностью.
В работе представлен разработанный нами алгоритм Decay-based count, основанный на модели распада радиоактивного вещества (см. раздел «Модель распада»), с высокой эффективностью решающий задачу поиска тяжелых элементов.
Задача поиска тяжелых элементов
Классификация задач
В описываемом классе задач можно выделить следующие подклассы:
- Threshold-. Требуется выделить потоки, имеющую большую интенсивность чем заданная доля интенсивности всего входящего трафика.
- Top-. Требуется выделить заданное количество самых интенсивных потоков.
- Выделение потоков, интенсивность которых превышает некоторое заданное абсолютное значение.
Предлагаемый алгоритм относится к последнему из перечисленных подклассов.
Целевая архитектура
В зависимости от платформы, на которой предполагается запускать данный поточный алгоритм, имеется набор аппаратных ограничений. Иногда требуется встраивать нужную функциональность в сетевое оборудование (свитч, коммутатор и т. п.). Предлагаемый алгоритм предполагается использовать на универсальном процессоре, но при некоторых значениях параметров допускает встраивание в сетевое оборудование.
Параметры задачи
- Абсолютное значение интенсивности потока, которое считается «опасным». Задачей алгоритма является выявление потоков, интенсивность которых превышает заданный порог.
- Размер ключа — идентификатора, по которому определяется тип события. В данной реализации, как и во многих других алгоритмах, требуется хранить значения ключей в таблице, поэтому размер ключа влияет на затраты памяти.
- Способ вычисления оценки интенсивности одного потока по временам прихода однотипных событий. По сути это алгоритмическое определение того, что такое интенсивность потока. В этом случае вычисляется экспоненциальное скользящее среднее, которое имеет единственный параметр — характерное время , в течение которого учитывается вес события после его прихода.
Точность решения
- Оценкой качества алгоритма может быть относительная или абсолютная погрешность в оценке интенсивности потоков. Также используют -аппроксимацию в качестве оценки точности: если с вероятностью погрешность составляет не более , то говорят, что алгоритм имеет характеристику точности .
- Если ошибка имеет качественный, а не количественный характер, как, например, включение или невключение данного потока в список самых интенсивных в задаче top-, то для оценки берутся вероятности ложноположительного и ложноотрицательного срабатывания.
Накладные расходы
Как правило, основной характеристикой алгоритма является максимальная интенсивность входящего потока, которую он способен обработать. То есть важно лишь время обработки одного события. Однако на практике влияют и другие аппаратные ограничения, такие как размер памяти, используемой для хранения накопленной информации о потоке. Особенно жесткие аппаратные ограничения имеют место при встраивании функционала в сетевое оборудование. Но и на обычных компьютерах наличие большого количества оперативной памяти DRAM помогает далеко не всегда, поскольку доступ в DRAM может занимать неприемлемо много времени. Для того чтобы достичь требуемой производительности, приходится идти на компромисс с точностью измерения и ограничивать размер используемой памяти, чтобы она помещалась в кэш процессора. В данной реализации при осмысленных значениях параметров таблица помещается в L2 кэш процессора. В результате удалось добиться того, чтобы время обработки одного события составляло несколько десятков тактов процессора.
Методы оценки интенсивности потока
Для оценки интенсивности повторений событий заданного типа требуется посчитать количество событий в течение некоторого времени. Для этого нужно фиксировать время наступления события и каким-то образом сохранять его. Обычно для этой цели используют счетчик, который инкрементируется при наступлении соответствующего события. Тогда интенсивность оценивается как отношение значения счетчика к интервалу времени, в течение которого проводится измерение. Более аккуратные способы измерения актуального значения интенсивности используют различные варианты скользящего среднего. Например, экспоненциальное скользящее среднее (exponential moving average, EMA) — разновидность взвешенного скользящего среднего с экспоненциально убывающими весами.
В работе предлагается новый метод вычисления EMA. Здесь используется модель экспоненциального распада, которая описывает такое физическое явление как радиоактивный распад. Эта модель имеет ряд преимуществ по сравнению с традиционным подходом. Во-первых, представление данных оказывается более экономичным по памяти. Во-вторых, модель распада допускает эффективную по скорости реализацию операции обновления счетчика — она требует небольшое количество целочисленных арифметических операций и одно кэшируемое обращение к памяти.
Методы учета множества потоков
В задаче поиска тяжелых элементов проблемой является не только высокая интенсивность входного трафика, но и большое количество различных потоков (типов событий), за которыми приходится следить. Наивная реализация предполагает заведение отдельного счетчика на каждый поток, что приводит к значительному расходу памяти. При этом есть опасность не только в исчерпании всей доступной памяти, но в существенной замедлении скорости работы из-за промахов в кэш. Поэтому, как правило, отказываются от точного решения задачи поиска тяжелых элементов, выбрасывая часть накопленной информации о потоках. Известно множество методов ограничения объема используемой памяти и уменьшения времени обработки события, некоторые из которых приведены ниже:
- Packet sampling
- Space saving algorithm
- HashParallel
- HashPipe
- Count-min sketch
Формализация задачи
Прежде чем переходить к описанию алгоритма, необходимо с достаточной математической строгостью сформулировать задачу измерения потока событий, что мы и сделаем в данном разделе.
Последовательность однотипных событий задается в виде множества элементарных событий , где индекс пробегает конечный или бесконечный дискретный интервал .
В простейшем случае событие определяется только временем его наступления: , причем события упорядочены во времени: для . В большинстве реализаций систем учета событий время считается дискретной величиной: , однако для теоретических рассуждений бывает удобно обобщить и считать время непрерывным: .
Основной вопрос, на который должны отвечать системы учета событий, — это оценка интенсивности потока. Интенсивность может быть строго формализована для равномерного потока событий. Равномерный поток определяется следующим образом:
где , — параметры потока — период и фаза, соответственно. То есть события наступают через равные промежутки времени. Тогда интенсивность такого потока, по определению, выражается как .
Для неравномерных потоков формальное определение интенсивности может отличаться в зависимости от постановки задачи. Модель распада остается работоспособной и полезной и в этом случае, однако оценка качества вычисления истинной интенсивности дана ниже только для случая равномерных потоков.
В некоторых моделях требуется дополнительно учитывать некоторую характеристику события, например, его вес — величина вклада данного события в измеряемую интенсивность. Тогда событие определяется не только временем его наступления, но и весом: .
В типичных реализациях систем учета событий заводится счетчик , который некоторым образом накапливает информацию о потоке событий, и в любой момент времени по его текущему значению можно получить оценку интенсивности потока , такую что . Обновление счетчика происходит по приходу очередного события :
где — некоторая функция, которая определяется реализацией. Ниже приведено несколько примеров с вариантами реализации функции :
- Простой подсчет количества событий: ;
- Подсчет количества событий с учетом веса: ;
- Вычисление экспоненциального скользящее среднего (EMA) с параметром . Здесь счетчик хранит две величины: собственно значение EMA и время последнего обновления.
где .
В некоторых задачах требуется различать потоки событий. Пусть имеется множество различных типов событий, занумерованных индексом , и требуется учитывать отдельно потоки сообщений каждого типа. Тогда событие описывается как (или, с учетом веса события, ), где — тип события. Множество индексов , относящихся к данному типу события обозначим .
Модель распада
Модель распада описывается следующим образом:
где — «количество вещества» в нулевой момент времени, — количество в момент времени , — параметр модели (так называемая постоянная распада). Название данной модели отражает тот факт, что она описывает физическое явление радиоактивного распада.
Дополнительно введем следующие обозначения:
В нашем случае в качестве параметра модели вместо удобнее использовать , поскольку будет иметь размерность времени и неформально может определяться как характерный интервал времени, в течение которого собирается история событий.
Будем по определению считать, что каждому типу события соответствует величина , имеющая физический смысл «количества вещества» и зависящая от времени, которая при наступлении события скачком увеличивается на единицу, а в остальное время уменьшается по приведенному выше экспоненциальному закону.
На рис. 1 показано, как меняется со временем значение для равномерных потоков с разной интенсивностью и для неравномерного потока.
Рисунок 1: Значение для разных потоков
Величина не хранится явно в памяти, но может быть вычислена в любой момент. Хранится же значение , такое что в момент времени величина выражается следующим образом:
Данное представление соответствует модели распада.
Вычисление счетчика в модели распада эквивалентно вычислению экспоненциального
скользящего среднего с точностью до нормирующего множителя (константы). Важной особенностью данного представления является то, что единственное значение, хранимое в счетчике, заменяет собой пару (время последнего события, накопленная величина), которую хранят при традиционном подходе.
Обновление счетчика
Нетривиальной операцией является обновление значения счетчика при наступлении очередного события. В этом случае требуется заменить на новое значение , которое определяется из следующего равенства:
Здесь слева стоит значение сразу после наступления события, а справа — значение непосредственно до события, увеличенное на вклад события (равный единице). Ниже будут предложены эффективные способы вычисления результата обновления.
В терминах функции из определения операция обновления выражается так:
Здесь время исполнения операции совпадает со временем прихода сообщения.
Определение интенсивности
Пусть имеется равномерный поток событий интенсивности , то есть события наступают с периодом . Равномерный поток задается согласно определению.
Если измерение производится сразу после наступления очередного события, то есть для некоторого , то накопленное в течение длительного времени значение счетчика будет выражаться следующим рядом:
откуда
где — относительное значение счетчика.
В более общем случае момент измерения может оказаться между событиями:
, . В этом случае значение счетчика будет отличаться в меньшую сторону на величину :
Задача измерения интенсивности заключается в том, чтобы по значению счетчика оценить интенсивность. В предположении, что поток равномерный, можно получить оценки истинной интенсивности равномерного потока сверху и снизу, подставляя в предыдущее уравнение крайние значения и :
где
Обе оценки и монотонно зависят от значения счетчика (см. рис. 2), поэтому, например, сравнение текущего значения счетчика с пороговым значением не требует дополнительных вычислений.
Рисунок 2: График функций и для
В модели распада интенсивность произвольных (не обязательно равномерных) потоков по определению задается приведёнными выше оценками и . Причем, если измерение происходит сразу после обработки события, то интенсивность считается в точности равной нижней оценке.
Границы применимости модели распада
Существуют ограничения на значение интенсивности, которая может быть корректно измерена в модели распада.
Во-первых, если время наступления событий измеряется как дискретная величина, то период потока не может быть меньшим единицы. То есть интенсивность потока не должна превышать . Отсюда следует ограничение на относительное значение счетчика — оно не должно превышать значения , которое определяется из формулы:
Величина оценивается следующим образом:
где .
Во-вторых, оценка интенсивности слабых (малоинтенсивных) потоков затруднена: при малых относительных значениях счетчика точность верхней и нижней оценки и ухудшается, а при отрицательных значениях нижняя оценка интенсивности вырождается в нуль.
Также есть ограничение на время работы реализаций модели распада, связанное с переполнением счетчиков. Поскольку значение счетчика не может убежать от более, чем на , время работы системы фактически определяется разрядностью счетчика и длительностью одного такта. Если для хранения счетчика используется 64-разрядный регистр, то он не переполнится в течение 100 лет. Но в реализациях с малоразрядными регистрами должен быть предусмотрен механизм сброса счетчиков.
Алгоритмы учета множества потоков
Особенности модели распада
Особенностью использования EMA в качестве значения счетчика является то, что при прекращении потока событий накопленное значение быстро (экспоненциально по времени) деградирует и становится неотличимым от нуля. В модели распада этот факт используется для автоматического сброса счетчика: хотя значение счетчика будет всё время возрастать с приходом событий, через некоторое время после прекращения потока событий величину можно будет считать равной нулю, не меняя явно значения счетчика. Время , за которое любое накопленное ранее значение распадается до условного нуля, зависит от параметра и требуемой точности. Оно выражается как , где — время распада значения, накопленного в результате единичного события. В разделе «Табличная реализация» дано точное выражение , но здесь достаточно иметь в виду следующий факт: при фиксированной точности.
Отсюда следует оценка сверху на размер хранилища счетчиков при учете множества потоков для случая, когда информация вообще не будет теряться — достаточно иметь ячеек. Есть множество применений задачи поиска тяжелых элементов, где не требуется больших значений , и всё хранилище помещается оперативную память или даже в кэш процессора L3 или L2. В этом случае обеспечивается малое время доступа к хранилищу, так что задача становится выполнимой при высоких значениях интенсивности входного потока.
Для реализации хранилища годится хэш-таблица, где ключом является тип события. При этом пустыми считаются ячейки, у которых значение счетчика удовлетворяет условию .
Численная реализация Decay-based count
Операция обновления значения
Введем следующее обозначение:
Тогда операция обновления выражается следующим образом:
Таким образом, задача сводится к эффективному вычислению приближения функции . Время удобно представлять целым числом, например, измерять его в тактах процессора, так что требуется построить целочисленное отображение , такое, что:
Для данной задачи точность важна не относительная, а абсолютная, поскольку со значениями времени используются в основном аддитивные операции. Очевидно, что из-за целочисленности представления времени погрешность меньше 0.5 такта недостижима.
Кроме того, операция измерения текущего времени, как правило, дает некоторую погрешность. Например, если есть способ измерения времени с точностью в 10 тактов, то достаточно потребовать, чтобы давало приближение примерно такой же точности:
Можно предложить несколько разных способов вычисления разной сложности и степени эффективности.
Вычисление : FPU
Проще всего использовать арифметику с плавающей точкой и непосредственно вычислять по определению. Время выполнения этой операции составляет около 100 тактов процессора, что довольно много по сравнению предлагаемым ниже методом.
Вычисление : табличная реализация
Идея табличной реализации состоит в том, чтобы сохранить предвычисленные значения функции в таблице.
Во-первых, используя тождество
достаточно строить только для .
Во-вторых, поскольку
существует , такое что при . Где можно найти из следующих соображений:
откуда
Таким образом, достаточно определить для .
График функции представлен на рис. 3. Особенность этой функции такова, что с изменением параметра будет происходить одинаковое масштабирование по обеим осям.
Рисунок 3: График функции
Очевидная реализация состоит в построении таблицы из ячеек, где будут храниться предвычисленные значения. Поскольку все значения функции на данном интервале находятся в промежутке между 0 и , итоговый размер таблицы составляет бит.
Алгоритм обновления значения выглядит следующим образом:
Абсолютная точность этого метода составляет 1/2, поскольку он дает наилучшее целочисленное приближение вещественнозначной функции.
Результаты измерения эффективности
Сравнивались между собой следующие три реализации экспоненциального скользящего среднего:
1. наивная реализация EMA;
2. модель распада через FPU (то есть с вызовом функций exp() и log() математической библиотеки);
3. модель распада табличным методом.
Исходный код теста на си: pastebin.com/wiiEe6MP.
Время выполнения одного вызова функции update() при (в этом случае таблица для вычисления помещается в кэш L1) в реализациях 1, 2 и 3 составляет 125, 100, 11 тактов процессора, соответственно.
Использование экспоненциального скользящего среднего — удобный способ подсчёта событий и оценки интенсивности. Однако данная операция вычислительно затратна, что сильно ограничивает возможности её применения. Наша реализация алгоритма на основе модели распада, во-первых, красива, а во-вторых, более эффективна, нежели наивная реализация вычисления ЕМА. Эффективность обеспечивается за счет двух факторов: табличное вычисление трансцендентной функции и более экономное по памяти представление счетчика.
Благодарность
Данная публикация подготовлена нами в пробном режиме в рамках проекта по освещению механизмов работы сети фильтрации Qrator. Спасибо Антону Орлову, Артему Гавриченкову и Евгению Наградову за наводящие вопросы и предложения.
Автор: Shapelez