Hadoop metrics filtering

Окт 31 2014

Hadoop and hbase is a complicated software with lots of stuff inside. It’s essential to keep an eye on them to be sure your installation is heavy and not going to break in next five minutes.

To do this, hadoop has a subsystem, called metrics which provides a way to send some value outside. Usually, this is just a number, representing something — count of requests performed, size of some buffer, etc.

The most common thing is to drop these values into ganglia to build nice charts out of them. There are lots of tutorials how to do this on the net — just google for «ganglia hadoop».

This article describes less known feature — filtering of metrics, which becomes unavoidable for mid-range HBase installations.

I suppose some prior knowledge about hadoop and ganglia.

Why filter?

Some time ago, HBase developers decided that emitting metrics about regionservers is not enough and started to produce metrics of regions itself. As regions tend to migrate from node to node, new ganglia chart will eventually be created for every region on every machine in cluster.

Let’s calculate. It’s about 30 metrics for region. If you have 1000 regions live on 100 machines (pretty moderate), it gives us 3 millions of fresh, completely useless RRD files on your ganglia servers. They are useless, as on every region migrate, partly-built chart will migrate to another rrd file.

I faced this problem right after CDH4 migration and it was disasterous, as we had much larger cluster than on this toy example (300 machines, 20k regions). At that time, the only way to resolve this was patch hbase to stop emitting these values. After HBase 0.94 there is better solution — metrics2 filters.

Filter syntax

To start filter events, several decisions must be made:

  • filter class
  • level of filtering
  • what to filter

Filter class

There are two classes implemented which provide actual filtering with different filtering syntax:

  • org.apache.hadoop.metrics2.filter.GlobFilter
  • org.apache.hadoop.metrics2.filter.RegexFilter


Filter syntax

The filtering rule has the following syntax:


  • subsystem – kind of daemon: hbase, yarn, hdfs, etc
  • sink|source – have no idea what it is, just used sink and it works
  • sink_name – arbitrary name of sink used
  • sources|record|metric – level of filter to operate
  • include|exclude – will filter exclude or include metrics. If all rules are exclude, it works on a black list logic, if all are include, white list logic used.

Filter level

There are three levels to perform filtering:

  • sources – large group of metrics, usually subsystem (see next)
  • record – set of metrics grouped together. By default, class name taken as a record name
  • metric – name of emitted metric, for example blockCacheHitCount (please note that this is short name, not the full metric’s name appeared in ganglia. So, filter won’t get ‘regionserver.Server.blockCacheHitCount’, only ‘blockCacheHitCount’)

Names to filter

It’s a bit tricky to get list of metrics groups to do filtering, as they are hardcoded in sources. The simplest way to find all metrics provided by daemon is to get it from ‘Metrics dump’ tab in web interface in master or RS. It returns json with all metrics with their group and values. For example, small part of master’s dump:

}, {
"name" : "Hadoop:service=HBase,name=Master,sub=AssignmentManger",
"modelerType" : "Master,sub=AssignmentManger",
"tag.Context" : "master",
"tag.Hostname" : "dhcp-21-64",
"ritOldestAge" : 0,
"ritCount" : 0,
"BulkAssign_num_ops" : 1,
"BulkAssign_min" : 232,
"BulkAssign_max" : 232,
"BulkAssign_mean" : 232.0,
"BulkAssign_median" : 232.0,
"BulkAssign_75th_percentile" : 232.0,
"BulkAssign_95th_percentile" : 232.0,
"BulkAssign_99th_percentile" : 232.0,
"ritCountOverThreshold" : 0,
"Assign_num_ops" : 1,
"Assign_min" : 82,
"Assign_max" : 82,
"Assign_mean" : 82.0,
"Assign_median" : 82.0,
"Assign_75th_percentile" : 82.0,
"Assign_95th_percentile" : 82.0,
"Assign_99th_percentile" : 82.0
}, {

Under key ‘name’ we get source and record of these set of metrics (master’s assignment manager which does region assignment). ‘Master’ is a source (top-level) and ‘AssignmentManger’ (note the typo) is a record. The final metric’s name will be dot-combination of these parts (with random lower-case transform): «master.AssignmentManger.Assign_max»

So, to filter out AssignmentManager metrics from ganglia, you can write something like this:


Rules to grab

These rules filters out not very interesting or just useless metrics (from my point of view):

# Warning: this must be an address of gmond mentioned in gmetad's sources directive
# select glob filter for everything
# remove these messy useless pseudo-statistical metrics
# filter out regions metrics completely, as Ganglia have no idea how to separate them from hosts

Warning notes

There are several things which must be kept in mind when you configure filters:

  • in hadoop-2.3.0, metrics2 supports only one filter expression for include/exclude rules per filtering level – it takes only the first one and ignores the rest. As it’s not clear from the documentation (maybe, this fixed already), it’s a bit confusing.
  • there is no good documentation and schema definition for config file, so, typos in config do not cause warning messages in log – type carefully, check twice. Personally, I wasted about three days due to this — small typo, no warnings.
  • in sink address you should put address of one of gmond your gmetad collecting data from


7 комментариев

How to migrate oozie from derby to mysql — an easy way

Апр 07 2014

Some time ago, I faced the problem with our oozie installation running on top of DerbyDB — it becomes too slow and had lots of errors with DB locks. Fast search shows that derby (default oozie backend DB) isn’t good for relatively large systems, so migration to mysql is required. The switch itself is quite straightforward, but if you have existing data in derby, it can be painful to move them into mysql. But, if you know exact steps, the whole process is not hard. Ok, let’s go.

Continue Reading »

No responses yet

Numenta NuPIC: первые шаги

Окт 05 2013

(там код лучше читается :))


