TimescaleDB

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 15:19, 18 января 2019.
TimeScaleDB
Logo-timescale.png
Разработчики: Timescale
Выпущена: 2017
Постоянный выпуск: 0.12
Состояние разработки: Active
Написана на: C
Операционная система: Linux, OS X, Windows
Тип ПО: СУБД
Лицензия: Apache 2.0
Веб-сайт www.timescale.com

TimescaleDB – база данных с открытым исходным кодом для хранения временных рядов, основанная на PostgreSQL. Полностью поддерживает SQL. Сочетает в себе качества реляционных и NoSQL баз данных. Благодаря тому, что TimescaleDB основана на PostgreSQL[Источник 1], она может быть интегрирована с основными программами экосистемы PostgreSQL: Grafana, Prometheus, Hibernate, kafka и т. д. [Источник 2]

Для взаимодействия с API СУБД есть официальные клиенты ADO.NET, JDBC, ODBC и библиотека на C.

Обзор

Модель данных временных рядов

Модель данных временных рядов показывает, как система или процесс меняются с течением времени. Основные характеристики:

  • в каждой записи обязательно хранится временная метка
  • данные только записываются, но не обновляются
  • новые данные, как правило, приходят с новыми метками времени

TimescaleDB использует модель "широкой таблицы" (wide-table), в отличие от многих других баз данных для хранения временных рядов, которые используют подход "узкой таблицы" (narrow-table). [Источник 1]

Архитектура

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

В TimescaleDB вводится особый тип таблиц - гипертаблицы (hypertables). Они являются абстракцией или виртуальным представлением множества отдельных таблиц, содержащих данные, которые называются чанками (chunks).

Чанки - это разбиение гипертаблицы на одно или несколько измерений. Все гипертаблицы обязательно разбиваются по времени, а также могут быть разбиты по различным ключам разбиения, например по deviceId, userId, location и т.д.

Рисунок 1 – Стандартная структура TimescaleDB

Гипертаблицы

Первичной точкой взаимодействия с данными является гипертаблица (hypertable) - абстракция одной непрерывной таблицы во всех пространственных и временных измерениях. К данной таблице можно получить доступ через стандартный SQL.

Практически все пользовательские взаимодействия с TimescaleDB происходят с гипертаблицами. Создание таблиц и индексов, изменение таблиц, вставка данных, выбор данных и т.д. выполняются на гипертаблице.

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

Создание гипертаблицы в TimescaleDB можно выполнить с помощью двух простых команд SQL: CREATE TABLE(со стандартным синтаксисом SQL), за которым следует SELECT create_hypertable().

Индексы по времени и по ключам разбиения автоматически создаются в гипертаблицах, хотя могут быть созданы дополнительные индексы (TimescaleDB поддерживает полный диапазон типов индексов PostgreSQL).

Чанки

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

Каждый чанк является стандартной таблицей базы данных. Чанк фактически является наследованной таблицей PostgreSQL от родительской гипертаблицы.

Чанки имеют оптимальный размер. При этом гарантируется, что все B-деревья индексов будут находиться в памяти при вставке новых значений в гипертаблицу. Избегая чрезмерно больших чанков, избегаются дорогостоящие операции при удалении данных, например, удаляя не строки поштучно, а сразу целые чанки данных.

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

Рисунок 2 – Hypertable и Chunk в TimescaleDB

Сравнение с PostgreSQL

У TimescaleDB, в отличие от PostgreSQL или любой другой реляционной СУБД, при использовании модели данных временных рядов есть три главных преимущества: [Источник 1]

  1. Выше скорость вставки данных временных рядов[Источник 1], особенно видна разница на больших размерах базы (см. рисунок 3).
  2. Количество выполняемых запросов в секунду на порядок выше. [Источник 3]
  3. Ориентированная на временные ряды функциональность.

При этом TimescaleDB полностью поддерживает функциональность PostgreSQL, включая pg_dump и pg_restore, JOIN таблиц и геопространственные запросы c PostGIS.

Рисунок 3 – Сравнение зависимости частоты вставки от количества записей в PostgreSQL и TimescaleDB [Источник 3]

Производительность выполнения запросов

