क्या Google ने किसी डिवाइस पर A/B OTA का इस्तेमाल किया है?
हां. A/B अपडेट के लिए, मार्केटिंग नाम बिना रुकावट वाले अपडेट है. अक्टूबर 2016 से Pixel और Pixel XL
फ़ोन में A/B अपडेट की सुविधा दी गई है. साथ ही, सभी Chromebook में A/B अपडेट के लिए, update_engine
का इस्तेमाल किया जाता है. Android 7.1 और इसके बाद के वर्शन में, ज़रूरी प्लैटफ़ॉर्म कोड को सार्वजनिक किया गया है.
A/B OTA, सामान्य OTA से बेहतर क्यों हैं?
A/B OTA की मदद से, अपडेट करने पर उपयोगकर्ताओं को बेहतर अनुभव मिलता है. हर महीने मिलने वाले सुरक्षा अपडेट के आंकड़ों से पता चलता है कि यह सुविधा पहले ही सफल साबित हो चुकी है: मई 2017 तक, 95% Pixel उपयोगकर्ताओं ने एक महीने के अंदर, सुरक्षा से जुड़ा सबसे नया अपडेट इंस्टॉल कर लिया था. वहीं, Nexus के 87% उपयोगकर्ताओं ने एक महीने के अंदर, सुरक्षा से जुड़ा सबसे नया अपडेट इंस्टॉल किया था. इसके अलावा, Pixel उपयोगकर्ता, Nexus उपयोगकर्ताओं की तुलना में अपडेट को ज़्यादा तेज़ी से इंस्टॉल करते हैं. OTA के दौरान, अपडेट करने में गड़बड़ी होने पर, डिवाइस बूट नहीं हो पाएगा. हालांकि, जब तक नई सिस्टम इमेज बूट नहीं हो जाती, तब तक Android के पास पिछली सिस्टम इमेज पर वापस जाने की सुविधा होती है.
system_other क्या है?
ऐप्लिकेशन, .apk फ़ाइलों में सेव किए जाते हैं. ये फ़ाइलें, ZIP संग्रह होती हैं. हर .apk फ़ाइल में, एक या उससे ज़्यादा .dex फ़ाइलें होती हैं. इनमें पोर्टेबल Dalvik बाइटकोड होता है. .odex फ़ाइल (ऑप्टिमाइज़ की गई .dex फ़ाइल), .apk फ़ाइल से अलग होती है. इसमें डिवाइस के लिए खास मशीन कोड हो सकता है. अगर .odex फ़ाइल उपलब्ध है, तो Android, ऐप्लिकेशन को पहले से कंपाइल की गई स्पीड पर चला सकता है इसके लिए, हर बार ऐप्लिकेशन लॉन्च होने पर, कोड कंपाइल होने का इंतज़ार नहीं करना पड़ता. .odex फ़ाइल होना ज़रूरी नहीं है: Android, .dex कोड को सीधे तौर पर इंटरप्रेटेशन या Just-In-Time (JIT) कंपाइलेशन के ज़रिए चला सकता है. हालांकि, अगर जगह उपलब्ध है, तो .odex फ़ाइल से लॉन्च स्पीड और रन-टाइम स्पीड का सबसे अच्छा कॉम्बिनेशन मिलता है.
उदाहरण के लिए: Android 7.1 पर चलने वाले Nexus 6P की installed-files.txt के लिए, सिस्टम इमेज का कुल साइज़ 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 का इस्तेमाल किया होता, तो हम 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 से अपडेट किए गए ऐप्लिकेशन की .odex फ़ाइलें, हमेशा
/dataपर मौजूद रही हैं. ऐसा तब से है, जब उन्हें पहला अपडेट मिला था. - जिन ऐप्लिकेशन को उपयोगकर्ता नहीं चलाता उनके लिए, .odex फ़ाइल की ज़रूरत नहीं होती.
- प्रोफ़ाइल के हिसाब से कंपाइलेशन, पहले से कंपाइल किए गए ऐप्लिकेशन की तुलना में छोटी .odex फ़ाइलें जनरेट करता है. ऐसा इसलिए, क्योंकि पहले से कंपाइल किए गए ऐप्लिकेशन में, सिर्फ़ परफ़ॉर्मेंस के लिए ज़रूरी कोड को ऑप्टिमाइज़ किया जाता है.
ओईएम के लिए उपलब्ध ट्यूनिंग विकल्पों के बारे में जानने के लिए, ART को कॉन्फ़िगर करना लेख पढ़ें.
क्या /data पर .odex फ़ाइलों की दो कॉपी नहीं होती हैं?
यह थोड़ा मुश्किल है ... नई सिस्टम इमेज लिखे जाने के बाद, नई .odex फ़ाइलें जनरेट करने के लिए, dex2oat के नए वर्शन को नई .dex फ़ाइलों के साथ चलाया जाता है. यह तब होता है, जब पुराना सिस्टम अब भी चल रहा होता है. इसलिए, पुरानी और नई .odex फ़ाइलें, दोनों /data पर एक साथ मौजूद होती हैं.
OtaDexoptService (frameworks/base/+/android17-release/services/core/java/com/android/server/pm/OtaDexoptService.java) में मौजूद कोड, हर पैकेज को ऑप्टिमाइज़ करने से पहले, getAvailableSpace को कॉल करता है. इससे
/data में ज़्यादा जगह इस्तेमाल होने से बचा जा सकता है. ध्यान दें कि यहां उपलब्ध का मतलब, अब भी कम जगह उपलब्ध होना है. इसका मतलब है कि सिस्टम में जगह कम होने की सामान्य सीमा तक पहुंचने से पहले , बची हुई जगह (इसे प्रतिशत और बाइट की संख्या, दोनों में मापा जाता है). इसलिए, अगर /data पूरी तरह से भर गया है, तो हर .odex फ़ाइल की दो कॉपी नहीं होंगी. इसी कोड में, BULK_DELETE_THRESHOLD भी होता है: अगर डिवाइस, उपलब्ध जगह को भरने के करीब पहुंच जाता है (जैसा कि अभी बताया गया है), तो उन ऐप्लिकेशन की .odex फ़ाइलें हटा दी जाती हैं जिनका इस्तेमाल नहीं किया जाता. यह एक और ऐसा मामला है जिसमें हर .odex फ़ाइल की दो कॉपी नहीं होती हैं.
सबसे खराब स्थिति में, जब /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 फ़ाइलों की दो कॉपी मौजूद हों.
हालांकि, (a) यह अस्थायी है और (b) ऐसा सिर्फ़ तब होता है, जब आपके पास /data पर काफ़ी जगह खाली हो. अपडेट के दौरान को छोड़कर, सिर्फ़ एक कॉपी होती है. साथ ही, ART की सामान्य मज़बूत सुविधाओं के तहत, यह कभी भी /data को .odex फ़ाइलों से नहीं भरेगा. ऐसा इसलिए, क्योंकि यह समस्या, A/B सिस्टम के अलावा दूसरे सिस्टम पर भी हो सकती है.
क्या इन सभी फ़ाइलों को लिखने/कॉपी करने से, फ़्लैश मेमोरी का इस्तेमाल नहीं बढ़ता?
फ़्लैश मेमोरी का सिर्फ़ थोड़ा हिस्सा फिर से लिखा जाता है: Pixel के पूरे सिस्टम अपडेट में, करीब 2.3 जीबी डेटा लिखा जाता है. (ऐप्लिकेशन को भी फिर से कंपाइल किया जाता है. हालांकि, यह A/B के अलावा दूसरे सिस्टम पर भी लागू होता है.) आम तौर पर, ब्लॉक पर आधारित पूरे OTA में, इसी तरह का डेटा लिखा जाता था. इसलिए, फ़्लैश मेमोरी के इस्तेमाल की दरें भी इसी तरह की होनी चाहिए.
क्या दो सिस्टम पार्टिशन को फ़्लैश करने से, फ़ैक्ट्री में फ़्लैश करने का समय बढ़ जाता है?
नहीं. Pixel के सिस्टम इमेज के साइज़ में कोई बढ़ोतरी नहीं हुई है. इसमें सिर्फ़ जगह को दो पार्टिशन में बांटा गया है.
क्या .odex फ़ाइलों को B पर रखने से, फ़ैक्ट्री डेटा रीसेट के बाद रीबूट होने में ज़्यादा समय लगता है?
हां. अगर आपने किसी डिवाइस का इस्तेमाल किया है, OTA लिया है, और फ़ैक्ट्री डेटा रीसेट किया है, तो पहले रीबूट में ज़्यादा समय लगेगा. ऐसा इसलिए, क्योंकि पहले OTA के बाद, .odex फ़ाइलें B से हट जाएंगी. इसलिए, उन्हें /data में कॉपी नहीं किया जा सकेगा. उदाहरण के लिए, Pixel XL पर, पहले रीबूट में 1 मिनट 40 सेकंड लगेंगे. वहीं, सामान्य तौर पर 40 सेकंड लगते हैं. यह एक समझौता है.
सामान्य बूट की तुलना में, फ़ैक्ट्री डेटा रीसेट एक रेयर ऑपरेशन होना चाहिए. इसलिए, इसमें लगने वाला समय
कम अहमियत रखता है. (इससे उन उपयोगकर्ताओं या समीक्षकों पर कोई असर नहीं पड़ता जिन्हें अपना डिवाइस फ़ैक्ट्री से
मिलता है. ऐसा इसलिए, क्योंकि उस मामले में B पार्टिशन उपलब्ध होता है.) JIT कंपाइलर का इस्तेमाल करने का मतलब है कि हमें
सब कुछ फिर से कंपाइल करने की ज़रूरत नहीं है. इसलिए, यह उतना बुरा नहीं है जितना आपको लग सकता है. मेनिफ़ेस्ट में coreApp="true" का इस्तेमाल करके, ऐप्लिकेशन को पहले से कंपाइल करने के लिए मार्क भी किया जा सकता है: (frameworks/base/+/android17-release/packages/SystemUI/AndroidManifest.xml#23). फ़िलहाल, इसका इस्तेमाल system_server करता है. ऐसा इसलिए, क्योंकि सुरक्षा की वजहों से, इसे JIT की अनुमति नहीं है.
क्या .odex फ़ाइलों को /system के बजाय /data पर रखने से, OTA के बाद रीबूट होने में ज़्यादा समय लगता है?
नहीं. जैसा कि ऊपर बताया गया है, नए सिस्टम के लिए ज़रूरी फ़ाइलें जनरेट करने के लिए, dex2oat का नया वर्शन तब चलाया जाता है, जब पुरानी सिस्टम इमेज अब भी चल रही होती है. अपडेट को तब तक उपलब्ध नहीं माना जाता, जब तक यह काम पूरा नहीं हो जाता.
क्या हमें 32 जीबी A/B डिवाइस शिप करना चाहिए? 16 जीबी? 8 जीबी?
32 जीबी डिवाइस अच्छी तरह से काम करता है. यह Pixel पर साबित हो चुका है. वहीं, 16 जीबी में से 320 एमबी का मतलब है कि 2% की कमी. इसी तरह, 8 जीबी में से 320 एमबी का मतलब है कि 4% की कमी. ज़ाहिर है कि 4 जीबी वाले डिवाइसों पर, A/B अपडेट की सुविधा देने का सुझाव नहीं दिया जाएगा. ऐसा इसलिए, क्योंकि 320 एमबी का ओवरहेड, कुल उपलब्ध जगह का करीब 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 अपडेट में, इसके उलट होता है. ऐसा इसलिए, क्योंकि उपयोगकर्ता अब भी अपने डिवाइस का इस्तेमाल कर रहा होता है. हमारा मकसद, अपडेट का कम से कम असर डालना होता है. इसलिए, अपडेट में जान-बूझकर ज़्यादा समय लगता है. Java सिस्टम अपडेट क्लाइंट में मौजूद लॉजिक के ज़रिए (Google के लिए यह GmsCore है, जो GMS से मिलने वाला मुख्य पैकेज है), Android, ऐसा समय चुनने की कोशिश भी करता है जब उपयोगकर्ता अपने डिवाइसों का इस्तेमाल नहीं कर रहे होते. प्लैटफ़ॉर्म, अपडेट को रोकने/फिर से शुरू करने की सुविधा देता है. साथ ही, क्लाइंट इसका इस्तेमाल करके, अपडेट को रोक सकता है. ऐसा तब किया जाता है, जब उपयोगकर्ता डिवाइस का इस्तेमाल करने लगता है. इसके बाद, जब डिवाइस फिर से इस्तेमाल में नहीं होता, तो अपडेट को फिर से शुरू किया जा सकता है.
OTA लेने के दौरान, दो चरण होते हैं. इन्हें यूज़र इंटरफ़ेस (यूआई) में, प्रोग्रेस बार के नीचे 1/2 चरण और 2/2 चरण के तौर पर साफ़ तौर पर दिखाया जाता है. पहला चरण, डेटा ब्लॉक लिखने से जुड़ा है. वहीं, दूसरा चरण, .dex फ़ाइलों को पहले से कंपाइल करने से जुड़ा है. परफ़ॉर्मेंस पर पड़ने वाले असर के मामले में, ये दोनों चरण काफ़ी अलग हैं. पहला चरण, सामान्य इनपुट/आउटपुट (आई/ओ) है. इसके लिए, कम संसाधनों (रैम, सीपीयू, आई/ओ) की ज़रूरत होती है. ऐसा इसलिए, क्योंकि इसमें सिर्फ़ ब्लॉक को धीरे-धीरे कॉपी किया जाता है.
दूसरे चरण में, dex2oat को चलाकर, नई सिस्टम इमेज को पहले से कंपाइल किया जाता है. ज़ाहिर है कि इसकी ज़रूरतों पर कम पाबंदियां होती हैं. ऐसा इसलिए, क्योंकि इसमें असल ऐप्लिकेशन कंपाइल किए जाते हैं. साथ ही, छोटे और आसान ऐप्लिकेशन को कंपाइल करने की तुलना में, बड़े और मुश्किल ऐप्लिकेशन को कंपाइल करने में ज़्यादा काम करना पड़ता है. वहीं, पहले चरण में, डिस्क ब्लॉक में कोई भी ब्लॉक, दूसरे ब्लॉक से बड़ा या ज़्यादा मुश्किल नहीं होता.
यह प्रोसेस, Google Play के बैकग्राउंड में किसी ऐप्लिकेशन के अपडेट को इंस्टॉल करने जैसी होती है. ऐसा 5 ऐप्लिकेशन अपडेट किए गए सूचना दिखाने से पहले किया जाता है. यह प्रोसेस, सालों से की जा रही है.
अगर कोई उपयोगकर्ता, अपडेट का इंतज़ार कर रहा है, तो क्या होगा?
GmsCore में मौजूदा तरीके से, बैकग्राउंड में होने वाले अपडेट और उपयोगकर्ता की ओर से शुरू किए गए अपडेट के बीच अंतर नहीं किया जाता. हालांकि, आने वाले समय में ऐसा किया जा सकता है. अगर उपयोगकर्ता ने साफ़ तौर पर अपडेट इंस्टॉल करने के लिए कहा है या वह अपडेट की प्रोग्रेस स्क्रीन देख रहा है, तो हम अपडेट के काम को प्राथमिकता देंगे. ऐसा इसलिए, क्योंकि हम मान लेंगे कि वह अपडेट पूरा होने का इंतज़ार कर रहा है.
अगर कोई अपडेट लागू नहीं हो पाता है, तो क्या होगा?
A/B के अलावा दूसरे अपडेट में, अगर कोई अपडेट लागू नहीं हो पाता था, तो उपयोगकर्ता के पास आम तौर पर ऐसा डिवाइस होता था जिसका इस्तेमाल नहीं किया जा सकता. सिर्फ़ एक अपवाद था. ऐसा तब होता था, जब कोई ऐप्लिकेशन शुरू होने से पहले ही गड़बड़ी हो जाती थी उदाहरण के लिए, पैकेज की पुष्टि नहीं हो पाती थी. A/B अपडेट में, अपडेट लागू नहीं होने पर, फ़िलहाल चल रहे सिस्टम पर कोई असर नहीं पड़ता. अपडेट को बाद में फिर से इंस्टॉल किया जा सकता है.