งานสร้างแบบกระจาย

รายงานปัญหา ดูแหล่งที่มา

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

การแคชระยะไกล

ประเภทที่เรียบง่ายที่สุดของบิลด์แบบกระจายคือบิลด์ที่ใช้ประโยชน์จากการแคชระยะไกลเท่านั้น ดังที่แสดงในรูปที่ 1

บิลด์ที่แจกจ่ายพร้อมการแคชระยะไกล

รูปที่ 1 บิลด์แบบกระจายที่แสดงการแคชระยะไกล

ทุกระบบที่สร้างบิลด์ รวมถึงเวิร์กสเตชันของนักพัฒนาซอฟต์แวร์และระบบการผสานรวมอย่างต่อเนื่องจะใช้การอ้างอิงบริการแคชระยะไกลทั่วไป บริการนี้อาจเป็นระบบพื้นที่เก็บข้อมูลภายในเครื่องที่ทำงานรวดเร็วและมีระยะสั้น เช่น Redis หรือบริการระบบคลาวด์อย่าง Google Cloud Storage เมื่อใดก็ตามที่ผู้ใช้ต้องสร้างอาร์ติแฟกต์ ไม่ว่าจะโดยตรงหรือเป็นทรัพยากร Dependency ระบบจะตรวจสอบกับแคชระยะไกลก่อนว่ามีอาร์ติแฟกต์ดังกล่าวอยู่ในนั้นแล้วหรือยัง หากเป็นเช่นนั้น แอป จะดาวน์โหลดอาร์ติแฟกต์แทนการสร้างได้ หากไม่ใช่ ระบบจะสร้างอาร์ติแฟกต์และอัปโหลดผลลัพธ์กลับไปยังแคช ซึ่งหมายความว่าทรัพยากร Dependency ระดับต่ำที่ไม่เปลี่ยนแปลงบ่อยนักสามารถสร้างขึ้นเพียงครั้งเดียวและแชร์กับผู้ใช้ได้ แทนที่จะต้องให้ผู้ใช้แต่ละคนสร้างใหม่ ที่ Google มีอาร์ติแฟกต์มากมายที่จะแสดงผลจากแคชแทนที่จะสร้างขึ้นใหม่ตั้งแต่ต้น ซึ่งช่วยลดค่าใช้จ่ายในการใช้งานระบบบิลด์ได้เป็นอย่างมาก

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

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

การดำเนินการจากระยะไกล

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

ระบบปฏิบัติการระยะไกล

รูปที่ 2 ระบบการดำเนินการระยะไกล

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

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

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

การเผยแพร่บิลด์ที่ Google

ตั้งแต่ปี 2008 Google ได้ใช้ระบบบิลด์แบบกระจายซึ่งใช้ทั้งการแคชระยะไกลและการเรียกใช้จากระยะไกล ตามที่แสดงในรูปที่ 3

ระบบบิลด์ระดับสูง

รูปที่ 3 ระบบบิลด์ที่กระจายของ Google

แคชระยะไกลของ Google เรียกว่า ObjFS ซึ่งประกอบด้วยแบ็กเอนด์ที่จัดเก็บ เอาต์พุตของการสร้างใน Bigtables ที่กระจายทั่วทั้งกลุ่มเครื่องที่ใช้งานจริงของเรา และ Daemon ฟรอนท์เอนด์ FUSE ชื่อ objfsd ที่ทำงานบนเครื่องของนักพัฒนาซอฟต์แวร์แต่ละราย Daemon ของ FUSE ช่วยให้วิศวกรสามารถเรียกดูเอาต์พุตของบิลด์ราวกับเป็นไฟล์ปกติที่จัดเก็บไว้ในเวิร์กสเตชัน แต่จะมีการดาวน์โหลดเนื้อหาไฟล์ตามคำขอเฉพาะสำหรับบางไฟล์ที่ผู้ใช้ขอโดยตรงเท่านั้น การแสดงเนื้อหาไฟล์แบบออนดีมานด์ช่วยลดทั้งการใช้งานเครือข่ายและดิสก์ได้อย่างมาก และระบบสามารถสร้างความเร็วเป็น 2 เท่าเมื่อเทียบกับตอนที่เราจัดเก็บเอาต์พุตของบิลด์ทั้งหมดไว้ในดิสก์ภายในของนักพัฒนาซอฟต์แวร์

ระบบดำเนินการระยะไกลของ Google มีชื่อว่า Forge ไคลเอ็นต์ Forge ใน Blaze (ตำแหน่งเทียบเท่าภายในของ Bazel) ชื่อผู้จัดจำหน่ายจะส่งคำขอสำหรับการดำเนินการแต่ละอย่างไปยังงานที่ทำงานอยู่ในศูนย์ข้อมูลที่เรียกว่า Scheduler เครื่องจัดตารางเวลาจะเก็บแคชของผลการดำเนินการไว้ ทำให้สามารถส่งคืนการตอบกลับได้ทันทีถ้าระบบได้สร้างการดำเนินการไว้แล้ว หากไม่เป็นเช่นนั้น การดำเนินการจะอยู่ในคิว กลุ่มงานของ Executor ขนาดใหญ่จะอ่านการทำงานจากคิวนี้อย่างต่อเนื่อง เรียกใช้งาน และจัดเก็บผลลัพธ์ใน ObjFS Bigtables โดยตรง ผลลัพธ์เหล่านี้พร้อมให้ผู้ดำเนินการดำเนินการในอนาคต หรือพร้อมให้ผู้ใช้ปลายทางดาวน์โหลดผ่าน objfsd

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