はじめに
ClickHouse引き続いてシャーディング周りの操作方法を確認したので書いておきます。が…正直書いている本人、これが正しいのかさらに懐疑的です。
設定(config.xml)
シャーディングの設定自体はReplicatedMergeTreeあたりと同じノリで行おうと思います。今回は試しに1号機と2号機のシャードを分けてみます。
1号機
<macros>
<set>1</set>
<shard>1</shard>
<replica>clickhouse01</replica>
</macros>
2号機
<macros>
<set>1</set>
<shard>2</shard>
<replica>clickhouse01</replica>
</macros>
分散した各サーバ全てにSELECTなどのクエリがいきわたるよう、今度はクラスターの設定を行います。zookeeperからクラスタ設定自動生成する手段、無いのかなー…。なお、クラスタ設定はオンラインで適用されるため、ClickHouseの再起動は不要です。不要なんですが、以前のクラスタ定義が、system.clustersテーブルに残り続けているので、不快な人は再起動したほうがいいかもしれません。
1号機2号機両方
<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テーブルを一度指定してみましたが、残念ながらエラーになりました。したがってこの順にマージしていく必要があるのかな、と思っています。