Numenta NuPIC — открытая реализация алгоритмов, моделирующих процессы запоминания информации человеком, происходящие в неокортексе. Исходные коды с примерами расположены тут https://github.com/numenta/nupic

В двух словах, назначение NuPIC можно описать как «фиговина, выявляющая, запоминающая и прогнозирующая пространственные и временные закономерности в данных». Именно этим большую часть времени занимается человеческий мозг — запоминает, обобщает и прогнозирует. Очень хорошее описание этих процессов можно найти в книге Джеффа Хокинса «On Intelligence» (русский перевод «Об интеллекте»).

На сайте www.numenta.org есть подробный документ, детально описывающий алгоритмы и принципы работы, а также несколько видео.

Сборка и установка

Описана в readme файле в репозитории, поэтому детализировать не буду. Для работы, nupic потребуется python2.7 (или 2.6) с заголовочными файлами.

Параметры и структура модели

Ключевым понятием nupic является модель неокортекса (или просто — модель), представляющая собой набор клеток, обрабатывающих и запоминающих входные данные. В процессе обработки входных данных, клетки прогнозируют вероятное развитие событий, что автоматически формирует прогноз на будущее. Про то, как это делается, я расскажу в следующей статье, сейчас лишь общее описание самых необходимых вещей.

Модель состоит из нескольких процессов, поведение каждого из которых задается набором параметров.


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

Например, на вход модели мы хотим подавать числа из интервала от 1 до 100 (скажем, текущую относительную влажность). Если просто взять бинарное представление чисел, что значения 7 и 8, расположены рядом, но бинарное их представление отличается очень сильно (0b0111 и 0b1000). Чтобы этого избежать, encoder преобразует числовые значения в набор единичных бит, сдвинутых пропорционально пропорционально значению. Например, для диапазона значений от 1 до 10 и трех единичных бит, получаем следующее представление:

  • 1 -> 111000000000
  • 2 -> 011100000000
  • 3 -> 001110000000
  • 7 -> 000000111000
  • 10 -> 000000000111

Если на входе несколько значений, то их бинарные представления просто объединяются вместе.
Аналогично представляются значения с плавающей точкой и дискретный набор значений (true/false, и другие перечислимые типы).

Spatial Pooler

Основная задача SP — обеспечить активацию близкого набора клеток на похожий набор данных, добавляя в эту активацию элемент случайности. Подробное обсуждение как это делается выходит за рамки статьи интересующиеся могут подождать продолжения, либо обратиться к первоисточнику (whitepaper).

Temporal Pooler

Помимо определения похожих образов входных данных, NuPIC умеет различать контекст этих данных, анализируя их поток во времени. Достигается это за счет многослойности набора клеток (так называемые клеточные колонки), и подробное описание также выходит за намеченные рамки. Тут достаточно сказать, что без этого, система не отличала бы символ B в последовательности ABCABC от того же символа в CBACBA.

Практика: синус

Довольно теории, перейдем к практической стороне вопроса. Для начала возьмем простую функцию синуса, подадим на вход модели и посмотрим насколько хорошо она сможет ее понять и предсказать.

Полный код примера находится тут https://github.com/Shmuma/nupic-examples/tree/master/01-sin, разберем ключевые моменты.

