Bioyino - ตัวรวบรวมเมตริกแบบกระจายและปรับขนาดได้

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

Bioyino - ตัวรวบรวมเมตริกแบบกระจายและปรับขนาดได้

จากบทความก่อนหน้านี้ของเรา (1, 2) คุณจะพบว่าจนกระทั่งบางครั้งเรารวบรวมเครื่องหมายโดยใช้ บรูเบค- เขียนเป็นภาษา C จากมุมมองของโค้ด มันง่ายเหมือนปลั๊ก (ซึ่งเป็นสิ่งสำคัญเมื่อคุณต้องการมีส่วนร่วม) และที่สำคัญที่สุดคือจัดการปริมาณ 2 ล้านเมตริกต่อวินาที (MPS) ของเราที่จุดสูงสุด โดยไม่มีปัญหาใดๆ เอกสารระบุการสนับสนุน MPS 4 ล้านโดยมีเครื่องหมายดอกจัน ซึ่งหมายความว่าคุณจะได้รับตัวเลขตามที่ระบุหากคุณกำหนดค่าเครือข่ายอย่างถูกต้องบน Linux (เราไม่ทราบว่าคุณจะได้รับ MPS ได้จำนวนเท่าใดหากคุณออกจากเครือข่ายเหมือนเดิม) แม้จะมีข้อได้เปรียบเหล่านี้ แต่เราก็มีข้อร้องเรียนร้ายแรงหลายประการเกี่ยวกับ brubeck

ข้อเรียกร้อง 1. Github ผู้พัฒนาโครงการ หยุดสนับสนุนแล้ว: การเผยแพร่แพตช์และการแก้ไข ยอมรับการประชาสัมพันธ์ของเราและ (ไม่ใช่แค่ของเราเท่านั้น) ในช่วงไม่กี่เดือนที่ผ่านมา (ในช่วงเดือนกุมภาพันธ์-มีนาคม 2018) กิจกรรมได้กลับมาดำเนินต่อ แต่ก่อนหน้านั้นเกือบ 2 ปีของความสงบอย่างสมบูรณ์ นอกจากนี้โครงการยังอยู่ระหว่างการพัฒนา สำหรับความต้องการภายในของ Gihubซึ่งอาจกลายเป็นอุปสรรคสำคัญในการแนะนำฟีเจอร์ใหม่ได้

ข้อเรียกร้อง 2. ความแม่นยำในการคำนวณ Brubeck รวบรวมค่าทั้งหมด 65536 ค่าสำหรับการรวม ในกรณีของเรา สำหรับตัวชี้วัดบางตัว ในช่วงระยะเวลาการรวม (30 วินาที) อาจมีค่าเข้ามามากขึ้น (1 ที่จุดสูงสุด) จากการสุ่มตัวอย่างนี้ค่าสูงสุดและต่ำสุดจึงดูไร้ประโยชน์ ตัวอย่างเช่นเช่นนี้:

Bioyino - ตัวรวบรวมเมตริกแบบกระจายและปรับขนาดได้
อย่างที่เป็นอยู่

Bioyino - ตัวรวบรวมเมตริกแบบกระจายและปรับขนาดได้
มันควรจะเป็นอย่างไร

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

และในที่สุด อ้างสิทธิ์ X- ในขณะที่เขียน เราพร้อมที่จะนำเสนอให้กับการใช้งานสถิติการทำงานทั้งหมด 14 รายการไม่มากก็น้อยที่เราพบ ลองจินตนาการว่าโครงสร้างพื้นฐานเดี่ยวบางส่วนเติบโตขึ้นมากจนการยอมรับ MPS 4 ล้านครั้งนั้นไม่เพียงพออีกต่อไป หรือแม้ว่าจะยังไม่เติบโต แต่ตัวชี้วัดก็มีความสำคัญสำหรับคุณอยู่แล้ว แม้แต่การที่กราฟตกลงไปเพียง 2-3 นาทีก็อาจกลายเป็นเรื่องสำคัญได้แล้ว และทำให้เกิดภาวะซึมเศร้าในหมู่ผู้จัดการที่ผ่านไม่ได้ เนื่องจากการรักษาอาการซึมเศร้าเป็นงานที่ไม่เห็นคุณค่า จึงจำเป็นต้องมีวิธีแก้ปัญหาทางเทคนิค

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

