พื้นที่เก็บข้อมูลเมตริก: วิธีที่เราเปลี่ยนจาก Graphite+Whisper เป็น Graphite+ClickHouse

สวัสดีทุกคน! ในตัวเขา บทความล่าสุด ฉันเขียนเกี่ยวกับการจัดระบบตรวจสอบแบบโมดูลาร์สำหรับสถาปัตยกรรมไมโครเซอร์วิส ไม่มีอะไรหยุดนิ่ง โครงการของเราเติบโตอย่างต่อเนื่อง และจำนวนตัววัดที่จัดเก็บก็เพิ่มขึ้นเช่นกัน วิธีที่เราจัดระเบียบการเปลี่ยนจาก Graphite+Whisper เป็น Graphite+ClickHouse ภายใต้สภาวะโหลดสูง อ่านเกี่ยวกับความคาดหวังจากการเปลี่ยนแปลงและผลลัพธ์ของการย้ายภายใต้การตัด

พื้นที่เก็บข้อมูลเมตริก: วิธีที่เราเปลี่ยนจาก Graphite+Whisper เป็น Graphite+ClickHouse

ก่อนที่ฉันจะบอกคุณว่าเราจัดระเบียบการเปลี่ยนแปลงจากการจัดเก็บหน่วยวัดใน Graphite+Whisper เป็น Graphite+ClickHouse ได้อย่างไร ฉันต้องการให้ข้อมูลเกี่ยวกับเหตุผลในการตัดสินใจดังกล่าวและเกี่ยวกับข้อเสียของ Whisper ที่เราใช้ชีวิตร่วมกันมาเป็นเวลานาน

ปัญหากราไฟท์+วิสเปอร์

1. โหลดสูงบนระบบย่อยของดิสก์

ในช่วงของการเปลี่ยนแปลง มีเมตริกประมาณ 1.5 ล้านเมตริกมาถึงเราต่อนาที ด้วยโฟลว์ดังกล่าว การใช้งานดิสก์บนเซิร์ฟเวอร์จึงอยู่ที่ ~30% โดยทั่วไป สิ่งนี้ค่อนข้างยอมรับได้ - ทุกอย่างทำงานได้อย่างเสถียร เขียนเร็ว อ่านเร็ว... จนกระทั่งทีมพัฒนาทีมใดทีมหนึ่งเปิดตัวฟีเจอร์ใหม่ และเริ่มส่งเมตริก 10 ล้านเมตริกต่อนาทีให้เรา นั่นคือตอนที่ระบบย่อยของดิสก์รัดกุมขึ้น และเราเห็นการใช้งาน 100% ปัญหาได้รับการแก้ไขอย่างรวดเร็วแต่ยังมีสารตกค้างอยู่

2. ขาดการจำลองแบบและความสม่ำเสมอ

เป็นไปได้มาก เช่นเดียวกับทุกคนที่ใช้/ใช้ Graphite+Whisper เราได้เทสตรีมของตัววัดเดียวกันลงบนเซิร์ฟเวอร์ Graphite หลายเครื่องพร้อมกันเพื่อสร้างความทนทานต่อข้อผิดพลาด และไม่มีปัญหาพิเศษใด ๆ ในเรื่องนี้ - จนกระทั่งถึงช่วงเวลาที่เซิร์ฟเวอร์ตัวใดตัวหนึ่งขัดข้องด้วยเหตุผลบางประการ บางครั้งเราสามารถจัดการเซิร์ฟเวอร์ที่ล่มได้เร็วเพียงพอ และ carbon-c-relay ก็สามารถโหลดตัววัดจากแคชลงไปได้ แต่บางครั้งก็ไม่เป็นเช่นนั้น และยังมีช่องโหว่ในหน่วยเมตริก ซึ่งเราเติมด้วย rsync ขั้นตอนค่อนข้างยาว พระคุณที่ช่วยให้รอดเพียงอย่างเดียวก็คือสิ่งนี้เกิดขึ้นน้อยมาก นอกจากนี้เรายังสุ่มชุดเมตริกเป็นระยะๆ และเปรียบเทียบกับเมตริกอื่นๆ ที่เป็นประเภทเดียวกันบนโหนดข้างเคียงของคลัสเตอร์ ในกรณีประมาณ 5% ค่านิยมหลายประการมีความแตกต่างกัน ซึ่งเราไม่ค่อยพอใจนัก

