การวิเคราะห์ TSDB ในโพร 2

การวิเคราะห์ TSDB ในโพร 2

ฐานข้อมูลอนุกรมเวลา (TSDB) ใน Prometheus 2 เป็นตัวอย่างที่ยอดเยี่ยมของโซลูชันทางวิศวกรรมที่นำเสนอการปรับปรุงที่สำคัญเหนือพื้นที่จัดเก็บ v2 ใน Prometheus 1 ในแง่ของความเร็วในการสะสมข้อมูล การดำเนินการสืบค้น และประสิทธิภาพของทรัพยากร เรากำลังนำ Prometheus 2 ไปใช้งานใน Percona Monitoring and Management (PMM) และฉันได้มีโอกาสทำความเข้าใจประสิทธิภาพของ Prometheus 2 TSDB ในบทความนี้ ผมจะพูดถึงผลลัพธ์ของการสังเกตเหล่านี้

ปริมาณงาน Prometheus โดยเฉลี่ย

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

ทดสอบโหลด

ในระหว่างการทดสอบ ฉันมุ่งเน้นไปที่ความสามารถในการรวบรวมข้อมูล ฉันปรับใช้ Prometheus 2.3.2 ที่คอมไพล์ด้วย Go 1.10.1 (ซึ่งเป็นส่วนหนึ่งของ PMM 1.14) บนบริการ Linode โดยใช้สคริปต์นี้: StackScript. เพื่อการสร้างโหลดที่สมจริงที่สุด ใช้สิ่งนี้ StackScript ฉันเปิดตัวโหนด MySQL หลายโหนดที่มีโหลดจริง (การทดสอบ Sysbench TPC-C) ซึ่งแต่ละโหนดจำลองโหนด Linux/MySQL 10 โหนด
การทดสอบต่อไปนี้ทั้งหมดดำเนินการบนเซิร์ฟเวอร์ Linode ที่มีคอร์เสมือน 32 ตัวและหน่วยความจำ 20 GB โดยรันการจำลองโหลด 800 ตัวที่ตรวจสอบอินสแตนซ์ MySQL สองร้อยอินสแตนซ์ หรือในแง่ Prometheus เป้าหมาย 440 รายการ การบันทึกข้อมูล 380 รายการต่อวินาที บันทึก 1,7 รายการต่อวินาที และอนุกรมเวลาที่ใช้งานอยู่ XNUMX ล้านชุด

ออกแบบ

แนวทางปกติของฐานข้อมูลแบบดั้งเดิม รวมถึงฐานข้อมูลที่ใช้โดย Prometheus 1.x ก็คือ ขีดจำกัดหน่วยความจำ. หากไม่เพียงพอที่จะจัดการโหลด คุณจะพบกับเวลาแฝงที่สูง และคำขอบางรายการก็จะล้มเหลว การใช้งานหน่วยความจำใน Prometheus 2 สามารถกำหนดค่าได้ผ่านปุ่ม storage.tsdb.min-block-durationซึ่งกำหนดระยะเวลาที่การบันทึกจะถูกเก็บไว้ในหน่วยความจำก่อนที่จะล้างลงดิสก์ (ค่าเริ่มต้นคือ 2 ชั่วโมง) จำนวนหน่วยความจำที่ต้องการจะขึ้นอยู่กับจำนวนอนุกรมเวลา ป้ายกำกับ และส่วนที่เพิ่มในสตรีมขาเข้าสุทธิ ในแง่ของพื้นที่ดิสก์ Prometheus ตั้งเป้าที่จะใช้ 3 ไบต์ต่อบันทึก (ตัวอย่าง) ในทางกลับกัน ความต้องการหน่วยความจำจะสูงกว่ามาก

แม้ว่าจะสามารถกำหนดค่าขนาดบล็อกได้ แต่ไม่แนะนำให้กำหนดค่าด้วยตนเอง ดังนั้นคุณจึงถูกบังคับให้มอบหน่วยความจำให้ Prometheus เท่าที่จำเป็นสำหรับปริมาณงานของคุณ
หากมีหน่วยความจำไม่เพียงพอที่จะรองรับสตรีมของตัววัดที่เข้ามา Prometheus จะขาดหน่วยความจำหรือ OOM Killer จะเข้าถึงได้
การเพิ่มการสลับเพื่อชะลอการแครชเมื่อหน่วยความจำของ Prometheus ไม่เพียงพอไม่ได้ช่วยอะไรได้มากนัก เนื่องจากการใช้ฟังก์ชันนี้จะทำให้การใช้หน่วยความจำเพิ่มขึ้นอย่างมาก ฉันคิดว่ามันเกี่ยวข้องกับ Go คนเก็บขยะ และวิธีการจัดการกับการแลกเปลี่ยน
อีกวิธีที่น่าสนใจคือการกำหนดค่าเฮดบล็อกให้ถูกฟลัชลงดิสก์ ณ เวลาหนึ่ง แทนที่จะนับตั้งแต่เริ่มต้นกระบวนการ

