Использование InfluxDB с Java
1. обзор
InfluxDB is a high-performance store for time-series data. Он поддерживает вставку и запросы данных в реальном времени с помощью языка запросов, подобного SQL.
В этой вводной статье мы продемонстрируем, как подключиться к серверу InfluxDb, создать базу данных, записать информацию временного ряда и затем запросить базу данных.
2. Настроить
Чтобы подключиться к базе данных, нам нужно добавить запись в наш файлpom.xml:
org.influxdb
influxdb-java
2.8
Последнюю версию этой зависимости можно найти наMaven Central.
Нам также понадобится экземпляр InfluxDB. Инструкции дляdownloading and installing a database можно найти на веб-сайтеInfluxData.
3. Подключение к серверу
3.1. Создание подключения
Для создания соединения с базой данных требуется передать URLString и учетные данные пользователя в фабрику соединений:
InfluxDB influxDB = InfluxDBFactory.connect(databaseURL, userName, password);
3.2. Проверка подключения
Communications with the database are performed over a RESTful API, поэтому они непостоянны.
API предлагает специальную услугу «ping» для подтверждения работоспособности соединения. Если соединение хорошее, ответ содержит версию базы данных. В противном случае он содержит“unknown”.
Поэтому после создания соединения мы можем проверить это, выполнив:
Pong response = this.influxDB.ping();
if (response.getVersion().equalsIgnoreCase("unknown")) {
log.error("Error pinging server.");
return;
}
3.3. Создание базы данных
Создание базы данных InfluxDB аналогично созданию базы данных на большинстве платформ. But we need to create at least one retention policy before using it.с
A retention policy tells the database how long a piece of data should be stored. Временные ряды, такие как статистика ЦП или памяти, как правило, накапливаются в больших наборах данных.
Типичная стратегия управления размером баз данных временных рядов -downsampling. «Необработанные» данные сохраняются с высокой скоростью, суммируются, а затем удаляются через короткое время.
Retention policies simplify this by associating a piece of data with an expiration time. InfluxData имеетin-depth explanation на своем сайте.
После создания базы данных мы добавим одну политику с именемdefaultPolicy.. Она просто будет хранить данные в течение 30 дней:
influxDB.createDatabase("example");
influxDB.createRetentionPolicy(
"defaultPolicy", "example", "30d", 1, true);
Чтобы создать политику хранения, нам понадобятсяname,,database, иinterval,areplication factor (который должен быть 1 для базы данных с одним экземпляром) иbooleanуказывает, что это политика по умолчанию.
3.4. Установка уровня ведения журнала
Внутри InfluxDB API используетRetrofit и предоставляет интерфейс для функции ведения журнала Retrofit черезlogging interceptor.
Итак, мы можем установить уровень ведения журнала, используя:
influxDB.setLogLevel(InfluxDB.LogLevel.BASIC);
И теперь мы можем видеть сообщения, когда мы открываем соединение и проверяем его:
Dec 20, 2017 5:38:10 PM okhttp3.internal.platform.Platform log
INFO: --> GET http://127.0.0.1:8086/ping
Доступные уровни:BASIC,FULL,HEADERS иNONE..
4. Добавление и получение данных
4.1. Точки
Итак, теперь мы готовы начать вставку и получение данных.
Базовая единица информации в InfluxDB - этоPoint,, который по сути является меткой времени и картой значения ключа.
Давайте посмотрим на точку, содержащую данные об использовании памяти:
Point point = Point.measurement("memory")
.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS)
.addField("name", "server1")
.addField("free", 4743656L)
.addField("used", 1015096L)
.addField("buffer", 1010467L)
.build();
Мы создали запись, которая содержит триLongs в качестве статистики памяти, имя хоста и метку времени.
Давайте посмотрим, как добавить это в базу данных.
4.2. Написание партий
Time series data tends to consist of many small points, and writing those records one at a time would be very inefficient. Предпочтительный метод - собирать записи в пакеты.
API InfluxDB предоставляет объектBatchPoint:
BatchPoints batchPoints = BatchPoints
.database(dbName)
.retentionPolicy("defaultPolicy")
.build();
Point point1 = Point.measurement("memory")
.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS)
.addField("name", "server1")
.addField("free", 4743656L)
.addField("used", 1015096L)
.addField("buffer", 1010467L)
.build();
Point point2 = Point.measurement("memory")
.time(System.currentTimeMillis() - 100, TimeUnit.MILLISECONDS)
.addField("name", "server1")
.addField("free", 4743696L)
.addField("used", 1016096L)
.addField("buffer", 1008467L)
.build();
batchPoints.point(point1);
batchPoints.point(point2);
influxDB.write(batchPoints);
Мы создаемBatchPoint, а затем добавляем к немуPoints. Мы установили временную метку для нашей второй записи равной 100 миллисекундам в прошлом, поскольку временные метки являются основным индексом. Если мы отправим две точки с одинаковой отметкой времени, останется только одна.
Обратите внимание, что мы должны связатьBatchPoints с базой данных и политикой хранения.
4.3. Написание по одному
Пакетирование может быть непрактичным для некоторых случаев использования.
Давайте включим пакетный режим с одним вызовом соединения InfluxDB:
influxDB.enableBatch(100, 200, TimeUnit.MILLISECONDS);
Мы включили пакетирование 100 для вставки на сервер или отправки того, что у него есть каждые 200 миллисекунд.
С включенным пакетным режимом мы все еще можем писать по одному. Однако требуется дополнительная настройка:
influxDB.setRetentionPolicy("defaultPolicy");
influxDB.setDatabase(dbName);
Более того, теперь мы можем записывать отдельные точки, и они собираются в пакетном режиме фоновым потоком:
influxDB.write(point);
Before we enqueue individual points, we need to set a database (аналогично командеuse в SQL)and set a default retention policy. Поэтому, если мы хотим воспользоваться преимуществом понижающей дискретизации с несколькими политиками хранения, создание пакетов - это лучший способ.
В пакетном режиме используется отдельный пул потоков. Поэтому рекомендуется отключить его, когда он больше не нужен:
influxDB.disableBatch();
Закрытие соединения также отключит пул потоков:
influxDB.close();
4.4. Сопоставление результатов запроса
Запросы возвращаютQueryResult, которые мы можем сопоставить с POJO.
Прежде чем мы рассмотрим синтаксис запроса, давайте создадим класс для хранения нашей статистики памяти:
@Measurement(name = "memory")
public class MemoryPoint {
@Column(name = "time")
private Instant time;
@Column(name = "name")
private String name;
@Column(name = "free")
private Long free;
@Column(name = "used")
private Long used;
@Column(name = "buffer")
private Long buffer;
}
Класс аннотируется@Measurement(name = “memory”), что соответствуетPoint.measurement(“memory”), которое мы использовали для создания нашегоPoints.
Для каждого поля в нашемQueryResult мы добавляем аннотацию@Column(name = “XXX”) с именем соответствующего поля.
QueryResults отображаются в POJO сInfluxDBResultMapper.
4.5. Запрос InfluxDB
Итак, давайте использовать наш POJO с точками, которые мы добавили в базу данных в нашем двухточечном пакете:
QueryResult queryResult = connection
.performQuery("Select * from memory", "example");
InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
List memoryPointList = resultMapper
.toPOJO(queryResult, MemoryPoint.class);
assertEquals(2, memoryPointList.size());
assertTrue(4743696L == memoryPointList.get(0).getFree());
Запрос показывает, как наше измерение с именемmemory сохраняется в виде таблицыPoints, из которой мы можем использоватьselect.
InfluxDBResultMapper принимает ссылку наMemoryPoint.class сQueryResult и возвращает список точек.
После сопоставления результатов мы проверяем, что получили два, проверяя длинуList, полученную в результате запроса. Затем мы смотрим на первую запись в списке и видим объем свободной памяти для второй точки, которую мы вставили. The default ordering of query results from InfluxDB is ascending by timestamp.
Давайте изменим это:
queryResult = connection.performQuery(
"Select * from memory order by time desc", "example");
memoryPointList = resultMapper
.toPOJO(queryResult, MemoryPoint.class);
assertEquals(2, memoryPointList.size());
assertTrue(4743656L == memoryPointList.get(0).getFree());
Добавлениеorder by time desc меняет порядок наших результатов.
Запросы InfluxDB выглядят очень похоже на SQL. Есть обширный справочникon their site.
5. Заключение
Мы подключились к серверу InfluxDB, создали базу данных с политикой хранения, а затем вставили и получили данные с сервера.
Полный исходный код примеров -over on GitHub.