หน้านี้จะครอบคลุมวิธีใช้ผู้ปฏิบัติงานถาวร ประโยชน์ ข้อกำหนด และ วิธีที่คนทำงานส่งผลต่อการทำแซนด์บ็อกซ์
ผู้ปฏิบัติงานถาวรเป็นกระบวนการที่ใช้เวลานานซึ่งเริ่มต้นโดยเซิร์ฟเวอร์ Bazel
ทำหน้าที่เป็น Wrapper ของเครื่องมือจริง (ปกติแล้วคือคอมไพเลอร์) หรือ
เครื่องมือด้วยตนเอง เพื่อให้ได้รับประโยชน์จากผู้ปฏิบัติงานอย่างต่อเนื่อง เครื่องมือจะต้อง
รองรับการคอมไพล์ตามลำดับ และ Wrapper ต้องใช้การแปล
ระหว่าง API ของเครื่องมือกับรูปแบบคำขอ/คำตอบที่อธิบายไว้ด้านล่าง เรื่อง
ผู้ปฏิบัติงานอาจถูกเรียกโดยมีและไม่มีแฟล็ก --persistent_worker
ใน
บิลด์เดียวกัน และมีหน้าที่เริ่มต้นและพูดคุยกับ
รวมถึงการปิดระบบผู้ปฏิบัติงานเมื่อออกจากระบบ มีการกำหนดอินสแตนซ์ของผู้ปฏิบัติงานแต่ละรายการแล้ว
(แต่ไม่ได้ถูกแบ่งตาม) ไดเรกทอรีการทำงานที่แยกต่างหากภายใต้
<outputBase>/bazel-workers
การใช้ผู้ปฏิบัติงานถาวร กลยุทธ์การดำเนินการที่ลดลง โอเวอร์เฮดการเริ่มต้น ทำให้สามารถคอมไพล์ JIT ได้มากขึ้น และเปิดใช้การแคชสำหรับ เช่น ต้นไม้ไวยากรณ์นามธรรมในการดำเนินการ กลยุทธ์นี้ ได้รับการปรับปรุงเหล่านี้โดยการส่งคำขอหลายรายการไปยัง ขั้นตอนได้
มีการใช้งานผู้ปฏิบัติงานถาวรสำหรับหลายภาษา รวมถึง Java Scala Kotlin และอื่นๆ
โปรแกรมที่ใช้รันไทม์ NodeJS สามารถใช้ @bazel/worker ไลบรารีตัวช่วยไปยัง ใช้โปรโตคอลผู้ปฏิบัติงาน
การใช้ผู้ปฏิบัติงานถาวร
Bazel 0.27 ขึ้นไป
ใช้ผู้ปฏิบัติงานถาวรโดยค่าเริ่มต้นเมื่อดำเนินการบิลด์ แต่ดำเนินการจากระยะไกล
การดำเนินการจะมีความสำคัญเหนือกว่า สำหรับการดำเนินการที่ไม่รองรับผู้ปฏิบัติงานถาวร
Bazel ย้อนกลับไปที่การเริ่มอินสแตนซ์เครื่องมือสำหรับการดำเนินการแต่ละรายการ คุณสามารถ
ตั้งค่าบิลด์ของคุณให้ใช้ผู้ปฏิบัติงานถาวรโดยการตั้งค่า worker
กลยุทธ์สำหรับเครื่องมือที่เกี่ยวข้อง
การช่วยจำ ตามแนวทางปฏิบัติที่ดีที่สุด ตัวอย่างนี้จะระบุ local
เป็น
การสำรองสำหรับกลยุทธ์ worker
:
bazel build //my:target --strategy=Javac=worker,local
การใช้กลยุทธ์ผู้ปฏิบัติงานแทนกลยุทธ์ในพื้นที่จะช่วยเพิ่มการรวบรวม จะได้รับความเร็วอย่างมีนัยสำคัญ ทั้งนี้ขึ้นอยู่กับการใช้งาน สำหรับ Java บิลด์อาจเป็น 2-4 เร็วขึ้น บางครั้งก็เพิ่มขึ้นสำหรับการคอมไพล์แบบเพิ่มขึ้นเรื่อยๆ การรวบรวม Bazel คือ เร็วขึ้นประมาณ 2.5 เท่าสำหรับผู้ปฏิบัติงาน ดูรายละเอียดเพิ่มเติมได้ที่ "การเลือกจำนวนผู้ปฏิบัติงาน"
หากคุณมีสภาพแวดล้อมบิลด์ระยะไกลที่ตรงกับบิลด์ในเครื่องด้วย
คุณสามารถใช้การทดสอบ
กลยุทธ์ไดนามิก
ซึ่งจะแข่งกับการดำเนินการจากระยะไกลและการดำเนินการของผู้ปฏิบัติงาน หากต้องการเปิดใช้โฆษณาแบบไดนามิก
ให้ส่งต่อ
--experimental_spawn_scheduler
แจ้ง กลยุทธ์นี้ช่วยให้พนักงานทำงานได้โดยอัตโนมัติ คุณจึงไม่จำเป็นต้อง
ระบุกลยุทธ์ worker
แต่คุณยังใช้ local
หรือ sandboxed
เป็น
วิดีโอสำรอง
การเลือกจำนวนผู้ปฏิบัติงาน
จำนวนอินสแตนซ์เริ่มต้นของผู้ปฏิบัติงานต่อความทรงจำคือ 4 แต่สามารถปรับเปลี่ยนได้
พร้อมด้วย
worker_max_instances
แจ้ง แต่การใช้ CPU ที่มีและมาจากการใช้ CPU อย่างเหมาะสม
จำนวนการคอมไพล์ JIT และแคช Hit ที่คุณได้รับ ยิ่งพนักงานมากขึ้น ก็ยิ่งมีมากขึ้น
เป้าหมายจะจ่ายค่าใช้จ่ายในการเริ่มต้นในการเรียกใช้โค้ดที่ไม่ใช่ JITT และไม่พบปัญหาใดๆ
แคช หากคุณมีเป้าหมายที่จะสร้างจำนวนน้อย ผู้ปฏิบัติงานคนเดียวอาจให้
ตัวเลือกที่ดีที่สุดระหว่างความเร็วในการคอมไพล์และการใช้ทรัพยากร (เช่น
ดูปัญหา #8586
แฟล็ก worker_max_instances
จะกำหนดจำนวนอินสแตนซ์ของผู้ปฏิบัติงานสูงสุดต่อ
ตั้งค่าการจดจำและแฟล็ก (ดูด้านล่าง) ดังนั้นในระบบที่ผสมผสานกัน คุณอาจติดมากับ
หน่วยความจำค่อนข้างมากหากใช้ค่าเริ่มต้น สำหรับบิลด์ส่วนเพิ่ม
ของอินสแตนซ์ Worker จำนวนมากมีขนาดเล็กลง
กราฟนี้แสดงเวลาคอมไพล์จากรอยขีดข่วนสำหรับ Bazel (target
//src:bazel
) ในเวิร์กสเตชัน Intel Xeon 3.5 GHz Linux แบบไฮเปอร์เทรด 6 แกน
RAM ขนาด 64 GB สำหรับการกำหนดค่าผู้ปฏิบัติงานแต่ละรายการ จะมีการเรียกใช้บิลด์ที่สะอาด 5 รายการและ
คือค่าเฉลี่ยของ 4 ปัจจัยสุดท้าย
รูปที่ 1 กราฟการปรับปรุงประสิทธิภาพของบิลด์ที่สะอาด
สำหรับการกำหนดค่านี้ ผู้ปฏิบัติงาน 2 คนจะให้คอมไพล์ที่เร็วที่สุด แม้ว่าจะมีเพียง 14% เท่านั้น ที่ดีขึ้นเมื่อเทียบกับพนักงาน 1 คน ผู้ปฏิบัติงาน 1 คนเป็นตัวเลือกที่ดีหากคุณต้องการ ใช้หน่วยความจำน้อยลง
โดยทั่วไปแล้ว การรวบรวมเนื้อหาที่เพิ่มขึ้นเรื่อยๆ จะให้ประโยชน์มากกว่า บิลด์ที่สะอาดคือ ค่อนข้างเกิดขึ้นไม่บ่อยนัก แต่การเปลี่ยนไฟล์เดียวระหว่างคอมไพล์เหล่านี้เป็นเรื่องปกติ ดังนี้ โดยเฉพาะในการพัฒนาที่เน้นทดสอบ ตัวอย่างข้างต้นยังมีบางผลิตภัณฑ์ที่ไม่ใช่ Java การสร้างแพ็กเกจใหม่ซึ่งสามารถลดเวลาการคอมไพล์ที่เพิ่มขึ้นได้
การคอมไพล์เฉพาะซอร์สของ Java ใหม่เท่านั้น
(//src/main/java/com/google/devtools/build/lib/bazel:BazelServer_deploy.jar
)
หลังจากเปลี่ยนแปลงค่าคงที่สตริงภายในใน
AbstractContainerizingSandboxedSpawn.java
ทำให้เร่งความเร็วได้ 3 เท่า (เพิ่มขึ้นเฉลี่ย 20 บิลด์สำหรับอุ่นเครื่อง 1 บิลด์
ทิ้ง):
รูปที่ 2 กราฟการปรับปรุงประสิทธิภาพของบิลด์ที่เพิ่มขึ้น
การเร่งความเร็วจะขึ้นอยู่กับการเปลี่ยนแปลงที่เกิดขึ้น การเพิ่มความเร็วของปัจจัย 6 คือ วัดในสถานการณ์ข้างต้นเมื่อมีการเปลี่ยนแปลงค่าคงที่ที่ใช้กันทั่วไป
การแก้ไขผู้ปฏิบัติงานถาวร
คุณสามารถส่งผ่าน
--worker_extra_flag
Flag เพื่อระบุการตั้งค่าสถานะเริ่มต้นให้กับผู้ปฏิบัติงาน ซึ่งคีย์ตามความสามารถในการจำ ตัวอย่างเช่น
การส่ง --worker_extra_flag=javac=--debug
จะเปิดการดีบักสำหรับ Javac เท่านั้น
สามารถตั้งค่าแฟล็กผู้ปฏิบัติงานได้เพียง 1 รายการต่อการใช้แฟล็กนี้ และสำหรับ Mnemonic ได้รายการเดียวเท่านั้น
ผู้ปฏิบัติงานไม่ได้สร้างขึ้นแยกต่างหากสำหรับการช่วยจำแต่ละรายการ แต่รวมถึงผู้ปฏิบัติงานด้วย
ที่แตกต่างกันใน Flag การเริ่มต้น การสร้างความจำและการเริ่มต้นแต่ละครั้ง
แฟล็กจะรวมเข้าด้วยกันเป็น WorkerKey
และสำหรับ WorkerKey
แต่ละรายการจนถึง
สร้างผู้ปฏิบัติงานได้ worker_max_instances
ราย โปรดดูส่วนถัดไปเกี่ยวกับ
การกำหนดค่าการดำเนินการยังสามารถระบุแฟล็กการตั้งค่าได้ด้วย
คุณสามารถใช้
--high_priority_workers
แฟล็กเพื่อระบุการช่วยจำที่ควรเรียกใช้ตามลำดับความสำคัญปกติ
การช่วยจำ วิธีนี้ช่วยจัดลำดับความสำคัญให้กับการดำเนินการที่สำคัญเสมอ
เส้นทาง หากมีผู้ปฏิบัติงานที่ต้องการส่งคำขอที่มีลำดับความสำคัญสูง 2 คนขึ้นไป
ป้องกันไม่ให้ผู้ปฏิบัติงานคนอื่นๆ ทำงาน แฟล็กนี้สามารถใช้ได้หลายครั้ง
ผ่าน
--worker_sandboxing
แฟล็กทำให้คำขอของผู้ปฏิบัติงานแต่ละรายใช้ไดเรกทอรีแซนด์บ็อกซ์ที่แยกต่างหากสำหรับทุกคำขอ
อินพุต การตั้งค่าแซนด์บ็อกซ์ใช้เวลานานขึ้น
โดยเฉพาะอย่างยิ่งใน macOS แต่ให้การรับประกันความถูกต้องที่ดีกว่า
--worker_quit_after_build
การแจ้งว่าไม่เหมาะสมจะมีประโยชน์สำหรับการแก้ไขข้อบกพร่องและการทำโปรไฟล์เป็นหลัก ธงนี้จะบังคับให้ผู้ปฏิบัติงานทั้งหมด
ที่ควรออกจากการสร้าง
เมื่อสร้างเสร็จแล้ว นอกจากนี้คุณยังสามารถ
--worker_verbose
ถึง
ได้รับผลลัพธ์เพิ่มเติมเกี่ยวกับสิ่งที่พนักงานกำลังทำอยู่ การตั้งค่าสถานะนี้จะแสดงใน
verbosity
ใน WorkRequest
ซึ่งช่วยให้ติดตั้งใช้งานสำหรับผู้ปฏิบัติงานได้ด้วย
มีรายละเอียดมากขึ้น
ผู้ปฏิบัติงานเก็บบันทึกในไดเรกทอรี <outputBase>/bazel-workers
สำหรับ
ตัวอย่าง
/tmp/_bazel_larsrc/191013354bebe14fdddae77f2679c3ef/bazel-workers/worker-1-Javac.log
ชื่อไฟล์จะประกอบด้วยรหัสผู้ปฏิบัติงานและเทคนิคช่วยจำ เนื่องจากเราสามารถ
มากกว่า 1 WorkerKey
ต่อความทรงจำ คุณอาจเห็นมากกว่า worker_max_instances
ไฟล์บันทึกสำหรับช่วยจำที่ระบุ
สำหรับบิลด์ของ Android โปรดดูรายละเอียดที่ หน้าประสิทธิภาพบิลด์ของ Android
การนำผู้ปฏิบัติงานอย่างต่อเนื่องไปใช้
ดูข้อมูลเพิ่มเติมได้ที่หน้าการสร้างผู้ปฏิบัติงานถาวร ข้อมูลเกี่ยวกับวิธีสร้างพนักงาน
ตัวอย่างนี้แสดงการกำหนดค่า Starlark สำหรับผู้ปฏิบัติงานที่ใช้ JSON
args_file = ctx.actions.declare_file(ctx.label.name + "_args_file")
ctx.actions.write(
output = args_file,
content = "\n".join(["-g", "-source", "1.5"] + ctx.files.srcs),
)
ctx.actions.run(
mnemonic = "SomeCompiler",
executable = "bin/some_compiler_wrapper",
inputs = inputs,
outputs = outputs,
arguments = [ "-max_mem=4G", "@%s" % args_file.path],
execution_requirements = {
"supports-workers" : "1", "requires-worker-protocol" : "json" }
)
เมื่อใช้คําจํากัดความนี้ การใช้การดําเนินการนี้ครั้งแรกจะเริ่มด้วยการดําเนินการ
บรรทัดคำสั่ง /bin/some_compiler -max_mem=4G --persistent_worker
คำขอ
เพื่อคอมไพล์ Foo.java
จะมีหน้าตาดังนี้
หมายเหตุ: แม้ว่าข้อกำหนดบัฟเฟอร์โปรโตคอลจะใช้ "กรณีงู" (request_id
),
โปรโตคอล JSON ใช้ "รูปแบบอูฐ" (requestId
) ในเอกสารนี้ เราจะใช้
รูปแบบอูฐในตัวอย่าง JSON แต่ใช้ตัวอักษรแบบงูเมื่อพูดถึงฟิลด์
โดยไม่คำนึงถึงโปรโตคอล
{
"arguments": [ "-g", "-source", "1.5", "Foo.java" ]
"inputs": [
{ "path": "symlinkfarm/input1", "digest": "d49a..." },
{ "path": "symlinkfarm/input2", "digest": "093d..." },
],
}
ผู้ปฏิบัติงานได้รับข้อมูลนี้ใน stdin
ในรูปแบบ JSON ที่คั่นด้วยการขึ้นบรรทัดใหม่ (เนื่องจาก
มีการตั้งค่า requires-worker-protocol
เป็น JSON) จากนั้นพนักงานจะดำเนินการ
และส่ง WorkResponse
ในรูปแบบ JSON ไปยัง Bazel ใน Stouts Bazel แล้ว
แยกวิเคราะห์คำตอบนี้และแปลงเป็น Pro ของ WorkResponse
ด้วยตนเอง ถึง
สื่อสารกับผู้ปฏิบัติงานที่เกี่ยวข้องโดยใช้ Protobuf ที่เข้ารหัสแบบไบนารีแทน
ระบบจะตั้งค่า JSON requires-worker-protocol
เป็น proto
ดังนี้
execution_requirements = {
"supports-workers" : "1" ,
"requires-worker-protocol" : "proto"
}
หากไม่รวม requires-worker-protocol
ไว้ในข้อกำหนดการดำเนินการ
Bazel จะกำหนดค่าเริ่มต้นในการสื่อสารกับผู้ปฏิบัติงานเพื่อใช้ Protocolbuf
Bazel ดึง WorkerKey
มาจากเทคนิคการจำและแฟล็กที่แชร์ ดังนั้นถ้าสิ่งนี้
อนุญาตให้เปลี่ยนพารามิเตอร์ max_mem
ได้ พนักงานที่แยกต่างหากควร
สำหรับค่าแต่ละค่าที่ใช้ ซึ่งอาจทำให้เกิดการใช้หน่วยความจำมากเกินไปหาก
ใช้รูปแบบมากเกินไป
ปัจจุบันผู้ปฏิบัติงานแต่ละคนประมวลผลคำขอได้ทีละ 1 คำขอเท่านั้น การทดสอบ ฟีเจอร์ผู้ปฏิบัติงานมัลติเพล็กซ์อนุญาตให้ใช้ หากเครื่องมือที่สำคัญเป็นแบบมัลติเทรดและ Wrapper ได้รับการตั้งค่าเป็น เข้าใจเรื่องนี้
ใน ที่เก็บ GitHub นี้ คุณจะเห็น Wrapper ของผู้ปฏิบัติงานที่เขียนด้วย Java รวมทั้งใน Python หากคุณ กำลังทำงานใน JavaScript หรือ TypeScript แพ็กเกจ@bazel/worker และ ตัวอย่างผู้ปฏิบัติงาน Nodejs อาจเป็นประโยชน์
ผู้ปฏิบัติงานส่งผลต่อแซนด์บ็อกซ์อย่างไร
การใช้กลยุทธ์ worker
โดยค่าเริ่มต้นจะไม่เรียกใช้การดำเนินการใน
sandbox ซึ่งคล้ายกับกลยุทธ์ local
คุณสามารถตั้งค่า
--worker_sandboxing
Flag เพื่อเรียกใช้ผู้ปฏิบัติงานทั้งหมดภายในแซนด์บ็อกซ์ โดยตรวจสอบว่า
การดำเนินการกับเครื่องมือจะทำให้เห็นเฉพาะไฟล์อินพุตที่เครื่องมือควรจะมีเท่านั้น เครื่องมือ
จึงอาจยังทำให้ข้อมูลระหว่างคำขอรั่วไหลภายใน เช่น ผ่าน
แคช กำลังใช้กลยุทธ์dynamic
กำหนดให้ผู้ปฏิบัติงานได้รับแซนด์บ็อกซ์
เพื่อให้ผู้ปฏิบัติงานใช้แคชของคอมไพเลอร์ได้อย่างถูกต้อง ระบบจะส่งผ่านไดเจสต์ กับไฟล์อินพุตแต่ละไฟล์ ดังนั้นคอมไพเลอร์หรือ Wrapper จะตรวจสอบได้ว่าอินพุต ยังคงสามารถใช้งานได้โดยไม่ต้องอ่านไฟล์
แม้ในขณะที่ใช้ไดเจสต์อินพุตเพื่อป้องกันการแคชที่ไม่พึงประสงค์ โดยมีการทำแซนด์บ็อกซ์ มีการตั้งค่าแซนด์บ็อกซ์ที่เข้มงวดน้อยกว่าแซนด์บ็อกซ์ทั้งหมด เนื่องจากเครื่องมืออาจ เก็บสถานะภายในอื่นๆ ที่ได้รับผลกระทบจากคำขอก่อนหน้าไว้
ผู้ปฏิบัติงาน Multiplex จะใช้แซนด์บ็อกซ์ได้ในกรณีที่ผู้ปฏิบัติงานรองรับเท่านั้น
และแซนด์บ็อกซ์นี้ต้องเปิดใช้
แยกต่างหากด้วย
แฟล็ก --experimental_worker_multiplex_sandboxing
ดูรายละเอียดเพิ่มเติมใน
เอกสารการออกแบบ)
อ่านเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับผู้ปฏิบัติงานถาวรได้ที่