เนื่องจากเรามีพื้นที่สำหรับการปรับขนาด เราจึงตัดสินใจเริ่มต้นด้วยการทนทานต่อข้อผิดพลาด "เกี่ยวกับ! ความอดทนต่อความผิดพลาด! มันง่ายมาก เราทำได้” เราคิดและเปิดตัวเซิร์ฟเวอร์ 2 เครื่อง โดยสร้างสำเนาของ brubeck ไว้ในแต่ละเซิร์ฟเวอร์ ในการดำเนินการนี้ เราต้องคัดลอกการรับส่งข้อมูลพร้อมหน่วยวัดไปยังเซิร์ฟเวอร์ทั้งสองเครื่องและเขียนเพื่อสิ่งนี้ด้วย ยูทิลิตี้ขนาดเล็ก- เราได้แก้ไขปัญหาการยอมรับข้อผิดพลาดด้วยสิ่งนี้ แต่... ไม่ค่อยดีนัก ในตอนแรก ทุกอย่างดูดีมาก: brubeck แต่ละตัวจะรวบรวมเวอร์ชันการรวมกลุ่มของตัวเอง เขียนข้อมูลลงใน Graphite ทุกๆ 30 วินาที เขียนทับช่วงเวลาเก่า (ซึ่งทำที่ฝั่ง Graphite) หากเซิร์ฟเวอร์ตัวหนึ่งทำงานล้มเหลวกะทันหัน เราจะมีเซิร์ฟเวอร์ตัวที่สองพร้อมสำเนาข้อมูลที่รวบรวมไว้ของตัวเองเสมอ แต่นี่คือปัญหา: หากเซิร์ฟเวอร์ล้มเหลว "เลื่อย" จะปรากฏบนกราฟ นี่เป็นเพราะความจริงที่ว่าช่วงเวลา 30 วินาทีของ brubeck ไม่ได้ซิงโครไนซ์และในขณะที่เกิดข้อขัดข้องหนึ่งในนั้นจะไม่ถูกเขียนทับ เมื่อเซิร์ฟเวอร์ตัวที่สองเริ่มทำงาน สิ่งเดียวกันนี้จะเกิดขึ้น ค่อนข้างทนได้ แต่ฉันต้องการดีกว่านี้! ปัญหาเรื่องความสามารถในการขยายขนาดยังไม่หมดไป ตัววัดทั้งหมดยังคง "บิน" ไปยังเซิร์ฟเวอร์เดียว ดังนั้นเราจึงถูกจำกัดไว้ที่ 2-4 ล้าน MPS เท่าเดิม ขึ้นอยู่กับระดับเครือข่าย

