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

รายงานปัญหา ดูซอร์สโค้ด รุ่น Nightly · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

บิวด์ที่เผยแพร่ที่ Google

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

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

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

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

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

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