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

วันที่ รายงานปัญหา ดูแหล่งที่มา ตอนกลางคืน · 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.

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

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

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

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

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

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

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

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

    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