หากคุณคิดเพียงเล็กน้อยเกี่ยวกับปัญหาและในขณะเดียวกันก็ขุดหิมะด้วยพลั่วแนวคิดที่ชัดเจนต่อไปนี้อาจเข้ามาในใจ: คุณต้องมีสถิติที่สามารถทำงานในโหมดกระจายได้ นั่นคือสิ่งหนึ่งที่ใช้การซิงโครไนซ์ระหว่างโหนดในเวลาและตัวชี้วัด “แน่นอนว่าวิธีแก้ปัญหาดังกล่าวอาจมีอยู่แล้ว” เราพูดและไปที่ Google…. และพวกเขาก็ไม่พบอะไรเลย หลังจากอ่านเอกสารสำหรับ statsd ต่างๆ (https://github.com/etsy/statsd/wiki#server-implementations ณ วันที่ 11.12.2017 ธันวาคม XNUMX) เราไม่พบสิ่งใดเลย เห็นได้ชัดว่าทั้งนักพัฒนาและผู้ใช้โซลูชันเหล่านี้ยังไม่เคยพบกับตัวชี้วัดมากมาย ไม่เช่นนั้นพวกเขาจะคิดอะไรบางอย่างขึ้นมาอย่างแน่นอน

จากนั้นเราก็จำสถิติ "ของเล่น" - bioyino ซึ่งเขียนที่ Just for Fun hackathon (ชื่อของโครงการถูกสร้างขึ้นโดยสคริปต์ก่อนที่จะเริ่มแฮ็คกาธอน) และตระหนักว่าเราต้องการสถิติของเราเองอย่างเร่งด่วน เพื่ออะไร?

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

สิ่งที่จะเขียนบน? แน่นอนในรัส ทำไม

  • เพราะมีโซลูชันต้นแบบอยู่แล้ว
  • เพราะผู้เขียนบทความรู้จัก Rust อยู่แล้วในเวลานั้นและกระตือรือร้นที่จะเขียนอะไรบางอย่างเพื่อการผลิตโดยมีโอกาสนำมันไปไว้ในโอเพ่นซอร์ส
  • เนื่องจากภาษาที่มี GC ไม่เหมาะสำหรับเราเนื่องจากลักษณะของการรับส่งข้อมูลที่ได้รับ (เกือบเรียลไทม์) และการหยุดชั่วคราวของ GC นั้นไม่สามารถยอมรับได้ในทางปฏิบัติ
  • เพราะคุณต้องการประสิทธิภาพสูงสุดเทียบได้กับ C
  • เพราะ Rust ช่วยให้เกิดการทำงานพร้อมกันอย่างไม่เกรงกลัวใคร และหากเราเริ่มเขียนมันด้วย C/C++ เราก็จะพบกับช่องโหว่ บัฟเฟอร์ล้น สภาพการแข่งขัน และคำที่น่ากลัวอื่นๆ มากกว่า brubeck

นอกจากนี้ยังมีข้อโต้แย้งกับสนิม บริษัทไม่มีประสบการณ์ในการสร้างโครงการใน Rust และตอนนี้เราก็ไม่มีแผนที่จะใช้ในโครงการหลักด้วย ดังนั้นจึงมีความกลัวอย่างมากว่าจะไม่มีอะไรเกิดขึ้น แต่เราตัดสินใจที่จะลองเสี่ยงดู

เวลาผ่านไป...

ในที่สุด หลังจากพยายามล้มเหลวหลายครั้ง เวอร์ชันแรกก็พร้อมใช้งาน เกิดอะไรขึ้น นี่คือสิ่งที่เกิดขึ้น

Bioyino - ตัวรวบรวมเมตริกแบบกระจายและปรับขนาดได้

แต่ละโหนดจะได้รับชุดตัววัดของตัวเองและสะสมไว้ และไม่รวมตัววัดสำหรับประเภทเหล่านั้นที่ต้องใช้ชุดเต็มสำหรับการรวมขั้นสุดท้าย โหนดเชื่อมต่อถึงกันด้วยโปรโตคอลการล็อคแบบกระจายซึ่งช่วยให้คุณสามารถเลือกโหนดเดียวเท่านั้น (ที่นี่เราร้องไห้) ที่คุ้มค่าที่จะส่งการวัดไปยังผู้ยิ่งใหญ่ ขณะนี้ปัญหานี้ได้รับการแก้ไขโดย กงสุลแต่ในอนาคตความทะเยอทะยานของผู้เขียนขยายไปถึง เป็นเจ้าของ การนำไปใช้ Raft ซึ่งแน่นอนว่าผู้ที่มีค่าควรที่สุดจะเป็นผู้นำที่เป็นเอกฉันท์ นอกเหนือจากความเห็นพ้องต้องกันแล้ว โหนดค่อนข้างบ่อย (หนึ่งครั้งต่อวินาทีโดยค่าเริ่มต้น) ส่งส่วนต่างๆ ของตัววัดที่รวบรวมไว้ล่วงหน้าที่พวกเขาจัดการเพื่อรวบรวมในวินาทีนั้นไปให้เพื่อนบ้านของตน ปรากฎว่าการปรับขนาดและความทนทานต่อข้อผิดพลาดยังคงอยู่ แต่ละโหนดยังคงมีชุดตัววัดครบชุด แต่ตัววัดถูกส่งแบบรวมแล้วผ่าน TCP และเข้ารหัสลงในโปรโตคอลไบนารี่ ดังนั้น ค่าใช้จ่ายในการทำซ้ำจึงลดลงอย่างมากเมื่อเทียบกับ UDP แม้จะมีตัววัดขาเข้าจำนวนมาก การสะสมต้องใช้หน่วยความจำน้อยมากและ CPU น้อยกว่าด้วยซ้ำ สำหรับการวัดแบบบีบอัดได้สูงของเรา ข้อมูลนี้มีขนาดเพียงไม่กี่สิบเมกะไบต์เท่านั้น โบนัสเพิ่มเติมคือ เราจะไม่เขียนข้อมูลที่ไม่จำเป็นซ้ำในกราไฟท์ เช่นเดียวกับกรณีของ Burbeck

แพ็กเก็ต UDP ที่มีหน่วยวัดจะไม่สมดุลระหว่างโหนดบนอุปกรณ์เครือข่ายผ่าน Round Robin แบบธรรมดา แน่นอนว่าฮาร์ดแวร์เครือข่ายไม่ได้แยกวิเคราะห์เนื้อหาของแพ็กเก็ต ดังนั้นจึงสามารถดึงแพ็กเก็ตได้มากกว่า 4M ต่อวินาที ไม่ต้องพูดถึงตัวชี้วัดที่ฮาร์ดแวร์ไม่รู้อะไรเลย หากเราคำนึงว่าตัวชี้วัดไม่ได้มาทีละตัวในแต่ละแพ็กเก็ต เราก็ไม่คาดว่าจะเกิดปัญหาด้านประสิทธิภาพใดๆ ในที่นี้ หากเซิร์ฟเวอร์ขัดข้อง อุปกรณ์เครือข่ายอย่างรวดเร็ว (ภายใน 1-2 วินาที) จะตรวจพบข้อเท็จจริงนี้ และลบเซิร์ฟเวอร์ที่ขัดข้องออกจากการหมุน ด้วยเหตุนี้ โหนดแบบพาสซีฟ (เช่น ไม่ใช่ผู้นำ) จึงสามารถเปิดและปิดได้ในทางปฏิบัติโดยไม่ต้องสังเกตเห็นการขาดทุนบนกราฟ ค่าสูงสุดที่เราเสียไปเป็นส่วนหนึ่งของตัวชี้วัดที่เข้ามาในช่วงวินาทีสุดท้าย การสูญเสีย/การปิดเครื่อง/การเปลี่ยนผู้นำอย่างกะทันหันจะยังคงสร้างความผิดปกติเล็กน้อย (ช่วงเวลา 30 วินาทียังคงไม่ซิงค์กัน) แต่หากมีการสื่อสารระหว่างโหนด ปัญหาเหล่านี้สามารถลดลงได้ เช่น โดยการส่งแพ็กเก็ตการซิงโครไนซ์ออกไป .

เล็กน้อยเกี่ยวกับโครงสร้างภายใน แน่นอนว่าแอปพลิเคชันเป็นแบบมัลติเธรด แต่สถาปัตยกรรมเธรดนั้นแตกต่างจากที่ใช้ใน brubeck เธรดใน brubeck เหมือนกัน - แต่ละเธรดมีหน้าที่รับผิดชอบในการรวบรวมข้อมูลและการรวมกลุ่ม ใน bioyino คนงานแบ่งออกเป็นสองกลุ่ม: ผู้ที่รับผิดชอบด้านเครือข่ายและผู้ที่รับผิดชอบในการรวมกลุ่ม แผนกนี้ช่วยให้คุณจัดการแอปพลิเคชันได้อย่างยืดหยุ่นมากขึ้น โดยขึ้นอยู่กับประเภทของตัววัด: ในกรณีที่จำเป็นต้องมีการรวมกลุ่มแบบเข้มข้น คุณสามารถเพิ่มตัวรวบรวมได้ ในกรณีที่มีการรับส่งข้อมูลเครือข่ายจำนวนมาก คุณสามารถเพิ่มจำนวนโฟลว์เครือข่ายได้ ในขณะนี้ บนเซิร์ฟเวอร์ของเรา เราทำงานใน 8 เครือข่ายและ 4 โฟลว์การรวม

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

ปัญหามากมายระหว่างการพัฒนาเกิดจากส่วนของเครือข่ายที่รับผิดชอบในการรับเมตริก เป้าหมายหลักของการแยกโฟลว์เครือข่ายออกเป็นเอนทิตีที่แยกจากกันคือความปรารถนาที่จะลดเวลาที่ใช้โฟลว์ ไม่ เพื่ออ่านข้อมูลจากซ็อกเก็ต ตัวเลือกที่ใช้ UDP แบบอะซิงโครนัสและ recvmsg ปกติหายไปอย่างรวดเร็ว: ตัวเลือกแรกใช้ CPU พื้นที่ผู้ใช้มากเกินไปสำหรับการประมวลผลเหตุการณ์ ตัวเลือกที่สองต้องใช้สวิตช์บริบทมากเกินไป ดังนั้นตอนนี้จึงถูกนำมาใช้ รับเงินคืน มีบัฟเฟอร์ขนาดใหญ่ (และบัฟเฟอร์ เจ้าหน้าที่สุภาพบุรุษ ไม่มีประโยชน์อะไรกับคุณ!) การสนับสนุน UDP ปกติสงวนไว้สำหรับกรณีขนาดเล็กที่ไม่จำเป็นต้องใช้ recvmmsg ในโหมดมัลติข้อความเป็นไปได้ที่จะบรรลุสิ่งสำคัญ: โดยส่วนใหญ่แล้วเธรดเครือข่ายจะกวาดคิวระบบปฏิบัติการ - อ่านข้อมูลจากซ็อกเก็ตและถ่ายโอนไปยังบัฟเฟอร์พื้นที่ผู้ใช้โดยเปลี่ยนเป็นครั้งคราวเพื่อให้บัฟเฟอร์ที่เต็มไป ผู้รวบรวม คิวในซ็อกเก็ตไม่สะสมจริงจำนวนแพ็กเก็ตที่ดร็อปไม่เพิ่มขึ้น

หมายเหตุ

ในการตั้งค่าเริ่มต้น ขนาดบัฟเฟอร์ถูกกำหนดให้มีขนาดค่อนข้างใหญ่ หากคุณตัดสินใจลองใช้เซิร์ฟเวอร์ด้วยตัวเองกะทันหัน คุณอาจพบว่าหลังจากส่งตัววัดจำนวนเล็กน้อยแล้ว ตัววัดเหล่านั้นจะไม่มาถึงแบบ Graphite แต่จะเหลืออยู่ในบัฟเฟอร์สตรีมเครือข่าย หากต้องการทำงานกับเมตริกจำนวนน้อย คุณต้องตั้งค่า bufsize และ job-queue-size ให้เป็นค่าที่น้อยลงในการกำหนดค่า

สุดท้ายนี้ แผนภูมิบางส่วนสำหรับผู้ชื่นชอบแผนภูมิ

สถิติเกี่ยวกับจำนวนตัวชี้วัดขาเข้าสำหรับแต่ละเซิร์ฟเวอร์: มากกว่า 2 ล้าน MPS

Bioyino - ตัวรวบรวมเมตริกแบบกระจายและปรับขนาดได้

ปิดใช้งานโหนดใดโหนดหนึ่งและแจกจ่ายเมตริกขาเข้าอีกครั้ง

Bioyino - ตัวรวบรวมเมตริกแบบกระจายและปรับขนาดได้

สถิติเกี่ยวกับตัวชี้วัดขาออก: มีเพียงโหนดเดียวเท่านั้นที่ส่งเสมอ - หัวหน้าการโจมตี

Bioyino - ตัวรวบรวมเมตริกแบบกระจายและปรับขนาดได้

สถิติการทำงานของแต่ละโหนดโดยคำนึงถึงข้อผิดพลาดในโมดูลระบบต่างๆ

Bioyino - ตัวรวบรวมเมตริกแบบกระจายและปรับขนาดได้

รายละเอียดของตัวชี้วัดที่เข้ามา (ชื่อตัวชี้วัดถูกซ่อนอยู่)

Bioyino - ตัวรวบรวมเมตริกแบบกระจายและปรับขนาดได้

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

แน่นอนว่าทุกคนยินดีที่จะช่วยในการพัฒนาโครงการ: สร้างการประชาสัมพันธ์ ปัญหา หากเป็นไปได้เราจะตอบสนอง ปรับปรุง ฯลฯ

ถึงอย่างนั้น ทุกคนก็ซื้อช้างของเราสิ!



ที่มา: will.com

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