3. รอยเท้าขนาดใหญ่

เนื่องจากเราเขียนใน Graphite ไม่เพียงแต่โครงสร้างพื้นฐานเท่านั้น แต่ยังรวมไปถึงการวัดทางธุรกิจด้วย (และตอนนี้ก็มีการวัดจาก Kubernetes ด้วย) เรามักจะได้รับสถานการณ์ที่การวัดมีค่าเพียงไม่กี่ค่า และไฟล์ .wsp ถูกสร้างขึ้นโดยคำนึงถึงการเก็บรักษาทั้งหมด และใช้พื้นที่ตามจำนวนที่จัดสรรไว้ล่วงหน้า ซึ่งสำหรับเราคือ ~2MB ปัญหายังรุนแรงขึ้นอีกจากความจริงที่ว่ามีไฟล์ที่คล้ายกันจำนวนมากปรากฏขึ้นเมื่อเวลาผ่านไป และเมื่อสร้างรายงานเกี่ยวกับไฟล์เหล่านั้น การอ่านจุดว่างต้องใช้เวลาและทรัพยากรจำนวนมาก

ฉันต้องการทราบทันทีว่าปัญหาที่อธิบายไว้ข้างต้นสามารถจัดการได้โดยใช้วิธีการต่างๆ และมีระดับประสิทธิผลที่แตกต่างกัน แต่ยิ่งคุณเริ่มได้รับข้อมูลมากเท่าไรก็ยิ่งแย่ลงเท่านั้น

มีทุกสิ่งที่กล่าวมา (โดยคำนึงถึงสิ่งก่อนหน้า บทความ) เช่นเดียวกับการเพิ่มจำนวนเมตริกที่ได้รับอย่างต่อเนื่อง ความปรารถนาที่จะถ่ายโอนเมตริกทั้งหมดไปยังช่วงเวลาการจัดเก็บ 30 วินาที (สูงสุด 10 วินาทีหากจำเป็น) เราตัดสินใจลองใช้ Graphite+ClickHouse เป็นทางเลือกที่มีแนวโน้มแทน Whisper

กราไฟท์+คลิกเฮาส์. ความคาดหวัง

หลังจากได้ไปเยี่ยมเยียนการพบปะของหนุ่ม ๆ จากยานเดกซ์หลายครั้งเมื่อได้อ่าน บทความสองสามเรื่องเกี่ยวกับHabréหลังจากที่ได้อ่านเอกสารประกอบและพบส่วนประกอบที่เหมาะสมสำหรับการเชื่อมโยง ClickHouse ภายใต้ Graphite เราจึงตัดสินใจดำเนินการ!

ฉันต้องการรับสิ่งต่อไปนี้:

  • ลดการใช้ระบบย่อยของดิสก์จาก 30% เป็น 5%
  • ลดจำนวนพื้นที่ว่างจาก 1TB เป็น 100GB
  • สามารถรับ 100 ล้านเมตริกต่อนาทีเข้าสู่เซิร์ฟเวอร์
  • การจำลองข้อมูลและความทนทานต่อข้อผิดพลาดนอกกรอบ
  • อย่านั่งในโครงการนี้เป็นเวลาหนึ่งปีและทำการเปลี่ยนแปลงภายในกรอบเวลาที่เหมาะสม
  • สลับโดยไม่ต้องหยุดทำงาน

ค่อนข้างทะเยอทะยานใช่ไหม?

กราไฟท์+คลิกเฮาส์. ส่วนประกอบ

ฉันเลือกเพื่อรับข้อมูลผ่านโปรโตคอล Graphite แล้วบันทึกใน ClickHouse คาร์บอนคลิกเฮาส์ (โกลัง).

