• LogHouse ภายในของ ClickHouse เติบโตจาก 19PiB และราว 40 ล้านล้านแถวใน 1 ปี เป็นการจัดเก็บล็อกแบบไม่บีบอัดมากกว่า 100PB และเกือบ 500 ล้านล้านแถว
  • เส้นทางการเก็บข้อมูลเดิมที่มี OpenTelemetry เป็นศูนย์กลางสลับไปมาระหว่าง JSON, ฟอร์แมต OTel และฟอร์แมต ClickHouse Native ทำให้ ต้นทุน CPU และความเสี่ยงที่ล็อกจะถูกทิ้งเพิ่มขึ้น
  • ClickHouse ใช้ SysEx(System Tables Exporter) คัดลอกตารางระบบไปยัง LogHouse แบบ ระดับไบต์ ประมวลผล 37M logs/s ด้วย CPU 70 คอร์
  • OTel ยังคงมีประโยชน์สำหรับล็อกความขัดข้องที่อิง stdout·stderr และ ฟอร์แมตมาตรฐานที่ไม่ผูกกับผู้ขาย แต่ telemetry หลักของ ClickHouse กำลังย้ายไปเน้น SysEx และ wide events
  • หลังนำ HyperDX มาใช้ กำลังผสาน UI แบบ ClickHouse native, การค้นหาด้วยไวยากรณ์ Lucene, การวิเคราะห์ด้วย SQL และการสำรวจที่ไม่ขึ้นกับสคีมา เพื่อแทนที่บทบาทบางส่วนของ UI แบบกำหนดเองที่อิง Grafana

LogHouse เติบโตถึงระดับ 100PB และ 500 ล้านล้านแถว

  • LogHouse เป็นแพลตฟอร์ม logging ภายในที่สร้างขึ้นเพื่อมอนิเตอร์ ClickHouse Cloud และก่อนหน้านี้ยังทำหน้าที่แทนที่ค่าใช้จ่าย Datadog ที่เพิ่มขึ้นด้วย
  • เมื่อ 1 ปีก่อน รองรับข้อมูลไม่บีบอัด 19PiB และ 37 ล้านล้านแถว ปัจจุบันจัดเก็บข้อมูลไม่บีบอัด มากกว่า 100PB และเกือบ 500 ล้านล้านแถว
  • องค์ประกอบหลักของข้อมูลที่จัดเก็บในปัจจุบันมีดังนี้
    • SysEx: 93.6PB, 431 ล้านล้านแถว
    • OTel: 14.5PB, 16.7 ล้านล้านแถว
  • ก่อนหน้านี้ telemetry ทั้งหมดผ่าน OpenTelemetry แต่ตอนนี้ข้อมูลส่วนใหญ่เข้ามาจาก SysEx ซึ่งเป็น exporter เฉพาะทางที่ ClickHouse สร้างขึ้น

ข้อจำกัดของ OpenTelemetry pipeline

  • OpenTelemetry เหมาะเป็น pipeline มาตรฐานเริ่มต้น สำหรับส่งล็อกของทุก Pod ในสภาพแวดล้อม Kubernetes ไปยัง ClickHouse
  • ล็อกข้อความ stdout ของ ClickHouse เพียงอย่างเดียวไม่เพียงพอสำหรับการวิเคราะห์เชิงปฏิบัติการ และการวิเคราะห์จริงต้องใช้ล็อกแบบมีโครงสร้าง, เมตริก, รายละเอียดการรัน, disk I/O และสถานะงานเบื้องหลังจากตาราง system
  • เส้นทางล็อก OTel เดิมผ่านหลายขั้นตอนการแปลง
    • อินสแตนซ์ ClickHouse ของลูกค้าเขียนล็อกเป็น JSON ไปยัง stdout
    • kubelet เก็บล็อกไว้ที่ /var/log/…
    • OTel collector อ่านล็อกจากดิสก์ แล้ว parse JSON แปลงเป็น representation ในหน่วยความจำ
    • collector แปลงสิ่งนี้กลับเป็นฟอร์แมตล็อก OTel
    • ClickHouse Go client แปลงอีกครั้งเป็นฟอร์แมต ClickHouse Native แล้ว insert เข้า LogHouse
  • ในทางปฏิบัติ OTel pipeline ยังรวม edge collector, การส่งผ่าน OTLP, gateway collector และการประมวลผลเพิ่มเติม ทำให้แต่ละขั้นเพิ่ม overhead·latency·complexity
  • เมื่อสเกลใหญ่ขึ้น ปัญหา 2 อย่างเด่นชัดขึ้น
    • ประเภท ClickHouse Native ต้องผ่าน JSON และฟอร์แมต OTel ทำให้เปลือง CPU และความครบถ้วนของข้อมูลลดลง
    • OTel agent บนโหนด Kubernetes ติดขีดจำกัด CPU·หน่วยความจำ และทิ้งบรรทัดล็อกเมื่อทราฟฟิกพุ่งสูง
  • คาดว่าหากจะประมวลผล 20M rows/s ด้วย OTel โดยไม่สูญเสียข้อมูล จะต้องใช้ประมาณ 8,000 CPU cores ทั่วทั้ง agent และ collector

