การแก้ไขข้อบกพร่องของ Hit แคชระยะไกลสำหรับการดำเนินการระยะไกล

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

หน้านี้จะอธิบายวิธีตรวจสอบอัตรา Hit ของแคชและวิธีตรวจสอบการไม่พบแคชในบริบทของการดำเนินการระยะไกล

หน้านี้ถือว่าคุณมีบิลด์และ/หรือการทดสอบที่ใช้การเรียกใช้จากระยะไกลได้สําเร็จ และคุณต้องการตรวจสอบว่าคุณใช้แคชระยะไกลอย่างมีประสิทธิภาพ

ตรวจสอบอัตรา Hit ของแคช

ในเอาต์พุตมาตรฐานของการเรียกใช้ Bazel ให้ดูบรรทัด INFO ที่แสดงรายการกระบวนการ ซึ่งสอดคล้องกับการดำเนินการของ Bazel โดยคร่าวๆ บรรทัดดังกล่าวจะแสดงรายละเอียดว่าการดำเนินการนั้นทําที่ใด มองหาป้ายกํากับ remote ซึ่งระบุการดำเนินการที่ดำเนินการจากระยะไกล linux-sandbox สำหรับการดำเนินการที่ดำเนินการในแซนด์บ็อกซ์ในเครื่อง และค่าอื่นๆ สำหรับกลยุทธ์การดำเนินการอื่นๆ การดําเนินการที่มาจากแคชระยะไกลจะแสดงเป็น remote cache hit

เช่น

INFO: 11 processes: 6 remote cache hit, 3 internal, 2 remote.

ในตัวอย่างนี้ มี Hit ของแคชระยะไกล 6 รายการ และการดําเนินการ 2 รายการไม่มี Hit ของแคชและดําเนินการจากระยะไกล คุณสามารถละเว้นส่วนภายใน 3 ส่วนได้ โดยปกติแล้วจะเป็นการดำเนินการภายในเล็กๆ น้อยๆ เช่น การสร้างลิงก์สัญลักษณ์ ระบบจะไม่รวมการตีกลับจากแคชในเครื่องไว้ในสรุปนี้ หากคุณได้รับ 0 กระบวนการ (หรือตัวเลขต่ำกว่าที่คาดไว้) ให้เรียกใช้ bazel clean ตามด้วยคำสั่งบิลด์/ทดสอบ

การแก้ปัญหาการพบแคช

หากไม่ได้อัตรา Hit ของแคชตามที่คาดไว้ ให้ทําดังนี้

ตรวจสอบว่าการเรียกใช้คําสั่งบิลด์/ทดสอบเดิมอีกครั้งทําให้พบรายการในแคช

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

  2. เรียกใช้ bazel clean คำสั่งนี้จะล้างแคชในเครื่อง ซึ่งจะช่วยให้คุณตรวจสอบ Hit ของแคชระยะไกลได้โดยไม่ต้องปิดบังผลลัพธ์ด้วย Hit ของแคชในเครื่อง

  3. เรียกใช้บิลด์และทดสอบที่คุณกำลังตรวจสอบอีกครั้ง (ในเครื่องเดียวกัน)

  4. ตรวจสอบบรรทัด INFO เพื่อดูอัตราการค้นพบแคช หากไม่เห็นกระบวนการใดๆ ยกเว้น remote cache hit และ internal แสดงว่าระบบกําลังสร้างและเข้าถึงแคชอย่างถูกต้อง ในกรณีนี้ ให้ข้ามไปยังส่วนถัดไป

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

    ก. เรียกใช้บิลด์หรือการทดสอบที่เป็นปัญหาอีกครั้งเพื่อดูบันทึกการดำเนินการ

      bazel clean
      bazel --optional-flags build //your:target --execution_log_binary_file=/tmp/exec1.log

    ข. เปรียบเทียบบันทึกการดำเนินการระหว่างการเรียกใช้ 2 ครั้ง ตรวจสอบว่าการดำเนินการในไฟล์บันทึกทั้ง 2 ไฟล์เหมือนกัน ความคลาดเคลื่อนเป็นเบาะแสเกี่ยวกับการเปลี่ยนแปลงที่เกิดขึ้นระหว่างการเรียกใช้ อัปเดตบิลด์เพื่อลดความคลาดเคลื่อนเหล่านั้น

    หากแก้ปัญหาการแคชได้และตอนนี้การเรียกใช้ซ้ำทำให้เกิด Hit แคชทั้งหมด ให้ข้ามไปยังส่วนถัดไป

    หากรหัสการกระทําเหมือนกันแต่ไม่มีการตีข้อมูลแคช แสดงว่าอาจมีบางอย่างในการกําหนดค่าที่ป้องกันไม่ให้แคช ดำเนินการต่อในส่วนนี้เพื่อดู ปัญหาที่พบบ่อย

    หากไม่จำเป็นต้องแยกความแตกต่างของบันทึกการดำเนินการ ให้ใช้แฟล็ก --execution_log_json_file ที่มนุษย์อ่านได้แทน แต่จะไม่สามารถใช้ในการเปรียบเทียบแบบเสถียรได้เนื่องจากมีเวลาดำเนินการและไม่รับประกันการจัดเรียง

  6. ตรวจสอบว่าการดำเนินการทั้งหมดในบันทึกการดำเนินการมีการตั้งค่า cacheable เป็น "จริง" หาก cacheable ไม่ปรากฏในบันทึกการดำเนินการสําหรับการดําเนินการหนึ่งๆ แสดงว่ากฎที่เกี่ยวข้องอาจมีแท็ก no-cache ในคําจํากัดความในไฟล์ BUILD ดูที่ช่อง progress_message ที่มนุษย์อ่านได้ในบันทึกการดำเนินการเพื่อช่วยระบุว่าการดำเนินการนั้นมาจากที่ใด

  7. หากการดำเนินการเหมือนกันและ cacheable แต่ไม่มี Hit ของแคช แสดงว่าบรรทัดคำสั่งของคุณอาจมี --noremote_accept_cached ซึ่งจะปิดใช้การค้นหาแคชสำหรับบิลด์

    หากหาบรรทัดคำสั่งจริงได้ยาก ให้ใช้บรรทัดคำสั่งตามมาตรฐานจากโปรโตคอลเหตุการณ์การสร้าง ดังนี้

    ก. เพิ่ม --build_event_text_file=/tmp/bep.txt ลงในคำสั่ง Bazel เพื่อรับบันทึกในรูปแบบข้อความ

    ข. เปิดบันทึกเวอร์ชันข้อความของบันทึกและค้นหาข้อความ structured_command_line ด้วย command_line_label: "canonical" ซึ่งจะแสดงรายการตัวเลือกทั้งหมดหลังจากขยาย

    ค. ค้นหา remote_accept_cached และตรวจสอบว่ามีการตั้งค่าเป็น false หรือไม่

    ง. หาก remote_accept_cached เป็น false ให้ตรวจสอบว่ามีการกําหนดค่าเป็น false ที่ใด นั่นคือที่บรรทัดคําสั่งหรือในไฟล์ bazelrc