การวิเคราะห์ TSDB ในโพร 2

ดังที่คุณเห็นจากกราฟ การฟลัชไปยังดิสก์จะเกิดขึ้นทุกๆ สองชั่วโมง หากคุณเปลี่ยนพารามิเตอร์ min-block-duration เป็นหนึ่งชั่วโมง การรีเซ็ตเหล่านี้จะเกิดขึ้นทุกชั่วโมง โดยเริ่มหลังจากผ่านไปครึ่งชั่วโมง
หากคุณต้องการใช้กราฟนี้และกราฟอื่นๆ ในการติดตั้ง Prometheus คุณสามารถใช้สิ่งนี้ได้ แผงควบคุม. ได้รับการออกแบบมาสำหรับ PMM แต่มีการปรับเปลี่ยนเล็กน้อย จึงเหมาะกับการติดตั้ง Prometheus ทุกรุ่น
เรามีบล็อกที่ใช้งานอยู่ที่เรียกว่า head block ซึ่งจัดเก็บไว้ในหน่วยความจำ บล็อกที่มีข้อมูลที่เก่ากว่านั้นมีให้ผ่านทาง mmap(). ซึ่งช่วยลดความจำเป็นในการกำหนดค่าแคชแยกต่างหาก แต่ยังหมายความว่าคุณจะต้องเหลือพื้นที่ว่างเพียงพอสำหรับแคชของระบบปฏิบัติการ หากคุณต้องการสืบค้นข้อมูลที่เก่ากว่าที่บล็อกหลักสามารถรองรับได้
นอกจากนี้ยังหมายความว่าการใช้หน่วยความจำเสมือนของ Prometheus จะดูค่อนข้างสูงซึ่งไม่ใช่เรื่องที่ต้องกังวล

การวิเคราะห์ TSDB ในโพร 2

จุดออกแบบที่น่าสนใจอีกจุดหนึ่งคือการใช้ WAL (บันทึกการเขียนล่วงหน้า) ดังที่คุณเห็นจากเอกสารประกอบการจัดเก็บข้อมูล Prometheus ใช้ WAL เพื่อหลีกเลี่ยงความล้มเหลว น่าเสียดายที่กลไกเฉพาะในการรับประกันความอยู่รอดของข้อมูลไม่ได้รับการบันทึกไว้อย่างดี Prometheus เวอร์ชัน 2.3.2 จะล้าง WAL ไปยังดิสก์ทุกๆ 10 วินาที และตัวเลือกนี้ไม่สามารถกำหนดค่าได้โดยผู้ใช้

การบดอัด

Prometheus TSDB ได้รับการออกแบบเหมือนกับร้านค้า LSM (Log Structured Merge) โดยบล็อกส่วนหัวจะถูกล้างลงดิสก์เป็นระยะๆ ในขณะที่กลไกการบดอัดจะรวมหลายบล็อกเข้าด้วยกันเพื่อหลีกเลี่ยงการสแกนบล็อกมากเกินไประหว่างการสืบค้น ที่นี่คุณสามารถดูจำนวนบล็อกที่ฉันสังเกตเห็นในระบบทดสอบหลังจากโหลดมาหนึ่งวัน

การวิเคราะห์ TSDB ในโพร 2

หากคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับร้านค้า คุณสามารถตรวจสอบไฟล์ meta.json ซึ่งมีข้อมูลเกี่ยวกับบล็อกที่มีอยู่และความเป็นมาของบล็อกเหล่านั้น

{
       "ulid": "01CPZDPD1D9R019JS87TPV5MPE",
       "minTime": 1536472800000,
       "maxTime": 1536494400000,
       "stats": {
               "numSamples": 8292128378,
               "numSeries": 1673622,
               "numChunks": 69528220
       },
       "compaction": {
               "level": 2,
               "sources": [
                       "01CPYRY9MS465Y5ETM3SXFBV7X",
                       "01CPYZT0WRJ1JB1P0DP80VY5KJ",
                       "01CPZ6NR4Q3PDP3E57HEH760XS"
               ],
               "parents": [
                       {
                               "ulid": "01CPYRY9MS465Y5ETM3SXFBV7X",
                               "minTime": 1536472800000,
                               "maxTime": 1536480000000
                       },
                       {
                               "ulid": "01CPYZT0WRJ1JB1P0DP80VY5KJ",
                               "minTime": 1536480000000,
                               "maxTime": 1536487200000
                       },
                       {
                               "ulid": "01CPZ6NR4Q3PDP3E57HEH760XS",
                               "minTime": 1536487200000,
                               "maxTime": 1536494400000
                       }
               ]
       },
       "version": 1
}

