1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Clickhouse] MergeTreeを設定したら、裏側はどんな動きでしょうか

Posted at

概要

この記事はここ引用し、知識を整理するために、記載しました。

なぜMergeTreeはいる?

データをClickHouseに書き込む時、ClickHouseはデータを複数のブロックを分けて、保存しているそうです。ClickHouseは、ブロックのデータを確保し、そのブロックのデータを変更したりはしない。(新しいデータをインサートする時は、ブロックに上書きしたりしないと自分の認識です。)ブロックは多くなると、データは下記のように、不連続となると思います。

スクリーンショット 2021-03-27 16.50.08.png

不連続のデータは検索する時、効率は下がるため、ClickHoseは裏側で、定期的に同じパーティションと設定されているデータをマージするようです。

スクリーンショット 2021-03-27 16.55.52.png

MergeTreeはどうやってマージするのか

ClickHouseではテーブルを作成する時、よく使っているテーブルエンジンMergeTreeですが、MergeTreeを設定する時、ClickHouseはどうやって、パーティションをマージしているんでしょうか?例えば、下記のSQLを使って、テーブルを作成してみました。

CREATE TABLE test 
(
    user_id String,
    date Date, 
    group_id String
) ENGINE = MergeTree()
    ORDER BY (user_id, date,group_id) 
    PRIMARY KEY (user_id, date)
    PARTITION BY toYYYYMM(date)
    SETTINGS index_granularity= 8192 ;

上記のSQLを実行し終わると、下記のところにファイルは作成された。

#path database/metadata/test.sql
ATTACH DATABASE _ UUID '0eb2002c-834c-4eb7-ac2f-35160d976765'
ENGINE = Atomic

上記のUUIDを使って、検索してみたら、このUUIDを使って、命名しているディレクトリーはあった。

# database/store/0eb/0eb2002c-834c-4eb7-ac2f-35160d976765

上記のディレクトリーの配下にはtest.sqlというファイルがあり、それはさっき実行したSQL文でした。

-- database/store/0eb/0eb2002c-834c-4eb7-ac2f-35160d976765/test.sql--
ATTACH TABLE _ UUID '48794f04-7524-46f7-a489-66cabed437c1'
(
    `user_id` String,
    `date` Date,
    `group_id` String
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(date)
PRIMARY KEY (user_id, date)
ORDER BY (user_id, date, group_id)
SETTINGS index_granularity = 8192

ちょっと、データをインサートしてみます。

INSERT INTO test (`user_id`, `date`, `group_id`) values ('1', toDate(now()), '1');

上記のtest.sqlにもテーブルのUUIDは記載していますので、もう一回このUUIDを使って、検索してみたら、デーブルのパーティションを管理するディレクトリにたどり着けます。

# database/store/487/48794f04-7524-46f7-a489-66cabed437c1/

ちょっとこのディレクトの配下みてみると、下記の感じです。

└── 48794f04-7524-46f7-a489-66cabed437c1    (テーブルのUUID)
    ├── 202103_1_1_0                        (parition名)
    │   ├── checksums.txt
    │   ├── columns.txt                     (カラム定義に関するファイル)
    │   ├── count.txt
    │   ├── data.bin
    │   ├── data.mrk3
    │   ├── default_compression_codec.txt
    │   ├── minmax_date.idx                (paritionキーを設定すると、作成されるファイル)
    │   ├── partition.dat                  (paritionキーを設定すると、作成されるファイル)

    │   └── primary.idx                    (primaryキー情報)
    ├── detached
    └── format_version.txt

上記のファイルによって、ClickHouseはテーブルのインデックスなど管理しているようですね。この時、あること気付きました。パーティション名はテーブルを作成した時、設定されているPARTITION BY toYYYYMM(date)によって、命名したように見えますね。パーティション名の構成は下記の感じです。

paritionID_minBlockNum_maxBlockNum_level

paritionIDの作成は2パターンがあるようですが、PARTITION BYを設定する場合は、設定されるキーによって作成し、PARTITION BYを設定していない場合はall という名前を使います。minBlockNummaxBlockNummaxBlockNumlevelについて、自分の理解は曖昧ですので、ここでは割愛です。
次はマージの過程をみてみると、下記のイメージです。

スクリーンショット 2021-03-27 18.50.05.png

minBlockNummaxBlockNumlevelは上記のイメージで計算しているようです。

まとめ

一部のことはまだ理解していないんですが、パーティションのマージについて、一応イメージを掴みました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?