С моей прошлой публикации о распределенной базе данных CrateDB прошло около года. Проект на основе Elasticsearch и PrestoDB написан на Java. Он за это время активно развивался и обрастал новым функционалом в github репозитарии:
- поддержка outer join;
- case when… then… end в запросах;
- функции для работы с пространственными(Geospatial) данными;
- возможно отображение данных временных рядов (Time Series) в Grafana;
- ограниченная поддержка подзапросов;
- узлы кластера работающие в режиме только чтения;
- эмуляцией подмножества протокола PostgreSQL 9.5;
Приятной неожиданностью было обнаружить в github проекта, что в команде CrateDB есть русскоговорящий разработчик Руслан. Достаточно быстро получил от него ответ на вопросы про внутреннее устройство и зависимости проекта.
Когда в прошлый раз на хабре я рассказывал про особенности работы с запросами в статье «JOIN the dark side of the SQL», то упоминал о недостатках монструозного по объему родного jdbc драйвера для crate и неполной поддержке join операций. Эти недочеты устранили в последних версиях (>1.0)!
Теперь можно пользоваться jdbc драйвером PostgreSQL, утилитами командной строки pg и не нужно паковать вместе с приложением отдельный драйвер для crate. Это стало возможно благодаря частичной эмуляции wire протокола PostgreSQL 9.5 на сервере. С оглядкой на то что не поддерживаются транзакции (поэтому установлен autocommit), аутентификация с любым логином/паролем успешная, не поддерживается SSL для соединений и поддерживается только кодировка символов UTF-8. Еще не поддерживается COPY подпротокол pg и подпротокол вызова хранимых функций. При этом надо помнить, что синтаксис SQL запросов и подмножество поддерживаемых функций специфичны для CrateDB.
Наконец-то в сервере появилась поддержка Left, Right и Full Outer Join. Хоть не применяются специальные оптимизации планировщика и join реализован как nested loop, но при этом фильтры применяются распределенно — на каждой шарде таблиц из запроса.
Появился странный синтаксис в SELECT, напоминающий PL/SQL CASE:
CASE WHEN condition THEN result
[WHEN ...]
[ELSE result]
END
С подзапросами в FROM пока чудо не случилось. Поддерживаются либо подзапросы с агрегатами, либо запросы которые парсер может легко перезаписать. Надеюсь, что через год проект удивит тем что будут доступны сложные подзапросы.
Для работы с пространственными данными в запросах доступны функции distance, within, intersects, latitude/longitude. Работа с геоданными давно была в Elasticsearch, на основе которого создана эта распределенная база данных.
Есть плагин доступа к данным для Grafana. Можно рисовать графики для данных мониторинга и телеметрии, хранящихся в CrateDB.
Необходимо настроить параметры подключения и указать запросы для выборки данных.
Загрузку и старт CrateDB для экспериментов можно сделать так:
java -jar groovy-grape-aether-2.4.5.1.jar https://raw.githubusercontent.com/igor-suhorukov/crate-io-installer/master/crate-io.groovy
Для запуска CrateDB 1.0.4 использовал свой Groovy скрипт, который автоматически устанавливает базу данных в домашнюю директорию пользователя:
@Grab(group='org.codehaus.plexus', module='plexus-archiver', version='2.10.2')
import org.codehaus.plexus.archiver.tar.TarGZipUnArchiver
import com.github.igorsuhorukov.smreed.dropship.MavenClassLoader;
@Grab(group='org.codehaus.plexus', module='plexus-container-default', version='1.6')
import org.codehaus.plexus.logging.console.ConsoleLogger;
def artifact = 'crate'
def version = '1.0.4'
def userHome= System.getProperty('user.home')
def destDir = new File("$userHome/.crate-io")
def crateIoDir= new File(destDir, "$artifact-$version");
if(!crateIoDir.exists()){
destDir.mkdirs()
String sourceFile = MavenClassLoader.using("https://dl.bintray.com/crate/crate/").getArtifactUrlsCollection("io.crate:$artifact:tar.gz:$version", null).get(0).getFile()
final TarGZipUnArchiver unArchiver = new TarGZipUnArchiver()
unArchiver.setSourceFile(new File(sourceFile))
unArchiver.enableLogging(new ConsoleLogger(ConsoleLogger.LEVEL_DEBUG,"Logger"))
unArchiver.setDestDirectory(destDir)
unArchiver.extract()
}
def proc = "$crateIoDir.absolutePath/bin/crate".execute()
proc.consumeProcessOutput(System.out, System.err)
proc.waitFor()
Либо запустить базу в Docker контейнере или десятком других способов.
Заключение
При использовании CrateDB в своем проекте, надо помнить что прежде всего это распределенная база данных на основе Elasticsearch, поэтому полноценного ACID не будет. Но если важна горизонтальная масштабируемость, полнотекстовый поиск и возможность выполнять SQL запросы — это отличный кандидат для хранения данных проекта. Радует то что проект развивается семимильными шагами и доступен для использования под лицензией Apache 2.0.
Автор: igor_suhorukov