자주 묻는 질문(FAQ)

Google에서 A/B OTA를 적용한 기기가 있나요?

예. A/B 업데이트의 마케팅 이름은 원활한 업데이트입니다. A/B로 출시된 2016년 10월 이후의 Pixel 및 Pixel XL 휴대전화와 모든 Chromebook은 동일한 A/B update_engine 구현을 사용합니다. 필요한 플랫폼 코드 구현은 Android 7.1 이상에서 공개됩니다.

A/B OTA가 더 나은 이유는 뭔가요?

A/B OTA는 업데이트 다운로드 시 향상된 사용자 환경을 제공합니다. 월별 보안 업데이트의 측정 결과에 따르면 이 기능은 이미 성공을 거둔 것으로 증명되었습니다. 2017년 5월 기준, Pixel 소유자의 95%가 1개월 후에 최신 보안 업데이트를 실행 중이었습니다. 이는 87%인 Nexus 사용자와 비교되는 수치이며 Pixel 사용자가 Nexus 사용자보다 더 빨리 기기를 업데이트합니다. 이제는 OTA 도중에 블록을 업데이트하는 데 실패해도 기기 부팅에 실패하지 않으며, 새 시스템 이미지가 정상적으로 부팅될 때까지는 Android가 이전의 작동하는 시스템 이미지로 돌아갈 수 있는 기능을 유지합니다.

A/B는 2016 Pixel 파티션 크기에 어떻게 영향을 미쳤나요?

다음 표에는 배포 시 A/B 구성과 내부 테스트를 거친 비 A/B 구성을 비교한 내용이 자세히 나와 있습니다.

Pixel 파티션 크기 A/B 비 A/B
부트로더 50*2 50
부팅 32*2 32
복구 0 32
캐시 0 100
라디오 70*2 70
공급업체 300*2 300
시스템 2048*2 4096
합계 5000 4680

A/B 업데이트를 적용하려면 플래시에서 320MiB만 늘리면 되며, 복구 파티션 제거로 32MiB가, 캐시 파티션 제거로 100MiB가 확보됩니다. 그러면 부트로더, 부팅 파티션과 라디오 파티션의 B 파티션 비용이 균형을 이루게 됩니다. 공급업체 파티션은 크기가 두 배가 되었습니다(크기 증가의 대부분을 차지). Pixel의 A/B 시스템 이미지는 원래 비 A/B 시스템 이미지의 절반 크기입니다.

Pixel A/B 및 내부적으로 테스트된 비 A/B 변형의 경우(A/B만 제공됨) 사용된 공간의 차이는 320MiB 밖에 나지 않습니다. 32GiB 기기에서는 이 차이가 1% 미만입니다. 16GiB 기기의 경우에는 2% 미만이며 8GiB 기기의 경우에는 약 4%입니다(세 기기의 시스템 이미지가 모두 동일하다는 가정하에).

SquashFS를 사용하지 않는 이유는 무엇인가요?

SquashFS를 이용한 실험은 있었지만 최첨단 기기에 요구되는 성능은 달성할 수 없었습니다. 휴대기기에 SquashFS를 사용하거나 권장하지 않습니다.

구체적으로는 SquashFS의 사용으로 시스템 파티션 크기의 약 50%가 절약되었지만 제대로 압축된 대부분의 파일은 사전 컴파일된 .odex 파일이었습니다. 이러한 파일은 압축비가 매우 높았지만(80%에 근접) 시스템 파티션 나머지 부분의 압축비는 매우 낮았습니다. 또한 Android 7.0의 SquashFS는 다음과 같은 성능 문제를 야기했습니다.

  • Pixel은 초기에 출시된 기기에 비해 플래시 속도가 매우 빠르지만 예비 CPU 주기 수는 그리 크지 않습니다. 따라서 플래시에서 더 적은 바이트를 읽지만 I/O에 더 많은 CPU가 필요하다는 점이 잠재적인 병목 현상으로 작용했습니다.
  • 로드 취소된 시스템에서 실행되는 인위적 벤치마크에 관해 뛰어난 성능을 보이는 I/O 변경사항은 간혹 실제 로드(예: Nexus 6의 암호화) 하의 실제 사용 사례에서 제대로 작동하지 않을 때가 있습니다.
  • 벤치마킹은 일부 위치에서 85%의 회귀율을 보였습니다.

