「ClickHouse Meetup Tokyo」エンジニアレポート
はじめまして。ClickHouse Meetup TokyoでジーニーのLTを担当しました、R&D本部 基盤技術開発部の犬伏です。 前回の記事: 「ClickHouse MeetupTokyo」イベントレポート 今回の「ClickHouse Meetup Tokyo」エンジニアレポートでは、LT発表者の視点からイベントを振り返ります。 次回の記事:「ClickHouseの構成を考え直してみた」では、Meetupの後、過去に弊社で構築された構成をどのように修正したかを概説します。
目次
ClickHouseとは
Meetupの所感
弊社LTの発表スライド
弊社LTでの質疑応答まとめ
まとめ、今後について
ClickHouseとは
ClickHouseは露Yandex社が開発するオープンソースの列指向のDBMSであり、行指向のDBMS(例えばMySQL)とは得意分野の異なるDBMSです。 今回の本題は別のところにあるので、ClickHouseそのものについての説明は省略します。 ClickHouseそのものの詳細については以下のリンク先を参照ください:
Meetupの所感
Meetupを開催したことによるメリット
LT発表用のスライドを作成する過程で、
現状のシステムについて、開発上のこれまでの経緯や現状の構成などへの理解が深まった
ClickHouseそのもののドキュメントを再読することで、忘れていた機能や追加された新機能に気付けた
ClickHouse開発者の方々に現状の構成や課題に対してアドバイスをもらえた
Meetupの様子は前回の記事: 「ClickHouse Meetup Tokyo」イベントレポート をご覧ください。 MeetupのYouTube配信: https://www.youtube.com/watch?v=728Yywcd5ys ClickHouse開発チームの発表スライド: https://github.com/ClickHouse/clickhouse-presentations/tree/master/meetup34
弊社LTの発表スライド
ClickHouse導入事例紹介 from Geniee, Inc. / 株式会社ジーニー
弊社LTでの質疑応答まとめ
※ 注意:回答で例示される挙動は、 ClickHouse 19.7.3.9 の挙動を元にしていますので、新しいバージョンでは挙動が異なる可能性があります。(Yandex社のAlexeyさんによる回答を除く)
質問1. クエリの静的解析について「共通部分式削除」とあったが、同じサブクエリもキャッシュされるのか?
回答 by Alexey (Yandex)
No.
Usual expressions are cached. Similar expressions will be executed only once.
But sub-queries are not.
補足
スライドでの私の意図は、例えば下に示すクエリAで、 SUM(x) が一度のみ計算されるというものでした。
しかし、サブクエリに関してはキャッシュされないため、同じ意味の表現であっても書いた回数だけ計算され時間がかかってしまうようです。
クエリA:
SELECT
SUM(a) / SUM(x),
SUM(b) + SUM(x)
FROM default.test
質問2.冗長構成にして欲しいと言われているのですが、どんなところを気をつければいいか?
回答
replication(データ複製)をしてくれるテーブルエンジン(table engine)が用意されています。
ZooKeeperをコーディネータとして利用することで、テーブルとして同期を取ってくれます。
質問3. INSERT後にそれが反映されるタイミングはサーバーごとに異なる?
回答
はい、ただし正常な設定では1秒程度以下の遅れです。(Replicatedなテーブルを想定して回答)
補足
Replicatedなテーブルの場合には、一度ZooKeeperを経由するため、反映は同期しません。
DistributedテーブルにINSERTした場合、データがそれぞれのshardに分散されるため、INSERTが完了したと応答した時点と、SELECTの対象になるタイミングは厳密には一致しません。
当然INSERTが詰まったりすればその限りではないが、スループット内の範囲であれば1秒も見ておけば十分
INSERTが詰まる場合の例:大量のデータのINSERT、頻繁過ぎるINSERT、一度に多くのパーティションにINSERTされるようなINSERT、貧弱すぎるレプリカ間の接続など
質問4. ClickHouse自体の監視はどのように行っているのか。内部のmetricsをexportしているのか?
回答
ClickHouseには system という名前のデータベースがあり、様々なメトリクスがそこに保存されています。
クエリのログについては query_log オプションを設定することで保存させることができます。
たとえば、レプリケーションの遅延等も system データベースのテーブルから取得できます。
補足
監視についての公式ドキュメント(レプリケーションの遅延の取得方法も含む)
system テーブルについて
query_log オプションについて
質問5. 監査用のログ(誰がログインして、誰がどういう操作をして、という情報)は取得可能ですか?
回答 by Alexey (Yandex)
How to monitor user activity in ClickHouse:
First, you can enable query_log. Every query will be logged in this table when thequery is started and when it is finished.
You will see all query properties, such as who threw the query.
補足
query_log を有効化すれば、すべての実行されたクエリ及びその実行の詳細(いつ、誰が、どんなクエリを投げたか)を取得できます。
質問6. 2年前のジーニーの記事の構成をもとに分散テーブルを使ってデータ分散(sharding)をしている状況で、前日のテーブルの内容を差し替えたい。どうすればいいか?
説明
サーバーが1台の時にはうまく行くが、複数サーバーでshardingを始めたらつらくなった。
弊社の記事の構成では、分散テーブルを使っていなかったので、テーブルの差し替え方法が説明されていなかった。
回答
Distributedテーブルに INSERT すれば勝手にデータが分散されるので、これを利用します。
https://clickhouse.tech/docs/en/operations/table_engines/distributed/
sharding_key を設定しないと INSERT できないので注意が必要です。
手順は次の通り:
昨日分の一時テーブル tmp_reports_YYYYMMDD と、これを参照する Distributed テーブルtmp_dist_reports_YYYYMMDD を作る
この際、トップレベルのMergeテーブルの正規表現に tmp_dist_reports_YYYYMMDDテーブルがマッチしないように注意すること(さもないと昨日分のデータが重複することになる)
tmp_dist_reports_YYYYMMDD に対して更新するデータの INSERT を行う(裏で勝手に sharding される)
すべてのサーバー上の tmp_reports_YYYYMMDD について sharding と replication が済むのを待つ
RENAME TABLE reports_YYYYMMDD TO trash_reports_YYYYMMDD, tmp_reports_YYYYMMDD TO reports_YYYYMMDD ON CLUSTER <cluster_name>をすると、全 shard のテーブルが入れ替わり、データの差し替えが完了する
ただし、過去の弊社の記事による構成は運用上望ましくないため、次の記事「ClickHouseの構成を考え直してみた」にて詳述する構成自体の改善方法に従って構築をやり直すことをおすすめします。
質問7. 日毎にテーブルを持つ構成の問題点
説明
2年前の弊社の記事の構成を見て、同じように日別のテーブルを持って同じように失敗している。どう解決すればよいか。
回答
例えば、次のような運用上の不都合が発生します:
数年分のデータ(つまり数千個のReplicatedテーブル)を保持していると、数日に1回程度の頻度で XID overflow によりクエリが失敗するようになります。
このため、数日に一度、XID overflow が発生する前にサーバーを再起動して ZooKeeper XID をリセットするといった運用が必要になります。
SELECTの際に、Mergeテーブルがまずサーバー内で数千のDistributedテーブルへのSELECTに分解されるため、他のshardへのSELECTがすべてのDistributedテーブルから独立して行われ、結果connection が不必要に大量に乱立することとなり、ConnectionPool が枯渇し、Cannot schedule a taskに至ることがあります。
こうなったクエリは応答不能( KILL QUERY で殺せない)となることがあり、サーバー再起動でしか対処できなくなります。
特に ConnectionPool すべてを確保した状態で応答不能になると、他のクエリ実行も不可能になります。
テーブルがたくさん存在するため、列の追加や削除などのテーブル構成に対する操作が非常な手間を伴います。
次の記事「ClickHouseの構成を考え直してみた」にて詳述する構成自体の改善方法に従って構築をやり直すことをおすすめします。
質問8. 自社では1クラスターあたり少ない台数でClickHouseを動かしているが、最大どのぐらいまでスケールするのか
回答 by Alexey (Yandex)
How big can ClickHouse cluster be?
600 servers, but this is not the biggest cluster.
A Chinese company uses more than 1000 servers.
ClickHouse can scale.
質問9. 障害後の復旧の自動化など、運用上の工夫等あれば
説明
運用していて、Replica か ZooKeeper cluster が死んで、CREATE TABLE ができなかった
ZooKeeper cluster がダウンしたら Replicated Table は readonly になる
回答
以下の公式ドキュメントにまとまっている。
Replica が死んだ場合の回復方法
新しいサーバーにClickHouseをインストールし、Replicatedテーブルを正しいZooKeeperパスとともに作成し、ZooKeeper及び既存のクラスターと接続すれば、自動的にreplicationが行われ、いずれ追いつきます。
ZooKeeper cluster が死んだ場合の回復方法
ClickHouse replicated tables will be readonly mode. INSERT cannot be performed.
ZooKeeper itself has also a replication.
質問10. 中国で1000台の ClickHouse cluster があるとのことだが、そのクラスターの ZooKeeper はどうなっているのか?
回答 by Alexey (Yandex)
That company does not use ZooKeeper.
Yandex uses 3 ZooKeeper servers and this is the recommended configuration.
How to better configure ZooKeeper:
Use SSDs.
10M nodes -> typical amount of memory is 128GB of RAM.
まとめ、今後について
今回は、(著者が社内のClickHouseの構成変更を終えたため、まずは)Meetupの振り返りを投稿しました。
次回の記事:「ClickHouseの構成を考え直してみた」では、Meetupの後、過去に弊社で構築された構成をどのように修正したかを概説します。
ジーニーの採用情報はこちら!