Вы сконфигурировали Logstash для анализа ваших данных

и отправки их в Elasticsearch

Elasticsearch делает работу по определению того, какие ваши типы данных, и как с ними обращаться. Но что, если вы знаете, что у вас будет много данных, и вы хотите настроить Elasticsearch для максимально эффективного хранения этих данных?

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

Что такое mapping?

Проще говоря, маппинг определяет, как поля интерпретируются Elasticsearch.

Elasticsearch является мощным средством, т.к. Вы можете отправлять в него данные, и он будет строить предположения относительно того, что должно отображаться в каждом поле. Мы называем это индексированием «без схемы», что является отличным вариантом, если вы только начинаете работать с Elasticsearch. Это также удобно в случаях, когда Вы постоянно отправляете новые данные, и не знаете, какие поля будут в нем.

Как упоминалось, есть большие преимущества в том, что данные собираются Elasticsearch, и «картирование»  сообщает Elasticsearch, как именно обрабатывать эти данные. Например, если Вы отправляете IP-адрес (например, 8.8.8.8, который является одним из DNS-серверов Google), он будет отображаться как поле строки в JSON, отправленном в Elasticsearch:

Несмотря на то, что IP-адрес является для нас IP-адресом, Elasticsearch будет рассматривать его как строку. Чтобы задавать больше значений, вы должны задать Elasticsearch, как относиться к величинам. Делается это с помощью функции сопоставления. Если IP-адрес отображается как тип ip в Elasticsearch, вы можете выполнить запрос и выполнить фильтрацию по диапазону IP-адресов — вы даже можете использовать нотацию CIDR — для включения только IP-адресов в пределах данной подсети.

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

ПРИМЕЧАНИЕ. Для целей этого упражнения мы будем использовать версии 5.3.0 Logstash и Elasticsearch. Если вы используете более старую версию Elasticsearch, особенно версию 2.x, ваше картирование, вероятно, будет сильно отличаться от нашего.

Получение Logstash для отправки данных образца Elasticsearch

Тут представлен  пример с данными журнала доступа Apache.

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

Самое приятное то, что мы можем сделать это на своем ноутбуке: не нужно запускать это на производственном узле или даже промежуточном — можно раскрутить локальный экземпляр Elasticsearch и Logstash и получить результаты, которые мне нужны.

Давайте отправим несколько строк:

И выход в узле Elasticsearch будет выглядеть примерно так:

Получение и редактирование результатов картирования

У нас есть индекс, давайте посмотрим, как выглядит наше картирование:

Теперь, если Вы отредактируете my_mapping.json в вашем любимом текстовом редакторе, вы увидите что-то вроде этого:

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

Конечно, my_index — это имя индекса, которое мы указали, а отображения указывает на следующие картирование для индекса. Mytype — это document_type, который мы указали в плагине вывода elasticsearch, а properties — там, где будут определены все поля.

Как Вы можете видеть, почти каждое поле имеет тип text и содержит вторичный тип подполя ключевого слова. Тип ключевого слова важен, потому что он обрабатывает все содержимое поля (вплоть до количества символов ignore_above) в качестве единого объекта. Это гарантирует, что поле пользовательского агента, содержащее имена операционной системы, такие как «Windows 10», идентифицируется Elasticsearch как «Windows 10», а не «Windows» и «10» разделены.

Как насчет некоторых других областей? Взгляните на вложенные поля в разделе geoip:

Вы видите, что есть еще один блок свойств в geoip? Это похоже на инкапсуляцию всех полей. Всякий раз, когда вы сталкиваетесь с новым уровнем в определении отображения, вы увидите другой блок свойств.

Внутри объекта geoip есть несколько числовых полей и поле IP:

На этом этапе я хочу сделать несколько важных замечаний о Logstash и grok, а также их отношении к картированию Elasticsearch. Независимо от того, как вы можете транслировать поле с помощью grok (поддерживающего типы int и float), Elasticsearch не будет точно знать, что вы намереваетесь, если не нанесете его точно. Logstash отобразит вашу строку журнала как JSON, содержащую все поля, которые вы сконфигурировали. Как правило, это будет содержать строки и цифры. Числа будут целыми числами (целые числа) или значениями с плавающей запятой (числа с десятичными знаками). После этого Elalesearch может интерпретировать эти типы полей либо путем их явного сопоставления, либо с помощью ранее упомянутого подхода без схемы.

