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

หน้านี้จะอธิบายวิธีตรวจสอบอัตรา 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 ของแคชตามที่คาดไว้ ให้ทำดังนี้

ตรวจสอบว่าการเรียกใช้คำสั่งบิลด์/ทดสอบเดียวกันอีกครั้งจะสร้าง 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 ไฟล์เหมือนกัน ความคลาดเคลื่อนเป็นเบาะแสเกี่ยวกับการเปลี่ยนแปลงที่เกิดขึ้นระหว่างการเรียกใช้ อัปเดตบิลด์เพื่อขจัดความคลาดเคลื่อนเหล่านั้น

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

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

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

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

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

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

    ก. เพิ่ม --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 ให้ตรงกับลําดับการดําเนินการในบันทึกที่ 1 เพื่อให้เปรียบเทียบได้ง่าย

    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. ใช้ข้อความที่คุณชื่นชอบแตกต่างจาก /tmp/exec1.log.txt และ /tmp/exec2.log.txt