ClickHouse รุ่นล่าสุด เวอร์ชันเสถียร 1.1.54253 ได้รับเลือกให้เป็นฐานข้อมูลสำหรับจัดเก็บอนุกรมเวลา มีปัญหาเมื่อทำงานกับมัน: มีข้อผิดพลาดมากมายหลั่งไหลเข้ามาในบันทึกและยังไม่ชัดเจนว่าจะทำอย่างไรกับพวกเขา ในการหารือกับ โรมัน โลโมโนซอฟ (ผู้เขียน carbon-clickhouse, Graphite-clickhouse และอื่นๆ อีกมากมาย) เลือกอันที่เก่ากว่า ปล่อย 1.1.54236. ข้อผิดพลาดหายไป - ทุกอย่างเริ่มทำงานอย่างปัง

เลือกอ่านข้อมูลจาก ClickHouse กราไฟท์-сlickhouse (โกลัง). เป็น API สำหรับกราไฟท์ - คาร์โบนาปี (โกลัง). ClickHouse ใช้เพื่อจัดระเบียบการจำลองระหว่างตาราง ผู้ดูแลสวนสัตว์. สำหรับการวัดเส้นทางเราทิ้งสิ่งที่เรารักไว้ คาร์บอน-c-รีเลย์ (C) (ดูบทความก่อนหน้า).

กราไฟท์+คลิกเฮาส์. โครงสร้างตาราง

“กราไฟท์” คือฐานข้อมูลที่เราสร้างขึ้นสำหรับการตรวจสอบตาราง

“graphite.metrics” - ตารางที่มีกลไก ReplicatedReplacingMergeTree (จำลองแบบ การแทนที่ MergeTree). ตารางนี้จะจัดเก็บชื่อของเมตริกและเส้นทางไปยังเมตริกเหล่านั้น

CREATE TABLE graphite.metrics ( Date Date, Level UInt32, Path String, Deleted UInt8, Version UInt32 ) ENGINE = ReplicatedReplacingMergeTree('/clickhouse/tables/replicator/graphite.metrics', ‘r1’, Date, (Level, Path), 8192, Version);

“graphite.data” - ตารางที่มีกลไก ReplicatedGraphiteMergeTree (จำลองแบบ .data) GraphiteMergeTree). ตารางนี้เก็บค่าเมตริก

CREATE TABLE graphite.data ( Path String, Value Float64, Time UInt32, Date Date, Timestamp UInt32 ) ENGINE = ReplicatedGraphiteMergeTree('/clickhouse/tables/replicator/graphite.data', 'r1', Date, (Path, Time), 8192, 'graphite_rollup')

“graphite.date_metrics” เป็นตารางที่เติมตามเงื่อนไขด้วยกลไก ReplicatedReplacingMergeTree ตารางนี้จะบันทึกชื่อของตัวชี้วัดทั้งหมดที่พบในระหว่างวัน เหตุผลในการสร้างได้อธิบายไว้ในส่วนนี้ "ปัญหา" ในตอนท้ายของบทความนี้

CREATE MATERIALIZED VIEW graphite.date_metrics ( Path String,  Level UInt32,  Date Date) ENGINE = ReplicatedReplacingMergeTree('/clickhouse/tables/replicator/graphite.date_metrics', 'r1', Date, (Level, Path, Date), 8192) AS SELECT toUInt32(length(splitByChar('.', Path))) AS Level, Date, Path FROM graphite.data

“graphite.data_stat” - ตารางที่กรอกข้อมูลตามเงื่อนไข ด้วยกลไก ReplicatedAggregatingMergeTree (จำลองแบบ การรวมตัวผสานต้นไม้). ตารางนี้จะบันทึกจำนวนเมตริกขาเข้า โดยแบ่งออกเป็น 4 ระดับที่ซ้อนกัน

