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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

งานสร้างที่เผยแพร่ที่ Google

ตั้งแต่ปี 2008 Google ได้ใช้ระบบบิลด์แบบกระจายที่ใช้ทั้งการแคชระยะไกลและการดำเนินการจากระยะไกล ดังที่อธิบายไว้ในรูปที่ 3

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

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

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

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

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