Для создания модели по набору параметров, используется класс ModelFactory:

from nupic.frameworks.opf.modelfactory import ModelFactory

model = ModelFactory.create(model_params.MODEL_PARAMS)
model.enableInference({'predictedField': 'y'})

MODEL_PARAMS — это довольно развесистый dict с полным набором параметров модели. Все параметры нас сейчас не интересуют, но на некоторых стоит остановится.

        'sensorParams': {
            'encoders': {
                'y': {
                    'fieldname': u'y',
                    'n': 100,
                    'name': u'y',
                    'type': 'ScalarEncoder',
                    'minval': -1.0,
                    'maxval': 1.0,
                    'w': 21

Здесь задаются параметры encodera, преобразующего значение синуса (в диапазоне от -1 до 1) в битовое представление. Значения minval и maxval определяют диапазон, значение n задает общее количество бит в результате, а w — количество единичных бит (оно почему-то должно быть нечетным). Таким образом, весь диапазон разделяется на 79 интервалов с шагом 0.025. Для проверки вполне достаточно.

Остальные параметры менять пока не нужно — их много, но значения по умолчанию вполне работают. Даже после прочтения witepaper и нескольких месяцев копания с кодом, точное назначение некоторых опций остается для меня загадкой.

Вызов метода enableInference у модели, указывает какой из входных параметров мы хотим прогнозировать (он может быть только один).

Подготовка закончена, можно накачивать модель данными. Делается это так:

res = model.run({'y': y})

В аргументы подается dict, в котором перечислены все входные значения. На выходе модель возвращает объект, содержащий в себекопию входных данных (как в оригинальном представлении, так и в закодированном), а также прогноз на следующий шаг. Больше всего нас интересует именно прогноз в поле inferences:

{'encodings': [array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  1.,  1.,  1.,  1.,
        1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.], dtype=float32)],
 'multiStepBestPredictions': {1: 0.2638645383168643},
 'multiStepPredictions': {1: {0.17879642297981466: 0.0083312500347378464,
                              0.20791169081775931: 0.0083320832430621525,
                              0.224951054343865: 0.020831041503470333,
                              0.24192189559966773: 0.054163124704840825,
                              0.2638645383168643: 0.90834250051388887}},

Прогнозировать мы можем на несколько шагов сразу, поэтому в словаре multiStepPredictions ключом является количество шагов прогноза, а значением — другой словарь с прогнозом в ключе и вероятностью в значении. Для примера выше, модель предсказывает значение 0.26386 с вероятностью 90.83%, значение 0.2419 с вероятностью 5.4% и т.д.

Наиболее вероятный прогноз находится в поле multiStepBestPredictions.

Вооружившись всем этим знанием, пытаемся прогнозировать простой синус. Ниже показаны графики прогонов программы, с указанием параметров запуска. На верхнем графике синяя линия — оригинальный синус, зеленая — прогноз модели, сдвинутый на один шаг влево. На нижнем графике среднеквадратичная ошибка за 360 значений назад (полный период).

Вначале ошибка довольно велика, и прогнозируемое значение заметно отличается от оригинального значения (sin-predictor.py -s 100):

Через 1000 шагов:

Прогресс налицо. Через 10000 шагов:

Через 10000 шагов, последние 360 значений:

No responses yet

Первые эксперименты с NuPIC

Сен 02 2013

Слегка поигрался с NuPIC — пока еще только в общих чертах представляя что происходит внутри и как все настраивается.

На вход подается значение функции, система выдает прогноз.

Вот, например, синус (вверху синим сама функция, зеленым — предсказание, внизу — дельта):

Чем-то значения чуть меньше -0.5 модели не нравятся.

Но если слегка подкрутить параметры, то можно добиться лучших характеристик:

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



А теперь посложнее — после x=200, сдвигаем синус по фазе:

Видно, что модель запомнила момент сдвига и, в дальнейшем, попыталась его учесть, но подтверждения не получила и, через какое-то время забыла об этом артефакте.

5 комментариев


Сен 02 2013

Решил снова возобновить этот бложек. Интересно, надолго ли хватит в этот раз.

No responses yet


Янв 26 2013

Снова тест Люшера :)

No responses yet

MITx 6.002 закончился

Июн 11 2012

Отличный курс, с прекрасной подачей материала, логичным изложением, зубодробительными экзаменами и прекрасно реализованный технически. Экзамен я чуть было не пропустил — засела в голове дата начала 11 июля, а это был дедлайн по сдаче экзамена. В итоге вчера 14 часов подряд решал задачи.

Результаты неплохие, я доволен:

Тест Люшера :).