Мы уже видели, насколько хорошо Elasticsearch обрабатывает строки и текстовые значения при использовании подхода без схемы. Он также лучше всего подходит к числовым значениям. Как правило, любое целое значение будет отображаться как длинное. Значения с десятичными знаками будут отображаться как число floats или double. Как уже упоминалось, вы можете сэкономить пространство памяти, а также некоторые накладные расходы для вычислений и агрегаций, если вы сопоставляете свои значения с минимально возможным примитивным значением. Это одно из основных преимуществ создания пользовательского картирования. Например, широта и долгота могут быть легко представлены half_floats, а dma_code может быть представлен как short. Каждое из этих изменений сокращает накладные расходы в Elasticsearch.

А как насчет нашего IP-адреса с самого начала?

Это поле ip идентифицируется как текст и ключевое слово, а не как IP. Чтобы сопоставить IP-поле как тип ip, замените этот целый блок следующим:

Довольно просто, правда? На этом этапе вы можете удивиться, почему я демонстрирую только отображение поля ip в объекте geoip, а не в поле clientip или в обоих. Это связано с тем, что в некоторых конфигурациях веб-сервера данные журнала, которые становятся полем клиента, могут содержать адрес IPv4, адрес IPv6 или имя узла. Если вы должны были сопоставить поле clientip как тип ip, а строка журнала с именем хоста должны были быть нажаты на Elasticsearch, это привело бы к ошибке, и этот документ бы не индексировался из-за конфликта отображения.

Поле местоположения также является специальным типом отображения. Это массив долготы и широты, обозначающий одну точку на карте. Elasticsearch хранит их как тип отображения geo_point, который позволяет пользователям выполнять географические поиски и отображать точки на картах в Кибане. Сопоставьте географическую точку следующим образом:

Со всеми этими изменениями отредактированное картирование для этого раздела должно выглядеть следующим образом:

Поле ответа, которое находится вне блока geoip, также является числом, но оно было сохранено в виде строки. Это связано с тем, что подшаблон grok, создавший это поле, не передает его как int или float. Впрочем, это неважно! Картирование могут принуждать число, хранящееся в виде строки, в числовой тип сопоставления. Поскольку коды ответа HTTP будут иметь только 3 цифры, а наименьший тип сопоставления — short, это должно выглядеть так:

Создание шаблонов

Итак, теперь у нас есть большой картированный файл с несколькими изменениями. Как изменить этот файл картирования в шаблон?

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

Шаблон elasticsearch в самом базовом представлении содержит шаблон индекса, который должен совпадать, идентифицироваться как шаблон картирования по умолчанию. В этом примере я включил версию, если вы хотите отслеживать изменения в шаблоне, и значение refresh_interval по умолчанию, равное 5 секундам, что помогает повысить производительность при более высоких нагрузках индексирования.

Чтобы сделать это полным шаблоном, вам необходимо заменить несколько строк из файла my_mapping.json. Скопируйте этот файл в файл my_template.json и откройте его в своем редакторе. Затем замените 4 верхние строки, которые должны выглядеть следующим образом:

С помощью этих строк:

Каждая следующая строка должна быть:

ВАЖНО: Мы удалили 4 фигурные скобки и заменили их на 3. Это означает, что у нас есть слишком много закрывающих фигурных скобок в конце нашего файла, поэтому прокрутите вниз и удалите один из них.

Вот так:

Сохранение шаблонов и их загрузка

Сохраните файл, и вы сможете его загрузить:

Если ваше картирование является точным, вы увидите:

Проверка шаблонов

Итак, теперь самое время протестировать наш шаблон. Удалите my_index из Elasticsearch, запустив первую строку в консоли Kibana:

Или эту строку в командной строке:

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