เมื่อมีโค้ดเบสขนาดใหญ่ เชนของ Dependency อาจซับซ้อนมาก แม้แต่ไบนารีที่เรียบง่ายก็มักจะขึ้นอยู่กับเป้าหมายการสร้างหลายหมื่นรายการ ที่ สเกลนี้ การสร้างให้เสร็จสมบูรณ์ในเวลาที่เหมาะสม บนเครื่องเดียวเป็นไปไม่ได้ ระบบบิลด์ใดๆ ก็ไม่สามารถหลีกเลี่ยงกฎพื้นฐาน ของฟิสิกส์ที่กำหนดไว้ในฮาร์ดแวร์ของเครื่องได้ วิธีเดียวที่จะทำให้การดำเนินการนี้สำเร็จ คือการใช้ระบบบิลด์ที่รองรับบิลด์แบบกระจาย ซึ่งหน่วยของ งานที่ระบบดำเนินการจะกระจายไปยังเครื่องจำนวนเท่าใดก็ได้ที่ปรับขนาดได้ สมมติว่าเราแบ่งงานของระบบออกเป็นหน่วยเล็กๆ มากพอ (จะกล่าวถึงในภายหลัง) วิธีนี้จะช่วยให้เราสร้างบิลด์ขนาดใดก็ได้ให้เสร็จสมบูรณ์ได้เร็วที่สุดเท่าที่เราต้องการจ่าย ความสามารถในการปรับขนาดนี้เป็นเป้าหมายสำคัญ ที่เรามุ่งมั่นที่จะบรรลุด้วยการกำหนดระบบบิลด์ที่อิงตามอาร์ติแฟกต์
การแคชระยะไกล
การบิลด์แบบกระจายที่ง่ายที่สุดคือการบิลด์ที่ใช้ประโยชน์จากการแคชระยะไกลเท่านั้น ซึ่งแสดงในรูปที่ 1
รูปที่ 1 บิลด์แบบกระจายที่แสดงการแคชระยะไกล
ทุกระบบที่ทำการบิลด์ รวมถึงทั้งเวิร์กสเตชันของนักพัฒนาแอปและระบบการผสานรวมอย่างต่อเนื่อง จะใช้การอ้างอิงไปยังบริการแคชระยะไกลทั่วไปร่วมกัน บริการนี้อาจเป็นระบบพื้นที่เก็บข้อมูลระยะสั้นที่รวดเร็วและในพื้นที่ เช่น Redis หรือบริการระบบคลาวด์ เช่น Google Cloud Storage เมื่อใดก็ตามที่ผู้ใช้ต้องการ สร้างอาร์ติแฟกต์ ไม่ว่าจะโดยตรงหรือเป็นทรัพยากร Dependency ระบบจะตรวจสอบ กับแคชระยะไกลก่อนเพื่อดูว่ามีอาร์ติแฟกต์นั้นอยู่แล้วหรือไม่ หากเป็นเช่นนั้น ระบบจะดาวน์โหลดอาร์ติแฟกต์แทนการสร้าง หากไม่มี ระบบจะสร้างอาร์ติแฟกต์ เองและอัปโหลดผลลัพธ์กลับไปที่แคช ซึ่งหมายความว่า การขึ้นต่อระดับต่ำซึ่งไม่ค่อยมีการเปลี่ยนแปลงจะสร้างเพียงครั้งเดียวและแชร์ กับผู้ใช้ได้ แทนที่จะให้ผู้ใช้แต่ละรายสร้างใหม่ ที่ Google เราใช้ อาร์ติแฟกต์จำนวนมากจากแคชแทนที่จะสร้างขึ้นใหม่ทั้งหมด ซึ่งช่วย ลดต้นทุนในการเรียกใช้ระบบบิลด์ของเราได้อย่างมาก
หากต้องการให้ระบบแคชระยะไกลทำงาน ระบบบิลด์ต้องรับประกันว่าบิลด์จะทำซ้ำได้อย่างสมบูรณ์ กล่าวคือ สำหรับเป้าหมายการสร้างใดๆ จะต้องสามารถ กำหนดชุดอินพุตไปยังเป้าหมายนั้นได้ เพื่อให้ชุดอินพุตเดียวกัน สร้างเอาต์พุตเดียวกันทุกประการในเครื่องใดก็ได้ นี่เป็นวิธีเดียวที่จะ รับประกันว่าผลลัพธ์ของการดาวน์โหลดอาร์ติแฟกต์จะเหมือนกับผลลัพธ์ ของการสร้างด้วยตนเอง โปรดทราบว่าการดำเนินการนี้กำหนดให้แต่ละอาร์ติแฟกต์ในแคช ต้องมีคีย์ทั้งในเป้าหมายและแฮชของอินพุต เพื่อให้วิศวกร แต่ละคนทำการแก้ไขเป้าหมายเดียวกันได้พร้อมกัน และแคชระยะไกลจะจัดเก็บอาร์ติแฟกต์ทั้งหมดที่ได้และแสดง อย่างเหมาะสมโดยไม่มีข้อขัดแย้ง
แน่นอนว่าการดาวน์โหลดอาร์ติแฟกต์ต้องเร็วกว่าการสร้างอาร์ติแฟกต์จึงจะได้รับประโยชน์จากแคชระยะไกล แต่ก็ไม่ได้เป็นเช่นนั้นเสมอไป โดยเฉพาะอย่างยิ่งหากเซิร์ฟเวอร์แคชอยู่ไกลจากเครื่องที่ทำการสร้าง เครือข่ายและระบบบิลด์ของ Google ได้รับการปรับแต่งอย่างพิถีพิถันเพื่อให้แชร์ผลลัพธ์ของบิลด์ได้อย่างรวดเร็ว
การดำเนินการจากระยะไกล
การแคชระยะไกลไม่ใช่การสร้างแบบกระจายที่แท้จริง หากแคชหายไปหรือหากคุณ ทำการเปลี่ยนแปลงระดับต่ำที่ต้องสร้างทุกอย่างใหม่ คุณยังคงต้อง ทำการสร้างทั้งหมดในเครื่องของคุณ เป้าหมายที่แท้จริงคือการรองรับการดำเนินการจากระยะไกล ซึ่งสามารถกระจายงานจริงของการสร้างไปยังผู้ปฏิบัติงานจำนวนเท่าใดก็ได้ รูปที่ 2 แสดงระบบการดำเนินการจากระยะไกล
รูปที่ 2 ระบบการดำเนินการจากระยะไกล
เครื่องมือบิลด์ที่ทำงานในเครื่องของผู้ใช้แต่ละราย (ซึ่งผู้ใช้เป็นวิศวกรหรือระบบบิลด์อัตโนมัติ) จะส่งคำขอไปยังมาสเตอร์บิลด์ส่วนกลาง มาสเตอร์การสร้างจะแบ่งคำขอออกเป็นการดำเนินการที่เป็นคอมโพเนนต์และกำหนดเวลา การดำเนินการเหล่านั้นในกลุ่มผู้ปฏิบัติงานที่ปรับขนาดได้ Worker แต่ละตัว จะดำเนินการตามที่ได้รับคำสั่งโดยใช้ข้อมูลที่ผู้ใช้ระบุ และ เขียนอาร์ติแฟกต์ที่ได้ ระบบจะแชร์อาร์ติแฟกต์เหล่านี้ในเครื่องอื่นๆ ที่ดำเนินการซึ่งต้องใช้อาร์ติแฟกต์ดังกล่าวจนกว่าจะสร้างเอาต์พุตสุดท้ายและส่งไปยังผู้ใช้ได้
ส่วนที่ซับซ้อนที่สุดในการติดตั้งใช้งานระบบดังกล่าวคือการจัดการการสื่อสาร ระหว่าง Worker, Master และเครื่องของผู้ใช้ Worker อาจ ต้องอาศัยอาร์ติแฟกต์ระดับกลางที่สร้างโดย Worker อื่น และต้องส่งเอาต์พุตสุดท้าย กลับไปยังเครื่องของผู้ใช้ เราสามารถทำได้โดยสร้างแคชแบบกระจายที่อธิบายไว้ก่อนหน้านี้ โดยให้แต่ละ Worker เขียนผลลัพธ์ของตัวเองลงในแคชและอ่านทรัพยากร Dependency จากแคช บล็อกหลักจะป้องกันไม่ให้ Worker ดำเนินการต่อจนกว่าทุกอย่างที่ Worker ขึ้นอยู่ด้วยจะเสร็จสิ้น ในกรณีนี้ Worker จะอ่านอินพุตจากแคชได้ ระบบจะแคชผลิตภัณฑ์ขั้นสุดท้ายด้วย เพื่อให้เครื่องในพื้นที่ดาวน์โหลดได้ โปรดทราบว่าเรายังต้องการวิธีแยกต่างหากในการส่งออกการเปลี่ยนแปลงในเครื่องในโครงสร้างแหล่งที่มาของผู้ใช้ เพื่อให้ Worker สามารถใช้การเปลี่ยนแปลงเหล่านั้นก่อนที่จะสร้าง
หากต้องการให้ระบบนี้ทำงานได้ ส่วนต่างๆ ทั้งหมดของระบบบิลด์ที่อิงตามอาร์ติแฟกต์ที่อธิบายไว้ ก่อนหน้านี้จะต้องทำงานร่วมกัน สภาพแวดล้อมในการสร้างต้องอธิบายตัวเองได้อย่างสมบูรณ์ เพื่อให้เราสามารถเปิดใช้งาน Worker ได้โดยไม่ต้องมีคนเข้ามาเกี่ยวข้อง กระบวนการบิลด์ ต้องมีอยู่ในตัวเองอย่างสมบูรณ์ เนื่องจากแต่ละขั้นตอนอาจ ดำเนินการในเครื่องที่แตกต่างกัน เอาต์พุตต้องเป็นแบบดีเทอร์มินิสติกโดยสมบูรณ์ เพื่อให้ผู้ปฏิบัติงานแต่ละรายเชื่อถือผลลัพธ์ที่ได้รับจากผู้ปฏิบัติงานรายอื่นๆ ได้ การรับประกันดังกล่าวเป็นสิ่งที่ระบบที่อิงตามงานทำได้ยากมาก ซึ่งทำให้การสร้างระบบการดำเนินการจากระยะไกลที่เชื่อถือได้บนระบบดังกล่าวเป็นไปได้ยาก
บิวด์แบบกระจายที่ Google
ตั้งแต่ปี 2008 Google ใช้ระบบบิลด์แบบกระจายที่ใช้ทั้ง การแคชระยะไกลและการดำเนินการระยะไกล ซึ่งแสดงในรูปที่ 3
รูปที่ 3 ระบบบิลด์แบบกระจายของ Google
แคชระยะไกลของ Google เรียกว่า ObjFS โดยประกอบด้วยแบ็กเอนด์ที่จัดเก็บเอาต์พุตบิลด์ใน Bigtable ซึ่งกระจายอยู่ทั่วกลุ่มเครื่องที่ใช้ในการผลิต และแดมอน FUSE ของฟรอนต์เอนด์ชื่อ objfsd ที่ทำงานในเครื่องของนักพัฒนาซอฟต์แวร์แต่ละคน Daemon ของ FUSE ช่วยให้วิศวกรเรียกดูเอาต์พุตการสร้างได้ราวกับว่าเอาต์พุตเหล่านั้นเป็นไฟล์ปกติที่จัดเก็บไว้ในเวิร์กสเตชัน แต่จะดาวน์โหลดเนื้อหาของไฟล์ตามคำขอเฉพาะสำหรับไฟล์ไม่กี่ไฟล์ที่ผู้ใช้ขอโดยตรงเท่านั้น การแสดงเนื้อหาไฟล์ตามต้องการช่วยลดการใช้งานทั้งเครือข่ายและดิสก์ได้อย่างมาก และระบบสามารถสร้างได้เร็วขึ้นเป็น 2 เท่าเมื่อเทียบกับตอนที่เราจัดเก็บ เอาต์พุตการสร้างทั้งหมดไว้ในดิสก์ภายในของนักพัฒนาซอฟต์แวร์
ระบบการดำเนินการจากระยะไกลของ Google เรียกว่า Forge ไคลเอ็นต์ Forge ใน Blaze (เทียบเท่าภายในของ Bazel) ที่ชื่อ Distributor จะส่งคำขอสำหรับการดำเนินการแต่ละอย่างไปยังงานที่ทำงานใน ศูนย์ข้อมูลของเราที่ชื่อ Scheduler ตัวกำหนดเวลารักษาแคชของผลลัพธ์การดำเนินการ ซึ่งช่วยให้สามารถแสดงการตอบกลับได้ทันทีหากผู้ใช้รายอื่นในระบบได้สร้างการดำเนินการนั้นแล้ว หากไม่ ระบบจะจัดคิวการดำเนินการ กลุ่มงาน Executor จำนวนมากจะอ่านการดำเนินการจากคิวนี้อย่างต่อเนื่อง ดำเนินการ และจัดเก็บผลลัพธ์ใน Bigtable ของ ObjFS โดยตรง ผู้ดำเนินการจะใช้ผลลัพธ์เหล่านี้สำหรับดำเนินการในอนาคต หรือผู้ใช้ปลายทางจะดาวน์โหลดผ่าน objfsd ก็ได้
ผลลัพธ์สุดท้ายคือระบบที่ปรับขนาดเพื่อรองรับการสร้างทั้งหมดที่ดำเนินการใน Google ได้อย่างมีประสิทธิภาพ และขนาดของการบิลด์ของ Google นั้นใหญ่โตมากจริงๆ โดย Google เรียกใช้การบิลด์หลายล้านรายการที่ดำเนินการทดสอบหลายล้านกรณีและสร้างเอาต์พุตการบิลด์ขนาดเพตะไบต์ จากซอร์สโค้ดหลายพันล้านบรรทัดทุกวัน ระบบดังกล่าวไม่เพียงช่วยให้วิศวกรของเราสร้างโค้ดเบสที่ซับซ้อนได้อย่างรวดเร็ว แต่ยังช่วยให้เราสามารถใช้เครื่องมือและระบบอัตโนมัติจำนวนมากที่ต้องอาศัยการบิลด์ของเราด้วย