Edited at

ClickHouse シャーディングの方法とシャーディングされたテーブルへのSELECT方法

More than 1 year has passed since last update.


はじめに

ClickHouse引き続いてシャーディング周りの操作方法を確認したので書いておきます。が…正直書いている本人、これが正しいのかさらに懐疑的です。


設定(config.xml)

シャーディングの設定自体はReplicatedMergeTreeあたりと同じノリで行おうと思います。今回は試しに1号機と2号機のシャードを分けてみます。

1号機


/etc/clickhouse-server/config.xml

    <macros>

<set>1</set>
<shard>1</shard>
<replica>clickhouse01</replica>
</macros>

2号機


/etc/clickhouse-server/config.xml

    <macros>

<set>1</set>
<shard>2</shard>
<replica>clickhouse01</replica>
</macros>

分散した各サーバ全てにSELECTなどのクエリがいきわたるよう、今度はクラスターの設定を行います。zookeeperからクラスタ設定自動生成する手段、無いのかなー…。なお、クラスタ設定はオンラインで適用されるため、ClickHouseの再起動は不要です。不要なんですが、以前のクラスタ定義が、system.clustersテーブルに残り続けているので、不快な人は再起動したほうがいいかもしれません。

1号機2号機両方


/etc/clickhouse-server/config.xml

    <remote_servers>

<cluster01>
<shard>
<replica>
<host>clickhouse01</host>
<port>9000</port>
<user>default</user>
<password></password>
</replica>
</shard>
<shard>
<replica>
<host>clickhouse02</host>
<port>9000</port>
<user>default</user>
<password></password>
</replica>
</shard>
</cluster01>
</remote_servers>

このように設定をいれておくと、クラスタ名「cluster01」で、2ノード構成で、互いの接続にはdefaultユーザを使う、という設定ができます。clickhouse01とclickhouse02はDNSやhostsで名前が引けるのが前提です。


データテーブル作成

とりあえずこんな風にして、再度ReplicatedMergeTreeテーブルを両方で作ります。

CREATE TABLE sharding_access_log_20171222 (

log_date Date,
url String,
referrer String,
ip String,
ua String,
created_at DateTime
) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{set}-{shard}/sharding_access_log' , '{replica}', log_date, (log_date, url, referrer, ip, ua, created_at), 8192)

その後各々にデータを入れて、各々にSELECTを打ってみますが…各々のデータしか見えません。残念。


参照用のDistributedテーブルの作成

各サーバに散らばった各テーブルを参照するために、Distributedテーブルを作成します。内部的にはこれもViewに該当します。

CREATE TABLE d_sharding_access_log_20171222 (

log_date Date,
url String,
referrer String,
ip String,
ua String,
created_at DateTime
) ENGINE = Distributed(cluster01,default,sharding_access_log_20171222);

このd_sharding_access_log_20171222にSELECTを行うことで、2017/12/22分の全サーバのアクセスログを横断的に見ることができるようになりました。あと一歩ですね。


distributedテーブルをさらに横断的にみるMergeテーブルを作成

全日のデータを全シャード横断的にみるために、以下のようにまたまたViewとなるテーブルを作成します。

CREATE TABLE sharding_access_logs (

log_date Date,
url String,
referrer String,
ip String,
ua String,
created_at DateTime
) ENGINE = Merge(default,'^d_sharding_access_log_.*');

これで、このsharding_access_logsテーブルに対してSELECTを発行すれば全てのログが…見えます。

なお、Distributedテーブルを作る際にMergeテーブルを一度指定してみましたが、残念ながらエラーになりました。したがってこの順にマージしていく必要があるのかな、と思っています。