На компьютерах с одним дисковым накопителем многие простые запросы, например индексированный поиск или сканирование таблицы, равны по скорости выполнения на PostgreSQL и TimescaleDB.

Например, в таблице с 100 миллионами строк с индексированными столбцами time, hostname, cpu такой запрос займет меньше 5 мс для обеих СУБД:

SELECT date_trunc('minute', time) AS minute, max(user_usage)
  FROM cpu
  WHERE hostname = 'host_1234'
    AND time >= '2017-01-01 00:00' AND time < '2017-01-01 01:00'
  GROUP BY minute ORDER BY minute;

Однако как раз запросы более сложные, с GROUP BY по временным колонкам, часто выполняются быстрее в TimescaleDB[Источник 3].

Например, запрос:

SELECT date_trunc('hour', time) as hour,
    hostname, avg(usage_user)
  FROM cpu
  WHERE time >= '2017-01-01' AND time < '2017-01-02'
  GROUP BY hour, hostname
  ORDER BY hour;

Такой запрос возвращает 33 из 100 миллиона строк и работает в 5 раз быстрее в TimescaleDB.

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

Данный запрос в 396 раз быстрее чем на PostgreSQL (82 мс против 32566 мс):

SELECT date_trunc('minute', time) AS minute, max(usage_user)
  FROM cpu
  WHERE time < '2017-01-01'
  GROUP BY minute
  ORDER BY minute DESC
  LIMIT 5;

Ориентированная на временные ряды функциональность

Дополнительная функциональность, которую предлагает TimescaleDB:

  • оптимизация определенных запросов (описывалось выше)
  • аналитика, ориентированная на временные ряды
  • ориентированное на временные ряды управление данными
Аналитика

Во-первых, "округление" времени [Источник 3] - более продвинутая date_trunc функция, позволяющая работать с произвольным периодом времени (например, 5 минут, 6 часов и т. д.).

Во-вторых, агрегирование последних (функция last) и первых (функция first) элементов[Источник 3]: функции позволяют получать значение одной колонки в порядке следования за другой. Например, last(temperature, time) вернет самое позднее по времени значение температуры из элементов, сгруппированных по time (например, hour - час).

Еще пример:

SELECT time_bucket('3 hours', time) AS period
    asset_code,
    first(price, time) AS opening, last(price, time) AS closing,
    max(price) AS high, min(price) AS low
  FROM prices
  WHERE time > NOW() - interval '7 days'
  GROUP BY period, asset_code
  ORDER BY period DESC, asset_code;

Такой финансовый запрос выдаст начальную, конечную, самую высокую и низкую цену каждого актива.

Управление данными

Данные временных рядов очень быстро накапливаются. В связи с этим возникла политика хранения данных в виде "хранить необработанные данные только в течение недели."

TimescaleDB позволяет удалять старые данные чанками вместо строк:

SELECT drop_chunks(interval '7 days', 'conditions');

Запрос удалит все чанки из гипертаблицы, содержащие только данные, хранимые больше 7 дней. Такой подход позволяет лишиться проблемы фрагментации данных.

Сравнение с InfluxDB

Характеристика InfluxDB TimescaleDB
Описание СУБД для хранения данных временных рядов, событий и метрик СУБД, основанная на PostgreSQL, оптимизированная под быструю вставку и сложные запросы с данными временных рядов
Год релиза 2013 2017
Язык реализации Go C
Доступные ОС сервера Linux, OS X Linux, OS X, Windows
Схема данных Не нужна Нужна
Типы данных Числа и строки Числа, строки, логический тип данных (boolean), массивы, JSON, BLOB, геопространственные измерения, валюты, бинарные данные и другие сложные типы данных
Поддержка XML Нет Есть
Вторичные индексы Нет Есть
SQL SQL-подобный язык Есть
Виды API HTTP API, JSON over UDP Библиотека на C, потоковые API для больших объектов, ADO.NET, JDBC, ODBC
Поддерживаемые языки .Net, Clojure, Erlang, Go, Haskell, Java, JavaScript, JavaScript (Node.js), Lisp, Perl, PHP, Python, R, Ruby, Rust, Scala .Net, C, C++, Delphi, Java, JavaScript, Perl, PHP, Python, R, Ruby, Scheme, Tcl
Серверные скрипты Нет Функции пользователя, PL/pgSQL, PL/Tcl, PL/Perl, PL/Python, PL/Java, PL/PHP, PL/R, PL/Ruby, PL/Scheme, PL/Unix shell
Триггеры Нет Есть
Методы разделения Шардинг Разделение по времени и пространству атрибутов (хэшированием)
Методы репликации Выбираемый фактор репликации Мастер-слейв репликация с горячим чтением и резервированием на слейвах
Внешние ключи Нет Есть
Концепт транзакций Нет ACID
Контроль доступа Просто управление с помощью аккаунтов пользователей Детальные права доступа в соответствии с SQL стандартом

