JDBCを使用してClickHouseにアクセスする

こんにちはHabr! 少し前までは、Yandexで開催されたPyDataモスクワ会議に出席することができました。 私は自分をpython開発者と呼ぶことはできませんが、分析とデータ分析の分野に興味があります。 このイベントを訪れて、Yandexで開発され、オープンライセンスの下でGitHubに投稿されたClickHouse DBMSの存在について学びました。 国内のルーツを持つ列SQL DBMSに興味がわきました。 この記事では、ClickHouseのインストールと構成の経験と、Hibernateを使用してSpringアプリケーションからアクセスしようとする経験を共有します。

組み立てと設置


ドキュメントのページからDBMSの知識を始めました。

RAMの使用に関する推奨事項に非常に驚いた。 開発では、データがある限りメモリを使用することをお勧めします(いずれの場合も、データボリュームは200 GB未満です)。 クラスタ内のすべてのマシンの合計メモリについて話しているのか、それとも各マシンのメモリについて話しているのかは明確ではありません。 いずれにせよ、私は仮想マシン用に8 GBのメモリのみで満足することができました。 テストデータセットのサイズは、非圧縮形式で60 GBを超えていました。

私が対処しなければならなかった最初の困難は、Ubuntuを使用することの推奨とrpmパッケージの欠如でした(UPD:後にこのリポジトリを発見しました)。 私はrpmシステムを好み、Centos 7のソースコードからDBMSを構築することにしました。

Yandexのスタッフが、組み立ての指示を用意してくれました。 ここにはいくつかの興味深い点があります。


DBMS自体の構築には約40分かかりました。 私の場合のクリックハウスの設定は、データベースを別のセクションに保存することにしたので、設定/usr/local/etc/clickhouse-server/config.xmlを編集することでした。 sudo /usr/local/bin/clickhouse-server --config /usr/local/etc/clickhouse-server/config.xmlを使用してサーバーを起動できました

この投稿の例を使用してDBMSの動作を確認し、1987年から2015年までのアメリカへの空の旅に関するデータをダウンロードすることにしました。 ダウンロードプロセスとサンプルリクエストは上記のとおりです。 ロードに24分かかりました。ディスク上のデータベースのサイズは14 GBで、ダウンロードしたデータのボリュームは61.6 GBでした。
私のマシンでの上記の記事からのテスト要求の実行時間は次のとおりです。
リクエスト時間s
2015年に最も人気のあった目的地2.067
どの都市からより多くの便が出発するか3.744
どの都市から最大数の方向に飛行できるか7.012
フライトの出発の遅れは曜日にどのように依存しますか3.195
どの都市、飛行機からの出発が1時間以上遅れているか3.392
最長のフライトは何ですか12.466
航空会社による到着遅延分布4.596
どの航空会社がフライトを停止しました1.653
2015年にさらに多くの都市が飛び始めました0.380
都市が季節性により依存しているフライト8.806

繰り返しになりますが、マシンのメモリはわずか8 GBであり、これは開発者が推奨する容量のほぼ8分の1であることに注意してください。 この点で、上記の数値は、クリックハウスが開発者のラップトップ上で本番よりもどのように動作するかについての非常に大雑把な推定に過ぎません。 一般に、DBMSは安定して動作し、私の意見では、十分に迅速に動作しました。 分析された表には、1億6600万件のレコードがありました。

ClickHouseとJavaの友達


クリックハウスに関する私の研究の次のステップは、Javaからクリックハウスにアクセスすることです。 Yandexのメンバーがjdbc ドライバーをアップロードしました。

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です。 デフォルトのユーザー名とパスワードを設定する必要はありません。 クリックハウスでリモートマシンからの接続を許可するには、構成ファイルに<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"); } 

ご覧のとおり、異常なことは何もありません。 完全なサンプルコードはこちらから入手できます

Hibernateはどうですか?


次のステップは、ORMを接続する試みでした。 JDBCがあるのでORMがあると単純に信じて、Spring Data JPAに到達しました。 しかし、残念ながら、ここで多くの問題に遭遇しました。 まず、データベースに接続するときに、SQLダイアレクトを指定する必要があります。 ClickHouseに実装された方言が見つかりませんでした。

その結果、標準のorg.hibernate.dialect.Dialect子孫を作成しただけです。

 public class ClickHouseDialect extends Dialect { } 

これで、データベースへの接続が可能になります。 クエリを実行すると問題が始まります。 実は、クリックハウステーブル名のエイリアスをサポートしていません 。 つまり、次の形式のクエリ:

 SELECT alias.column from tablename alias 

for clickHouseは無効です。

問題は、SQLダイアレクトを定義することにより、明らかに休止状態ではテーブルのエイリアス生成を無効にできないことです。 いずれにせよ、私はこれを達成する方法を見つけることができませんでした。

休止状態のコードを少し掘り下げた後、私はこの機能がコアに非常に深く結び付けられているという結論に達し始めました。 ただし、休止状態での私の経験はそれほど素晴らしいものではありません。 誰かがこの制限を回避するための既知の方法を共有してくれたら嬉しいです。

まとめ


クリックハウスの探索は刺激的な経験でした。 DBMSは良い面を見せています。 ソースコードからコンパイルし、コンソールクライアントとjdbcを使用してクエリを実行しました。 残念ながら、ANSI SQL構造のサポートが不完全なため、Hibernateを簡単に接続できませんでした。 ただし、DBMSの目的を考慮する必要があります。 クリックハウスの主なニッチは、複雑な分析クエリです。そのほとんどは、全体または一部を手作業で記述する必要があります。 ORMを使用してデータを「そのまま」表示および選択するだけの能力は不要ではありませんが。

特に最近コミュニティ内のclikchouseへの注目が高まり、Yandexからプロジェクトが積極的にサポートされていることを考えると、プロジェクトの発展を観察することは非常に興味深いと思います。

Source: https://habr.com/ru/post/J332112/


All Articles