สวัสดีฮับ.
หากมีใครเอาเปรียบระบบ
ClickHouse แก้ปัญหาที่อธิบายไว้ได้ดี ตัวอย่างเช่น หลังจากถ่ายโอนข้อมูล 2TiB จาก Whisper แล้ว ข้อมูลเหล่านั้นจะพอดีกับ 300GiB ฉันจะไม่อาศัยการเปรียบเทียบโดยละเอียดมีบทความมากมายในหัวข้อนี้ นอกจากนี้ จนกระทั่งเมื่อไม่นานมานี้ ไม่ใช่ทุกอย่างที่สมบูรณ์แบบด้วยพื้นที่จัดเก็บ ClickHouse ของเรา
ปัญหาเกี่ยวกับพื้นที่บริโภค
เมื่อมองแวบแรกทุกอย่างควรทำงานได้ดี กำลังติดตาม retention
) จากนั้นสร้างตารางตามคำแนะนำของแบ็กเอนด์ที่เลือกสำหรับเว็บกราไฟท์:
เพื่อที่จะเข้าใจว่าอันไหนคุณต้องรู้ว่าส่วนแทรกทำงานอย่างไรและเส้นทางชีวิตของข้อมูลเพิ่มเติมในตารางเอ็นจิ้นของตระกูล *เมิร์จทรี ClickHouse (แผนภูมินำมาจาก
- แทรกแล้ว
блок
ข้อมูล. ในกรณีของเรา มันคือเมตริกที่มาถึง
- แต่ละบล็อกดังกล่าวจะถูกจัดเรียงตามคีย์ก่อนที่จะเขียนลงดิสก์
ORDER BY
ระบุไว้เมื่อสร้างตาราง - หลังจากเรียงลำดับแล้ว
кусок
(part
) ข้อมูลถูกเขียนลงดิสก์
- เซิร์ฟเวอร์จะตรวจสอบในพื้นหลังเพื่อให้มีชิ้นส่วนดังกล่าวไม่มากนัก และเปิดใช้งานพื้นหลัง
слияния
(merge
ซึ่งต่อไปนี้จะรวมกัน)
- เซิร์ฟเวอร์หยุดเรียกใช้การรวมข้อมูลทันทีที่ข้อมูลหยุดไหลเข้าสู่
партицию
(partition
) แต่คุณสามารถเริ่มกระบวนการได้ด้วยตนเองด้วยคำสั่งOPTIMIZE
. - หากพาร์ติชันเหลือเพียงชิ้นเดียว คุณจะไม่สามารถเรียกใช้การผสานโดยใช้คำสั่งปกติได้ คุณต้องใช้
OPTIMIZE ... FINAL
ดังนั้น ตัวชี้วัดแรกก็มาถึง และพวกเขาก็ใช้พื้นที่บางส่วน เหตุการณ์ที่ตามมาอาจแตกต่างกันบ้างขึ้นอยู่กับหลายปัจจัย:
- คีย์การแบ่งพาร์ติชันอาจมีขนาดเล็กมาก (หนึ่งวัน) หรือใหญ่มาก (หลายเดือน)
- การกำหนดค่าการเก็บรักษาอาจเหมาะสมกับเกณฑ์การรวมข้อมูลที่สำคัญหลายประการภายในพาร์ติชันที่ใช้งานอยู่ (ซึ่งมีการบันทึกหน่วยวัด) หรืออาจจะไม่
- หากมีข้อมูลจำนวนมาก ชิ้นแรกสุดซึ่งเกิดจากการรวมพื้นหลังอาจมีขนาดใหญ่อยู่แล้ว (หากคุณเลือกคีย์การแบ่งพาร์ติชันที่ไม่เหมาะสม) จะไม่รวมตัวเองเข้ากับชิ้นเล็กๆ ใหม่
และมันจะจบลงเหมือนเดิมเสมอ พื้นที่ที่ถูกครอบครองโดยหน่วยวัดใน ClickHouse จะเพิ่มขึ้นก็ต่อเมื่อ:
- อย่าสมัคร
OPTIMIZE ... FINAL
ด้วยตนเองหรือ - อย่าแทรกข้อมูลลงในพาร์ติชั่นทั้งหมดอย่างต่อเนื่อง เพื่อว่าไม่ช้าก็เร็วการผสานพื้นหลังจะเริ่มขึ้น
วิธีที่สองดูเหมือนจะเป็นวิธีที่ง่ายที่สุดในการนำไปใช้ ดังนั้นจึงไม่ถูกต้องและได้ลองใช้ก่อน
ฉันเขียนสคริปต์ Python ที่ค่อนข้างเรียบง่ายซึ่งส่งการวัดจำลองทุกวันในช่วง 4 ปีที่ผ่านมาและรัน cron ทุก ๆ ชั่วโมง
เนื่องจากการดำเนินการทั้งหมดของ ClickHouse DBMS นั้นขึ้นอยู่กับความจริงที่ว่าระบบนี้จะทำงานเบื้องหลังทั้งหมดไม่ช้าก็เร็ว แต่ก็ไม่รู้ว่าเมื่อใด ฉันไม่สามารถรอช่วงเวลาที่ชิ้นส่วนขนาดใหญ่เก่าจะยอมเริ่มรวมเข้าด้วยกัน อันเล็กๆ ใหม่ เห็นได้ชัดว่าเราจำเป็นต้องมองหาวิธีบังคับการเพิ่มประสิทธิภาพโดยอัตโนมัติ
ข้อมูลในตารางระบบ ClickHouse
มาดูโครงสร้างตารางกันดีกว่า
- ชื่อฐานข้อมูล (
database
); - ชื่อตาราง (
table
); - ชื่อพาร์ติชันและ ID (
partition
&partition_id
); - เมื่อชิ้นนี้ถูกสร้างขึ้น (
modification_time
); - วันที่ต่ำสุดและสูงสุดเป็นชิ้น ๆ (แบ่งพาร์ติชันตามวัน) (
min_date
&max_date
);
มีโต๊ะด้วย
- ชื่อฐานข้อมูล (
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 โปรแกรมก็จะเริ่มทำงานในโหมด daemon คำขอจะถูกดำเนินการชั่วโมงละครั้ง โดยตรวจสอบว่ามีพาร์ติชั่นใหม่ที่เก่ากว่าสามวันปรากฏขึ้นมาและสามารถปรับให้เหมาะสมได้หรือไม่
แผนเร่งด่วนของเราคือการจัดหาแพ็คเกจ deb เป็นอย่างน้อย และหากเป็นไปได้ก็จัดให้มี rpm ด้วย
แทนการสรุป
กว่า 9 เดือนที่ผ่านมา ฉันอยู่ในบริษัทของฉัน
มีการใช้เบียร์และผู้ดูแลระบบหลายลิตรในการพัฒนาคำขอร่วมกับ
ที่มา: will.com