SysEx: collector ที่ปรับมาเฉพาะสำหรับการส่ง ClickHouse-to-ClickHouse

  • ClickHouse สร้าง System Tables Exporter(SysEx) เพื่อส่งข้อมูลโดยตรงจากตารางระบบ ClickHouse ใน Pod ของลูกค้าไปยังตาราง LogHouse
  • SysEx ทำ การคัดลอกระดับไบต์ ระหว่างต้นทางและปลายทาง จึงรักษาประเภท ClickHouse Native และตัดการแปลงกลางทางออก
  • ด้วยโครงสร้างนี้ วิศวกรสามารถเปลี่ยนคิวรีที่เคยใช้ดีบัก live instance ให้กลายเป็นคิวรีข้อมูลย้อนหลังของ fleet ทั้งหมดใน LogHouse ได้ง่าย
    • สคีมาตารางเหมือนกัน และเพิ่มเพียงคอลัมน์ enrichment เช่นชื่อ Pod และเวอร์ชัน ClickHouse
  • สถาปัตยกรรมประกอบด้วย pool ของ SysEx scraper และ hash ring
    • hash ring จัดสรร Pod ของลูกค้าให้กับ scraper replica เฉพาะเพื่อกระจายโหลด
    • scraper รัน SELECT บน system table ของ Pod ต้นทาง แล้ว stream ข้อมูลไปยัง LogHouse
    • scraper ประสานการส่งต่อไบต์ระหว่างต้นทางและปลายทางโดยไม่ deserialize
  • เพื่อเลี่ยงการพลาด buffer flush ของตารางระบบ SysEx ใช้ sliding time window และโดยทั่วไปจะคิวรีช้ากว่า realtime 5 นาที
  • พฤติกรรมเริ่มต้นของ Go ClickHouse client คือแปลงข้อมูลเป็น Go native type ดังนั้น ClickHouse จึง contribute ฟีเจอร์ เพื่อข้าม internal marshalling ไปยัง clickhouse-go
  • SysEx เป็นโมเดลแบบ pull จึงไม่ต้องใช้ buffering หนักเหมือน OTel และหาก LogHouse ใช้งานไม่ได้ชั่วคราวหรือ telemetry ต้นทางเพิ่มขึ้นฉับพลัน ก็สามารถ scrape window ย้อนหลังเพื่อ backfill ได้

สคีมาแบบไดนามิกและ snapshot ของสถานะ

  • SysEx ต้องให้สคีมาต้นทางและเป้าหมายตรงกัน แต่สคีมาของ ClickHouse system table เปลี่ยนบ่อยจากการเพิ่มเมตริกและคอลัมน์ใหม่
  • เพื่อจัดการเรื่องนี้ เมื่อ SysEx พบ system table จะตรวจสอบสคีมาและ hash จากนั้นตรวจว่ามีตารางสคีมาเดียวกันใน LogHouse หรือไม่
    • ถ้ามี จะ insert ลงตารางเดิม
    • ถ้าไม่มี จะสร้าง เวอร์ชันสคีมา ใหม่ เช่น text_log_6
  • ตอนคิวรี ใช้ Merge table engine ของ ClickHouse เพื่อรวมสคีมาหลายรุ่นให้เป็น logical view เดียว
  • Merge table engine เลือกเฉพาะคอลัมน์ที่เข้ากันได้ หรือจำกัดคิวรีไว้เฉพาะตารางที่มีคอลัมน์ที่ขอ ทำให้ค้นดูได้แม้สคีมาเปลี่ยนโดยไม่ต้องจัดการเอง
  • ClickHouse ยังจับ in-memory system table เช่น system.processes เป็น snapshot เป็นระยะและเก็บไว้ใน LogHouse
  • snapshot เหล่านี้ใช้วิเคราะห์สถานะคลัสเตอร์, สคีมาตาราง และการตั้งค่าคลัสเตอร์ ณ เวลาใดเวลาหนึ่งย้อนหลัง