SquashFS가 더욱 발전하고 CPU 영향을 줄이기 위한 기능(예: 일반적으로 액세스되지만 압축되면 안 되는 파일의 허용 목록)을 추가함에 따라 Google은 계속해서 이를 평가하며 기기 제조업체를 대상으로 권장사항을 제공할 예정입니다.

SquashFS 없이 시스템 파티션 크기를 어떻게 절반으로 줄였나요?

애플리케이션은 .apk 파일에 저장되며 실질적으로 이 파일은 ZIP 보관 파일입니다. 각 .apk 안에는 이식성 있는 Dalvik 바이트 코드를 포함하는 1개 이상의 .dex 파일이 있습니다. .odex 파일(최적화된 .dex)은 .apk 파일과 분리되어 있으며 기기와 관련된 기계어 코드를 포함할 수 있습니다. .odex 파일을 사용할 수 있는 경우 Android는 애플리케이션이 실행될 때마다 코드가 컴파일되기를 기다릴 필요 없이 AOT 컴파일 속도로 애플리케이션을 실행할 수 있습니다. .odex 파일이 꼭 필요하지는 않습니다. Android는 실제로 .dex 코드를 해석 또는 JIT(Just-In-Time) 컴파일을 통해 직접적으로 실행할 수 있지만 .odex 파일은 공간이 있을 경우 최상의 실행 속도 및 런타임 속도 조합을 제공합니다.

예: Android 7.1을 실행하고 총 2,628MiB(2,755,792,836바이트)의 시스템 이미지 크기를 가진 Nexus 6P의 installed-files.txt는 파일 유형별 전체 시스템 이미지 크기에 관한 최대 기여 요소의 분석이 다음과 같이 이루어집니다.

.odex 1,391,770,312바이트 50.5%
.apk 846,878,259바이트 30.7%
.so(네이티브 C/C++ 코드) 202,162,479바이트 7.3%
.oat 파일/.art 이미지 163,892,188바이트 5.9%
글꼴 38,952,361바이트 1.4%
icu 로케일 데이터 27,468,687바이트 0.9%

이러한 수치는 다른 기기의 경우에도 비슷합니다. 따라서 Nexus/Pixel 기기에서는 .odex 파일이 시스템 파티션의 약 절반을 차지합니다. 따라서 계속해서 ext4를 사용하되 공장에서 B 파티션에 .odex 파일을 쓰고 첫 번째 부팅 시 이를 /data에 복사할 수 있습니다. ext4 A/B에 사용되는 실제 저장소는 SquashFS A/B와 동일합니다. SquashFS를 사용했다면 system_b 대신 system_a에 사전 선택된 .odex 파일을 제공했을 것이기 때문입니다.

.odex 파일을 /data에 복사하면 /system에서 절약된 공간을 /data 때문에 잃게 되지 않나요?

꼭 그렇지는 않습니다. Pixel에서는 .odex 파일이 차지하는 공간 대부분이 일반적으로 /data에 있는 앱을 위한 것입니다. 이러한 앱은 Google Play 업데이트를 받습니다. 따라서 시스템 이미지의 .apk 및 .odex 파일이 기기 수명 대부분에 걸쳐 사용되지 않습니다. 이러한 파일은 사용자가 실제로 각 앱을 사용할 때 작은 프로필 기반 .odex 파일로 교체되거나 완전히 제외될 수 있습니다. 따라서 사용자가 사용하지 않는 앱을 위한 공간이 필요하지 않습니다. 자세한 내용은 Google I/O 2016 대담 The Evolution of ART를 참고하세요.

비교가 어려운 데에는 몇 가지 중요한 이유가 있습니다.

  • Google Play에서 업데이트된 앱은 항상 첫 번째 업데이트를 받는 즉시 /data에 .odex 파일이 있습니다.
  • 사용자가 실행하지 않는 앱에는 .odex 파일이 전혀 필요하지 않습니다.
  • 프로필 기반 컴파일은 AOT 컴파일보다 더 작은 .odex 파일을 생성합니다. 이는 프로필 기반 컴파일이 성능에 중요한 코드만 최적화하기 때문입니다.

OEM에 사용 가능한 조정 옵션에 관한 자세한 내용은 ART 구성을 참고하세요.