ตรวจสอบการแคชในเครื่องต่างๆ

หลังจากที่การพบแคชเกิดขึ้นตามที่คาดไว้ในเครื่องเดียวกัน ให้เรียกใช้บิลด์/การทดสอบเดียวกันในเครื่องอื่น หากคุณสงสัยว่าการแคช ไม่เกิดขึ้นในอุปกรณ์ต่างๆ ให้ทำดังต่อไปนี้

  1. ทำการแก้ไขเล็กน้อยในบิลด์เพื่อหลีกเลี่ยงการใช้แคชที่มีอยู่

  2. เรียกใช้บิลด์ในเครื่องแรกโดยทำดังนี้

     bazel clean
     bazel ... build ... --execution_log_binary_file=/tmp/exec1.log
  3. เรียกใช้บิลด์ในเครื่องที่ 2 โดยตรวจสอบว่าได้รวมการแก้ไขจากขั้นตอนที่ 1 ไว้แล้ว

     bazel clean
     bazel ... build ... --execution_log_binary_file=/tmp/exec2.log
  4. เปรียบเทียบบันทึกการดำเนินการของ 2 รันไทม์ หากบันทึกไม่เหมือนกัน ให้ตรวจสอบการกําหนดค่าบิลด์เพื่อหาความคลาดเคลื่อน รวมถึงพร็อพเพอร์ตี้จากสภาพแวดล้อมโฮสต์ที่รั่วไหลไปยังบิลด์ใดบิลด์หนึ่ง

การเปรียบเทียบบันทึกการดำเนินการ

บันทึกการดำเนินการมีบันทึกการดำเนินการทั้งหมดที่ดำเนินการในระหว่างการสร้าง การดำเนินการแต่ละรายการจะมีองค์ประกอบ SpawnExec ที่มีข้อมูลทั้งหมดจากคีย์การดำเนินการ ดังนั้นหากบันทึกเหมือนกัน คีย์แคชการดำเนินการก็จะเหมือนกัน

หากต้องการเปรียบเทียบบันทึกสำหรับบิลด์ 2 รายการที่ไม่ได้แชร์ Hit ของแคชตามที่คาดไว้ ให้ทำดังนี้

  1. รับบันทึกการดำเนินการจากบิลด์แต่ละรายการและจัดเก็บเป็น /tmp/exec1.log และ /tmp/exec2.log

  2. ดาวน์โหลดซอร์สโค้ด Bazel และไปที่โฟลเดอร์ Bazel โดยใช้คำสั่งด้านล่าง คุณต้องใช้ซอร์สโค้ดเพื่อแยกวิเคราะห์บันทึกการเรียกใช้ด้วยโปรแกรมแยกวิเคราะห์ execlog

    git clone https://github.com/bazelbuild/bazel.git
    cd bazel
    
  3. ใช้โปรแกรมแยกวิเคราะห์บันทึกการดำเนินการเพื่อแปลงบันทึกเป็นข้อความ การเรียกใช้ต่อไปนี้ยังจัดเรียงการดำเนินการในบันทึกที่ 2 เพื่อให้ตรงกับลำดับการดำเนินการในบันทึกแรกเพื่อให้เปรียบเทียบได้ง่าย

    bazel build src/tools/execlog:parser
    bazel-bin/src/tools/execlog/parser \
      --log_path=/tmp/exec1.log \
      --log_path=/tmp/exec2.log \
      --output_path=/tmp/exec1.log.txt \
      --output_path=/tmp/exec2.log.txt
    
  4. ใช้ข้อความที่คุณต้องการแทนที่ diff /tmp/exec1.log.txt และ /tmp/exec2.log.txt