One response so far

Полежал в больничке

Май 16 2012

Сделали операцию на носу — выпрямили перегородку (выкорчевав из неё большущую кость) и удалили кисты в обех пазухах. Манипуляции не из приятных, но, в принципе, ничего страшного — больше боялся. Делали эндоскопом, под общим наркозом, в 16:30 погрузили на стол, в 18:00 очнулся, в 20:00 отвезли в палату. Ночью постельный режим, в носу тампоны (здоровенные, сантиметров 30 каждый). Наутро их вытащили, нос почистили и жизнь начала стремительно налаживаться. Сейчас (спустя 6 дней после операции) уже нос вполне себе дышит, немного побаливает, но разница уже ощутима.

Страховка покрыла процентов 70% стоимости, насчет исправления перегородки закочевряжились — косметическая, типа и все тут. Какая к чертям косметическая, если эндоскоп с моей перегородкой не прошел бы ни фига. Доплатил 13 тыр, все равно им дороже все остальное обошлось (только день стационара — 1800 рублей). Форма носа не изменилась кстати — как была картошка, так и осталась. В Рыбинске никакого эндоскопа не сделали бы, конечно — разрезали бы поллица нафиг.

Через полторы недели переезд из Москвы в Рыбинск (насовсем), потом сразу в деревню (на лето).

Традиционный тест Люшера.

4 комментария

Зачем уменьшать размер базовых элементов процессоров

Апр 22 2012

При прохождении прекрасного курса электроники от MIT, нашел ответ на давно занимавший меня вопрос — зачем производители процессоров всеми силами стремятся уменьшить размер элементов (техпроцесс)? Казалось бы, от уменьшения одна головная боль — строже нормы чистоты помещения, сложнее изготавливать шаблон для литографии, начинают влиять квантовые эффекты, сложнее контролировать качество и т.п. Миллионы долларов вкладываются в исследования, а нафига, собственно?

После изучения структуры MOSFET-транзистора и других элементарных вещей, я для себя сформулировал три причины.

Первая: эффекты, связанные с длиной волны света и частотой сигналов. Вся электроника (и не только она) строится на абстракциях и упрощениях. Для того, чтобы можно было безбоязненно комбинировать элементы между собой, не выполняя заново полный анализ, для элементов должен выполнятся принцип суперпозиции.

Чтобы выполнялся принцип суперпозиции, должно выполнятся требование, согласно которому масштаб сигнала должен быть значительно больше чем задержка распространения сигнала в схеме. То есть, при частоте в 3 ГГц, зная скорость света, получаем что размер схемы должен быть значительно меньше 10 см. Значительно, это значит раза в 3-4.

Вторая: энергопотребление и тепловыделение. Чем меньше элемент, тем меньше он потребляет и выделяет энергии. Правда, с уменьшением размера, увеличиваются сложности с теплоотводом, так что, видимо плюсы и минусы компенсируются.

Третья: MOSFET-транзиторы, из которых современный процессор состоит чуть более чем полностью, представляют собой не просто переключатель, управляемый напряжением. Из своей структуры, он также представляет собой маленький конденсатор, емкость которого исчисляется фемто-фарадами, но все-таки не нулевая. Каждый конденсатор вносит небольшую задержку в распространение цифрового сигнала, которая при увеличении количества связанных компонентов суммируется. В результате, на выходе вместо прямоугольного импулься мы получаем примерно вот такое:

Паразитную емкость можно уменьшить, уменьшив размеры самого транзистора. Количество же транзисторов, как мы знаем, подчиняется закону Мура, соответственно, размер их также должен уменьшаться пропорционально, чтобы задержки в гигагерцовых сигналах не сводили на нет итоговую производительность.

No responses yet

cs373, наглядное сравнение методов управления

Мар 24 2012

На 5-й неделе курса cs373, последовательно строится PID-controller. Теория управления — это одна из тех тем, которых мне «не додали» в институте, поэтому тем интереснее было смотреть лекции и делать задания.

Вот, например, траектория автомобиля, который изначально находится в точке (0, 1), а стремится оказаться на линии y=0. Стремится не сам, конечно, а им управляют. От того, как именно управляют, зависит результат.

Полный PID-controller:


PI-controller идет в расколбас:

И, наконец, самое смешное — ID-controller:

2 комментария

Older posts »