Google เคยใช้ A/B OTA ในอุปกรณ์ใดบ้าง
ใช่ ชื่อทางการตลาดของการอัปเดต A/B คือ การอัปเดตที่ราบรื่น โทรศัพท์ Pixel และ Pixel XL
ที่วางจำหน่ายตั้งแต่เดือนตุลาคม 2016 มาพร้อมกับ A/B และ Chromebook ทั้งหมดใช้การติดตั้งใช้งาน
update_engine
แบบ A/B เหมือนกัน การติดตั้งใช้งานโค้ดแพลตฟอร์มที่จำเป็นเป็นแบบสาธารณะใน Android 7.1 และ
ขึ้นไป
เหตุใด A/B OTA จึงดีกว่า
A/B OTA มอบประสบการณ์การใช้งานที่ดีขึ้นแก่ผู้ใช้เมื่อทำการอัปเดต การวัดผลจากการอัปเดตความปลอดภัยรายเดือนแสดงให้เห็นว่าฟีเจอร์นี้ประสบความสำเร็จแล้ว โดยในเดือนพฤษภาคม 2017 เจ้าของ Pixel 95% ใช้การอัปเดตความปลอดภัยล่าสุดหลังจากผ่านไป 1 เดือน เทียบกับผู้ใช้ Nexus 87% และผู้ใช้ Pixel อัปเดตเร็วกว่าผู้ใช้ Nexus การอัปเดตที่บล็อกระหว่าง OTA จะไม่ส่งผลให้อุปกรณ์บูตไม่ได้อีกต่อไป โดย Android จะยังคงสามารถกลับไปใช้ระบบอิมเมจที่ทำงานก่อนหน้าได้จนกว่าอิมเมจระบบใหม่จะบูตได้สำเร็จ
system_other คืออะไร
แอปพลิเคชันจะจัดเก็บไว้ในไฟล์ .apk ซึ่งเป็นไฟล์เก็บถาวร ZIP ไฟล์ .apk แต่ละไฟล์จะมี ไฟล์ .dex อย่างน้อย 1 ไฟล์อยู่ภายใน ซึ่งมี Dalvik bytecode แบบพกพา ไฟล์ .odex (ไฟล์ .dex ที่เพิ่มประสิทธิภาพ ) จะแยกจากไฟล์ .apk และอาจมีรหัสเครื่องที่เฉพาะเจาะจงกับอุปกรณ์ หากมีไฟล์ .odex Android จะเรียกใช้แอปพลิเคชันด้วยความเร็วในการคอมไพล์ล่วงหน้าได้ โดยไม่ต้องรอให้คอมไพล์โค้ดทุกครั้งที่เปิดแอปพลิเคชัน ไฟล์ .odex ไม่จำเป็นอย่างยิ่ง โดย Android สามารถเรียกใช้โค้ด .dex ได้โดยตรงผ่านการตีความหรือการคอมไพล์แบบ Just-In-Time (JIT) แต่ไฟล์ .odex จะให้การผสมผสานที่ดีที่สุดระหว่างความเร็วในการเปิดตัวและความเร็วในการรันไทม์หากมีพื้นที่ว่าง
ตัวอย่าง: สำหรับไฟล์ installed-files.txt จาก Nexus 6P ที่ใช้ Android 7.1 ซึ่งมีขนาดระบบ อิมเมจทั้งหมด 2628MiB (2755792836 ไบต์) การแบ่งสัดส่วนของผู้ที่มีส่วนร่วมมากที่สุดในขนาดระบบอิมเมจโดยรวม ตามประเภทไฟล์มีดังนี้
| .odex | 1391770312 ไบต์ | 50.5% |
| .apk | 846878259 ไบต์ | 30.7% |
| .so (โค้ด C/C++ แบบเนทีฟ) | 202162479 ไบต์ | 7.3% |
| ไฟล์ .oat/อิมเมจ .art | 163892188 ไบต์ | 5.9% |
| แบบอักษร | 38952361 ไบต์ | 1.4% |
| ข้อมูลภาษาของ ICU | 27468687 ไบต์ | 0.9% |
ตัวเลขเหล่านี้คล้ายกันสำหรับอุปกรณ์อื่นๆ ด้วย ดังนั้นในอุปกรณ์ Nexus/Pixel ไฟล์ .odex จะใช้พื้นที่ประมาณครึ่งหนึ่งของพาร์ติชันระบบ ซึ่งหมายความว่าเราสามารถใช้ ext4 ต่อไปได้ แต่เขียน
ไฟล์ .odex ลงในพาร์ติชัน B ที่โรงงาน แล้วคัดลอกไฟล์เหล่านั้นไปยัง /data เมื่อ
บูตครั้งแรก พื้นที่เก็บข้อมูลจริงที่ใช้กับ ext4 A/B จะเหมือนกับ SquashFS A/B เนื่องจากหากเรา
ใช้ SquashFS เราจะจัดส่งไฟล์ .odex ที่เพิ่มประสิทธิภาพล่วงหน้าใน system_a แทน
system_b
การคัดลอกไฟล์ .odex ไปยัง /data หมายความว่าพื้นที่ที่บันทึกไว้ใน /system จะหายไปใน /data ใช่ไหม
ก็ไม่เชิง ใน Pixel พื้นที่ส่วนใหญ่ที่ไฟล์ .odex ใช้ไปนั้นเป็นของแอป ซึ่งโดยทั่วไปจะ
อยู่ใน /data แอปเหล่านี้รับการอัปเดตจาก Google Play ดังนั้นไฟล์ .apk และ .odex ในอิมเมจระบบจึงไม่ได้ใช้ตลอดอายุการใช้งานส่วนใหญ่ของอุปกรณ์ ระบบสามารถยกเว้นไฟล์ดังกล่าวทั้งหมด
และแทนที่ด้วยไฟล์ .odex ขนาดเล็กที่ขับเคลื่อนด้วยโปรไฟล์เมื่อผู้ใช้ใช้แอปแต่ละแอป
จริง (จึงไม่จำเป็นต้องใช้พื้นที่สำหรับแอปที่ผู้ใช้ไม่ได้ใช้) โปรดดูรายละเอียดใน Google
I/O 2016 Talk เรื่อง The Evolution of Art
การเปรียบเทียบทำได้ยากด้วยเหตุผลสำคัญ 2-3 ประการ ดังนี้
-
แอปที่อัปเดตโดย Google Play จะมีไฟล์ .odex อยู่ใน
/dataทันทีที่ได้รับการอัปเดตครั้งแรก - แอปที่ผู้ใช้ไม่ได้เรียกใช้ไม่จำเป็นต้องมีไฟล์ .odex เลย
- การคอมไพล์ที่ขับเคลื่อนด้วยโปรไฟล์จะสร้างไฟล์ .odex ที่มีขนาดเล็กกว่าการคอมไพล์ล่วงหน้า (เนื่องจากไฟล์แรกจะเพิ่มประสิทธิภาพเฉพาะโค้ดที่สำคัญต่อประสิทธิภาพ)
โปรดดูรายละเอียดเกี่ยวกับตัวเลือกการปรับแต่งที่มีให้สำหรับ OEM ที่หัวข้อ การกำหนดค่า ART
ไม่มีไฟล์ .odex 2 ชุดใน /data ใช่ไหม
เรื่องนี้ซับซ้อนกว่านั้นเล็กน้อย... หลังจากเขียนอิมเมจระบบใหม่แล้ว ระบบจะเรียกใช้ dex2oat เวอร์ชันใหม่กับไฟล์ .dex ใหม่เพื่อสร้างไฟล์ .odex ใหม่ การดำเนินการนี้จะเกิดขึ้นขณะที่ระบบเก่ายังทำงานอยู่ ดังนั้นไฟล์ .odex เก่าและใหม่จึงอยู่ใน
/data พร้อมกัน
โค้ดใน OtaDexoptService (frameworks/base/+/android17-release/services/core/java/com/android/server/pm/OtaDexoptService.java) จะเรียกใช้ getAvailableSpace ก่อนที่จะเพิ่มประสิทธิภาพแต่ละแพ็กเกจเพื่อหลีกเลี่ยงการเติม
/data มากเกินไป โปรดทราบว่า available ในที่นี้ยังคงเป็นค่าที่ระมัดระวัง ซึ่งเป็นพื้นที่ที่เหลืออยู่ ก่อน ที่จะถึงเกณฑ์พื้นที่ว่างเหลือน้อยของระบบตามปกติ (วัดเป็นทั้ง
เปอร์เซ็นต์และจำนวนไบต์) ดังนั้นหาก /data เต็ม จะไม่มีไฟล์ .odex ทุกไฟล์ 2 ชุด โค้ดเดียวกันนี้ยังมี BULK_DELETE_THRESHOLD ด้วย หากอุปกรณ์ใกล้จะเติมพื้นที่ว่าง (ตามที่อธิบายไว้ข้างต้น) ระบบจะนำไฟล์ .odex ที่เป็นของแอป
ที่ไม่ได้ใช้ออก นี่เป็นอีกกรณีหนึ่งที่ไม่มีไฟล์ .odex ทุกไฟล์ 2 ชุด
ในกรณีที่แย่ที่สุดที่ /data เต็มโดยสมบูรณ์ การอัปเดตจะรอจนกว่า
อุปกรณ์จะรีบูตเข้าสู่ระบบใหม่และไม่จำเป็นต้องใช้ไฟล์ .odex ของระบบเก่าอีกต่อไป PackageManager จะจัดการเรื่องนี้ (frameworks/base/+/android17-release/services/core/java/com/android/server/pm/PackageManagerService.java#7215) หลังจากที่ระบบใหม่บูตได้สำเร็จแล้ว installd (frameworks/native/+/android17-release/cmds/installd/dexopt.cpp#2422) จะนำไฟล์ .odex ที่ระบบเก่าใช้ไปออก ทำให้อุปกรณ์กลับสู่สถานะคงที่ที่มีไฟล์เพียงชุดเดียว
ดังนั้น แม้ว่า /data อาจมีไฟล์ .odex ทั้งหมด 2 ชุด แต่ (ก) เป็นเพียงชั่วคราวและ (ข) จะเกิดขึ้นก็ต่อเมื่อคุณมีพื้นที่ว่างมากมายใน /data อยู่แล้ว จะมีไฟล์เพียงชุดเดียวเท่านั้น ยกเว้นระหว่างการอัปเดต และ ART จะไม่เติม /data ด้วยไฟล์ .odex อยู่แล้ว (เนื่องจากจะเป็นปัญหาในระบบที่ไม่ใช่ A/B ด้วย) ซึ่งเป็นส่วนหนึ่งของ
ฟีเจอร์ความเสถียรทั่วไปของ
ART
การเขียน/คัดลอกทั้งหมดนี้จะเพิ่มการสึกหรอของหน่วยความจำแฟลชใช่ไหม
ระบบจะเขียนแฟลชใหม่เพียงเล็กน้อยเท่านั้น โดยการอัปเดตระบบ Pixel แบบเต็มจะเขียนประมาณ 2.3GiB (ระบบจะคอมไพล์แอปใหม่ด้วย แต่การดำเนินการนี้จะเกิดขึ้นในระบบที่ไม่ใช่ A/B ด้วย) โดยปกติแล้ว OTA แบบเต็มที่อิงตามบล็อก จะเขียนข้อมูลในปริมาณที่คล้ายกัน ดังนั้นอัตราการสึกหรอของหน่วยความจำแฟลชจึงควรคล้ายกัน
การแฟลชพาร์ติชันระบบ 2 รายการจะเพิ่มเวลาในการแฟลชจากโรงงานใช่ไหม
ไม่ Pixel ไม่ได้เพิ่มขนาดระบบอิมเมจ (เพียงแค่แบ่งพื้นที่ออกเป็น 2 พาร์ติชัน)
การเก็บไฟล์ .odex ไว้ใน B จะทำให้การรีบูตหลังจากการรีเซ็ตข้อมูลเป็นค่าเริ่มต้นช้าลงใช่ไหม
ใช่ หากคุณเคยใช้อุปกรณ์ ทำ OTA และรีเซ็ตข้อมูลเป็นค่าเริ่มต้น การรีบูตครั้งแรกจะช้ากว่าปกติ (1 นาที 40 วินาที เทียบกับ 40 วินาทีใน Pixel XL) เนื่องจากไฟล์ .odex จะหายไปจาก B หลังจาก OTA ครั้งแรก จึงคัดลอกไปยัง /data ไม่ได้ นี่คือข้อแลกเปลี่ยน
การรีเซ็ตข้อมูลเป็นค่าเริ่มต้นควรเป็นการดำเนินการที่ไม่ค่อยเกิดขึ้นเมื่อเทียบกับการบูตตามปกติ ดังนั้นเวลาที่ใช้
มีความสำคัญน้อยกว่า (การดำเนินการนี้ไม่ส่งผลต่อผู้ใช้หรือผู้รีวิวที่ได้รับอุปกรณ์จาก
โรงงาน เนื่องจากในกรณีนี้พาร์ติชัน B จะพร้อมใช้งาน) การใช้คอมไพเลอร์ JIT หมายความว่าเรา
ไม่จำเป็นต้องคอมไพล์ ทุกอย่าง ใหม่ ดังนั้นจึงไม่ได้แย่อย่างที่คุณคิด นอกจากนี้ คุณยังทำเครื่องหมายแอปว่าต้องมีการคอมไพล์ล่วงหน้าได้โดยใช้
coreApp="true" ในไฟล์ Manifest (frameworks/base/+/android17-release/packages/SystemUI/AndroidManifest.xml#23) ปัจจุบัน system_server ใช้การดำเนินการนี้เนื่องจากไม่ได้รับอนุญาตให้ใช้ JIT ด้วยเหตุผลด้าน
ความปลอดภัย
การเก็บไฟล์ .odex ไว้ใน /data แทน /system จะทำให้การรีบูตหลังจากการทำ OTA ช้าลงใช่ไหม
ไม่ ตามที่อธิบายไว้ข้างต้น ระบบจะเรียกใช้ dex2oat ใหม่ขณะที่อิมเมจระบบเก่ายังทำงานอยู่เพื่อสร้างไฟล์ที่ระบบใหม่จะต้องใช้ ระบบจะไม่ถือว่าการอัปเดตพร้อมใช้งาน จนกว่าจะดำเนินการดังกล่าวเสร็จสิ้น
เราควรจัดส่งอุปกรณ์ A/B ขนาด 32GiB ใช่ไหม 16GiB 8GiB
32GiB ทำงานได้ดีตามที่พิสูจน์แล้วใน Pixel และ 320MiB จาก 16GiB หมายถึงการลดลง 2% เช่นเดียวกัน 320MiB จาก 8GiB หมายถึงการลดลง 4% เห็นได้ชัดว่า A/B ไม่ใช่ตัวเลือกที่แนะนำในอุปกรณ์ที่มี 4GiB เนื่องจากค่าใช้จ่ายเพิ่มเติม 320MiB เกือบ 10% ของพื้นที่ทั้งหมดที่พร้อมใช้งาน
AVB2.0 ต้องใช้ A/B OTA ใช่ไหม
ไม่ การเปิดเครื่องที่ได้รับการยืนยันของ Android กำหนดให้ใช้การอัปเดตที่อิงตามบล็อกมาโดยตลอด แต่ไม่จำเป็นต้องใช้การอัปเดต A/B
A/B OTA ต้องใช้ AVB2.0 ใช่ไหม
ไม่
A/B OTA ทำให้การป้องกันการย้อนกลับของ AVB2.0 หยุดทำงานใช่ไหม
ไม่ มีความสับสนเกิดขึ้นที่นี่เนื่องจากหากระบบ A/B บูตเข้าสู่ระบบอิมเมจใหม่ไม่สำเร็จ ระบบจะกลับไปใช้ระบบอิมเมจ "ก่อนหน้า" โดยอัตโนมัติ (หลังจากลองใหม่ตามจำนวนครั้งที่บูตโหลดเดอร์กำหนด) อย่างไรก็ตาม ประเด็นสำคัญคือ "ก่อนหน้า" ในความหมายของ A/B นั้นยังคงเป็นระบบอิมเมจ "ปัจจุบัน" อยู่ ทันทีที่อุปกรณ์บูตอิมเมจใหม่ได้สำเร็จ การป้องกันการย้อนกลับจะเริ่มทำงานและทำให้คุณย้อนกลับไม่ได้ แต่จนกว่าคุณจะบูตอิมเมจใหม่ได้สำเร็จ การป้องกันการย้อนกลับจะไม่ถือว่าอิมเมจใหม่เป็นระบบอิมเมจปัจจุบัน
หากคุณติดตั้งการอัปเดตขณะที่ระบบกำลังทำงานอยู่ การดำเนินการนี้จะช้าใช่ไหม
สำหรับการอัปเดตที่ไม่ใช่ A/B เป้าหมายคือการติดตั้งการอัปเดตให้เร็วที่สุดเท่าที่จะเป็นไปได้ เนื่องจากผู้ใช้ กำลังรอและใช้อุปกรณ์ไม่ได้ขณะที่ระบบกำลังใช้การอัปเดต สำหรับการอัปเดต A/B จะเป็นตรงกันข้าม เนื่องจากผู้ใช้ยังคงใช้อุปกรณ์อยู่ เป้าหมายคือการลดผลกระทบให้มากที่สุดเท่าที่จะเป็นไปได้ ดังนั้นการอัปเดตจึงจงใจให้ช้า นอกจากนี้ Android ยังพยายามเลือกเวลาที่ผู้ใช้ไม่ได้ใช้อุปกรณ์เลยผ่านตรรกะในไคลเอ็นต์การอัปเดตระบบ Java (ซึ่งสำหรับ Google คือ GmsCore ซึ่งเป็นแพ็กเกจหลักที่ GMS ให้บริการ) แพลตฟอร์มรองรับ การหยุดชั่วคราว/ดำเนินการต่อของการอัปเดต และไคลเอ็นต์สามารถใช้การดำเนินการนี้เพื่อหยุดการอัปเดตชั่วคราวหากผู้ใช้ เริ่มใช้อุปกรณ์ และดำเนินการต่อเมื่ออุปกรณ์ไม่มีการใช้งานอีกครั้ง
การทำ OTA มี 2 ระยะ ซึ่งแสดงอย่างชัดเจนใน UI เป็น ขั้นตอนที่ 1 จาก 2 และ ขั้นตอนที่ 2 จาก 2 ใต้แถบความคืบหน้า ขั้นตอนที่ 1 สอดคล้องกับการเขียนบล็อกข้อมูล, ส่วนขั้นตอนที่ 2 คือการคอมไพล์ไฟล์ .dex ล่วงหน้า ทั้ง 2 ระยะนี้แตกต่างกันมากในแง่ของ ผลกระทบต่อประสิทธิภาพ ระยะแรกเป็นการดำเนินการ I/O อย่างง่าย การดำเนินการนี้ต้องใช้ทรัพยากร (RAM, CPU, I/O) น้อยมากเนื่องจากเป็นการคัดลอกบล็อกไปมาอย่างช้าๆ
ระยะที่ 2 จะเรียกใช้ dex2oat เพื่อคอมไพล์อิมเมจระบบใหม่ล่วงหน้า เห็นได้ชัดว่าการดำเนินการนี้มีข้อกำหนดที่ไม่ชัดเจนนักเนื่องจากเป็นการคอมไพล์แอปจริง และเห็นได้ชัดว่าการคอมไพล์แอปขนาดใหญ่และซับซ้อนต้องใช้ความพยายามมากกว่าการคอมไพล์แอปขนาดเล็กและเรียบง่ายมาก ในขณะที่ ในระยะที่ 1 ไม่มีบล็อกดิสก์ที่มีขนาดใหญ่หรือซับซ้อนกว่าบล็อกอื่นๆ
กระบวนการนี้คล้ายกับตอนที่ Google Play ติดตั้งการอัปเดตแอปในเบื้องหลังก่อนที่จะ แสดงการแจ้งเตือน อัปเดตแอป 5 รายการแล้ว ซึ่งดำเนินการมาหลายปีแล้ว
จะเกิดอะไรขึ้นหากผู้ใช้รอการอัปเดตอยู่
การติดตั้งใช้งานปัจจุบันใน GmsCore ไม่ได้แยกความแตกต่างระหว่างการอัปเดตเบื้องหลังกับ การอัปเดตที่ผู้ใช้เริ่ม แต่ในอนาคตอาจมีการแยกความแตกต่าง ในกรณีที่ผู้ใช้ขอให้ติดตั้งการอัปเดตอย่างชัดเจน หรือกำลังดูหน้าจอความคืบหน้าของการอัปเดต เราจะ จัดลำดับความสำคัญของงานอัปเดตโดยสันนิษฐานว่าผู้ใช้กำลังรอให้การอัปเดตเสร็จสิ้น
จะเกิดอะไรขึ้นหากการใช้การอัปเดตไม่สำเร็จ
สำหรับการอัปเดตที่ไม่ใช่ A/B หากการอัปเดตใช้ไม่สำเร็จ โดยปกติแล้วผู้ใช้จะเหลืออุปกรณ์ที่ใช้ไม่ได้ ข้อยกเว้นเพียงอย่างเดียวคือหากความล้มเหลวเกิดขึ้นก่อนที่แอปพลิเคชันจะเริ่มทำงาน (เนื่องจากแพ็กเกจยืนยันไม่สำเร็จ เป็นต้น) สำหรับการอัปเดต A/B การใช้การอัปเดตไม่สำเร็จ จะไม่ส่งผลต่อระบบที่กำลังทำงานอยู่ ผู้ใช้เพียงแค่ลองอัปเดตอีกครั้งในภายหลังได้