はじめまして。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そのものの詳細については以下のリンク先を参照ください:
- https://clickhouse.tech/
- https://clickhouse.tech/docs/ja/
- GitHub: https://github.com/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の発表スライド
弊社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で、
クエリ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
データベースのテーブルから取得できます。
- ClickHouseには
- 補足
- 監視についての公式ドキュメント(レプリケーションの遅延の取得方法も含む)
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
テーブルがマッチしないように注意すること(さもないと昨日分のデータが重複することになる)
- この際、トップレベルのMergeテーブルの正規表現に
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の構成を考え直してみた」にて詳述する構成自体の改善方法に従って構築をやり直すことをおすすめします。
- Distributedテーブルに INSERT すれば勝手にデータが分散されるので、これを利用します。
質問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 すべてを確保した状態で応答不能になると、他のクエリ実行も不可能になります。
- こうなったクエリは応答不能(
- テーブルがたくさん存在するため、列の追加や削除などのテーブル構成に対する操作が非常な手間を伴います。
- 数年分のデータ(つまり数千個のReplicatedテーブル)を保持していると、数日に1回程度の頻度で XID overflow によりクエリが失敗するようになります。
- 次の記事「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 か ZooKeeper cluster が死んで、CREATE TABLE ができなかった
- 回答
- 以下の公式ドキュメントにまとまっている。
- 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の後、過去に弊社で構築された構成をどのように修正したかを概説します。
- 次回の記事は2020年3月中に公開予定です。
- 予定目次は次のとおりです:
- 2017年に弊社ブログで紹介した内容の振り返り
- 紹介した構造の説明
- 紹介した構造の問題点指摘
- 新規に構築した構造の決定過程
- 複数在り得たPARTITION構造
- distributed_aggregation_memory_efficientの設定
- 注意:過去に紹介した構造(Merge of Distributed)にこの設定を使用すると、ClickHouse 19.7.3.9では期待しない動作をしますのでご注意ください!!
- 頻出クエリ抽出
- 性能評価の結果
- 新規に構築した構造の説明
- 新規に構築した構造への移行手順
- おまけ
- 19.7.3.9以降の重要な更新について
- PREWHEREについて
- 2017年に弊社ブログで紹介した内容の振り返り