/data에는 .odex 파일 사본 두 개가 있지 않나요?

조금 더 복잡합니다. 새 시스템 이미지가 작성된 후에는 새 버전의 dex2oat가 새 .dex 파일에 실행되어 새 .odex 파일을 생성합니다. 이는 기존 시스템이 여전히 실행되는 동안 발생하므로 이전 및 새 .odex 파일이 모두 동시에 /data에 있게 됩니다.

OtaDexoptService의 코드(frameworks/base/+/master/services/core/java/com/android/server/pm/OtaDexoptService.java)는 각 패키지를 최적화하기 전에 getAvailableSpace를 호출하여 /data를 과도하게 채우는 것을 방지합니다. 여기서 available은 여전히 적습니다. 일반적인 시스템 공간 부족 임계값에 도달하기 전에 남은 공간의 크기이기 때문입니다(백분율 및 바이트 수로 측정됨). 따라서 /data가 가득 차면 모든 .odex 파일의 사본 두 개가 존재하지 않습니다. 같은 코드에는 BULK_DELETE_THRESHOLD도 있습니다. 방금 설명한 것처럼 기기가 가용 공간을 채우기 직전이 되면 사용되지 않는 앱에 속하는 .odex 파일이 제거됩니다. 이 역시 모든 .odex 파일의 사본 두 개가 없는 또 다른 사례입니다.

