CrateDB: снаружи как PostgreSQL, а внутри Elasticsearch

в 6:03, , рубрики: CrateDB, java, jdbc, nosql, open source, outer join, postgresql

С моей прошлой публикации о распределенной базе данных CrateDB прошло около года. Проект на основе Elasticsearch и PrestoDB написан на Java. Он за это время активно развивался и обрастал новым функционалом в github репозитарии:

  • поддержка outer join;
  • case when… then… end в запросах;
  • функции для работы с пространственными(Geospatial) данными;
  • возможно отображение данных временных рядов (Time Series) в Grafana;
  • ограниченная поддержка подзапросов;
  • узлы кластера работающие в режиме только чтения;
  • эмуляцией подмножества протокола PostgreSQL 9.5;
CrateDB: снаружи как PostgreSQL, а внутри Elasticsearch - 1

Приятной неожиданностью было обнаружить в 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: снаружи как PostgreSQL, а внутри Elasticsearch - 2
Необходимо настроить параметры подключения и указать запросы для выборки данных.
CrateDB: снаружи как PostgreSQL, а внутри Elasticsearch - 3

Загрузку и старт 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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js