์๋ ํ์ธ์, ํ๋ธ๋ฅด.
๋๊ตฐ๊ฐ๊ฐ ์์คํ
์ ์
์ฉํ๋ ๊ฒฝ์ฐ
ClickHouse๋ ์ค๋ช ๋ ๋ฌธ์ ๋ฅผ ์ ํด๊ฒฐํฉ๋๋ค. ์๋ฅผ ๋ค์ด ์์ญ์์์ 2TiB์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๋ฉด 300GiB์ ๋ง์ต๋๋ค. ๋น๊ต์ ๋ํด ์์ธํ ์ค๋ช ํ์ง๋ ์๊ฒ ์ต๋๋ค. ์ด ์ฃผ์ ์ ๋ํ ๊ธฐ์ฌ๊ฐ ๋ง์ด ์์ต๋๋ค. ๋ํ ์ต๊ทผ๊น์ง ClickHouse ์คํ ๋ฆฌ์ง์ ๋ชจ๋ ๊ฒ์ด ์๋ฒฝํ์ง๋ ์์์ต๋๋ค.
์๋น๋๋ ๊ณต๊ฐ์ ๋ฌธ์
์ธ๋ป ๋ณด๋ฉด ๋ชจ๋ ๊ฒ์ด ์ ์๋ํ ๊ฒ์
๋๋ค. ์ํ์ retention
), ์ ํํ graphite-web ๋ฐฑ์๋์ ๊ถ์ฅ ์ฌํญ์ ๋ฐ๋ผ ํ
์ด๋ธ์ ์์ฑํฉ๋๋ค.
์ด๋ ๊ฒ์ ์ดํดํ๋ ค๋ฉด ์ฝ์
์ด ์๋ํ๋ ๋ฐฉ์๊ณผ * ์ ํ๊ตฐ์ ์์ง ํ
์ด๋ธ์ ์๋ ๋ฐ์ดํฐ์ ์ถ๊ฐ ์๋ช
๊ฒฝ๋ก๋ฅผ ์์์ผ ํฉ๋๋ค.๋ณํฉํธ๋ฆฌ ClickHouse(์ฐจํธ๋ ๋ค์์์ ๊ฐ์ ธ์ด)
- ์ฝ์
๋จ
ะฑะปะพะบ
๋ฐ์ดํฐ. ์ฐ๋ฆฌ์ ๊ฒฝ์ฐ ๋์ฐฉํ ๊ฒ์ ์ธก์ ํญ๋ชฉ์ด์์ต๋๋ค.
- ์ด๋ฌํ ๊ฐ ๋ธ๋ก์ ๋์คํฌ์ ๊ธฐ๋ก๋๊ธฐ ์ ์ ํค์ ๋ฐ๋ผ ์ ๋ ฌ๋ฉ๋๋ค.
ORDER BY
ํ ์ด๋ธ์ ์์ฑํ ๋ ์ง์ ๋ฉ๋๋ค. - ์ ๋ ฌํ ํ,
ะบััะพะบ
(part
) ๋ฐ์ดํฐ๊ฐ ๋์คํฌ์ ๊ธฐ๋ก๋ฉ๋๋ค.
- ์๋ฒ๋ ์ด๋ฌํ ์กฐ๊ฐ์ด ๋ง์ง ์๋๋ก ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋ชจ๋ํฐ๋งํ๊ณ ๋ฐฑ๊ทธ๋ผ์ด๋๋ฅผ ์คํํฉ๋๋ค.
ัะปะธัะฝะธั
(merge
, ์ดํ ๋ณํฉ).
- ๋ฐ์ดํฐ๊ฐ ์๋ฒ๋ก ํ๋ฐํ๊ฒ ์ ์
๋๋ ๊ฒ์ ์ค์งํ์๋ง์ ์๋ฒ๋ ์์ฒด์ ์ผ๋ก ๋ณํฉ ์คํ์ ์ค์งํฉ๋๋ค.
ะฟะฐััะธัะธั
(partition
), ๊ทธ๋ฌ๋ ๋ค์ ๋ช ๋ น์ ์ฌ์ฉํ์ฌ ํ๋ก์ธ์ค๋ฅผ ์๋์ผ๋ก ์์ํ ์ ์์ต๋๋ค.OPTIMIZE
. - ํํฐ์
์ ์กฐ๊ฐ์ด ํ๋๋ง ๋จ์ ์์ผ๋ฉด ์ผ๋ฐ์ ์ธ ๋ช
๋ น์ ์ฌ์ฉํ์ฌ ๋ณํฉ์ ์คํํ ์ ์์ต๋๋ค.
OPTIMIZE ... FINAL
๋ฐ๋ผ์ ์ฒซ ๋ฒ์งธ ์ธก์ ํญ๋ชฉ์ด ๋์ฐฉํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๋ค์ ์ฝ๊ฐ์ ๊ณต๊ฐ์ ์ฐจ์งํฉ๋๋ค. ํ์ ์ด๋ฒคํธ๋ ์ฌ๋ฌ ์์ธ์ ๋ฐ๋ผ ๋ค์ ๋ฌ๋ผ์ง ์ ์์ต๋๋ค.
- ๋ถํ ํค๋ ๋งค์ฐ ์์ ์๋ ์๊ณ (ํ๋ฃจ), ๋งค์ฐ ํด ์๋ ์์ต๋๋ค(๋ช ๋ฌ).
- ๋ณด์กด ๊ตฌ์ฑ์ ํ์ฑ ํํฐ์ (๋ฉํธ๋ฆญ์ด ๊ธฐ๋ก๋๋ ๊ณณ) ๋ด์ ์ฌ๋ฌ ์ค์ํ ๋ฐ์ดํฐ ์ง๊ณ ์๊ณ๊ฐ์ ๋ง์ ์๋ ์๊ณ ๊ทธ๋ ์ง ์์ ์๋ ์์ต๋๋ค.
- ๋ฐ์ดํฐ๊ฐ ๋ง์ผ๋ฉด ๋ฐฑ๊ทธ๋ผ์ด๋ ๋ณํฉ์ผ๋ก ์ธํด ์ด๋ฏธ ๊ฑฐ๋ํ ์ ์๋ ๊ฐ์ฅ ์ด๊ธฐ ์ฒญํฌ(์ต์ ํ๋์ง ์์ ํํฐ์ ๋ ํค๋ฅผ ์ ํํ ๊ฒฝ์ฐ)๊ฐ ์๋ก์ด ์์ ์ฒญํฌ์ ๋ณํฉ๋์ง ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ํญ์ ๋๊ฐ์ด ๋๋์ฃ . ClickHouse์์ ์ธก์ ํญ๋ชฉ์ด ์ฐจ์งํ๋ ๊ณต๊ฐ์ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ์๋ง ์ฆ๊ฐํฉ๋๋ค.
- ์ ์ฉํ์ง ์๋๋ค
OPTIMIZE ... FINAL
์๋์ผ๋ก ๋๋ - ์กฐ๋ง๊ฐ ๋ฐฑ๊ทธ๋ผ์ด๋ ๋ณํฉ์ด ์์๋๋๋ก ์ง์์ ์ผ๋ก ๋ชจ๋ ํํฐ์ ์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ์ง ๋ง์ญ์์ค.
๋ ๋ฒ์งธ ๋ฐฉ๋ฒ์ด ๊ฐ์ฅ ๊ตฌํํ๊ธฐ ์ฌ์ด ๊ฒ ๊ฐ์์ ์ฌ๋ฐ๋ฅด์ง ์์ ๋จผ์ ์๋ํ์ต๋๋ค.
๋๋ ์ง๋ 4๋
๋์ ๋งค์ผ ๋๋ฏธ ์งํ๋ฅผ ๋ณด๋ด๊ณ ๋งค์๊ฐ cron์ ์คํํ๋ ๋งค์ฐ ๊ฐ๋จํ Python ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ์ต๋๋ค.
ClickHouse DBMS์ ์ ์ฒด ์์
์ ์ด ์์คํ
์ด ์กฐ๋ง๊ฐ ๋ชจ๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์
์ ์ํํ ๊ฒ์ด๋ผ๋ ์ฌ์ค์ ๊ธฐ๋ฐ์ผ๋ก ํ๊ณ ์์ง๋ง ์ธ์ ์ธ์ง ์ ์ ์๊ธฐ ๋๋ฌธ์ ์ค๋๋ ๊ฑฐ๋ํ ์กฐ๊ฐ๋ค์ด ๋ณํฉ๋๊ธฐ ์์ํ๋ ์๊ฐ์ ๊ธฐ๋ค๋ฆด ์ ์์์ต๋๋ค. ์๋ก์ด ์์ ๊ฒ๋ค. ๊ฐ์ ์ต์ ํ๋ฅผ ์๋ํํ๋ ๋ฐฉ๋ฒ์ ์ฐพ์์ผ ํ๋ค๋ ๊ฒ์ด ๋ถ๋ช
ํด์ก์ต๋๋ค.
ClickHouse ์์คํ ํ ์ด๋ธ์ ์ ๋ณด
ํ
์ด๋ธ ๊ตฌ์กฐ๋ฅผ ์ดํด๋ณด์
- DB ์ด๋ฆ(
database
); - ํ
์ด๋ธ ์ด๋ฆ(
table
); - ํํฐ์
์ด๋ฆ ๋ฐ ID(
partition
&partition_id
); - ์ํ์ด ๋ง๋ค์ด์ก์ ๋(
modification_time
); - ์กฐ๊ฐ์ ์ต์ ๋ฐ ์ต๋ ๋ ์ง(ํํฐ์
์ ๋ ์ง๋ณ๋ก ์ํ๋จ) (
min_date
&max_date
);
ํ
์ด๋ธ๋ ์์ด์
- DB ์ด๋ฆ(
Tables.database
); - ํ
์ด๋ธ ์ด๋ฆ(
Tables.table
); - ๋ค์ ์ง๊ณ๋ฅผ ์ ์ฉํด์ผ ํ๋ ์ธก์ ๊ธฐ๊ฐ(
age
);
๊ทธ๋์ :
- ์ฒญํฌ ํ ์ด๋ธ๊ณผ ์ง๊ณ ๊ท์น ํ ์ด๋ธ์ด ์์ต๋๋ค.
- ๊ต์ฐจ์ ์ ๊ฒฐํฉํ์ฌ ๋ชจ๋ ํ ์ด๋ธ *GraphiteMergeTree๋ฅผ ์ป์ต๋๋ค.
- ์ฐ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ ๋ชจ๋ ํํฐ์
์ ์ฐพ๊ณ ์์ต๋๋ค.
- ํ ์กฐ๊ฐ ์ด์
- ๋๋ ๋ค์ ์ง๊ณ ๊ท์น์ ์ ์ฉํ ๋๊ฐ ๋์์ผ๋ฉฐ,
modification_time
์ง๊ธ ์ด ์๊ฐ๋ณด๋ค ๋ ์ค๋๋์ด.
ะ ะตะฐะปะธะทะฐัะธั
์ด ์์ฒญ
SELECT
concat(p.database, '.', p.table) AS table,
p.partition_id AS partition_id,
p.partition AS partition,
-- ะกะฐะผะพะต "ััะฐัะพะต" ะฟัะฐะฒะธะปะพ, ะบะพัะพัะพะต ะผะพะถะตั ะฑััั ะฟัะธะผะตะฝะตะฝะพ ะดะปั
-- ะฟะฐััะธัะธะธ, ะฝะพ ะฝะต ะฒ ะฑัะดััะตะผ, ัะผ (*)
max(g.age) AS age,
-- ะะพะปะธัะตััะฒะพ ะบััะบะพะฒ ะฒ ะฟะฐััะธัะธะธ
countDistinct(p.name) AS parts,
-- ะะฐ ัะฐะผัั ััะฐัััั ะผะตััะธะบั ะฒ ะฟะฐััะธัะธะธ ะฟัะธะฝะธะผะฐะตััั 00:00:00 ัะปะตะดัััะตะณะพ ะดะฝั
toDateTime(max(p.max_date + 1)) AS max_time,
-- ะะพะณะดะฐ ะฟะฐััะธัะธั ะดะพะปะถะฝะฐ ะฑััั ะพะฟัะธะผะธะทะธัะพะฒะฐะฝะฝะฐ
max_time + age AS rollup_time,
-- ะะพะณะดะฐ ัะฐะผัะน ััะฐััะน ะบััะพะบ ะฒ ะฟะฐััะธัะธะธ ะฑัะป ะพะฑะฝะพะฒะปัะฝ
min(p.modification_time) AS modified_at
FROM system.parts AS p
INNER JOIN
(
-- ะัะต ะฟัะฐะฒะธะปะฐ ะดะปั ะฒัะตั
ัะฐะฑะปะธั *GraphiteMergeTree
SELECT
Tables.database AS database,
Tables.table AS table,
age
FROM system.graphite_retentions
ARRAY JOIN Tables
GROUP BY
database,
table,
age
) AS g ON
(p.table = g.table)
AND (p.database = g.database)
WHERE
-- ะขะพะปัะบะพ ะฐะบัะธะฒะฝัะต ะบััะบะธ
p.active
-- (*) ะ ัะพะปัะบะพ ัััะพะบะธ, ะณะดะต ะฟัะฐะฒะธะปะฐ ะฐะณะณัะตะณะฐัะธะธ ัะถะต ะดะพะปะถะฝั ะฑััั ะฟัะธะผะตะฝะตะฝั
AND ((toDateTime(p.max_date + 1) + g.age) < now())
GROUP BY
table,
partition
HAVING
-- ะขะพะปัะบะพ ะฟะฐััะธัะธะธ, ะบะพัะพััะต ะผะปะฐะดัะต ะผะพะผะตะฝัะฐ ะพะฟัะธะผะธะทะฐัะธะธ
(modified_at < rollup_time)
-- ะะปะธ ั ะฝะตัะบะพะปัะบะธะผะธ ะบััะบะฐะผะธ
OR (parts > 1)
ORDER BY
table ASC,
partition ASC,
age ASC
๋ณํฉํ์ฌ ๋์คํฌ ๊ณต๊ฐ์ ํ๋ณดํด์ผ ํ๋ ๊ฐ *GraphiteMergeTree ํ
์ด๋ธ ํํฐ์
์ ๋ฐํํฉ๋๋ค. ๋จ์ ์ ์ผํ ์ผ์ ์์ฒญ์ ํตํด ๊ทธ๊ฒ๋ค์ ๋ชจ๋ ์ดํด๋ณด๋ ๊ฒ์
๋๋ค. OPTIMIZE ... FINAL
. ์ต์ข
๊ตฌํ์์๋ ํ์ฑ ๋
นํ๊ฐ ์๋ ํํฐ์
์ ๊ฑด๋๋ฆด ํ์๊ฐ ์๋ค๋ ์ฌ์ค๋ ๊ณ ๋ คํ์ต๋๋ค.
์ด๊ฒ์ด ๋ฐ๋ก ํ๋ก์ ํธ๊ฐ ํ๋ ์ผ์
๋๋ค
ClickHouse๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฒ์์ ํ๋ก๊ทธ๋จ์ ์คํํ๋ฉด ๋ฐ๋ชฌ ๋ชจ๋์์ ์์ ์ด ์์๋ฉ๋๋ค. ํ ์๊ฐ์ ํ ๋ฒ์ฉ ์์ฒญ์ด ์คํ๋์ด ์ต์ ํํ ์ ์๋ XNUMX์ผ๋ณด๋ค ์ค๋๋ ์ ํํฐ์ ์ด ๋ํ๋๋์ง ํ์ธํฉ๋๋ค.
์ฐ๋ฆฌ์ ์ฆ๊ฐ์ ์ธ ๊ณํ์ ์ต์ํ deb ํจํค์ง๋ฅผ ์ ๊ณตํ๊ณ ๊ฐ๋ฅํ๋ค๋ฉด rpm๋ ์ ๊ณตํ๋ ๊ฒ์ ๋๋ค.
๋์ ๊ฒฐ๋ก
์ง๋ 9๊ฐ์ ์ด์ ํ์ฌ์ ๊ทผ๋ฌดํ์ต๋๋ค.
์์ฒญ์ ๊ฐ๋ฐํ๋ ๋ฐ ๋ช ๋ฆฌํฐ์ ๋งฅ์ฃผ์ ๊ด๋ฆฌ์ผ์ด ์์๋์์ต๋๋ค.
์ถ์ฒ : habr.com