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

    С моей прошлой публикации о распределенной базе данных 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.
    • +14
    • 7.5k
    • 4
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 4

      +1
      Радует то что проект развивается семимильными шагами

      У них финансирование хорошее.


      Что мне лично в их проекте нравится — Crate отлично подходит для GIS систем. То, что раньше пилили на ES запросах, теперь легко подружить с SQL.

        0
        Я просто не в теме GIS систем — там много на SQL пишут? Не все же оракл и постгис используют, скорее всего больше специализированных решений?!
          0

          В основном хранение метрики по передвижениям, POI и прочее. Есть у них один клиент, который crate только под эти нужны использует.

        0
        Джойны они хоть и добавили, но так и не научили их работать с «GROUP BY». При запросах можно либо одно либо другое. Из — за этого для аналитики приходиться использовать огромные флэт таблицы с большим количеством колонок

        Only users with full accounts can post comments. Log in, please.