การบดอัดใน Prometheus จะเชื่อมโยงกับเวลาที่เฮดบล็อกถูกฟลัชลงดิสก์ ณ จุดนี้ การดำเนินการดังกล่าวหลายอย่างอาจดำเนินการได้

การวิเคราะห์ TSDB ในโพร 2

ดูเหมือนว่าการบดอัดไม่ได้ถูกจำกัดในทางใดทางหนึ่ง และอาจทำให้ I/O ของดิสก์มีขนาดใหญ่ขึ้นอย่างรวดเร็วระหว่างการดำเนินการ

การวิเคราะห์ TSDB ในโพร 2

โหลด CPU พุ่งสูงขึ้น

การวิเคราะห์ TSDB ในโพร 2

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

การวิเคราะห์ TSDB ในโพร 2

เราจะเห็นได้ว่าหลังจากการบีบอัดแล้ว หน่วยความจำส่วนใหญ่จะเปลี่ยนสถานะจาก Cached เป็น Free ได้อย่างไร ซึ่งหมายความว่าข้อมูลที่อาจมีค่าได้ถูกลบออกจากที่นั่นแล้ว อยากรู้ว่าที่นี่ใช้หรือเปล่า fadvice() หรือเทคนิคการย่อขนาดอื่น ๆ หรือเป็นเพราะแคชถูกปลดปล่อยจากบล็อกที่ถูกทำลายระหว่างการบดอัด?

การกู้คืนหลังจากความล้มเหลว

การฟื้นฟูจากความล้มเหลวต้องใช้เวลาและด้วยเหตุผลที่ดี สำหรับการสตรีมขาเข้าล้านบันทึกต่อวินาที ฉันต้องรอประมาณ 25 นาทีในขณะที่ทำการกู้คืนโดยคำนึงถึงไดรฟ์ SSD

level=info ts=2018-09-13T13:38:14.09650965Z caller=main.go:222 msg="Starting Prometheus" version="(version=2.3.2, branch=v2.3.2, revision=71af5e29e815795e9dd14742ee7725682fa14b7b)"
level=info ts=2018-09-13T13:38:14.096599879Z caller=main.go:223 build_context="(go=go1.10.1, user=Jenkins, date=20180725-08:58:13OURCE)"
level=info ts=2018-09-13T13:38:14.096624109Z caller=main.go:224 host_details="(Linux 4.15.0-32-generic #35-Ubuntu SMP Fri Aug 10 17:58:07 UTC 2018 x86_64 1bee9e9b78cf (none))"
level=info ts=2018-09-13T13:38:14.096641396Z caller=main.go:225 fd_limits="(soft=1048576, hard=1048576)"
level=info ts=2018-09-13T13:38:14.097715256Z caller=web.go:415 component=web msg="Start listening for connections" address=:9090
level=info ts=2018-09-13T13:38:14.097400393Z caller=main.go:533 msg="Starting TSDB ..."
level=info ts=2018-09-13T13:38:14.098718401Z caller=repair.go:39 component=tsdb msg="found healthy block" mint=1536530400000 maxt=1536537600000 ulid=01CQ0FW3ME8Q5W2AN5F9CB7R0R
level=info ts=2018-09-13T13:38:14.100315658Z caller=web.go:467 component=web msg="router prefix" prefix=/prometheus
level=info ts=2018-09-13T13:38:14.101793727Z caller=repair.go:39 component=tsdb msg="found healthy block" mint=1536732000000 maxt=1536753600000 ulid=01CQ78486TNX5QZTBF049PQHSM
level=info ts=2018-09-13T13:38:14.102267346Z caller=repair.go:39 component=tsdb msg="found healthy block" mint=1536537600000 maxt=1536732000000 ulid=01CQ78DE7HSQK0C0F5AZ46YGF0
level=info ts=2018-09-13T13:38:14.102660295Z caller=repair.go:39 component=tsdb msg="found healthy block" mint=1536775200000 maxt=1536782400000 ulid=01CQ7SAT4RM21Y0PT5GNSS146Q
level=info ts=2018-09-13T13:38:14.103075885Z caller=repair.go:39 component=tsdb msg="found healthy block" mint=1536753600000 maxt=1536775200000 ulid=01CQ7SV8WJ3C2W5S3RTAHC2GHB
level=error ts=2018-09-13T14:05:18.208469169Z caller=wal.go:275 component=tsdb msg="WAL corruption detected; truncating" err="unexpected CRC32 checksum d0465484, want 0" file=/opt/prometheus/data/.prom2-data/wal/007357 pos=15504363
level=info ts=2018-09-13T14:05:19.471459777Z caller=main.go:543 msg="TSDB started"
level=info ts=2018-09-13T14:05:19.471604598Z caller=main.go:603 msg="Loading configuration file" filename=/etc/prometheus.yml
level=info ts=2018-09-13T14:05:19.499156711Z caller=main.go:629 msg="Completed loading of configuration file" filename=/etc/prometheus.yml
level=info ts=2018-09-13T14:05:19.499228186Z caller=main.go:502 msg="Server is ready to receive web requests."