การวิเคราะห์ทั้ง fleet และตัวเลขประสิทธิภาพ

  • ด้วย SysEx ลูกค้าสามารถรัน Advanced Dashboard queries ที่ใช้มอนิเตอร์อินสแตนซ์ ClickHouse รายตัว พร้อมกันบน fleet อินสแตนซ์ลูกค้าทั้งหมดได้
  • ในการวิเคราะห์ release จะรันคิวรีวินิจฉัยก่อนและหลัง deploy เพื่อตรวจสอบรูปแบบประสิทธิภาพคิวรี แนวโน้มการใช้ทรัพยากร และการเปลี่ยนแปลงอัตราข้อผิดพลาดแบบ realtime ในระดับ fleet
  • support dashboard ทำ correlation analysis ระหว่าง Advanced Dashboard queries กับล็อกเครือข่าย, Kubernetes events, data plane·control plane events ในอินเทอร์เฟซเดียวกัน
  • การเปรียบเทียบประสิทธิภาพตาม LogHouse มีดังนี้
    • OTel Collectors: ส่ง 2M logs/s ด้วย CPU cores มากกว่า 800
    • LogHouse Scrapers(SysEx): ส่ง 37M logs/s ด้วย CPU 70 คอร์
  • SysEx เพิ่มปริมาณ event จากแหล่งข้อมูลที่สำคัญที่สุดขึ้น 20 เท่า พร้อมลด CPU footprint เหลือน้อยกว่า 10% ของเดิม และทำให้ไม่ทิ้ง event ที่ edge

พื้นที่ที่ OpenTelemetry ยังจำเป็น

  • OpenTelemetry ยังคงเป็นตัวเลือกเริ่มต้นของ ClickStack เพราะให้ ฟอร์แมตมาตรฐานที่ไม่ผูกกับผู้ขาย และประสบการณ์ onboarding สำหรับผู้ใช้ใหม่
  • SysEx ผูกกับภายใน ClickHouse อย่างแน่นหนา และเป็นโครงสร้างแบบ pull ที่คิวรี live system table ดังนั้นหากบริการอยู่ใน crash loop หรือ down จะไม่สามารถ scrape ข้อมูลได้
  • OpenTelemetry จับล็อกที่ emit ไปยัง stdout และ stderr แบบ passive จึงเก็บล็อกระหว่างเกิดปัญหาได้แม้บริการจะไม่ได้อยู่ในสถานะ healthy อย่างสมบูรณ์
  • ClickHouse ยังคงรัน OpenTelemetry ในทุกบริการ ClickHouse แต่เปลี่ยนขอบเขตการเก็บข้อมูล
    • ก่อนหน้านี้ ingest ทั้งหมดจนถึง trace-level logs
    • ปัจจุบันเก็บเฉพาะ info-level ขึ้นไป
  • หลังการเปลี่ยนแปลงนี้ OTel collector และ gateway ทำงานด้วยทรัพยากรน้อยลงมาก และคงอยู่เป็น pipeline ที่เล็กลงในระดับ 2M log lines/s ตามที่กล่าวไว้ข้างต้น

