- PVSM.RU - https://www.pvsm.ru -
Привет! Не так давно я имел удовольствие посетить встречу PyData Moscow [1] на площадке Яндекса. Я не могу назвать себя python разрабочиком, но имею интересы в области аналитики и анализа данных. Посетив данное мероприятие, я узнал о существовании СУБД ClickHouse, разработанной в Яндексе и выложенной на GitHub [2] под открытой лицензией. Колоночная SQL СУБД с отечественными корнями пробудила во мне интерес. В этой статье я поделюсь опытом установки и настройки ClickHouse, а также попыткой доступа к ней из Spring приложения с помощью Hibernate.
Знакомство с СУБД я начал со страницы документации [3].
Весьма удивили рекомендации по использованию оперативной памяти. Разработки советуют использовать столько же памяти, сколько у вас данных (во всяком случае пока объем данных меньше 200 Гб). Не совсем ясно, идет ли речь о суммарной памяти всех машин в кластере или о памяти каждой машины. В любом случае, я смог довольствоваться лишь 8 гб памяти своей виртуальной машины. При этом размер тестового набора данных составлял больше 60 ГБ в несжатом виде.
Первая сложность, с которой мне пришлось стокнуться, – это рекомнедация использовать Ubuntu и остуствие rpm пакетов (UPD: позже я обнаружил вот этот репозиторий [4]). Я предпочитаю rpm системы и принял решения собрать СУБД из исходных кодов под Centos 7.
Ребята из Яндекса приготовили нам инструкции [5] для сборки. Здесь есть несколько любопытных моментов:
Сборка самой СУБД заняла порядка 40 минут. Настройка clickhouse в моем случае заключалась в правке конфигурационного /usr/local/etc/clickhouse-server/config.xml
, так как я решил хранить базу данных на отдельном разделе. Запусить сервер я смог с помощью sudo /usr/local/bin/clickhouse-server --config /usr/local/etc/clickhouse-server/config.xml
Проверить работу СУБД я решил на пример из этого [7] поста, загрузив данные об авиаперелётах в США с 1987 по 2015 год. Процесс загрузки и примеры запросов приведены выше. Загрузка у меня заняла 24 минуты, размер базы данных на диске составил 14 Гб при объеме загруженных данных в 61.6 Гб.
Время выполнения тестовых запросов из статьи выше на моей машине составило:
Запрос | Время, с |
---|---|
какие направления были самыми популярными в 2015 году | 2.067 |
из каких городов отправляется больше рейсов | 3.744 |
из каких городов можно улететь по максимальному количеству направлений | 7.012 |
как зависит задержка вылета рейсов от дня недели | 3.195 |
из каких городов, самолёты чаще задерживаются с вылетом более чем на час | 3.392 |
какие наиболее длинные рейсы | 12.466 |
распределение времени задержки прилёта, по авиакомпаниям | 4.596 |
какие авиакомпании прекратили перелёты | 1.653 |
в какие города стали больше летать в 2015 году | 0.380 |
перелёты в какие города больше зависят от сезонности | 8.806 |
Еще раз отмечу, что объем памяти моей машины составлял всего 8 ГБ, что почти в 8 раз меньше, чем рекомендуется разработчиками. В связи с этим цифры выше – не более чем очень грубая прикидка того, как clickhouse будет себя вести на ноутбуке разработчика, нежели в production. В целом СУБД работала стабильно и, на мой взгляд, достаточно быстро. В анализируемой таблице было 166 миллионов записей.
Следующий шаг в моем изучении clickhouse – попытка доступа к нему из Java. Ребята из Яндекса выложили jdbc драйвер [8].
Подключить его к maven проекту очень просто:
<dependency>
<groupId>ru.yandex.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
<version>${clickhouse-jdbc-version}</version>
</dependency>
При использовании есть всего несколько моментов, которые по незнанию могут вызвать сложности. Прежде всего, clikchouse поддерживает несколько протоколов. По-умолчанию родной бинарный протокол использует порт 9000, а http протокол – 8123. JDBC драйвер умеет работать только с http, поэтому указываем порт 8123. Название БД по-умолчиню – default. Имя пользователя и пароль по-умлочанию задавать не нужно. Чтобы clickhouse разрешал подключения с удаленных машин, в конфигурационном файле следует добавить строку <listen_host>::</listen_host>
.
Далее все как в обычном JDBC:
private static final String DB_URL = "jdbc:clickhouse://localhost:8123/default";
private final Connection conn;
/**
* Creates new instance
* @throws SQLException in case of connection issue
*/
public ClickHouseJDBCDemo() throws SQLException {
conn = DriverManager.getConnection(DB_URL);
}
/**
* Queries db to get most popular flight route for ths given year
* @param year year to query
* @throws SQLException in case of query issue
*/
public void popularYearRoutes(int year) throws SQLException {
String query = "SELECT " +
" OriginCityName, " +
" DestCityName, " +
" count(*) AS flights, " +
" bar(flights, 0, 20000, 40) AS bar " +
"FROM ontime WHERE Year = ? GROUP BY OriginCityName, DestCityName ORDER BY flights DESC LIMIT 20";
long time = System.currentTimeMillis();
try (PreparedStatement statement = conn.prepareStatement(query)) {
statement.setInt(1, year);
try (ResultSet rs = statement.executeQuery()) {
Util.printRs(rs);
}
}
System.out.println("Time: " + (System.currentTimeMillis() - time) +" ms");
}
Как видим, ничего необычного. Полный код примера доступен здесь [9].
Следующим моим шагом стала попытка подключить ORM. Наивно полагая, что раз есть JDBC, то будет и ORM, я потянулся к Spring Data JPA. Но, к сожалению, я столкнулся здесь с рядом проблем. Прежде всего, при подключении к БД необходимо указать SQL Dialect. Реализованного диалекта для ClickHouse мне найти не удалось.
В результате я просто создал потомок стандартного org.hibernate.dialect.Dialect
:
public class ClickHouseDialect extends Dialect {
}
Теперь подключится к базе данных становится возможным. Проблема начинается при выполнении запросов. Дело в том, что clickhouse не поддерживает [10] alias для имен таблиц. Другими словами, запрос вида:
SELECT alias.column from tablename alias
для clickHouse не является допустимым.
Проблема в том, что судя по всем hibernate не позволяет отключить генерацию alias для таблиц путем определения SQL Dialect. Во всяком случае мне не удалось найти, как этого добиться.
Немного покопавшись в коде hibernate я начал приходить к выводу, что эта функциональность зашита довольно глубоко [11] в его ядре. Впрочем, мой опыт использования hibernate не так уж велик. Буду рад, если кто-либо поделиться известным способом обойти подобное ограничение.
Исследовать clickhouse было увлекательным занятием. СУБД показала себя с хорошей стороны. Удалось собрать ее из исходных кодов, выполнить запросы с помощью консольного клиента и jdbc. К сожалению, неполная поддержка конструкций ANSI SQL не позволила легко подключить Hibernate. Впрочем, следует учитывать и назначение СУБД. Главная ниша clickhouse — сложные аналитические запросы, большинство из которых все равно придется полностью или частично писать руками. Хотя иметь возможность простого просмотра и выборки данных «из коробки» при помощи ORM было бы не лишним.
Полагаю, будет крайне интересно наблюдать за развитием проекта, особенно учитывая растущее внимание к clikchouse в сообществе последнее время и активную поддержку проекта со стороны Яндекса.
Автор: grekon
Источник [12]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/java/259378
Ссылки в тексте:
[1] PyData Moscow: https://events.yandex.ru/events/ds/23-jun-2017/
[2] GitHub: https://github.com/yandex/ClickHouse
[3] документации: https://clickhouse.yandex/docs/ru/introduction/index.html
[4] репозиторий: https://github.com/redsoftbiz/clickhouse-rpm
[5] инструкции: https://github.com/yandex/ClickHouse/blob/stable/doc/build.md
[6] статья: https://aferdyp.github.io/clickhouse/2017/02/23/building-clickHouse.html
[7] этого: https://habrahabr.ru/company/yandex/blog/303282/
[8] драйвер: https://github.com/yandex/clickhouse-jdbc
[9] здесь: https://github.com/kgrech/clickhouse-java/blob/master/src/main/java/ru/kgrech/clickhousespring/demo/ClickHouseJDBCDemo.java
[10] не поддерживает: https://clickhouse.yandex/docs/ru/query_language/queries.html#select
[11] глубоко : https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java#L1563
[12] Источник: https://habrahabr.ru/post/332112/?utm_source=habrahabr&utm_medium=rss&utm_campaign=sandbox
Нажмите здесь для печати.