CREATE MATERIALIZED VIEW graphite.data_stat ( Date Date,  Prefix String,  Timestamp UInt32,  Count AggregateFunction(count)) ENGINE = ReplicatedAggregatingMergeTree('/clickhouse/tables/replicator/graphite.data_stat', 'r1', Date, (Timestamp, Prefix), 8192) AS SELECT toStartOfMonth(now()) AS Date, replaceRegexpOne(Path, '^([^.]+.[^.]+.[^.]+).*$', '1') AS Prefix, toUInt32(toStartOfMinute(toDateTime(Timestamp))) AS Timestamp, countState() AS Count FROM graphite.data  GROUP BY Timestamp, Prefix

กราไฟท์+คลิกเฮาส์. แผนภาพปฏิสัมพันธ์ส่วนประกอบ

พื้นที่เก็บข้อมูลเมตริก: วิธีที่เราเปลี่ยนจาก Graphite+Whisper เป็น Graphite+ClickHouse

กราไฟท์+คลิกเฮาส์. การโยกย้ายข้อมูล

ดังที่เราจำได้จากความคาดหวังจากโปรเจ็กต์นี้ การเปลี่ยนไปใช้ ClickHouse ควรไม่มีการหยุดทำงาน ดังนั้น เราจึงต้องเปลี่ยนระบบการตรวจสอบทั้งหมดของเราไปยังพื้นที่เก็บข้อมูลใหม่ให้โปร่งใสที่สุดสำหรับผู้ใช้ของเรา
นี่คือวิธีที่เราทำมัน

  • มีการเพิ่มกฎลงใน carbon-c-relay เพื่อส่งสตรีมของการวัดเพิ่มเติมไปยัง carbon-clickhouse ของหนึ่งในเซิร์ฟเวอร์ที่เข้าร่วมในการจำลองแบบของตาราง ClickHouse

  • เราเขียนสคริปต์เล็กๆ ด้วยภาษา python ซึ่งอ่านไฟล์ .wsp ทั้งหมดจากที่จัดเก็บข้อมูลของเรา และส่งข้อมูลนี้ไปยัง carbon-clickhouse ที่ได้อธิบายไว้ข้างต้นใน 24 เธรดโดยใช้ไลบรารี่Whisper-dump จำนวนค่าเมตริกที่ยอมรับใน Carbon-Clickhouse สูงถึง 125 ล้าน/นาที และ ClickHouse ก็ไม่ทำให้เหนื่อยแม้แต่น้อย

  • เราสร้างแหล่งข้อมูลแยกต่างหากใน Grafana เพื่อดีบักฟังก์ชันที่ใช้ในแดชบอร์ดที่มีอยู่ เราระบุรายการฟังก์ชันที่เราใช้ แต่ไม่ได้นำไปใช้ใน carbonapi เราได้เพิ่มฟังก์ชันเหล่านี้และส่ง PR ไปยังผู้เขียน carbonapi (ขอขอบคุณเป็นพิเศษ)

  • หากต้องการสลับโหลดการอ่านในการตั้งค่าบาลานเซอร์ เราได้เปลี่ยนจุดสิ้นสุดจาก graphite-api (อินเทอร์เฟซ API สำหรับ Graphite+Whisper) เป็น carbonapi

กราไฟท์+คลิกเฮาส์. ผลลัพธ์

  • ลดการใช้ระบบย่อยของดิสก์จาก 30% เป็น 1%;

    พื้นที่เก็บข้อมูลเมตริก: วิธีที่เราเปลี่ยนจาก Graphite+Whisper เป็น Graphite+ClickHouse

  • ลดจำนวนพื้นที่ว่างจาก 1 TB เป็น 300 GB
  • เรามีความสามารถในการรับ 125 ล้านเมตริกต่อนาทีเข้าสู่เซิร์ฟเวอร์ (สูงสุด ณ เวลาที่ย้าย)
  • ถ่ายโอนตัวชี้วัดทั้งหมดไปยังช่วงเวลาการจัดเก็บสามสิบวินาที
  • ได้รับการจำลองข้อมูลและความทนทานต่อข้อผิดพลาด
  • สลับโดยไม่ต้องหยุดทำงาน
  • ใช้เวลาประมาณ 7 สัปดาห์ในการทำทุกอย่างให้เสร็จสิ้น