HyperDX และประสบการณ์สำรวจแบบ ClickHouse native

  • UI แรกของ LogHouse เป็นประสบการณ์ observability แบบกำหนดเองที่สร้างบน Grafana แต่เมื่อ SysEx และ wide-column telemetry เพิ่มขึ้น ก็ต้องการ UI ที่ผสานกับ ClickHouse ลึกขึ้น
  • HyperDX เป็น UI แบบ ClickHouse native ที่รองรับการสำรวจล็อก·trace, correlation analysis และการวิเคราะห์ขนาดใหญ่
  • สามารถคิวรีด้วยไวยากรณ์ Lucene ทำให้การสำรวจข้อมูลง่ายขึ้น และยังใช้ SQL ต่อไปได้สำหรับการวิเคราะห์ event ที่ซับซ้อน
  • แนวทางที่ไม่ขึ้นกับสคีมา ของ HyperDX v2.0 ไม่บังคับโครงสร้างตารางล็อกแบบคงที่เพียงชุดเดียว
    • จัดการฟอร์แมตข้อมูลของ OpenTelemetry pipeline ที่เป็นมาตรฐานแต่เปลี่ยนแปลงได้
    • จัดการ specialized wide-column table จาก SysEx และ custom exporter อื่นได้โดยไม่ต้องรู้สคีมาล่วงหน้าหรือใช้ grok pattern ที่ซับซ้อน
  • Grafana ยังมีบทบาทใน LogHouse
    • แอปภายในที่อิง Grafana ให้ระบุ namespace เพื่อรู้ตำแหน่งข้อมูลของแต่ละบริการและ route คิวรีไปยังอินสแตนซ์ ClickHouse ที่เหมาะสม
    • dashboard และ alert เดิมที่อิง Prometheus metrics ยังคงอยู่ใน Grafana
    • เมตริกระดับสูงอย่าง kube_state_metrics แม้ไม่เหมาะกับ deep investigation แต่เหมาะกับ alerting

Wide events และ observability แบบ high-cardinality

  • การนำ SysEx มาใช้ทำให้เปลี่ยนจากการเก็บข้อมูลที่เน้น stdout logs ไปเป็นโมเดลที่เน้น wide events ที่อิง system table และข้อมูล high-cardinality
  • ClickHouse เรียกสิ่งนี้ว่าการผสาน LogHouse กับ ClickStack แทน Observability 2.0
  • โมเดลนี้เก็บ high-cardinality telemetry จากหลายแหล่งไว้ใน warehouse กลาง แทนโมเดลสามเสาหลักแบบดั้งเดิม
  • แต่ละ row มี context จำนวนมาก เช่น query identifier, ชื่อ Pod, version metadata, network detail และไม่ pre-aggregate หรือทิ้ง dimension เพื่อให้เข้ากับข้อจำกัดของ metric store
  • ไม่สรุปข้อมูลตอน ingest แต่เก็บต้นฉบับไว้ตามเดิม แล้วเลื่อน aggregation ไปทำที่ query time
  • ความแตกต่างจาก Prometheus คือเก็บทุก data point
    • ฟิลด์อย่าง insertDuration จะไม่ถูก pre-aggregate แต่เก็บค่าแต่ละค่าพร้อม dimension ที่เกี่ยวข้อง
    • หากเก็บ timeseries ของทุก label combination ใน Prometheus จะเกิด cardinality explosion
    • histogram pre-aggregation ช่วยควบคุมการใช้ทรัพยากร แต่ทำให้ถามได้ยากว่า spike เฉพาะหนึ่งเกิดจาก insert ของ instance, table, time window ใด
  • Elasticsearch ก็สนับสนุน wide events และโครงสร้าง document ที่ยืดหยุ่น แต่ columnar design ของ ClickHouse ทำให้จัดเก็บและคิวรีข้อมูล event ปริมาณสูง·คาร์ดินาลิตีสูงได้อย่างมีประสิทธิภาพในสเกลใหญ่

เครื่องมือ data science และการวิเคราะห์ด้วย SQL

  • สามารถ visualize คุณลักษณะหลายอย่างจาก wide event หนึ่งรายการ และย้อนจากจุดเฉพาะใน chart กลับไปยัง raw log ได้
  • ClickHouse มี data visualization integrations และ language clients จึงใช้เครื่องมือที่อิง SQL เช่น Plotly, Jupyter notebook, Hex, Bokeh, Evidence ได้
  • การค้นหาด้วยไวยากรณ์ Lucene ของ HyperDX เหมาะกับการ lookup และ filter อย่างรวดเร็ว แต่คำถามที่ซับซ้อนต้องใช้ SQL
  • ClickHouse SQL สามารถแสดง join, time-based operations และ transformation ได้
    • ตัวอย่างคือจับคู่ event Killing กับ event Created ของ container เดียวกันจาก Kubernetes event stream ด้วย ASOF JOIN เพื่อคำนวณเวลาตั้งแต่ถูก terminate จน restart
    • คิวรีตัวอย่างประมวลผล 17.78M rows และ 581.49MB ใช้เวลา 0.099 วินาที และ peak memory 272.88MiB
  • ไม่ต้องสร้างและ deploy metric ที่ต้องการไว้ล่วงหน้าเป็น component แต่สามารถ derive ได้ที่ query time จาก wide events warehouse

