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

รายงานปัญหา ดูแหล่งที่มา รุ่น Nightly · 7.4 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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