บันทึกเป็นส่วนสำคัญของระบบ ช่วยให้คุณเข้าใจว่ามันทำงาน (หรือไม่ทำงาน) ตามที่คาดไว้ ภายใต้เงื่อนไขของสถาปัตยกรรมไมโครเซอร์วิส การทำงานกับบันทึกจะกลายเป็นวินัยที่แยกจากกันของโอลิมปิกพิเศษ มีปัญหามากมายที่ต้องแก้ไข:
- วิธีเขียนบันทึกจากแอปพลิเคชัน
- จะเขียนบันทึกได้ที่ไหน
- วิธีการส่งบันทึกเพื่อจัดเก็บและประมวลผล
- วิธีดำเนินการและจัดเก็บบันทึก
การใช้เทคโนโลยีการบรรจุตู้คอนเทนเนอร์ที่เป็นที่นิยมในปัจจุบันเพิ่มทรายที่ด้านบนของคราดในด้านตัวเลือกการแก้ปัญหา
นี่เป็นสำเนาของรายงานโดย Yuri Bushmelev "แผนที่คราดในด้านการรวบรวมและส่งมอบบันทึก"
ใครสนใจโปรดอยู่ใต้แมว
ฉันชื่อยูริ บุชเมเลฟ ฉันทำงานลาซาด้า วันนี้ฉันจะพูดถึงวิธีที่เราทำท่อนซุง วิธีที่เรารวบรวมมัน และสิ่งที่เราเขียนไว้ที่นั่น
เรามาจากไหน? พวกเราคือใคร? ลาซาด้าเป็นผู้ค้าปลีกออนไลน์อันดับ 1 ใน 4 ประเทศในเอเชียตะวันออกเฉียงใต้ ประเทศทั้งหมดเหล่านี้กระจายอยู่ในศูนย์ข้อมูล ขณะนี้มีศูนย์ข้อมูลทั้งหมด 80 แห่ง เหตุใดจึงสำคัญ เนื่องจากการตัดสินใจบางอย่างเกิดจากความจริงที่ว่ามีการเชื่อมโยงที่อ่อนแอมากระหว่างศูนย์ เรามีสถาปัตยกรรมไมโครเซอร์วิส ฉันรู้สึกประหลาดใจที่พบว่าเรามีไมโครเซอร์วิสถึง 20 รายการแล้ว เมื่อฉันเริ่มงานด้วยบันทึก มีเพียง 6 รายการเท่านั้น นอกจากนี้ ยังมีมรดก PHP ที่ค่อนข้างใหญ่ซึ่งฉันต้องใช้ชีวิตและทนกับมันด้วย ทั้งหมดนี้ทำให้เรามีข้อความมากกว่า XNUMX ล้านข้อความต่อนาทีสำหรับระบบโดยรวม นอกจากนี้ ฉันจะแสดงให้เห็นว่าเราพยายามที่จะอยู่กับสิ่งนี้อย่างไร และทำไมจึงเป็นเช่นนั้น
คุณต้องอยู่กับข้อความ 6 ล้านข้อความเหล่านี้ไม่ทางใดก็ทางหนึ่ง เราควรทำอย่างไรกับพวกเขา? ต้องการ 6 ล้านข้อความ:
- ส่งจากแอพ
- ยอมรับสำหรับการจัดส่ง
- ส่งมอบเพื่อการวิเคราะห์และการจัดเก็บ
- วิเคราะห์
- เก็บอย่างใด
เมื่อมีข้อความสามล้านข้อความ ฉันก็มีหน้าตาเหมือนกัน เพราะเราเริ่มต้นด้วยเงินเพียงเล็กน้อย เห็นได้ชัดว่ามีการเขียนบันทึกแอปพลิเคชันไว้ที่นั่น เช่น เชื่อมต่อกับฐานข้อมูลไม่ได้ เชื่อมต่อกับฐานข้อมูลได้ แต่ไม่สามารถอ่านข้อมูลบางอย่างได้ แต่นอกเหนือจากนี้ บริการไมโครแต่ละแห่งของเรายังเขียนบันทึกการเข้าถึงอีกด้วย คำขอแต่ละรายการที่มาถึงไมโครเซอร์วิสจะอยู่ในบันทึก เราจะทำเช่นนี้ทำไม? นักพัฒนาต้องการให้สามารถติดตามได้ บันทึกการเข้าถึงแต่ละรายการมีฟิลด์ traceid ซึ่งอินเทอร์เฟซพิเศษจะคลายห่วงโซ่ทั้งหมดและแสดงการติดตามอย่างสวยงาม การติดตามแสดงให้เห็นว่าคำขอเป็นอย่างไร และสิ่งนี้ช่วยให้นักพัฒนาของเราจัดการกับขยะที่ไม่รู้จักได้เร็วขึ้น
จะอยู่กับมันได้อย่างไร? ตอนนี้ฉันจะอธิบายสั้น ๆ เกี่ยวกับตัวเลือก - วิธีแก้ปัญหานี้โดยทั่วไป วิธีแก้ปัญหาการรวบรวม ถ่ายโอน และจัดเก็บบันทึก
วิธีการเขียนจากใบสมัคร? เห็นได้ชัดว่ามีหลายวิธี โดยเฉพาะอย่างยิ่งมีแนวทางปฏิบัติที่ดีที่สุดตามที่สหายที่ทันสมัยบอกเรา โรงเรียนเก่ามีสองประเภทตามที่ปู่พูด ยังมีวิธีอื่นๆ
ด้วยการรวบรวมบันทึกสถานการณ์จะใกล้เคียงกัน ไม่มีตัวเลือกมากมายสำหรับการแก้ไขส่วนนี้โดยเฉพาะ มีมากขึ้น แต่ยังไม่มากนัก
แต่ด้วยการส่งมอบและการวิเคราะห์ที่ตามมา จำนวนรูปแบบต่างๆ ก็เริ่มเพิ่มขึ้น ฉันจะไม่อธิบายแต่ละตัวเลือกในตอนนี้ ฉันคิดว่าตัวเลือกหลักเป็นที่รู้จักกันดีสำหรับทุกคนที่สนใจในหัวข้อนี้
ฉันจะแสดงให้คุณเห็นว่าเราทำที่ลาซาด้าได้อย่างไรและมันเริ่มต้นอย่างไร
ปีที่แล้วฉันมาที่ลาซาด้าและถูกส่งไปที่โครงการล็อก มันเป็นแบบนี้ที่นั่น บันทึกจากแอปพลิเคชันถูกเขียนไปยัง stdout และ stderr ทุกอย่างทำในรูปแบบที่ทันสมัย แต่จากนั้นนักพัฒนาก็โยนมันออกจากสตรีมมาตรฐานแล้วผู้เชี่ยวชาญด้านโครงสร้างพื้นฐานจะคิดออก ระหว่างผู้เชี่ยวชาญด้านโครงสร้างพื้นฐานและนักพัฒนา ยังมีผู้เผยแพร่ที่กล่าวว่า: "เอ่อ ... เอาล่ะ เราแค่รวมพวกเขาไว้ในไฟล์ด้วยเชลล์ แค่นั้น" และเนื่องจากทั้งหมดนี้อยู่ในคอนเทนเนอร์ พวกเขาจึงรวมมันไว้ในคอนเทนเนอร์โดยตรง แมปไดเร็กทอรีข้างในและวางไว้ที่นั่น ฉันคิดว่ามันค่อนข้างชัดเจนสำหรับทุกคนว่าเกิดอะไรขึ้น
มาดูกันต่ออีกหน่อย เราส่งมอบบันทึกเหล่านี้อย่างไร มีคนเลือก td-agent ซึ่งก็คล่องแต่ยังไม่คล่องนัก ฉันยังไม่เข้าใจความสัมพันธ์ของทั้งสองโครงการนี้ แต่ดูเหมือนว่าจะเกี่ยวกับสิ่งเดียวกัน และสิ่งนี้เขียนด้วยภาษา Ruby อย่างคล่องแคล่ว อ่านไฟล์บันทึก แยกวิเคราะห์เป็น JSON โดยใช้นิพจน์ทั่วไป จากนั้นพวกเขาก็ถูกส่งไปยังคาฟคา ยิ่งไปกว่านั้น ใน Kafka เรามี 4 หัวข้อแยกกันสำหรับแต่ละ API ทำไมต้อง 4? เนื่องจากมีการถ่ายทอดสด มีการจัดเตรียม และเนื่องจากมี stdout และ stderr นักพัฒนาสร้างมันขึ้นมา และพนักงานโครงสร้างพื้นฐานต้องสร้างมันในคาฟคา นอกจากนี้ คาฟคายังถูกควบคุมโดยหน่วยงานอื่น ดังนั้นจึงจำเป็นต้องสร้างตั๋วเพื่อสร้าง 4 หัวข้อที่นั่นสำหรับแต่ละ API ทุกคนลืมมันไป โดยทั่วไปแล้วมันเป็นขยะและของเสีย
เราทำอะไรต่อไปกับมัน? เราส่งไปที่คาฟคา จากคาฟคาท่อนซุงครึ่งหนึ่งบินไปที่ Logstash อีกครึ่งหนึ่งของบันทึกถูกแบ่งปัน บางตัวบินไปที่เกรย์ล็อกหนึ่ง บางตัวบินไปที่เกรย์ล็อกอื่น ด้วยเหตุนี้ ทั้งหมดนี้จึงรวมอยู่ในคลัสเตอร์ของ Elasticsearch เพียงกลุ่มเดียว นั่นคือความยุ่งเหยิงทั้งหมดนี้จบลงที่นั่น คุณไม่จำเป็นต้องทำอย่างนั้น!
นี่คือลักษณะเมื่อมองจากด้านบน คุณไม่จำเป็นต้องทำอย่างนั้น! ที่นี่พื้นที่ปัญหาจะถูกทำเครื่องหมายด้วยตัวเลขทันที จริงๆแล้วมีมากกว่านี้ แต่ 6 ตัวเป็นปัญหาจริงๆซึ่งต้องทำบางอย่าง ฉันจะบอกเกี่ยวกับพวกเขาแยกกันตอนนี้
ที่นี่ (1,2,3) เราเขียนไฟล์และด้วยเหตุนี้จึงมีการคราดสามรายการพร้อมกัน
ข้อแรก (1) คือเราต้องเขียนไว้ที่ใดที่หนึ่ง ไม่ใช่เรื่องดีเสมอไปที่จะให้ API สามารถเขียนลงไฟล์ได้โดยตรง เป็นที่พึงปรารถนาที่จะแยก API ไว้ในคอนเทนเนอร์ และดีกว่านั้นคือเป็นแบบอ่านอย่างเดียว ฉันเป็นผู้ดูแลระบบ ดังนั้นฉันจึงมีมุมมองทางเลือกเล็กน้อยเกี่ยวกับสิ่งเหล่านี้
ประเด็นที่สอง (2,3) คือเรามีคำขอจำนวนมากมาที่ API API เขียนข้อมูลจำนวนมากลงในไฟล์ ไฟล์กำลังเติบโต เราต้องหมุนพวกมัน เพราะไม่เช่นนั้นคุณจะไม่สามารถบันทึกดิสก์ใดๆ ที่นั่นได้ การหมุนสิ่งเหล่านี้ไม่ดีเพราะถูกเปลี่ยนเส้นทางผ่านเชลล์ไปยังไดเร็กทอรี ไม่มีทางที่เราจะหมุนมันได้ คุณไม่สามารถบอกให้แอปพลิเคชันเปิดที่จับอีกครั้ง เพราะนักพัฒนาจะมองว่าคุณเป็นคนโง่: "คำอธิบายอะไร โดยทั่วไปเราจะเขียนถึง stdout กรอบทำ copytruncate เป็น logrotate ซึ่งเพียงแค่สร้างสำเนาของไฟล์และเก็บต้นฉบับ ดังนั้นระหว่างกระบวนการคัดลอกเหล่านี้ พื้นที่ดิสก์มักจะหมด
(4) เรามีรูปแบบที่แตกต่างกันใน API ที่แตกต่างกัน ต่างกันเล็กน้อย แต่ regexp ต้องเขียนต่างกัน เนื่องจากมันถูกจัดการโดย Puppet จึงมีคลาสจำนวนมากที่มีแมลงสาบเป็นของตัวเอง นอกจากนี้ td-agent ส่วนใหญ่มักจะกินความจำ ทำตัวงี่เง่า เขาสามารถแสร้งทำเป็นว่าเขากำลังทำงานและไม่ทำอะไรเลย ภายนอกเป็นไปไม่ได้ที่จะเข้าใจว่าเขาไม่ได้ทำอะไรเลย อย่างดีที่สุด เขาจะล้มลง และจะมีคนมารับในภายหลัง อย่างแม่นยำยิ่งขึ้นการแจ้งเตือนจะบินเข้ามาและใครบางคนจะไปยกมือขึ้น
(6) และขยะและของเสียมากที่สุด - มันคือการค้นหาแบบยืดหยุ่น เพราะเป็นรุ่นเก่า เพราะตอนนั้นเราไม่มีอาจารย์เฉพาะทาง เรามีบันทึกที่ต่างกันซึ่งเขตข้อมูลอาจทับซ้อนกัน บันทึกที่แตกต่างกันของแอปพลิเคชันที่แตกต่างกันสามารถเขียนด้วยชื่อฟิลด์เดียวกัน แต่ในขณะเดียวกันอาจมีข้อมูลที่แตกต่างกันอยู่ภายใน นั่นคือ บันทึกหนึ่งมาพร้อมกับจำนวนเต็มในฟิลด์ ตัวอย่างเช่น ระดับ บันทึกอื่นมาพร้อมกับสตริงในฟิลด์ระดับ ในกรณีที่ไม่มีการทำแผนที่แบบคงที่ สิ่งที่ยอดเยี่ยมเช่นนี้ก็ปรากฏออกมา หากหลังจากการหมุนดัชนี ข้อความที่มีสตริงมาถึงก่อนในการค้นหาแบบยืดหยุ่น เราก็ดำเนินชีวิตได้ตามปกติ และถ้าข้อความแรกมาพร้อมกับจำนวนเต็ม ข้อความต่อมาทั้งหมดที่มาพร้อมกับสตริงจะถูกละทิ้งไป เนื่องจากประเภทฟิลด์ไม่ตรงกัน
เราเริ่มถามคำถามเหล่านี้ เราตัดสินใจที่จะไม่มองหาคนผิด
แต่มีบางอย่างต้องทำ! สิ่งที่ชัดเจนคือเราต้องสร้างมาตรฐาน เรามีมาตรฐานบางอย่างอยู่แล้ว บางส่วนเรานำมาในภายหลัง โชคดีที่รูปแบบบันทึกเดียวสำหรับ API ทั้งหมดได้รับการอนุมัติในเวลานั้น มันเขียนโดยตรงในมาตรฐานการโต้ตอบบริการ ดังนั้น ผู้ที่ต้องการรับบันทึกควรเขียนในรูปแบบนี้ หากมีคนไม่เขียนบันทึกในรูปแบบนี้ เราไม่รับประกันอะไรเลย
นอกจากนี้ ฉันต้องการให้มีมาตรฐานเดียวสำหรับวิธีการบันทึก การส่งมอบ และการรวบรวมบันทึก จริง ๆ แล้วเขียนไว้ที่ไหนและจะจัดส่งอย่างไร สถานการณ์ที่เหมาะสมคือเมื่อโปรเจ็กต์ใช้ไลบรารีเดียวกัน มีไลบรารีการบันทึกแยกต่างหากสำหรับ Go มีไลบรารีแยกต่างหากสำหรับ PHP ที่เรามีทุกคนควรใช้ให้หมด ในตอนนี้ ฉันจะบอกว่าเราประสบความสำเร็จถึง 80 เปอร์เซ็นต์แล้ว แต่บางคนยังคงกินกระบองเพชรต่อไป
และที่นั่น (บนสไลด์) “SLA สำหรับการจัดส่งบันทึก” แทบจะไม่เริ่มปรากฏขึ้นเลย ยังไม่มี แต่เรากำลังดำเนินการอยู่ เพราะมันสะดวกมากเมื่อ infra บอกว่าถ้าคุณเขียนในรูปแบบนั้นและรูปแบบดังกล่าวไปยังสถานที่นั้น ๆ และไม่เกิน N ข้อความต่อวินาทีเรามักจะส่งไปที่นั่น มันทำให้ปวดหัวมาก หากมี SLA ก็เยี่ยมมาก!
เราเริ่มต้นแก้ปัญหาอย่างไร? คราดหลักอยู่กับตัวแทน td มันไม่ชัดเจนว่าบันทึกของเราไปอยู่ที่ไหน พวกเขาจัดส่ง? พวกเขากำลังจะไป? พวกเขาอยู่ที่ไหน? ดังนั้นจึงมีการตัดสินใจแทนที่ td-agent ด้วยรายการแรก ฉันสรุปตัวเลือกสำหรับสิ่งที่จะแทนที่ด้วยสั้น ๆ ที่นี่
คล่องแคล่ว ประการแรก ฉันเจอเขาที่งานก่อนหน้านี้ และเขาก็ล้มลงที่นั่นเป็นระยะๆ ประการที่สองก็เหมือนกันเฉพาะในโปรไฟล์เท่านั้น
ไฟล์บีท มันดีสำหรับเราอย่างไร? ความจริงที่ว่าเขาอยู่ใน Go และเรามีความเชี่ยวชาญอย่างมากใน Go ดังนั้น ถ้ามีอะไร เราก็สามารถเพิ่มมันให้กับตัวเองได้ นั่นเป็นเหตุผลที่เราไม่เอามัน เพื่อที่จะไม่มีแม้แต่การล่อลวงให้เริ่มเขียนใหม่ด้วยตัวคุณเอง
ทางออกที่ชัดเจนสำหรับ sysadmin คือ syslogs ทุกประเภทในปริมาณนี้ (syslog-ng/rsyslog/nxlog)
หรือเขียนอะไรขึ้นมาเองแต่เราคัดทิ้ง เช่นเดียวกับ filebeat หากคุณเขียนบางสิ่ง การเขียนสิ่งที่มีประโยชน์ต่อธุรกิจจะดีกว่า ในการส่งมอบบันทึกจะเป็นการดีกว่าถ้าใช้ของสำเร็จรูป
ดังนั้นตัวเลือกจึงลงมาที่ตัวเลือกระหว่าง syslog-ng และ rsyslog ฉันเอนเอียงไปทาง rsyslog เพียงเพราะเรามีคลาสสำหรับ rsyslog ใน Puppet อยู่แล้ว และฉันไม่พบความแตกต่างที่ชัดเจนระหว่างพวกเขา syslog คืออะไร syslog คืออะไร ใช่ เอกสารบางอย่างแย่กว่า บางอย่างดีกว่า เขารู้วิธีนี้และเขาทำอย่างอื่น
และเล็กน้อยเกี่ยวกับ rsyslog ประการแรกมันเจ๋งเพราะมีโมดูลมากมาย มี RainerScript ที่มนุษย์อ่านได้ (ภาษาการกำหนดค่าสมัยใหม่) โบนัสที่ยอดเยี่ยมคือเราสามารถเลียนแบบพฤติกรรมของ td-agent ด้วยเครื่องมือมาตรฐาน และไม่มีอะไรเปลี่ยนแปลงสำหรับแอปพลิเคชัน นั่นคือเราเปลี่ยน td-agent เป็น rsyslog และยังไม่ได้แตะต้องสิ่งอื่นทั้งหมด และทันทีที่เราได้รับการจัดส่งที่ใช้งานได้ ต่อไป mmnormalize คือสิ่งที่ยอดเยี่ยมเกี่ยวกับ rsyslog อนุญาตให้คุณแยกวิเคราะห์บันทึก แต่ไม่ใช่กับ Grok และ regexp มันทำให้ต้นไม้ไวยากรณ์นามธรรม มันแยกวิเคราะห์บันทึกในลักษณะเดียวกับที่คอมไพเลอร์แยกวิเคราะห์ซอร์สโค้ด สิ่งนี้ช่วยให้คุณทำงานได้อย่างรวดเร็ว กิน CPU เพียงเล็กน้อย และโดยทั่วไปแล้ว มันเป็นสิ่งที่ยอดเยี่ยมมาก มีโบนัสอื่นๆ อีกเพียบ ฉันจะไม่อยู่กับพวกเขา
rsyslog มีข้อเสียมากกว่านั้นมาก พวกมันเหมือนกับโบนัส ปัญหาหลักคือคุณต้องสามารถปรุงอาหารได้และคุณต้องเลือกเวอร์ชัน
เราตัดสินใจว่าเราจะเขียนบันทึกในซ็อกเก็ตยูนิกซ์ และไม่อยู่ใน /dev/log เนื่องจากเรามีบันทึกระบบยุ่งเหยิง มี Journald ในไปป์ไลน์นี้ ลองเขียนลงในซ็อกเก็ตที่กำหนดเอง เราจะแนบไปกับชุดกฎแยกต่างหาก อย่าไปยุ่งเกี่ยวอะไรกันเลย ทุกอย่างจะโปร่งใสและเข้าใจได้ ดังนั้นเราจึงทำจริง ไดเร็กทอรีที่มีซ็อกเก็ตเหล่านี้ได้รับการกำหนดมาตรฐานและส่งต่อไปยังคอนเทนเนอร์ทั้งหมด คอนเทนเนอร์สามารถเห็นซ็อกเก็ตที่ต้องการ เปิดและเขียนลงไป
ทำไมไม่เป็นไฟล์? เพราะทุกคนได้อ่าน
Rsyslog ดำเนินการตามที่ระบุบนสไลด์และส่งบันทึกไปยังรีเลย์หรือคาฟคา คาฟคาเดินตามทางเก่า Rayleigh - ฉันพยายามใช้ rsyslog บริสุทธิ์เพื่อส่งบันทึก ไม่มี Message Queue โดยใช้เครื่องมือ rsyslog มาตรฐาน โดยพื้นฐานแล้วมันใช้งานได้
แต่มีความแตกต่างเกี่ยวกับวิธีใส่ลงในส่วนนี้ในภายหลัง (Logstash/Graylog/ES) ส่วนนี้ (rsyslog-rsyslog) ใช้ระหว่างศูนย์ข้อมูล นี่คือลิงค์ tcp ที่บีบอัดซึ่งช่วยให้คุณประหยัดแบนด์วิดท์และเพิ่มโอกาสที่เราจะได้รับบันทึกจากศูนย์ข้อมูลอื่นเมื่อช่องสัญญาณเต็ม เพราะเรามีอินโดนีเซียที่ทุกอย่างแย่ นั่นคือปัญหาที่เกิดขึ้นอย่างต่อเนื่อง
เราคิดว่าเราตรวจสอบจริง ๆ ได้อย่างไร ด้วยความน่าจะเป็นเท่าใดที่บันทึกที่เราบันทึกจากแอปพลิเคชันถึงจุดสิ้นสุดนั้น เราตัดสินใจที่จะเริ่มเมตริก Rsyslog มีโมดูลการรวบรวมสถิติของตัวเอง ซึ่งมีตัวนับบางชนิด ตัวอย่างเช่น สามารถแสดงขนาดของคิวหรือจำนวนข้อความที่เข้ามาสำหรับการกระทำดังกล่าว คุณสามารถรับบางสิ่งจากพวกเขาได้แล้ว นอกจากนี้ยังมีตัวนับแบบกำหนดเองที่คุณสามารถกำหนดค่าได้ และจะแสดงให้คุณเห็น เช่น จำนวนข้อความที่ API บางตัวบันทึกไว้ ต่อไป ฉันเขียน rsyslog_exporter ใน Python และเราส่งทั้งหมดไปที่ Prometheus และวางแผน เราต้องการเมตริก Graylog มาก แต่จนถึงตอนนี้เรายังไม่มีเวลาตั้งค่า
ปัญหาคืออะไร? ปัญหาเกิดจากข้อเท็จจริงที่เราพบ (อย่างกะทันหัน!) ว่า Live API ของเราเขียนข้อความ 50 ข้อความต่อวินาที นี่เป็นเพียง Live API ที่ไม่มีการแสดงละคร และ Graylog แสดงให้เราเห็นเพียง 12 ข้อความต่อวินาที และเกิดคำถามอันสมควรขึ้นว่า พวกที่เหลือ อยู่ที่ไหน? จากที่เราสรุปว่า Graylog ไม่สามารถรับมือได้ เราตรวจสอบแล้ว และแน่นอนว่า Graylog ที่มี Elasticsearch ไม่ได้เชี่ยวชาญโฟลว์นี้
ต่อไป การค้นพบอื่นๆ ที่เราได้ทำไประหว่างทาง
การเขียนไปยังซ็อกเก็ตถูกบล็อก มันเกิดขึ้นได้อย่างไร? เมื่อฉันใช้ rsyslog ในการจัดส่ง ถึงจุดหนึ่งเราได้ทำลายช่องทางระหว่างศูนย์ข้อมูล การจัดส่งขึ้นในที่หนึ่ง การจัดส่งขึ้นในที่อื่น ทั้งหมดนี้เกิดขึ้นกับเครื่องที่มี API ที่เขียนลงในซ็อกเก็ต rsyslog มีคิว จากนั้นคิวสำหรับเขียนไปยังซ็อกเก็ตยูนิกซ์ก็เต็ม ซึ่งตามค่าเริ่มต้นคือ 128 แพ็กเก็ต และเขียนถัดไป () ในบล็อกแอปพลิเคชัน เมื่อเราดูไลบรารีที่เราใช้ในแอปพลิเคชัน Go มีการเขียนไว้ที่นั่นว่าการเขียนไปยังซ็อกเก็ตนั้นเกิดขึ้นในโหมดไม่ปิดกั้น เราแน่ใจว่าไม่มีอะไรถูกบล็อก เพราะเราเคยอ่านเจอ
มีความจำเป็นต้องตรวจสอบขนาดของคิวซึ่งจะช่วยไม่ให้เหยียบคราดนี้ ประการแรก เราสามารถตรวจสอบได้เมื่อเราเริ่มสูญเสียข้อความ ประการที่สอง เราสามารถตรวจสอบได้ว่าโดยทั่วไปเรามีปัญหาในการจัดส่ง
และอีกช่วงเวลาที่ไม่พึงประสงค์ การขยาย 10 เท่าในสถาปัตยกรรมไมโครเซอร์วิสนั้นง่ายมาก เรามีคำขอเข้ามาไม่มากนัก แต่เนื่องจากกราฟที่ข้อความเหล่านี้ทำงานต่อไป เนื่องจากบันทึกการเข้าถึง เราจึงเพิ่มภาระในบันทึกจริงประมาณสิบเท่า น่าเสียดายที่ฉันไม่มีเวลาคำนวณตัวเลขที่แน่นอน แต่ไมโครเซอร์วิสคือสิ่งที่พวกเขาเป็น สิ่งนี้จะต้องเก็บไว้ในใจ กลายเป็นว่าตอนนี้ระบบย่อยการเก็บบันทึกโหลดมากที่สุดในลาซาด้า
จะแก้ปัญหาการค้นหาแบบยืดหยุ่นได้อย่างไร? หากคุณต้องการรับบันทึกอย่างรวดเร็วในที่เดียว เพื่อไม่ให้เรียกใช้ในเครื่องทั้งหมดและรวบรวมไว้ที่นั่น ให้ใช้ที่เก็บไฟล์ สิ่งนี้รับประกันว่าจะได้ผล มันทำจากเซิร์ฟเวอร์ใดก็ได้ คุณเพียงแค่ติดดิสก์ที่นั่นและใส่ syslog หลังจากนั้น คุณรับประกันได้ว่าบันทึกทั้งหมดจะถูกรวมไว้ในที่เดียว จากนั้นจึงค่อยกำหนดค่า elasticsearch, greylog หรืออย่างอื่น แต่คุณจะมีบันทึกทั้งหมดอยู่แล้ว และยิ่งไปกว่านั้น คุณสามารถจัดเก็บบันทึกเหล่านั้นได้ เท่าที่ดิสก์อาร์เรย์จะมีเพียงพอ
ตอนที่ฉันรายงาน โครงร่างเริ่มมีลักษณะเช่นนี้ เราหยุดเขียนไฟล์จริง ตอนนี้เป็นไปได้มากที่เราจะปิดส่วนที่เหลือ บนเครื่องที่ใช้ API เราจะหยุดเขียนไฟล์ ประการแรกมีที่เก็บไฟล์ซึ่งทำงานได้ดีมาก ประการที่สอง เครื่องเหล่านี้มีพื้นที่ว่างไม่เพียงพอ คุณต้องตรวจสอบอย่างต่อเนื่อง
ส่วนนี้กับ Logstash และ Graylog มันพุ่งปรี๊ดจริงๆ ดังนั้นคุณต้องกำจัดมัน คุณต้องเลือกอย่างใดอย่างหนึ่ง
เราตัดสินใจทิ้ง Logstash และ Kibana เพราะเรามีแผนกรักษาความปลอดภัย. การเชื่อมต่อคืออะไร? การเชื่อมต่อคือ Kibana ที่ไม่มี X-Pack และไม่มี Shield ไม่อนุญาตให้คุณแยกสิทธิ์การเข้าถึงบันทึก ดังนั้นพวกเขาจึงนำเกรย์ล็อก มันมีทุกอย่าง ฉันไม่ชอบมัน แต่มันใช้งานได้ เราซื้อฮาร์ดแวร์ใหม่ ติดตั้ง Graylog ใหม่ที่นั่น และย้ายบันทึกทั้งหมดที่มีรูปแบบเข้มงวดไปยัง Graylog แยกต่างหาก เราได้แก้ปัญหาประเภทต่างๆ ของฟิลด์เดียวกันในองค์กร
สิ่งที่รวมอยู่ใน Graylog ใหม่ เราเพิ่งเขียนทุกอย่างในนักเทียบท่า เราใช้เซิร์ฟเวอร์จำนวนมาก เปิดตัว Kafka สามอินสแตนซ์ เซิร์ฟเวอร์ Graylog เวอร์ชัน 7 2.3 ตัว (เพราะฉันต้องการ Elasticsearch เวอร์ชัน 5) ทั้งหมดนี้เกิดขึ้นจากการโจมตีจาก HDD เราเห็นอัตราการจัดทำดัชนีสูงถึง 100 ข้อความต่อวินาที เราเห็นตัวเลขว่าข้อมูล 140 เทราไบต์ต่อสัปดาห์
และคราดอีกครั้ง! เรามีการขายสองครั้งที่กำลังจะมาถึง เราได้ย้ายไปเกิน 6 ล้านโพสต์ เรา Graylog ไม่มีเวลาที่จะเคี้ยว อย่างใดคุณต้องเอาชีวิตรอดอีกครั้ง
นี่คือวิธีที่เรารอดชีวิตมาได้ เพิ่มเซิร์ฟเวอร์และ SSD อีกสองสามตัว ปัจจุบันเราอยู่อย่างนี้ ตอนนี้เรากำลังเคี้ยวข้อความ 160 ข้อความต่อวินาที เรายังไม่ถึงขีดจำกัด ดังนั้นจึงไม่มีความชัดเจนว่าเราจะเอามันออกมาได้มากน้อยเพียงใดตามความเป็นจริง
นี่คือแผนการของเราในอนาคต ในบรรดาสิ่งเหล่านี้ สิ่งที่สำคัญที่สุดคือความพร้อมใช้งานสูง เรายังไม่มีเลย รถยนต์หลายคันถูกตั้งค่าในลักษณะเดียวกัน แต่จนถึงตอนนี้ทุกอย่างต้องผ่านรถคันเดียว จำเป็นต้องใช้เวลาในการตั้งค่าการเฟลโอเวอร์ระหว่างกัน
รวบรวมเมตริกจาก Graylog
จำกัดอัตราเพื่อให้เรามี API บ้าๆ หนึ่งอันที่ไม่ทำลายแบนด์วิธและอื่นๆ ของเรา
และสุดท้าย ลงนาม SLA กับนักพัฒนาเพื่อให้เราให้บริการได้มากขนาดนั้น ถ้าเขียนมากไปก็ขออภัย
และเขียนเอกสาร
สรุปผลทุกอย่างที่เราได้ประสบมา ประการแรกมาตรฐาน ประการที่สอง syslog เป็นเค้ก ประการที่สาม rsyslog ทำงานเหมือนกับที่เขียนบนสไลด์ทุกประการ และไปที่คำถามกันเถอะ
คำถาม.
คำถาม: ทำไมพวกเขาถึงตัดสินใจไม่รับ ... (filebeat?)
ตอบ: จำเป็นต้องเขียนลงไฟล์. ฉันไม่ต้องการจริงๆ เมื่อ API ของคุณเขียนข้อความเป็นพันๆ ข้อความต่อวินาที แม้ว่าคุณจะหมุนเวียนชั่วโมงละครั้ง การดำเนินการนี้ก็ยังไม่ใช่ตัวเลือก คุณสามารถเขียนไปป์ ผู้พัฒนาถามฉันว่า: "จะเกิดอะไรขึ้นหากกระบวนการที่เราเขียนล้มเหลว" ฉันไม่พบว่าจะตอบพวกเขาอย่างไรและพูดว่า: "โอเค อย่าทำอย่างนั้น"
คำถาม: ทำไมคุณไม่เพียงแค่เขียนบันทึกไปยัง HDFS?
ตอบตอบ: นี่คือขั้นตอนต่อไป เราคิดเกี่ยวกับเรื่องนี้ตั้งแต่เริ่มต้น แต่เนื่องจากไม่มีทรัพยากรที่จะจัดการกับมันในขณะนี้ มันค้างอยู่ในการแก้ปัญหาระยะยาวของเรา
คำถาม: รูปแบบคอลัมน์จะเหมาะสมกว่า
ตอบ: ฉันเข้าใจ. เรา "เพื่อ" ด้วยมือทั้งสองข้าง
คำถาม: คุณเขียนถึง rsyslog มีทั้ง TCP และ UDP ที่นั่น แต่ถ้าเป็น UDP คุณจะรับประกันการจัดส่งได้อย่างไร
ตอบตอบ: มีสองจุด ก่อนอื่นฉันบอกทุกคนทันทีว่าเราไม่รับประกันการส่งมอบบันทึก เพราะเมื่อนักพัฒนามาและพูดว่า: “มาเริ่มเขียนข้อมูลทางการเงินที่นั่น แล้วคุณจะใส่ไว้ที่ไหนสักแห่งสำหรับเราเผื่อมีอะไรเกิดขึ้น” เราตอบพวกเขาว่า “เยี่ยมมาก! มาเริ่มบล็อกการเขียนลงในซ็อกเก็ตและทำธุรกรรม เพื่อให้คุณรับประกันว่าจะใส่ลงในซ็อกเก็ตให้เราและตรวจสอบให้แน่ใจว่าเราได้รับจากอีกด้านหนึ่ง และในขณะนี้ทุกคนก็ไม่จำเป็นในทันที และถ้าไม่ แล้วเรามีคำถามอะไร? หากคุณไม่ต้องการรับประกันการเขียนไปยังซ็อกเก็ต แล้วเหตุใดเราจึงรับประกันการส่งมอบ เรากำลังพยายามอย่างเต็มที่ เราพยายามส่งมอบให้ได้มากที่สุดและดีที่สุดเท่าที่จะเป็นไปได้ แต่เราไม่รับประกัน 100% ดังนั้นคุณไม่จำเป็นต้องเขียนข้อมูลทางการเงินที่นั่น มีฐานข้อมูลการทำธุรกรรมสำหรับสิ่งนี้
คำถาม: เมื่อ API สร้างข้อความบางส่วนไปยังบันทึกและถ่ายโอนการควบคุมไปยังไมโครเซอร์วิส คุณเคยพบปัญหาที่ข้อความจากไมโครเซอร์วิสต่างๆ ส่งผิดลำดับหรือไม่ ด้วยเหตุนี้ความสับสนจึงเกิดขึ้น
ตอบA: เป็นเรื่องปกติที่พวกเขาจะสั่งไม่เหมือนกัน คุณต้องพร้อมสำหรับสิ่งนี้ เนื่องจากการจัดส่งผ่านเครือข่ายใดๆ ไม่รับประกันการสั่งซื้อของคุณ หรือคุณจำเป็นต้องใช้ทรัพยากรพิเศษในการดำเนินการนี้ หากเราใช้พื้นที่จัดเก็บไฟล์ API แต่ละรายการจะบันทึกบันทึกลงในไฟล์ของตัวเอง แต่ rsyslog จะแยกย่อยออกเป็นไดเร็กทอรีที่นั่น API แต่ละรายการมีบันทึกของตัวเองที่นั่น ซึ่งคุณสามารถไปดู จากนั้นคุณสามารถเปรียบเทียบโดยใช้การประทับเวลาในบันทึกนี้ หากพวกเขาไปดูใน Graylog พวกเขาจะถูกจัดเรียงตามการประทับเวลา ทุกอย่างจะดีที่นั่น
คำถาม: การประทับเวลาอาจแตกต่างกันไปในหน่วยมิลลิวินาที
ตอบ: การประทับเวลาถูกสร้างขึ้นโดย API เอง อันที่จริงนี่คือประเด็นทั้งหมด เรามี NTP API สร้างการประทับเวลาแล้วในข้อความเอง มันไม่ได้ถูกเพิ่มโดย rsyslog
คำถาม: การโต้ตอบระหว่างศูนย์ข้อมูลไม่ชัดเจนมากนัก ภายในเฟรมเวิร์กของศูนย์ข้อมูล เป็นที่ชัดเจนว่าบันทึกถูกรวบรวมและประมวลผลอย่างไร การทำงานร่วมกันระหว่างศูนย์ข้อมูลเป็นอย่างไร? หรือศูนย์ข้อมูลแต่ละแห่งมีชีวิตของตัวเอง?
ตอบ: เกือบ. เรามีแต่ละประเทศตั้งอยู่ในศูนย์ข้อมูลแห่งเดียว ขณะนี้เราไม่มีการแพร่กระจายเพื่อให้ประเทศหนึ่งอยู่ในศูนย์ข้อมูลที่แตกต่างกัน ดังนั้นจึงไม่จำเป็นต้องรวมเข้าด้วยกัน ภายในศูนย์แต่ละแห่งจะมี Log Relay นี่คือเซิร์ฟเวอร์ Rsyslog ในความเป็นจริงสองเครื่องจัดการ พวกเขาตั้งค่าในลักษณะเดียวกัน แต่สำหรับตอนนี้ การจราจรจะผ่านหนึ่งในนั้น เธอบันทึกการรวมทุกอย่าง มีคิวดิสก์ในกรณี เธอกดบันทึกและส่งไปยังศูนย์ข้อมูลกลาง (สิงคโปร์) ซึ่งต่อไปพวกเขาถูกวางยาพิษใน Graylog และศูนย์ข้อมูลแต่ละแห่งมีที่เก็บไฟล์ของตัวเอง ในกรณีที่เราขาดการเชื่อมต่อ เรามีบันทึกทั้งหมดอยู่ที่นั่น พวกเขาจะอยู่ที่นั่น พวกเขาจะถูกเก็บไว้ที่นั่น
คำถาม: คุณได้รับบันทึกจากที่นั่นในสถานการณ์ที่ผิดปกติหรือไม่?
ตอบ: คุณสามารถไปที่นั่น (ไปที่ที่เก็บไฟล์) และดู
คำถาม: คุณจะตรวจสอบได้อย่างไรว่าคุณไม่สูญเสียบันทึก?
ตอบ: เรากำลังสูญเสียพวกเขาจริง ๆ และเรากำลังเฝ้าติดตามมัน การตรวจสอบเริ่มต้นเมื่อเดือนที่แล้ว ไลบรารีที่ Go API ใช้มีเมตริก เธอสามารถนับได้ว่าเธอล้มเหลวในการเขียนซ็อกเก็ตกี่ครั้ง ในขณะนี้มีฮิวริสติกที่ยุ่งยาก มีบัฟเฟอร์อยู่ที่นั่น พยายามเขียนข้อความจากซ็อกเก็ต หากบัฟเฟอร์ล้น บัฟเฟอร์จะเริ่มลดลง และเขานับจำนวนที่เขาทำตก ถ้าเคาน์เตอร์เริ่มล้นที่นั่น เราจะรู้เกี่ยวกับมัน ตอนนี้พวกมันกำลังมาที่โพรมีธีอุสด้วย และคุณสามารถดูกราฟได้ใน Grafana คุณสามารถตั้งค่าการเตือน แต่ยังไม่ชัดเจนว่าจะส่งให้ใคร
คำถาม: ใน elasticsearch คุณจัดเก็บบันทึกด้วยความซ้ำซ้อน คุณมีตัวจำลองกี่ตัว?
ตอบ: หนึ่งแบบจำลอง
คำถาม: มันเป็นเพียงบรรทัดเดียว?
ตอบ: นี่คือต้นแบบและแบบจำลอง ข้อมูลถูกจัดเก็บซ้ำ
คำถาม: คุณได้ปรับขนาดของบัฟเฟอร์ rsyslog หรือไม่?
ตอบ: เราเขียนดาตาแกรมไปยังซ็อกเก็ตยูนิกซ์ที่กำหนดเอง สิ่งนี้กำหนดข้อ จำกัด ให้เราทันที 128 กิโลไบต์ เราไม่สามารถเขียนเพิ่มเติมลงไปได้ เราได้เขียนสิ่งนี้ลงในมาตรฐาน ใครต้องการเข้าไปในที่เก็บข้อมูลพวกเขาเขียน 128 กิโลไบต์ นอกจากนี้ห้องสมุดยังตัดออกและตั้งค่าสถานะว่าข้อความถูกตัดออก เรามีฟิลด์พิเศษในมาตรฐานของข้อความเอง ซึ่งแสดงว่าข้อความนั้นถูกตัดระหว่างการบันทึกหรือไม่ เราจึงมีโอกาสติดตามช่วงเวลานี้
คำถาม: คุณเขียน JSON ที่เสียหายหรือไม่
ตอบ: JSON ที่เสียหายจะถูกยกเลิกระหว่างการถ่ายทอดเนื่องจากแพ็กเก็ตมีขนาดใหญ่เกินไป หรือ Graylog จะถูกทิ้ง เนื่องจากจะไม่สามารถแยกวิเคราะห์ JSON ได้ แต่มีความแตกต่างที่ต้องแก้ไขที่นี่และส่วนใหญ่จะเชื่อมโยงกับ rsyslog ฉันได้กรอกข้อมูลบางประเด็นแล้ว ซึ่งยังคงต้องดำเนินการต่อไป
คำถาม: ทำไมต้องคาฟคา? คุณเคยลอง RabbitMQ แล้วหรือยัง? Graylog ไม่เพิ่มขึ้นภายใต้การโหลดดังกล่าว?
ตอบ: มันใช้งานไม่ได้กับ Graylog และเกรย์ล็อกกำลังเป็นรูปเป็นร่าง เป็นปัญหาสำหรับเขาจริงๆ เขาเป็นคนประเภทหนึ่ง และในความเป็นจริงมันไม่จำเป็น ฉันอยากจะเขียนจาก rsyslog โดยตรงไปยัง elasticsearch แล้วดู Kibana แต่เราต้องจัดการกับปัญหากับเจ้าหน้าที่รักษาความปลอดภัย นี่เป็นตัวแปรที่เป็นไปได้ในการพัฒนาของเราเมื่อเราเลิกใช้ Graylog และใช้ Kibana Logstash จะไม่สมเหตุสมผล เพราะฉันสามารถทำเช่นเดียวกันกับ rsyslog และมีโมดูลสำหรับเขียนไปยัง elasticsearch ด้วย Graylog เรากำลังพยายามที่จะมีชีวิตอยู่ เรายังปรับแต่งเล็กน้อย แต่ยังมีช่องว่างสำหรับการปรับปรุง
เกี่ยวกับคาฟคา นั่นเป็นวิธีที่มันเกิดขึ้นในประวัติศาสตร์ เมื่อฉันมาถึง มันอยู่ที่นั่นแล้ว และบันทึกกำลังเขียนถึงมันแล้ว เราเพิ่งเพิ่มคลัสเตอร์ของเราและย้ายบันทึกเข้าไป เราจัดการเขา เรารู้ว่าเขารู้สึกอย่างไร สำหรับ RabbitMQ... เรากำลังมีปัญหากับ RabbitMQ และ RabbitMQ กำลังพัฒนาเพื่อเรา เรามีมันในการผลิตและมีปัญหากับมัน ตอนนี้ ก่อนการขาย เขาจะถูกทำให้เป็นผี และเขาจะเริ่มทำงานตามปกติ แต่ก่อนหน้านั้นฉันยังไม่พร้อมที่จะปล่อยให้มันเข้าสู่การผลิต มีอีกหนึ่งจุด Graylog สามารถอ่านเวอร์ชัน AMQP 0.9 และ rsyslog สามารถเขียนเวอร์ชัน AMQP 1.0 และไม่มีวิธีแก้ปัญหาเดียวที่สามารถทำได้ทั้งสองอย่างตรงกลาง มีอย่างใดอย่างหนึ่ง ตอนนี้มีเพียงคาฟคาเท่านั้น แต่ก็มีความแตกต่างเช่นกัน เนื่องจาก omkafka ของ rsyslog เวอร์ชันที่เราใช้อาจสูญเสียบัฟเฟอร์ข้อความทั้งหมดที่ดึงมาจาก rsyslog ตราบใดที่เรายังทนกับมัน
คำถาม: คุณใช้ Kafka เพราะคุณมีมันหรือไม่? ไม่ได้ใช้เพื่อวัตถุประสงค์อื่นใด?
ตอบ: Kafka ซึ่งใช้โดยทีม Data Science นี่เป็นโครงการแยกต่างหากซึ่งน่าเสียดายที่ฉันไม่สามารถพูดอะไรได้ ฉันไม่รู้. เธอดำเนินการโดยทีมวิทยาศาสตร์ข้อมูล เมื่อท่อนซุงเริ่มขึ้น พวกเขาตัดสินใจที่จะใช้มัน เพื่อไม่ให้เป็นของตนเอง ตอนนี้เราได้อัปเดต Graylog แล้ว และเราสูญเสียความเข้ากันได้ เพราะมี Kafka เวอร์ชันเก่า เราต้องสร้างของเราเอง ในขณะเดียวกัน เราได้ตัดสี่หัวข้อนี้สำหรับแต่ละ API เราสร้างช่องกว้างหนึ่งช่องสำหรับการแสดงสดทั้งหมด ช่องกว้างหนึ่งช่องสำหรับทุกระยะ และเราถ่ายทำทุกอย่างที่นั่น Graylog กวาดล้างสิ่งเหล่านี้ไปพร้อมกัน
คำถาม: ทำไมเราถึงต้องการชามานนี้ด้วยซ็อกเก็ต? คุณลองใช้ไดรเวอร์บันทึก syslog สำหรับคอนเทนเนอร์แล้วหรือยัง
ตอบ: เมื่อเราถามคำถามนี้ เรามีความสัมพันธ์ที่ตึงเครียดกับนักเทียบท่า มันเป็นนักเทียบท่า 1.0 หรือ 0.9 นักเทียบท่าเองก็แปลก ประการที่สอง หากคุณใส่บันทึกเข้าไปด้วย ... ฉันมีข้อสงสัยที่ยังไม่ได้รับการยืนยันว่ามันส่งบันทึกทั้งหมดผ่านตัวมันเองผ่าน docker daemon หากเรามี API หนึ่งตัวที่ผิดปกติ API ที่เหลือจะพบว่าไม่สามารถส่ง stdout และ stderr ได้ ฉันไม่รู้ว่าสิ่งนี้จะนำไปสู่ที่ใด ฉันมีความสงสัยในระดับความรู้สึกที่ไม่จำเป็นต้องใช้ไดรเวอร์ docker syslog ในสถานที่นี้ แผนกทดสอบการทำงานของเรามีคลัสเตอร์ Graylog พร้อมบันทึกเป็นของตัวเอง พวกเขาใช้ไดรเวอร์บันทึกนักเทียบท่าและทุกอย่างดูเหมือนจะเรียบร้อยดี แต่พวกเขาเขียน GELF ไปที่ Graylog ทันที ในตอนที่เราเริ่มต้นทั้งหมดนี้ เราต้องการให้มันทำงาน บางทีต่อไปเมื่อมีคนมาบอกว่ามันใช้งานได้ปกติมาเป็นร้อยปีแล้ว เราจะลองดู
คำถาม: คุณส่งข้อมูลระหว่างศูนย์ข้อมูลโดยใช้ rsyslog ทำไมไม่ไปที่คาฟคา?
ตอบ: เราทำสิ่งนี้ และมันก็เป็นอย่างนั้นจริงๆ ด้วยเหตุผลสองประการ หากแชนเนลนั้นตายสนิท บันทึกทั้งหมดของเราแม้จะอยู่ในรูปแบบบีบอัดก็จะไม่สามารถปีนผ่านได้ และคาฟคาก็ยอมให้พวกเขาแพ้ในกระบวนการ ด้วยวิธีนี้เราจะกำจัดการเกาะติดของท่อนซุงเหล่านี้ เราใช้คาฟคาในกรณีนี้โดยตรง ถ้าเรามีแชนเนลที่ดีและต้องการปล่อยให้เป็นอิสระ เราก็ใช้ rsyslog ของพวกเขา แต่ในความเป็นจริง คุณสามารถตั้งค่าเพื่อให้มันทิ้งสิ่งที่ไม่ผ่านเข้าไปได้ ในขณะนี้ เรากำลังใช้การส่ง rsyslog โดยตรงที่ไหนสักแห่ง ที่ไหนสักแห่ง คาฟคา
ที่มา: will.com