Google đã sử dụng OTA A/B trên bất kỳ thiết bị nào chưa?
Đúng. Tên tiếp thị cho cập nhật A/B là cập nhật liền mạch . Điện thoại Pixel và Pixel XL từ tháng 10 năm 2016 được cung cấp kèm theo A/B và tất cả Chromebook đều sử dụng cùng cách triển khai update_engine
của A/B. Việc triển khai mã nền tảng cần thiết được công khai trong Android 7.1 trở lên.
Tại sao A/B OTA tốt hơn?
OTA A/B cung cấp trải nghiệm người dùng tốt hơn khi nhận bản cập nhật. Đo lường từ các bản cập nhật bảo mật hàng tháng cho thấy tính năng này đã chứng tỏ sự thành công: Tính đến tháng 5 năm 2017, 95% chủ sở hữu Pixel đang chạy bản cập nhật bảo mật mới nhất sau một tháng so với 87% người dùng Nexus và người dùng Pixel cập nhật sớm hơn người dùng Nexus. Việc không cập nhật các khối trong OTA không còn dẫn đến thiết bị không khởi động được nữa; cho đến khi image hệ thống mới khởi động thành công, Android vẫn có khả năng quay lại image hệ thống làm việc trước đó.
A/B ảnh hưởng như thế nào đến kích thước phân vùng Pixel 2016?
Bảng sau đây chứa thông tin chi tiết về cấu hình A/B vận chuyển so với cấu hình không phải A/B được thử nghiệm nội bộ:
Kích thước phân vùng pixel | A/B | Không phải A/B |
---|---|---|
Bộ nạp khởi động | 50*2 | 50 |
Khởi động | 32*2 | 32 |
Sự hồi phục | 0 | 32 |
Bộ nhớ đệm | 0 | 100 |
Đài | 70*2 | 70 |
Người bán | 300*2 | 300 |
Hệ thống | 2048*2 | 4096 |
Tổng cộng | 5000 | 4680 |
Các bản cập nhật A/B chỉ yêu cầu tăng 320 MiB trong flash, tiết kiệm được 32MiB từ việc xóa phân vùng khôi phục và 100MiB khác được bảo toàn bằng cách xóa phân vùng bộ đệm. Điều này cân bằng chi phí của các phân vùng B cho bộ nạp khởi động, phân vùng khởi động và phân vùng radio. Phân vùng nhà cung cấp có kích thước gấp đôi (phần lớn tăng kích thước). Hình ảnh hệ thống A/B của Pixel có kích thước bằng một nửa hình ảnh hệ thống không phải A/B ban đầu.
Đối với các biến thể Pixel A/B và không phải A/B được thử nghiệm nội bộ (chỉ vận chuyển A/B), dung lượng sử dụng chỉ khác nhau 320MiB. Trên thiết bị 32GiB, con số này chỉ dưới 1%. Đối với thiết bị 16GiB, tỷ lệ này sẽ dưới 2% và đối với thiết bị 8GiB là gần 4% (giả sử cả ba thiết bị đều có cùng hình ảnh hệ thống).
Tại sao bạn không sử dụng SquashFS?
Chúng tôi đã thử nghiệm SquashFS nhưng không thể đạt được hiệu suất mong muốn cho một thiết bị cao cấp. Chúng tôi không sử dụng hoặc đề xuất SquashFS cho các thiết bị cầm tay.
Cụ thể hơn, SquashFS giúp tiết kiệm khoảng 50% kích thước trên phân vùng hệ thống, nhưng phần lớn các tệp được nén tốt là các tệp .odex được biên dịch trước. Những tệp đó có tỷ lệ nén rất cao (gần 80%), nhưng tỷ lệ nén cho phần còn lại của phân vùng hệ thống lại thấp hơn nhiều. Ngoài ra, SquashFS trong Android 7.0 còn nêu ra những lo ngại về hiệu suất sau:
- Pixel có đèn flash rất nhanh so với các thiết bị trước đó nhưng không có nhiều chu kỳ CPU dự phòng, do đó, việc đọc ít byte hơn từ flash nhưng cần nhiều CPU hơn cho I/O có thể là một nút thắt cổ chai.
- Các thay đổi I/O hoạt động tốt trên điểm chuẩn nhân tạo chạy trên hệ thống không tải đôi khi không hoạt động tốt trong các trường hợp sử dụng trong thế giới thực dưới tải trong thế giới thực (chẳng hạn như tiền điện tử trên Nexus 6).
- Điểm chuẩn cho thấy hồi quy 85% ở một số nơi.
Khi SquashFS hoàn thiện và bổ sung các tính năng để giảm tác động đến CPU (chẳng hạn như danh sách trắng gồm các tệp thường truy cập không nên nén), chúng tôi sẽ tiếp tục đánh giá và đưa ra đề xuất cho nhà sản xuất thiết bị.
Làm cách nào bạn giảm một nửa kích thước phân vùng hệ thống mà không có SquashFS?
Các ứng dụng được lưu trữ trong các tệp .apk, thực chất là các kho lưu trữ ZIP. Mỗi tệp .apk có bên trong một hoặc nhiều tệp .dex chứa mã byte Dalvik di động. Tệp .odex (được tối ưu hóa .dex) tồn tại riêng biệt với tệp .apk và có thể chứa mã máy dành riêng cho thiết bị. Nếu có sẵn tệp .odex, Android có thể chạy các ứng dụng với tốc độ được biên dịch trước mà không cần phải đợi mã được biên dịch mỗi khi ứng dụng được khởi chạy. Tệp .odex không thực sự cần thiết: Android thực sự có thể chạy mã .dex trực tiếp thông qua thông dịch hoặc biên dịch Just-In-Time (JIT), nhưng tệp .odex cung cấp sự kết hợp tốt nhất giữa tốc độ khởi chạy và tốc độ thời gian chạy nếu không gian có sẵn.
Ví dụ: Đối với tệp đã cài đặt-files.txt từ Nexus 6P chạy Android 7.1 với tổng kích thước hình ảnh hệ thống là 2628MiB (2755792836 byte), bảng phân tích những tác nhân đóng góp lớn nhất vào kích thước hình ảnh hệ thống tổng thể theo loại tệp như sau:
.odex | 1391770312 byte | 50,5% |
.apk | 846878259 byte | 30,7% |
.so (mã C/C++ gốc) | 202162479 byte | 7,3% |
Tệp .oat/hình ảnh .art | 163892188 byte | 5,9% |
Phông chữ | 38952361 byte | 1,4% |
dữ liệu miền địa phương icu | 27468687 byte | 0,9% |
Những số liệu này cũng tương tự đối với các thiết bị khác, vì vậy trên thiết bị Nexus/Pixel, tệp .odex chiếm khoảng một nửa phân vùng hệ thống. Điều này có nghĩa là chúng tôi có thể tiếp tục sử dụng ext4 nhưng ghi các tệp .odex vào phân vùng B tại nhà máy rồi sao chép chúng vào /data
trong lần khởi động đầu tiên. Dung lượng lưu trữ thực tế được sử dụng với ext4 A/B giống hệt với SquashFS A/B, vì nếu sử dụng SquashFS thì chúng tôi sẽ gửi các tệp .odex được chọn trước trên system_a thay vì system_b.
Không phải việc sao chép tệp .odex sang /data có nghĩa là dung lượng được lưu trên /system bị mất trên /data phải không?
Không chính xác. Trên Pixel, phần lớn dung lượng mà tệp .odex chiếm giữ là dành cho các ứng dụng thường tồn tại trên /data
. Các ứng dụng này nhận các bản cập nhật của Google Play, vì vậy các tệp .apk và .odex trên hình ảnh hệ thống không được sử dụng trong phần lớn thời gian sử dụng của thiết bị. Những tệp như vậy có thể bị loại trừ hoàn toàn và được thay thế bằng các tệp .odex nhỏ, dựa trên hồ sơ khi người dùng thực sự sử dụng từng ứng dụng (do đó không cần dung lượng cho các ứng dụng mà người dùng không sử dụng). Để biết chi tiết, hãy tham khảo buổi nói chuyện Google I/O 2016 Sự phát triển của nghệ thuật .
Việc so sánh là khó khăn vì một số lý do chính:
- Các ứng dụng được Google Play cập nhật luôn có tệp .odex trên
/data
ngay khi nhận được bản cập nhật đầu tiên. - Các ứng dụng mà người dùng không chạy không cần tệp .odex.
- Quá trình biên dịch theo hướng hồ sơ tạo ra các tệp .odex nhỏ hơn so với quá trình biên dịch trước thời hạn (vì quá trình biên dịch trước đây chỉ tối ưu hóa mã quan trọng về hiệu năng).
Để biết chi tiết về các tùy chọn điều chỉnh có sẵn cho OEM, hãy xem Định cấu hình ART .
Không có hai bản sao của tệp .odex trên /data phải không?
Nó phức tạp hơn một chút ... Sau khi hình ảnh hệ thống mới được viết, phiên bản mới của dex2oat sẽ chạy dựa trên các tệp .dex mới để tạo các tệp .odex mới. Điều này xảy ra trong khi hệ thống cũ vẫn đang chạy, vì vậy các tệp .odex cũ và mới đều được bật /data
cùng một lúc.
Mã trong OtaDexoptService ( frameworks/base/+/main/services/core/java/com/android/server/pm/OtaDexoptService.java
) gọi getAvailableSpace
trước khi tối ưu hóa từng gói để tránh điền quá mức /data
. Lưu ý rằng khả dụng ở đây vẫn mang tính bảo thủ: đó là lượng dung lượng còn lại trước khi đạt đến ngưỡng dung lượng thấp của hệ thống thông thường (được đo bằng cả phần trăm và số byte). Vì vậy, nếu /data
đầy, sẽ không có hai bản sao của mỗi tệp .odex. Mã tương tự cũng có BULK_DELETE_THRESHOLD: Nếu thiết bị sắp lấp đầy dung lượng trống (như vừa mô tả), thì các tệp .odex thuộc các ứng dụng không được sử dụng sẽ bị xóa. Đó là một trường hợp khác không có hai bản sao của mỗi tệp .odex.
Trong trường hợp xấu nhất khi /data
hoàn toàn đầy, bản cập nhật sẽ đợi cho đến khi thiết bị khởi động lại vào hệ thống mới và không còn cần các tệp .odex của hệ thống cũ nữa. PackageManager xử lý việc này: ( frameworks/base/+/main/services/core/java/com/android/server/pm/PackageManagerService.java#7215
). Sau khi hệ thống mới khởi động thành công, installd
( frameworks/native/+/main/cmds/installd/dexopt.cpp#2422
) có thể xóa các tệp .odex đã được hệ thống cũ sử dụng, đưa thiết bị trở lại trạng thái ổn định nơi chỉ có một bản sao.
Vì vậy, mặc dù /data
có thể chứa hai bản sao của tất cả các tệp .odex, nhưng (a) đây là tạm thời và (b) chỉ xảy ra nếu bạn vẫn còn nhiều dung lượng trống trên /data
. Ngoại trừ khi cập nhật, chỉ có một bản sao. Và như một phần của các tính năng mạnh mẽ chung của ART, nó sẽ không bao giờ lấp đầy /data
bằng các tệp .odex (vì đó cũng sẽ là một vấn đề trên hệ thống không phải A/B).
Chẳng phải tất cả việc viết/sao chép này đều làm tăng độ hao mòn của đèn flash sao?
Chỉ một phần nhỏ flash được ghi lại: bản cập nhật hệ thống Pixel đầy đủ ghi khoảng 2,3GiB. (Các ứng dụng cũng được biên dịch lại, nhưng điều đó cũng đúng với các ứng dụng không phải A/B.) Theo truyền thống, các OTA đầy đủ dựa trên khối đã ghi một lượng dữ liệu tương tự, do đó tốc độ hao mòn của flash sẽ tương tự.
Việc flash hai phân vùng hệ thống có làm tăng thời gian flash của nhà máy không?
Không. Pixel không tăng kích thước hình ảnh hệ thống (nó chỉ chia không gian thành hai phân vùng).
Việc giữ các tệp .odex trên B không làm cho việc khởi động lại sau khi thiết lập lại dữ liệu ban đầu bị chậm phải không?
Đúng. Nếu bạn thực sự đã sử dụng một thiết bị, sử dụng OTA và thiết lập lại dữ liệu ban đầu thì lần khởi động lại đầu tiên sẽ chậm hơn so với bình thường (1 phút 40 giây so với 40 giây trên Pixel XL) vì các tệp .odex sẽ bị mất từ B sau OTA đầu tiên và do đó không thể sao chép vào /data
. Đó là sự đánh đổi.
Thiết lập lại dữ liệu gốc phải là một thao tác hiếm khi so sánh với khởi động thông thường nên thời gian thực hiện ít quan trọng hơn. (Điều này không ảnh hưởng đến người dùng hoặc người đánh giá lấy thiết bị của họ từ nhà máy, vì trong trường hợp đó có sẵn phân vùng B.) Việc sử dụng trình biên dịch JIT có nghĩa là chúng tôi không cần phải biên dịch lại mọi thứ , vì vậy nó không tệ như bạn có thể nghĩ. Bạn cũng có thể đánh dấu các ứng dụng là yêu cầu biên dịch trước bằng cách sử dụng coreApp="true"
trong tệp kê khai: ( frameworks/base/+/main/packages/SystemUI/AndroidManifest.xml#23
). Điều này hiện được system_server
sử dụng vì nó không được phép vào JIT vì lý do bảo mật.
Việc không giữ các tệp .odex trên /data thay vì /system có khiến quá trình khởi động lại sau OTA bị chậm không?
Không. Như đã giải thích ở trên, dex2oat mới được chạy trong khi hình ảnh hệ thống cũ vẫn đang chạy để tạo các tệp mà hệ thống mới cần. Bản cập nhật không được coi là có sẵn cho đến khi công việc đó được hoàn thành.
Chúng tôi có thể (có nên) gửi thiết bị A/B 32GiB không? 16GiB? 8GiB?
32GiB hoạt động tốt như đã được chứng minh trên Pixel và 320MiB trên 16GiB có nghĩa là giảm 2%. Tương tự, 320MiB trên 8GiB giảm 4%. Rõ ràng A/B sẽ không phải là lựa chọn được đề xuất trên các thiết bị có 4GiB, vì chi phí 320MiB chiếm gần 10% tổng dung lượng có sẵn.
AVB2.0 có yêu cầu OTA A/B không?
Không. Khởi động được xác minh của Android luôn yêu cầu cập nhật dựa trên khối, nhưng không nhất thiết phải cập nhật A/B.
OTA A/B có yêu cầu AVB2.0 không?
KHÔNG.
Các OTA A/B có phá vỡ khả năng bảo vệ khôi phục của AVB2.0 không?
Không. Có một số nhầm lẫn ở đây vì nếu hệ thống A/B không khởi động được vào hình ảnh hệ thống mới thì hệ thống đó sẽ (sau một số lần thử lại được xác định bởi bộ tải khởi động của bạn) sẽ tự động trở lại hình ảnh hệ thống "trước đó". Tuy nhiên, điểm mấu chốt ở đây là "trước" theo nghĩa A/B thực ra vẫn là hình ảnh hệ thống "hiện tại". Ngay sau khi thiết bị khởi động thành công một hình ảnh mới, tính năng bảo vệ khôi phục sẽ hoạt động và đảm bảo rằng bạn không thể quay lại. Nhưng cho đến khi bạn thực sự khởi động thành công hình ảnh mới, tính năng bảo vệ khôi phục sẽ không coi đó là hình ảnh hệ thống hiện tại.
Nếu bạn đang cài đặt bản cập nhật trong khi hệ thống đang chạy, điều đó có chậm không?
Với các bản cập nhật không phải A/B, mục đích là cài đặt bản cập nhật nhanh nhất có thể vì người dùng đang chờ và không thể sử dụng thiết bị của họ trong khi bản cập nhật được áp dụng. Với cập nhật A/B thì điều ngược lại là đúng; bởi vì người dùng vẫn đang sử dụng thiết bị của họ nên mục tiêu là càng ít tác động càng tốt, vì vậy việc cập nhật được cố tình làm chậm. Thông qua logic trong ứng dụng khách cập nhật hệ thống Java (đối với Google là GmsCore, gói cốt lõi do GMS cung cấp), Android cũng cố gắng chọn thời điểm mà người dùng hoàn toàn không sử dụng thiết bị của họ. Nền tảng này hỗ trợ tạm dừng/tiếp tục cập nhật và khách hàng có thể sử dụng điều đó để tạm dừng cập nhật nếu người dùng bắt đầu sử dụng thiết bị và tiếp tục lại khi thiết bị không hoạt động trở lại.
Có hai giai đoạn khi sử dụng OTA, được hiển thị rõ ràng trong giao diện người dùng là Bước 1/2 và Bước 2/2 dưới thanh tiến trình. Bước 1 tương ứng với việc ghi các khối dữ liệu, trong khi bước 2 là biên dịch trước các tệp .dex. Hai giai đoạn này khá khác nhau về tác động hiệu suất. Giai đoạn đầu tiên là I/O đơn giản. Điều này đòi hỏi ít tài nguyên (RAM, CPU, I/O) vì nó chỉ sao chép chậm các khối xung quanh.
Giai đoạn thứ hai chạy dex2oat để biên dịch trước hình ảnh hệ thống mới. Điều này rõ ràng có ít giới hạn rõ ràng hơn về các yêu cầu của nó vì nó biên dịch các ứng dụng thực tế. Và rõ ràng là có nhiều công việc liên quan đến việc biên soạn một ứng dụng lớn và phức tạp hơn là một ứng dụng nhỏ và đơn giản; trong khi đó ở giai đoạn 1 không có khối đĩa nào lớn hơn hoặc phức tạp hơn các khối khác.
Quá trình này tương tự như khi Google Play cài đặt bản cập nhật ứng dụng ở chế độ nền trước khi hiển thị thông báo cập nhật 5 ứng dụng , như đã được thực hiện trong nhiều năm.
Điều gì sẽ xảy ra nếu người dùng thực sự đang chờ cập nhật?
Việc triển khai hiện tại trong GmsCore không phân biệt giữa các bản cập nhật nền và các bản cập nhật do người dùng thực hiện nhưng có thể làm như vậy trong tương lai. Trong trường hợp người dùng yêu cầu cài đặt bản cập nhật một cách rõ ràng hoặc đang xem màn hình tiến trình cập nhật, chúng tôi sẽ ưu tiên công việc cập nhật với giả định rằng họ đang tích cực chờ quá trình cập nhật kết thúc.
Điều gì xảy ra nếu không áp dụng được bản cập nhật?
Với các bản cập nhật không phải A/B, nếu bản cập nhật không áp dụng được, người dùng thường sẽ có một thiết bị không sử dụng được. Ngoại lệ duy nhất là nếu lỗi xảy ra trước khi ứng dụng khởi động (chẳng hạn như vì gói không thể xác minh). Với bản cập nhật A/B, việc không áp dụng bản cập nhật không ảnh hưởng đến hệ thống hiện đang chạy. Bản cập nhật có thể được thử lại sau.
Những hệ thống nào trên chip (SoC) hỗ trợ A/B?
Tính đến ngày 15-03-2017, chúng tôi có thông tin sau:
Android 7.x trở về trước | Android 8.x trở lên | |
Qualcomm | Tùy thuộc vào yêu cầu OEM | Tất cả các chipset sẽ nhận được hỗ trợ |
Mediatek | Tùy thuộc vào yêu cầu OEM | Tất cả các chipset sẽ nhận được hỗ trợ |
Để biết chi tiết về lịch trình, hãy kiểm tra với những người liên hệ SoC của bạn. Đối với các SoC không được liệt kê ở trên, hãy liên hệ trực tiếp với SoC của bạn.