กราไฟท์+คลิกเฮาส์. ปัญหา

ในกรณีของเรา มีข้อผิดพลาดอยู่บ้าง นี่คือสิ่งที่เราพบหลังจากการเปลี่ยนแปลง

  1. ClickHouse ไม่ได้อ่านการกำหนดค่าซ้ำทันทีเสมอไป บางครั้งจำเป็นต้องรีบูต ตัวอย่างเช่น ในกรณีของคำอธิบายของคลัสเตอร์ผู้ดูแลสวนสัตว์ในการกำหนดค่า ClickHouse จะไม่ถูกใช้จนกว่าจะรีบูตเซิร์ฟเวอร์คลิกเฮาส์
  2. คำขอ ClickHouse ขนาดใหญ่ไม่ผ่าน ดังนั้นใน Graphite-Clickhouse สตริงการเชื่อมต่อ ClickHouse ของเราจึงมีลักษณะดังนี้:
    url = "http://localhost:8123/?max_query_size=268435456&max_ast_elements=1000000"
  3. ClickHouse ค่อนข้างจะออกเวอร์ชันเสถียรเวอร์ชันใหม่ๆ บ่อยครั้ง ซึ่งอาจมีเรื่องเซอร์ไพรส์ โปรดใช้ความระมัดระวัง
  4. คอนเทนเนอร์ที่สร้างขึ้นแบบไดนามิกใน kubernetes จะส่งตัววัดจำนวนมากโดยมีอายุการใช้งานสั้นและสุ่ม เมตริกดังกล่าวมีคะแนนไม่มาก และไม่มีปัญหาเรื่องพื้นที่ แต่เมื่อสร้างข้อความค้นหา ClickHouse จะเลือกเมตริกเดียวกันนี้จำนวนมากจากตาราง 'เมตริก' ใน 90% ของกรณี ไม่มีข้อมูลอยู่นอกหน้าต่าง (24 ชั่วโมง) แต่จะใช้เวลาในการค้นหาข้อมูลนี้ในตาราง 'ข้อมูล' และในที่สุดก็หมดเวลา เพื่อแก้ไขปัญหานี้ เราเริ่มรักษามุมมองแยกต่างหากพร้อมข้อมูลเกี่ยวกับตัวชี้วัดที่พบในระหว่างวัน ดังนั้น เมื่อสร้างรายงาน (กราฟ) สำหรับคอนเทนเนอร์ที่สร้างขึ้นแบบไดนามิก เราจะสืบค้นเฉพาะตัวชี้วัดที่พบในหน้าต่างที่กำหนดเท่านั้น ไม่ใช่ตลอดเวลา ซึ่งทำให้การสร้างรายงานเร็วขึ้นอย่างมาก สำหรับวิธีแก้ปัญหาที่อธิบายไว้ข้างต้น ฉันรวบรวมไว้ กราไฟท์คลิกเฮาส์ (ส้อม)ซึ่งรวมถึงการใช้งานการทำงานกับตาราง date_metrics

กราไฟท์+คลิกเฮาส์. แท็ก

ด้วยเวอร์ชัน 1.1.0 Graphite อย่างเป็นทางการ แท็กสนับสนุน. และเรากำลังคิดอย่างจริงจังว่าจะทำอะไรและอย่างไรเพื่อสนับสนุนความคิดริเริ่มนี้ในสแต็กกราไฟท์+คลิกเฮาส์

กราไฟท์+คลิกเฮาส์. เครื่องตรวจจับความผิดปกติ

จากโครงสร้างพื้นฐานที่อธิบายไว้ข้างต้น เราได้นำต้นแบบของเครื่องตรวจจับความผิดปกติไปใช้ และใช้งานได้! แต่มีข้อมูลเพิ่มเติมเกี่ยวกับเขาในบทความถัดไป

สมัครสมาชิกกดลูกศรขึ้นแล้วมีความสุข!

ที่มา: will.com

เพิ่มความคิดเห็น