Установка

Для работы TimescaleDB должен быть установлен PostgreSQL 9.6.3+ или 10.2+.

Linux

Рассматривается установка на Ubuntu.

sudo add-apt-repository ppa:timescale/timescaledb-ppa
sudo apt-get update

# Установка для PG 9.6.3+
sudo apt install timescaledb-postgresql-9.6
# Установка для PG 10.2+
sudo apt install timescaledb-postgresql-10

Mac

С помощью Homebrew

Таким способом также установится через Homebrew и PostgreSQL (если уже не установлен):

brew tap timescale/tap

brew install timescaledb

/usr/local/bin/timescaledb_move.sh

Из исходников

Понадобится также CMake версии 3.4+, компилятор языка C (gcc, clang).

# Скачиваем репозиторий
git clone https://github.com/timescale/timescaledb.git
cd timescaledb
git checkout <release_tag>  # e.g., git checkout 0.12.1

# Начальная загрузка системы сборки
./bootstrap

# Сборка
cd build && make

# Установка
make install

Windows

Понадобится также установленный Visual C++ Redistributable for Visual Studio 2015 (и позже).

  1. Необходимо загрузить .zip файл с официального сайта в соответствии с PostgreSQL версией.
  2. Разархивировать файл.
  3. Запустить setup.exe
  4. При успешной установке в окне cmd.exe будет:
TimescaleDB installation completed succesfully.
Press ENTER/Return key to close...

После установки

Далее необходимо отредактировать postgresql.conf, например так:

psql -d postgres -c "SHOW config_file;"

И включить расширение timescaledb:

shared_preload_libraries = 'timescaledb'

Сохраняем файл. Дальше надо перезапустить PostgreSQL.

На Linux:

sudo service postgresql restart

На Mac с помощью Homebrew:

brew services restart postgresql

Docker

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

Запуск докер контейнера на порту 5432:

docker run -d --name timescaledb -p 5432:5432 -e POSTGRES_PASSWORD=password timescale/timescaledb

Использование

После перезапуска PostgreSQL надо зайти в psql. Там, чтобы подсоединить базу данных к timescale:

postgres=# \c timescale
You are now connected to database "timescale" as user "postgres".
timescale=# 

Затем необходимо включить расширение TimescaleDB:

timescale=# CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;
CREATE EXTENSION

Создание гипертаблицы требует наличия уже созданной таблицы PostgreSQL. Например, создадим сперва таблицу conditions:

CREATE TABLE conditions (
  time        TIMESTAMPTZ       NOT NULL,
  location    TEXT              NOT NULL,
  temperature DOUBLE PRECISION  NULL,
  humidity    DOUBLE PRECISION  NULL
);

Превратим таблицу conditions в гипертаблицу с помощью функции create_hypertable. В гипертаблице сделаем разбиение по пространству времени time и по пространству локации location на 4 раздела:

SELECT create_hypertable('conditions', 'time', 'location', 4);

Теперь для записи и чтения значений метрик можно использовать обычный SQL.

Источники

  1. 1,0 1,1 1,2 1,3 TimeScaleDB Documentation // Website. URL: https://docs.timescale.com/v0.12/introduction (дата обращения: 29.09.2018)
  2. TimeScaleDB // Website. URL: https://www.timescale.com (дата обращения: 02.10.2018)
  3. 3,0 3,1 3,2 3,3 3,4 Why Use TimescaleDB over Relational DBs? // Website. URL: https://docs.timescale.com/v0.12/introduction/timescaledb-vs-postgres (дата обращения: 29.09.2018)

Ссылки