概要
- 行のエンコード/デコードに
serdeを使用します。 serdeの属性skip_serializing、skip_deserializing、renameをサポートしています。- HTTP 経由で
RowBinaryフォーマットを使用します。- 将来的には、TCP 上の
Nativeへの切り替えが予定されています。
- 将来的には、TCP 上の
- TLS (
native-tlsおよびrustls-tlsの feature 経由) をサポートしています。 - 圧縮および解凍 (LZ4) をサポートしています。
- データの取得や挿入、DDL の実行、クライアント側でのバッチ処理のための API を提供します。
- 単体テストに便利なモックを提供します。
インストール
Cargo.toml に追加します。
Cargo の機能
lz4(既定で有効) —Compression::Lz4およびCompression::Lz4Hc(_)バリアントを有効にします。有効にすると、WATCHを除くすべてのクエリで既定でCompression::Lz4が使用されます。native-tls— OpenSSL にリンクするhyper-tlsを介して、HTTPSスキームの URL をサポートします。rustls-tls— OpenSSL にリンクしないhyper-rustlsを介して、HTTPSスキームの URL をサポートします。inserter—client.inserter()を有効にします。test-util— モックを追加します。例 を参照してください。使用はdev-dependenciesのみにしてください。watch—client.watch機能を有効にします。詳細は該当する節を参照してください。uuid— uuid クレートと連携するためにserde::uuidを追加します。time— time クレートと連携するためにserde::timeを追加します。
ClickHouse バージョンの互換性
wa-37420 機能を有効にしてください。注: この機能は、より新しい ClickHouse バージョンでは使用しないでください。
例
使い方
ch2rs クレートは、ClickHouse から行型を生成するのに便利です。
クライアントインスタンスの作成
HTTPS または ClickHouse Cloud への接続
rustls-tls または native-tls のいずれの Cargo feature でも利用できます。
次に、通常どおり client を作成します。この例では、接続情報を保存するために環境変数を使用します。
- クライアントリポジトリのClickHouse Cloud での HTTPS の例。これはオンプレミス環境での HTTPS 接続にも適用できます。
行を選択する
- プレースホルダー
?fieldsはno, name(Rowのフィールド) に置き換えられます。 - プレースホルダー
?は、後続のbind()呼び出しで指定された値に置き換えられます。 - 先頭の行またはすべての行を取得するには、それぞれ便利な
fetch_one::<Row>()メソッドとfetch_all::<Row>()メソッドを使用できます。 - テーブル名をバインドするには
sql::Identifierを使用できます。
query(...).with_option("wait_end_of_query", "1") を試し、サーバー側でレスポンスバッファリングを有効にできます。詳細はこちら。buffer_size オプションも有用です。
行の挿入
end()が呼び出されない場合、INSERTは中止されます。- ネットワーク負荷を分散するため、行はストリームとして順次送信されます。
- ClickHouse がバッチをアトミックに挿入するのは、すべての行が同じパーティションに収まり、その数が
max_insert_block_size未満の場合に限られます。
非同期 INSERT (サーバー側バッチ処理)
insert メソッドに async_insert オプションを指定するだけで実現できます (また、Client インスタンス自体に指定して、すべての insert 呼び出しに適用することもできます) 。
- 非同期 INSERT の例 (client リポジトリ) 。
Inserter 機能 (クライアント側バッチ処理)
inserter Cargo feature が必要です。
- いずれかのしきい値 (
max_bytes、max_rows、period) に達すると、Inserterはcommit()内でアクティブな insert を終了します。 - アクティブな
INSERTの終了間隔は、並列 inserter による負荷のスパイクを避けるために、with_period_biasを使って偏らせることができます。 Inserter::time_left()は、現在の period がいつ終了するかを検出するために使用できます。ストリームがまれにしか項目を送出しない場合は、Inserter::commit()を再度呼び出して制限値を確認してください。- 時間しきい値は、
inserterを高速化するために quanta クレート を使って実装されています。test-utilが enabled の場合は使用されません (そのため、カスタムテストではtokio::time::advance()で time を管理できます) 。 commit()呼び出しの間にあるすべての行は、同じINSERTステートメントに挿入されます。
DDL の実行
wait_end_of_query オプションを使って、すべてのレプリカに DDL が適用されるのを待つことを推奨します。次のように実行できます。
ClickHouseの設定
with_option メソッドを使うと、さまざまな ClickHouseの設定 を適用できます。例:
queryに加え、insertメソッドやinserterメソッドでも同様に機能します。さらに、すべてのクエリに共通のグローバル設定を行うために、同じメソッドをClientインスタンスに対して呼び出すこともできます。
クエリ ID
.with_option を使うと、query_id オプションを設定して、ClickHouse のクエリログでクエリを識別できます。
query と同様に、insert および inserter メソッドでも機能します。
query_id を手動で設定する場合は、一意であることを確認してください。これには UUID が適しています。セッションID
query_id と同様に、session_id を設定すると、同じセッションでステートメントを実行できます。session_id は、クライアントレベルでグローバルに設定することも、query、insert、または inserter の呼び出しごとに設定することもできます。
クラスター構成のデプロイメントでは、“スティッキーセッション” がないため、この機能を適切に利用するには、特定のクラスター ノード に接続する必要があります。たとえば、ラウンドロビンのロードバランサーでは、後続のリクエストが同じ ClickHouse ノードで処理されるとは限りません。
カスタムHTTPヘッダー
カスタム HTTP クライアント
データ型
次の追加例も参照してください。
(U)Int(8|16|32|64|128)は、対応する(u|i)(8|16|32|64|128)型、またはそれらをラップした newtype と相互変換できます。(U)Int256は直接サポートされていませんが、回避策があります。Float(32|64)は、対応するf(32|64)、またはそれらをラップした newtype と相互変換できます。Decimal(32|64|128)は、対応するi(32|64|128)、またはそれらをラップした newtype と相互変換できます。fixnumや、その他の符号付き固定小数点数実装を使うほうが便利です。Booleanはbool、またはそれをラップした newtype と相互変換できます。Stringは任意の文字列型またはバイト列型と相互変換できます。たとえば&str、&[u8]、String、Vec<u8>、SmartStringです。newtype もサポートされています。バイト列を保存する場合は、より効率的なserde_bytesの使用を検討してください。
FixedString(N)は、たとえば[u8; N]のようなバイトの配列としてサポートされています。
Enum(8|16)はserde_reprを使ってサポートされています。
UUIDはserde::uuidを使用することでuuid::Uuidとの間で相互変換されます。uuidfeature が必要です。
IPv6はstd::net::Ipv6Addrと相互に変換されます。IPv4はserde::ipv4を使用してstd::net::Ipv4Addrと相互に変換されます。
Dateはu16またはそれをラップした newtype と相互変換でき、1970-01-01からの経過日数を表します。また、time::Dateもserde::time::dateを使用することでサポートされますが、その場合はtimeフィーチャーが必要です。
Date32はi32またはそれをラップした newtype に対応し、1970-01-01からの経過日数を表します。また、time::Dateもserde::time::date32を使うことでサポートされますが、これにはtimefeature が必要です。
DateTimeはu32またはそれをラップした newtype と相互変換でき、UNIX epoch からの経過秒数を表します。また、time::OffsetDateTimeもserde::time::datetimeを使うことでサポートされますが、これにはtimefeature が必要です。
DateTime64(_)はi32またはそれをラップする newtype に相互変換され、Unix epoch からの経過時間を表します。また、time::OffsetDateTimeはserde::time::datetime64::*を使用することでサポートされますが、これにはtimefeature が必要です。
Tuple(A, B, ...)は(A, B, ...)またはそれをラップした newtype との相互変換に対応しています。Array(_)は任意のスライス (例:Vec<_>、&[_]) との相互変換に対応しています。独自の型もサポートされています。Map(K, V)はArray((K, V))と同様に扱われます。LowCardinality(_)は透過的にサポートされています。Nullable(_)はOption<_>との相互変換に対応しています。clickhouse::serde::*ヘルパーでは::optionを追加してください。
- 複数の配列の名前を変更して指定することで、
Nestedをサポートできます。
Geo型がサポートされています。Pointは(f64, f64)というタプルとして扱われ、それ以外の型は単に Point のスライスです。
Variant、Dynamic、 (新しい)JSONデータ型はまだサポートされていません。
モック化
SELECT、INSERT、WATCH クエリをテストするためのユーティリティが用意されています。この機能は test-util feature で有効にできます。必ず開発用依存関係としてのみ使用してください。
サンプル を参照してください。
トラブルシューティング
CANNOT_READ_ALL_DATA
CANNOT_READ_ALL_DATA エラーの最も一般的な原因は、アプリケーション側の行定義が ClickHouse 側の定義と一致していないことです。
次のテーブルを見てみましょう。
EventLog が型不一致のまま定義されている場合、たとえば次のようになります。
EventLog struct を正しく定義することで、この問題を修正できます。
既知の制限事項
Variant、Dynamic、 (新しい)JSONデータ型は、まだサポートされていません。- サーバー側のパラメータバインドは、まだサポートされていません。追跡状況については、この issue を参照してください。