/data가 완전히 가득 찬 최악의 경우에는 기기가 새 시스템으로 재부팅되고 더 이상 기존 시스템의 .odex 파일이 필요 없을 때까지 업데이트가 대기합니다. PackageManager가 이를 처리합니다(frameworks/base/+/master/services/core/java/com/android/server/pm/PackageManagerService.java#7215). 새 시스템이 성공적으로 부팅되면 installd(frameworks/native/+/master/cmds/installd/dexopt.cpp#2422)가 기존 시스템에서 사용했던 .odex 파일을 삭제하므로 사본이 하나만 있는 안정적인 상태로 기기를 되돌릴 수 있습니다.

따라서 /data가 모든 .odex 파일의 사본 두 개를 포함할 수는 있지만 (a) 이는 일시적이며, (b) /data에 여유 공간이 충분한 경우에만 발생합니다. 업데이트 도중을 제외하고는 1개의 사본만 있습니다. 또한 ART의 일반적인 견고성 기능의 일부로 /data를 .odex 파일로 채우지는 않습니다. 비 A/B 시스템에도 문제가 될 수 있기 때문입니다.

이러한 쓰기/복사가 플래시 마모를 증가시키지는 않나요?

플래시의 일부만 재작성되며, 전체 Pixel 시스템 업데이트 시 약 2.3GiB가 작성됩니다. 앱도 다시 컴파일되지만 이는 비 A/B의 경우에도 마찬가지입니다. 일반적으로 블록 기반 전체 OTA는 비슷한 양의 데이터를 작성했으므로 플래시 마모율도 비슷합니다.

두 개의 시스템 파티션을 플래시할 경우 팩토리 플래싱 시간이 증가하나요?

아니요. Pixel은 시스템 이미지 크기를 늘리지 않았으며 공간을 두 개의 파티션에 걸쳐 분할한 것 뿐입니다.

.odex 파일을 B에 유지할 경우 초기화 재부팅이 느려지지 않나요?

예. 실제로 기기를 사용하고 OTA를 가져와서 초기화를 실행했다면 첫 번째 재부팅이 안 그런 경우와 비교해 느려집니다(Pixel XL에서 1분40초 대 40초). .odex 파일이 첫 번째 OTA 이후 B에서 손실되어 /data에 복사할 수 없기 때문입니다. 이렇게 초기화에는 장단점이 있습니다.

초기화는 일반 부팅에 비해 흔하지 않은 작업이므로 소요 시간이 덜 중요합니다. 사용자나 리뷰어가 공장에서 기기를 수령하는 경우에는 B 파티션을 사용할 수 있으므로 관련이 없습니다. JIT 컴파일러를 사용하므로 모든 것을 다시 컴파일할 필요는 없는 만큼 큰 문제가 되지는 않습니다. 매니페스트(frameworks/base/+/master/packages/SystemUI/AndroidManifest.xml#23)에서 coreApp="true"를 사용하여 앱을 AOT 컴파일이 필요한 것으로 표시할 수도 있습니다. 현재 system_server에서 사용됩니다. 보안 상의 이유로 JIT에 허용되지 않기 때문입니다.

.odex 파일을 /system 대신 /data에 보관할 경우 OTA 이후의 재부팅이 느려지지 않나요?

아니요. 위에서 설명한 것처럼 새 dex2oat는 새 시스템에 필요한 파일을 생성할 수 있도록 기존 시스템 이미지와 동시에 실행됩니다. 업데이트는 이 작업이 완료될 때까지 사용 가능한 것으로 간주되지 않습니다.

32GiB A/B 기기를 제공할 수 있나요(제공해야 하나요)? 16GiB 또는 8GiB는 어떤가요?

32GiB도 Pixel에서 검증된 만큼 제대로 작동하며 16GiB의 320MiB는 2%의 감소율을 의미합니다. 마찬가지로 8GiB의 320MiB는 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는 자바 시스템 업데이트 클라이언트(Google의 경우 GMS에 의해 제공되는 코어 패키지인 GmsCore)를 통해 사용자가 기기를 아예 사용하지 않고 있는 시간을 선택하려고 시도합니다. 플랫폼은 업데이트 일시중지/재개를 지원하며, 클라이언트는 이를 사용하여 사용자가 기기를 사용하기 시작할 경우 업데이트를 일시중지하고 기기가 다시 유휴 상태가 되면 업데이트를 재개할 수 있습니다.

OTA를 적용받는 과정에는 두 단계가 있으며 진행률 표시줄 아래의 UI에 1/2단계2/2단계로 명확히 표시됩니다. 1단계는 데이터 블록 작성에 상응하며 2단계는 dex 파일의 사전 컴파일 과정입니다. 두 단계는 성능적 영향이라는 측면에서 아주 다릅니다. 첫 번째 단계는 단순한 I/O입니다. 이 작업에는 리소스(RAM, CPU, I/O)가 거의 필요하지 않습니다. 블록을 천천히 복사하기 때문입니다.

두 번째 단계에서는 dex2oat를 실행하여 새 시스템 이미지를 사전 컴파일합니다. 이 경우 실제 앱이 컴파일되므로 요구사항의 경계가 덜 명확합니다. 또한 작고 간단한 앱에 비해 크고 복잡한 앱을 컴파일하는 데 더 많은 작업이 필요합니다. 반면에 1단계에서는 다른 블록보다 더 크거나 복잡한 디스크 블록이 없습니다.

프로세스는 Google Play에서 수년 동안 그랬던 것처럼 앱 5개 업데이트됨 알림을 표시하기 전에 백그라운드에서 앱 업데이트를 설치했던 방식과 유사합니다.

사용자가 실제로 업데이트를 기다리고 있으면 어떡하나요?

GmsCore의 현재 구현은 백그라운드 업데이트와 사용자가 시작한 업데이트를 구분하지 않지만 앞으로는 구분이 이루어질 수도 있습니다. 사용자가 업데이트 설치를 명시적으로 요구했거나 업데이트 진행 화면을 보고 있는 경우에는 사용자가 업데이트 완료를 적극적으로 기다리고 있다는 가정하에 업데이트 작업을 우선순위로 지정합니다.

업데이트 적용이 실패하면 어떻게 되나요?

비 A/B 업데이트에서는 업데이트 적용에 실패할 경우 일반적으로 사용자가 기기를 사용할 수 없었습니다. 유일한 예외는 애플리케이션이 시작되기도 전에 적용이 실패하는 경우였습니다(예를 들면 패키지가 인증에 실패했기 때문). A/B 업데이트에서는 업데이트 적용에 실패해도 현재 실행 중인 시스템은 영향을 받지 않습니다. 업데이트는 나중에 재시도하면 됩니다.

어떤 SoC(단일 칩 시스템)가 A/B를 지원하나요?

2017년 3월 15일 기준, 지원 시스템은 다음과 같습니다.

Android 7.x 이전 Android 8.x 이후
Qualcomm OEM 요청에 따라 모든 칩셋에 지원 적용
Mediatek OEM 요청에 따라 모든 칩셋에 지원 적용

자세한 일정은 SoC 담당자에게 문의해 주세요. 위에 나열되지 않은 SoC는 SoC에 직접 문의하시기 바랍니다.