แหล่งข้อมูลที่เพิ่มเข้ามาใน LogHouse

  • LogHouse เพิ่ม data sink ที่อิง wide event มากขึ้นตามคำขอจากทีม engineering·support
  • kubenetmon: เครื่องมือโอเพนซอร์สสำหรับมอนิเตอร์เครือข่าย Kubernetes ใช้ Linux conntrack เพื่อจับ L3/L4 connection data และจำนวน byte·packet
    • ให้ metering สำหรับ forensics, workload·pod attribution และการติดตามต้นทุนอย่าง cross-region egress
    • โปรเจกต์: https://github.com/ClickHouse/kubenetmon
  • Kubernetes Event Exporter: fork exporter ยอดนิยมและเพิ่ม ClickHouse native sink เพื่อวิเคราะห์ Kubernetes API events ในสเกลใหญ่
    • fork: ClickHouse/kubernetes-event-exporter
    • ในอนาคตกำลังดำเนินแผนที่จะ ingest ไม่ใช่แค่ events แต่รวมถึง Kubernetes object model ทั้งหมดเข้า LogHouse และเก็บ snapshot ของทุกจุดเวลาที่มีการเปลี่ยนแปลง
  • Control Plane Data: เก็บข้อมูลปฏิบัติการของแผนก Control Plane ที่ยังไม่ได้ onboard เข้า LogHouse
  • Real User Monitoring(RUM): โปรเจกต์ที่กำลังดำเนินอยู่ ส่ง frontend performance metric จากเบราว์เซอร์ผู้ใช้ผ่าน public gateway ไปยัง OTel pipeline
  • Istio Access Log: ingest HTTP-level traffic data ของ Istio service mesh เพื่อจับ request·response pattern, latency และ routing decision
    • ผสานกับ system.query_log และ kubenetmon network flow เพื่อวิเคราะห์ข้าม SQL query, HTTP request และ packet flow

ขั้นถัดไป: zero-impact scraping และ JSON

  • SysEx scrape query ถูกจำกัดด้วย strict memory limit แต่ลูกค้าอาจกังวลเมื่อเห็นสิ่งนี้ในล็อกและเมตริก
  • ClickHouse กำลังสำรวจ zero-impact scraping ที่ไม่รันคิวรีบน live system
    • แนวทางที่ดูมีอนาคตคือใช้ plain rewritable disk บน S3 ที่ ClickHouse ใช้เขียน service log อยู่แล้ว
    • หาก SysEx worker pool mount disk-based log table โดยตรง ก็สามารถเลี่ยงการคิวรีอินสแตนซ์ ClickHouse ที่กำลังรันอยู่ได้
  • หากแนวทางนี้สำเร็จ จะรักษาข้อดีปัจจุบันอย่าง native format, high fidelity และการแปลงขั้นต่ำไว้ได้ พร้อมลดความกังวลเรื่องผลกระทบต่อการปฏิบัติการ
  • JSON type ของ ClickHouse ถึงสถานะ GA ใน 25.3 แล้ว โดยสร้างคอลัมน์ชนิดที่เหมาะสมแบบไดนามิกเมื่อมีฟิลด์ใหม่ และจัดการ ฟิลด์หลายประเภท กับ schema explosion ได้
  • LogHouse กำลังประเมินว่า JSON เหมาะกับรูปแบบการเข้าถึง observability ระดับใหญ่มากเพียงใด
    • หากค้นหาสตริงใน JSON blob ทั้งหมด อาจต้องสแกนคอลัมน์หลายพันคอลัมน์
    • มีทางเลี่ยงคือเก็บ raw string JSON ควบคู่กับ structured data
    • log·resource attribute ส่วนใหญ่มีขนาดเล็กและคงที่ ดังนั้น Map type ก็ยังเหมาะสม
    • HyperDX แปลง map access เป็นฟังก์ชัน JSONExtract โดยอัตโนมัติ

ยังไม่มีความคิดเห็น

ยังไม่มีความคิดเห็น