ปัญหาหลักของกระบวนการกู้คืนคือการใช้หน่วยความจำสูง แม้ว่าในสถานการณ์ปกติ เซิร์ฟเวอร์สามารถทำงานได้อย่างเสถียรด้วยหน่วยความจำจำนวนเท่ากัน แต่หากเกิดข้อขัดข้อง ก็อาจไม่สามารถกู้คืนได้เนื่องจาก OOM ทางออกเดียวที่ฉันพบคือปิดการใช้งานการรวบรวมข้อมูล เปิดเซิร์ฟเวอร์ ปล่อยให้มันกู้คืนและรีบูตโดยเปิดใช้งานการรวบรวมข้อมูล

อุ่นเครื่อง

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

การวิเคราะห์ TSDB ในโพร 2

การวิเคราะห์ TSDB ในโพร 2

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

โหลด CPU เพิ่มขึ้น

นอกเหนือจากการบีบอัดซึ่งสร้างโหลด I/O ที่ค่อนข้างสูงแล้ว ฉันยังสังเกตเห็นว่าโหลด CPU เพิ่มขึ้นอย่างรวดเร็วทุกๆ สองนาที การระเบิดจะนานขึ้นเมื่อกระแสอินพุตสูงและดูเหมือนว่าจะเกิดจากตัวรวบรวมขยะของ Go โดยมีคอร์อย่างน้อยบางส่วนถูกโหลดจนเต็ม

การวิเคราะห์ TSDB ในโพร 2

การวิเคราะห์ TSDB ในโพร 2

การกระโดดเหล่านี้ไม่ได้มีความสำคัญมากนัก ดูเหมือนว่าเมื่อสิ่งเหล่านี้เกิดขึ้น จุดเริ่มต้นภายในและตัววัดของ Prometheus จะไม่พร้อมใช้งาน ทำให้เกิดช่องว่างของข้อมูลในช่วงเวลาเดียวกันนี้

การวิเคราะห์ TSDB ในโพร 2

คุณยังสังเกตได้ว่าผู้ส่งออก Prometheus ปิดตัวลงหนึ่งวินาที

การวิเคราะห์ TSDB ในโพร 2

เราสามารถสังเกตความสัมพันธ์กับการเก็บขยะ (GC) ได้

การวิเคราะห์ TSDB ในโพร 2

ข้อสรุป

TSDB ใน Prometheus 2 นั้นรวดเร็ว สามารถจัดการอนุกรมเวลานับล้านรายการและในเวลาเดียวกันบันทึกหลายพันรายการต่อวินาทีโดยใช้ฮาร์ดแวร์ที่ค่อนข้างเรียบง่าย การใช้งาน CPU และดิสก์ I/O ก็น่าประทับใจเช่นกัน ตัวอย่างของฉันแสดงมากถึง 200 เมตริกต่อวินาทีต่อคอร์ที่ใช้

ในการวางแผนการขยาย คุณต้องจำเกี่ยวกับจำนวนหน่วยความจำที่เพียงพอ และต้องเป็นหน่วยความจำจริง จำนวนหน่วยความจำที่ใช้ที่ฉันสังเกตคือประมาณ 5 GB ต่อ 100 บันทึกต่อวินาทีของสตรีมขาเข้า ซึ่งเมื่อรวมกับแคชของระบบปฏิบัติการแล้ว จะให้หน่วยความจำว่างประมาณ 000 GB

แน่นอนว่า ยังมีงานอีกมากที่ต้องทำเพื่อลดการทำงานของ CPU และดิสก์ I/O และไม่น่าแปลกใจเมื่อพิจารณาว่า TSDB Prometheus 2 อายุน้อยเพียงใดเมื่อเปรียบเทียบกับ InnoDB, TokuDB, RocksDB, WiredTiger แต่ทั้งหมดมีความคล้ายคลึงกัน ปัญหาในช่วงแรกของวงจรชีวิต

ที่มา: will.com

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