การสำรวจเชิงลึกเกี่ยวกับ SDCardFS การแทนที่ FUSE ของ Google และการใช้งานจะช่วยลดค่าใช้จ่าย I/O ได้อย่างไร
เมื่อหลายเดือนก่อน Google ได้เพิ่มสิ่งที่เรียกว่า “SDCardFS” ไปยังสาขา AOSP อย่างเป็นทางการสำหรับเคอร์เนล Linux ในขณะนั้นการเคลื่อนไหวนั้นถูกสังเกตโดยเท่านั้น นักพัฒนาเคอร์เนลบางคนแต่อย่างอื่นก็บินไปอยู่ภายใต้เรดาร์ของผู้ใช้ส่วนใหญ่ ไม่แปลกใจเลยเมื่อพิจารณาจากข้อเท็จจริงที่ว่าผู้ใช้ส่วนใหญ่รวมทั้งตัวฉันเองด้วยก็ไม่รู้จริงๆ ว่าเกิดอะไรขึ้นภายใต้ระบบปฏิบัติการ Android และเคอร์เนลของมัน
อย่างไรก็ตามตอนล่าสุดของ นักพัฒนา Android หลังเวที พอดแคสต์เริ่มสนใจหัวข้อนี้อีกครั้ง พอดแคสต์ซึ่งจัดทำโดย Chet Haase (วิศวกรซอฟต์แวร์อาวุโสของ Google) สำรวจการเปลี่ยนแปลงล่าสุดและที่กำลังจะเกิดขึ้นกับเคอร์เนล ในรายการเป็นนักพัฒนาเคอร์เนล Linux ที่ทำงานให้กับทีม Android - Rom Lemarchand ทั้งคู่พูดคุยกันถึงการเปลี่ยนแปลงต่างๆ ที่เกิดขึ้นเพื่อรองรับการอัปเดต A/B แต่ในช่วง 5 นาทีสุดท้ายของตอนนี้ คุณ Lemarchand ได้พูดคุยเกี่ยวกับ "สิ่งที่ยิ่งใหญ่ถัดไป" ที่ทีมของเขากำลังดำเนินการอยู่ - SDCardFS.
ฉันต้องยอมรับว่าฉันได้เรียนรู้เกี่ยวกับการมีอยู่ของ SDCardFS หลังจากฟังพอดแคสต์นี้ แน่นอนว่าฉันไม่ใช่คนเดียวที่สนใจหัวข้อนี้ในฐานะ
กระทู้ Reddit ล่าสุด ได้แสดงให้เห็น. อย่างไรก็ตาม ฉันไม่พอใจกับคำอธิบายพื้นฐานที่นำเสนอในพอดแคสต์ และในความพยายามที่จะขจัดบางส่วน ข้อมูลที่ไม่ถูกต้องถูกแพร่กระจายไปทั่ว ฉันได้ค้นคว้าข้อมูลของตัวเองและพูดคุยกับผู้เชี่ยวชาญสองสามคนที่มีความรู้ที่เกี่ยวข้องเกี่ยวกับ วัตถุ.ขอขอบคุณอย่างยิ่งต่อนักพัฒนาซอฟต์แวร์ Michal Kowalczyk ที่ให้ความรู้ในบทความนี้และสละเวลาในการตอบคำถามของฉัน
"ภายนอก" คือภายในจริงๆ
ทันทีที่เข้าใจ เราจะต้องแก้ไขความเข้าใจผิดบางประการ ไม่เช่นนั้นบทความที่เหลือจะทำให้เกิดความสับสนอย่างมาก การหารือเกี่ยวกับประวัติของการ์ด SD และโทรศัพท์ Android จะเป็นประโยชน์
ในช่วงแรก ๆ ของโทรศัพท์ Android อุปกรณ์เกือบทุกเครื่องอาศัยการใช้การ์ด microSD ในการจัดเก็บ นี่เป็นเพราะความจริงที่ว่าโทรศัพท์ในขณะนั้นมาพร้อมกับความจุที่เก็บข้อมูลภายในเพียงเล็กน้อย อย่างไรก็ตาม การ์ด SD ที่ใช้จัดเก็บแอปพลิเคชันมักไม่ได้มอบประสบการณ์การใช้งานที่ยอดเยี่ยม อย่างน้อยก็เมื่อเทียบกับความเร็วที่หน่วยความจำแฟลชภายในสามารถอ่าน/เขียนข้อมูลได้ ดังนั้น การใช้การ์ด SD สำหรับการจัดเก็บข้อมูลภายนอกที่เพิ่มขึ้นจึงกลายเป็นข้อกังวลด้านประสบการณ์ผู้ใช้สำหรับ Google
เนื่องจากการแพร่หลายของการ์ด SD ในฐานะอุปกรณ์จัดเก็บข้อมูลภายนอก หลักการตั้งชื่อพื้นที่เก็บข้อมูลของ Android จึงมีพื้นฐานมาจากข้อเท็จจริงที่ว่าอุปกรณ์ทุกเครื่องมีช่องเสียบการ์ด microSD จริง แต่แม้กระทั่งบนอุปกรณ์ที่ไม่มีช่องเสียบการ์ด SD ป้ายกำกับ /sdcard ยังคงใช้เพื่อชี้ไปที่ชิปจัดเก็บข้อมูลภายในจริง สิ่งที่น่าสับสนกว่านั้นคืออุปกรณ์ที่ใช้ทั้งการ์ด SD แบบฟิสิคัลและชิปจัดเก็บข้อมูลความจุสูงสำหรับการจัดเก็บมักจะตั้งชื่อพาร์ติชันตามการ์ด SD ตัวอย่างเช่น ในอุปกรณ์เหล่านี้ จุดเชื่อมต่อ /sdcard จะอ้างอิงถึงชิปจัดเก็บข้อมูลภายในจริง ในขณะที่จุดเช่น /storage/sdcard1 จะอ้างอิงถึงการ์ดภายนอกทางกายภาพ
ดังนั้น แม้ว่าในทางปฏิบัติแล้วการ์ด microSD จะถือว่าเป็นที่จัดเก็บข้อมูลภายนอก แต่รูปแบบการตั้งชื่อส่งผลให้ "SDCard" ยังคงอยู่จนผ่านการใช้งานจริงของการ์ดจริงไปนานแล้ว ความสับสนในเรื่องพื้นที่จัดเก็บข้อมูลยังสร้างความปวดหัวให้กับนักพัฒนาแอพพลิเคชั่น เนื่องจากข้อมูลแอพพลิเคชั่นและสื่อถูกแยกออกจากพาร์ติชั่นทั้งสอง
พื้นที่เก็บข้อมูลเหลือน้อยของชิปจัดเก็บข้อมูลภายในรุ่นแรกๆ ส่งผลให้ผู้ใช้รู้สึกหงุดหงิดเมื่อพบว่าไม่สามารถติดตั้งแอปพลิเคชันได้อีกต่อไป (เนื่องจากพาร์ติชัน /data เต็ม) ในขณะเดียวกัน การ์ด microSD ที่มีความจุสูงกว่านั้นถูกจำกัดให้เก็บเฉพาะสื่อเท่านั้น (เช่น รูปภาพ เพลง และภาพยนตร์) ผู้ใช้ที่เรียกดูฟอรัมของเราในวันนั้นอาจจำชื่อเหล่านี้ได้: Link2SD และ Apps2SD สิ่งเหล่านี้เป็นโซลูชัน (รูท) ที่ช่วยให้ผู้ใช้สามารถติดตั้งแอปพลิเคชันและข้อมูลทั้งหมดลงในการ์ด SD จริงได้ แต่สิ่งเหล่านี้ยังห่างไกลจากโซลูชันที่สมบูรณ์แบบ ดังนั้น Google จึงต้องเข้ามามีส่วนร่วม
เป็นที่ทราบกันดีว่า Google ดึงปลั๊กการ์ด SD ออกตั้งแต่เนิ่นๆ Nexus One ยังคงเป็นอุปกรณ์ Nexus เพียงเครื่องเดียวที่มีช่องเสียบการ์ด microSD (และจะเป็นตลอดไปเนื่องจากแบรนด์ Nexus เสียชีวิตแล้ว) ด้วย Nexus S ขณะนี้มีพาร์ติชันแบบรวมเพียงพาร์ติชันเดียวสำหรับการจัดเก็บข้อมูลแอปพลิเคชันและสื่อทั้งหมด - พาร์ติชัน /data สิ่งที่ครั้งหนึ่งเคยรู้จักกันในชื่อจุดเมานต์ /sdcard ในตอนนี้เป็นเพียงการอ้างอิงถึงระบบไฟล์เสมือน (ใช้งานภายใต้ ฟิวส์ โปรโตคอลตามที่กล่าวไว้ด้านล่าง) ซึ่งอยู่ในพาร์ติชันข้อมูล - /data/media/0
เพื่อรักษาความเข้ากันได้และลดความสับสน Google ยังคงใช้พาร์ติชัน "sdcard" เสมือนนี้เพื่อเก็บสื่อ แต่ตอนนี้พาร์ติชันเสมือน "sdcard" นี้จริงๆ แล้วอยู่ภายใน /data สิ่งที่เก็บไว้ภายในนั้นจะนับรวมกับพื้นที่เก็บข้อมูลของชิปจัดเก็บข้อมูลภายใน ดังนั้นจึงขึ้นอยู่กับ OEM ที่จะพิจารณาว่าจะจัดสรรพื้นที่ให้กับแอปพลิเคชัน (/ข้อมูล) เทียบกับสื่อ (/data/media) เท่าใด
Google หวังว่าผู้ผลิตจะปฏิบัติตามตัวอย่างของพวกเขาและเลิกใช้การ์ด SD โชคดีที่เมื่อเวลาผ่านไป ผู้ผลิตโทรศัพท์สามารถจัดหาส่วนประกอบเหล่านี้ด้วยความจุที่สูงขึ้นแต่ยังคงความคุ้มค่าได้ ดังนั้น ความต้องการการ์ด SD จึงเริ่มมีน้อยลง แต่แบบแผนการตั้งชื่อยังคงมีอยู่เพื่อลดปริมาณความพยายามที่นักพัฒนาและ OEM จะต้องปรับตัว ในปัจจุบัน เมื่อเราอ้างถึง “ที่จัดเก็บข้อมูลภายนอก” เรากำลังหมายถึง อย่างใดอย่างหนึ่งจากสองสิ่ง: การ์ด microSD แบบถอดได้จริงหรือพาร์ติชัน “SDCard” เสมือนที่อยู่ใน /data/media อย่างหลังนี้ ในทางปฏิบัติแล้ว เป็นที่เก็บข้อมูลภายในจริงๆแต่แบบแผนการตั้งชื่อของ Google ทำให้มีความแตกต่างเนื่องจากผู้ใช้สามารถเข้าถึงข้อมูลนี้ได้ (เช่น เมื่อเสียบเข้ากับคอมพิวเตอร์)
ในปัจจุบัน เมื่อเราอ้างถึง “ที่จัดเก็บข้อมูลภายนอก” เรากำลังหมายถึง อย่างใดอย่างหนึ่งจากสองสิ่ง: การ์ด microSD แบบถอดได้จริงหรือพาร์ติชัน “SDCard” เสมือนที่อยู่ใน /data/media
ประวัติความเป็นมาของระบบไฟล์เสมือนของ Android
ตอนนี้ "sdcard" ถือเป็นระบบไฟล์เสมือน หมายความว่าสามารถจัดรูปแบบเป็นระบบไฟล์ใดก็ได้ที่ Google ต้องการ เริ่มต้นด้วย Nexus S และ Android 2.3 Google เลือกที่จะฟอร์แมต "sdcard" เป็น VFAT (virtual FAT) การเคลื่อนไหวนี้สมเหตุสมผลในขณะนั้น เนื่องจากการติดตั้ง VFAT จะทำให้คอมพิวเตอร์เกือบทุกเครื่องสามารถเข้าถึงข้อมูลที่จัดเก็บไว้ในโทรศัพท์ของคุณได้ อย่างไรก็ตาม มีสองประเด็นสำคัญเกี่ยวกับการดำเนินการเบื้องต้นนี้
สิ่งแรกเกี่ยวข้องกับผู้ใช้ปลายทาง (คุณ) เป็นหลัก ในการเชื่อมต่ออุปกรณ์ของคุณกับคอมพิวเตอร์ คุณจะต้องใช้โหมดที่เก็บข้อมูล USB เพื่อถ่ายโอนข้อมูล อย่างไรก็ตาม สิ่งนี้ทำให้อุปกรณ์ Android ต้องถอนการติดตั้งพาร์ติชันเสมือนก่อนที่คอมพิวเตอร์จะสามารถเข้าถึงข้อมูลได้ หากผู้ใช้ต้องการใช้อุปกรณ์ของตนขณะเสียบปลั๊ก หลายสิ่งหลายอย่างจะแสดงว่าไม่พร้อมใช้งาน
ที่ การแนะนำ Media Transfer Protocol (MTP) แก้ไขปัญหาแรกนี้แล้ว เมื่อเสียบปลั๊ก คอมพิวเตอร์ของคุณจะมองเห็นอุปกรณ์ของคุณเป็นอุปกรณ์ "ที่เก็บข้อมูลสื่อ" โดยจะขอรายการไฟล์จากโทรศัพท์ของคุณ และ MTP จะส่งคืนรายการไฟล์ที่คอมพิวเตอร์สามารถดาวน์โหลดได้จากอุปกรณ์ เมื่อมีการขอให้ลบไฟล์ MTP จะส่งคำสั่งเพื่อลบไฟล์ที่ร้องขอออกจากที่เก็บข้อมูล ต่างจากโหมด USB Mass Storage ที่จะติดตั้ง "sdcard" จริง ๆ MTP อนุญาตให้ผู้ใช้ใช้อุปกรณ์ต่อไปในขณะที่เสียบปลั๊กอยู่ นอกจากนี้ ระบบไฟล์ที่มีอยู่ในโทรศัพท์ Android ก็ไม่สำคัญอีกต่อไปสำหรับคอมพิวเตอร์ในการจดจำไฟล์บนอุปกรณ์
ประการที่สอง มีข้อเท็จจริงที่ว่า VFAT ไม่ได้จัดเตรียมการจัดการสิทธิ์ที่มีประสิทธิภาพตามที่ Google ต้องการ ในระยะแรก นักพัฒนาแอปพลิเคชันจำนวนมากจะถือว่า "sdcard" เป็นเหมือนพื้นที่ทิ้งข้อมูลแอปพลิเคชันของตน โดยไม่รู้ว่าจะเก็บไฟล์ไว้ที่ใด แอปพลิเคชันจำนวนมากเพียงสร้างโฟลเดอร์ที่มีชื่อแอปและจัดเก็บไฟล์ไว้ที่นั่น
เกือบทุกแอปพลิเคชันในขณะนั้นจำเป็นต้องมี เขียน_EXTERNAL_STORAGE สิทธิ์ในการเขียนไฟล์แอปพลิเคชันไปยังที่จัดเก็บข้อมูลภายนอก อย่างไรก็ตาม สิ่งที่น่าหนักใจกว่านั้นคือความจริงที่ว่าเกือบทุกแอปพลิเคชันจำเป็นต้องมี READ_EXTERNAL_STORAGE การอนุญาต - เพียงเพื่ออ่านไฟล์ข้อมูลของตัวเอง! ซึ่งหมายความว่าแอปพลิเคชันสามารถเข้าถึงข้อมูลที่จัดเก็บไว้ในที่จัดเก็บข้อมูลภายนอกได้อย่างง่ายดาย และการอนุญาตดังกล่าวมักได้รับจากผู้ใช้ เนื่องจากแอปจำนวนมากจำเป็นต้องทำเช่นเดียวกัน การทำงาน.
Google เห็นชัดเจนว่านี่เป็นปัญหา แนวคิดทั้งหมดที่อยู่เบื้องหลังการจัดการสิทธิ์คือการแบ่งแยกว่าแอปใดบ้างที่สามารถเข้าถึงได้และไม่สามารถเข้าถึงได้ หากเกือบทุกแอปได้รับสิทธิ์การเข้าถึงแบบอ่านข้อมูลผู้ใช้ที่อาจมีความละเอียดอ่อน แสดงว่าการอนุญาตนั้นไม่มีความหมาย ดังนั้น Google จึงตัดสินใจว่าพวกเขาต้องการแนวทางใหม่ นั่นคือสิ่งที่ FUSE เข้ามา
ระบบไฟล์ใน Userspace (FUSE)
ตั้งแต่ Android 4.4 เป็นต้นไป Google ตัดสินใจที่จะไม่ติดตั้งพาร์ติชัน “sdcard” เสมือนเป็น VFAT อีกต่อไป Google เริ่มใช้ FUSE เพื่อจำลอง FAT32 บนพาร์ติชันเสมือน "sdcard" แทน ด้วยการเรียกโปรแกรม sdcard FUSE เพื่อจำลองการอนุญาตไดเรกทอรีสไตล์ FAT-on-sdcardแอปพลิเคชันอาจเริ่มเข้าถึงข้อมูลที่จัดเก็บไว้ในที่จัดเก็บข้อมูลภายนอกได้ โดยไม่ต้องได้รับอนุญาตใด ๆ. อันที่จริง เริ่มต้นด้วย API ระดับ 19 READ_EXTERNAL_STORAGE ไม่จำเป็นต้องเข้าถึงไฟล์ที่อยู่อีกต่อไป บนที่จัดเก็บข้อมูลภายนอก - หากโฟลเดอร์ข้อมูลที่สร้างโดย FUSE daemon ตรงกับชื่อแพ็คเกจของแอป ฟิวส์จะจัดการ สังเคราะห์เจ้าของ กลุ่ม และโหมดของไฟล์บนที่จัดเก็บข้อมูลภายนอก เมื่อติดตั้งแอปพลิเคชันแล้ว
FUSE แตกต่างจากโมดูลในเคอร์เนลเนื่องจากอนุญาตให้ผู้ใช้ที่ไม่มีสิทธิ์สามารถเขียนระบบไฟล์เสมือนได้ เหตุผลที่ Google เลือกใช้ FUSE นั้นค่อนข้างง่าย - ทำตามที่พวกเขาต้องการและเป็นไปแล้ว เข้าใจและบันทึกไว้เป็นอย่างดี ในโลกของลินุกซ์ เพื่ออ้างอิง นักพัฒนาซอฟต์แวร์ของ Google ในเรื่องนี้:
"เนื่องจาก FUSE เป็น API ที่เสถียรดี จึงไม่จำเป็นต้องบำรุงรักษาใดๆ เลยเมื่อต้องย้ายระหว่างเวอร์ชันเคอร์เนล หากเราย้ายไปยังโซลูชันในเคอร์เนล เราจะลงทะเบียนเพื่อดูแลรักษาชุดแพตช์สำหรับเคอร์เนลเวอร์ชันที่เสถียรแต่ละเวอร์ชัน" -Jeff Sharkey วิศวกรซอฟต์แวร์ของ Google
อย่างไรก็ตาม เป็นที่ชัดเจนว่าค่าใช้จ่ายของ FUSE กำลังส่งผลกระทบต่อประสิทธิภาพ ท่ามกลางปัญหาอื่นๆ นักพัฒนาซอฟต์แวร์ที่ฉันพูดคุยด้วยเกี่ยวกับเรื่องนี้ Michal Kowalczyk เขียนโพสต์บล็อกที่ยอดเยี่ยม กว่าปีที่แล้วโดยให้รายละเอียดเกี่ยวกับปัญหาปัจจุบันของ FUSE รายละเอียดทางเทคนิคเพิ่มเติมสามารถอ่านได้ในบล็อกของเขา แต่ฉันจะอธิบายการค้นพบของเขา (โดยได้รับอนุญาตจากเขา) ในแง่ของคนธรรมดามากขึ้น
ปัญหาเกี่ยวกับฟิวส์
ใน Android ภูตพื้นที่ผู้ใช้ “sdcard” ใช้ FUSE เพื่อเมานต์ /dev/fuse ไปยังไดเร็กทอรีที่จัดเก็บข้อมูลภายนอกที่จำลองขณะบูต หลังจากนั้น sdcard daemon จะสำรวจอุปกรณ์ FUSE เพื่อหาข้อความที่ค้างอยู่จากเคอร์เนล หากคุณฟังพอดแคสต์ คุณอาจเคยได้ยินคุณ Lemarchand กล่าวถึง FUSE ที่แนะนำโอเวอร์เฮดระหว่างการดำเนินการ I/O - นี่คือสิ่งที่เกิดขึ้นโดยพื้นฐานแล้ว
ในโลกแห่งความเป็นจริง การกระทบต่อประสิทธิภาพนี้ส่งผลต่อ ใดๆ ไฟล์ที่จัดเก็บไว้ในที่จัดเก็บข้อมูลภายนอก
ปัญหา #1 - โอเวอร์เฮด I/O
สมมติว่าเราสร้างไฟล์ข้อความธรรมดาที่เรียกว่า “test.txt” และจัดเก็บไว้ใน /sdcard/test.txt (ซึ่งให้ ฉันเตือนคุณว่าจริง ๆ แล้ว /data/media/0/test.txt สมมติว่าผู้ใช้ปัจจุบันเป็นผู้ใช้หลักใน อุปกรณ์). หากเราต้องการอ่าน (command cat) ไฟล์นี้ เราคาดว่าระบบจะออกคำสั่ง 3 คำสั่ง: เปิด อ่าน แล้วปิด ดังที่นาย Kowalczyk สาธิตการใช้ สเตรซนั่นคือสิ่งที่เกิดขึ้น:
แต่เนื่องจากไฟล์อยู่ในที่จัดเก็บข้อมูลภายนอกซึ่งจัดการโดย sdcard daemon จึงมีการดำเนินการเพิ่มเติมมากมายที่จำเป็นต้องดำเนินการ ตามที่ Mr. Kowalczyk กล่าว มีขั้นตอนเพิ่มเติมอีก 8 ขั้นตอนที่จำเป็นสำหรับ แต่ละคำสั่งทั้ง 3 คำสั่งนี้:
- แอปพลิเคชัน Userspace ออกการเรียกระบบซึ่งจะถูกจัดการโดยไดรเวอร์ FUSE ในเคอร์เนล (เราเห็นในเอาต์พุต strace แรก)
- ไดรเวอร์ FUSE ในเคอร์เนลแจ้งเตือน userspace daemon (sdcard) เกี่ยวกับคำขอใหม่
- Userspace daemon อ่าน /dev/fuse
- Userspace daemon แยกวิเคราะห์คำสั่งและจดจำการทำงานของไฟล์ (เช่น เปิด)
- Userspace daemon ออกการเรียกระบบไปยังระบบไฟล์จริง (EXT4)
- เคอร์เนลจัดการการเข้าถึงข้อมูลทางกายภาพและส่งข้อมูลกลับไปยังพื้นที่ผู้ใช้
- Userspace แก้ไข (หรือไม่) ข้อมูลและส่งผ่าน /dev/fuse ไปยังเคอร์เนลอีกครั้ง
- เคอร์เนลทำการเรียกระบบดั้งเดิมให้เสร็จสิ้นและย้ายข้อมูลไปยังแอปพลิเคชันพื้นที่ผู้ใช้จริง (ในตัวอย่าง cat ของเรา)
ดูเหมือนว่านี้ มาก ของโอเวอร์เฮดเพียงคำสั่ง I/O เดียวที่จะรัน และคุณจะพูดถูก เพื่อสาธิตสิ่งนี้ Mr. Kowalczyk พยายามทดสอบ I/O ที่แตกต่างกันสองแบบ: การทดสอบหนึ่งเกี่ยวข้องกับการคัดลอกไฟล์ขนาดใหญ่ และอีกการทดสอบหนึ่งคือการคัดลอกไฟล์ขนาดเล็กจำนวนมาก เขาเปรียบเทียบความเร็วของ FUSE (บนพาร์ติชันเสมือนที่ติดตั้งเป็น FAT32) ที่จัดการการดำเนินการเหล่านี้กับ เคอร์เนล (บนพาร์ติชันข้อมูลที่จัดรูปแบบเป็น EXT4) และเขาพบว่า FUSE มีส่วนสำคัญอย่างยิ่ง ค่าใช้จ่าย
ในการทดสอบครั้งแรก เขาได้คัดลอกไฟล์ขนาด 725MB ภายใต้เงื่อนไขการทดสอบทั้งสอง เขาพบว่าการใช้งาน FUSE ถ่ายโอนไฟล์ขนาดใหญ่ ช้ากว่า 17%.
ในการทดสอบครั้งที่สอง เขาคัดลอกไฟล์ได้ 10,000 ไฟล์ โดยแต่ละไฟล์มีขนาด 5KB ในสถานการณ์สมมตินี้ การใช้งาน FUSE สิ้นสุดลงแล้ว ช้าลง 40 วินาที เพื่อคัดลอกข้อมูลโดยทั่วไปมูลค่า 50MB
ในโลกแห่งความเป็นจริง การกระทบต่อประสิทธิภาพนี้ส่งผลต่อ ใดๆ ไฟล์ที่จัดเก็บไว้ในที่จัดเก็บข้อมูลภายนอก ซึ่งหมายความว่าแอปต่างๆ เช่น Maps จัดเก็บไฟล์ขนาดใหญ่บน /sdcard แอปเพลงที่เก็บไฟล์เพลงจำนวนมาก แอปกล้องถ่ายรูปและรูปภาพ ฯลฯ การดำเนินการ I/O ใดๆ ที่เกี่ยวข้องกับการจัดเก็บข้อมูลภายนอกจะได้รับผลกระทบจากค่าใช้จ่ายของ FUSE แต่ค่าใช้จ่าย I/O ไม่ใช่ปัญหาเดียวของ FUSE
ปัญหา # 2 - การแคชสองครั้ง
การแคชข้อมูลเป็นสิ่งสำคัญในการปรับปรุงประสิทธิภาพการเข้าถึงข้อมูล ด้วยการจัดเก็บข้อมูลที่สำคัญไว้ในหน่วยความจำ เคอร์เนล Linux จึงสามารถเรียกคืนข้อมูลนั้นได้อย่างรวดเร็วเมื่อจำเป็น แต่เนื่องจากวิธีการใช้งาน FUSE ทำให้ Android เก็บแคชที่จำเป็นเป็นสองเท่า
ดังที่ Mr. Kowalczyk แสดงให้เห็น ไฟล์ขนาด 10MB คาดว่าจะถูกบันทึกในแคชเท่ากับ 10 MB แต่จะเพิ่มเป็นขนาดแคชแทน ประมาณ 20MB นี่เป็นปัญหาบนอุปกรณ์ที่มี RAM น้อยกว่า เนื่องจากเคอร์เนล Linux จัดเก็บใช้แคชของเพจเพื่อจัดเก็บข้อมูล หน่วยความจำ. คุณ Kowalczyk ทดสอบปัญหาการแคชสองครั้งโดยใช้แนวทางนี้:
- สร้างไฟล์ที่มีขนาดที่ทราบ (สำหรับการทดสอบ 10MB)
- คัดลอกไปที่ /sdcard
- วางแคชของหน้า
- ถ่ายภาพการใช้แคชของเพจ
- อ่านไฟล์ทดสอบ
- ถ่ายภาพการใช้แคชของเพจอีกครั้ง
สิ่งที่เขาพบคือก่อนการทดสอบ เคอร์เนลถูกใช้ 241MB สำหรับแคชเพจ เมื่อเขาอ่านไฟล์ทดสอบแล้ว เขาคาดว่าจะเห็นพื้นที่ 251MB ที่ใช้สำหรับแคชของหน้า แต่เขากลับพบว่าเคอร์เนลนั้นกำลังใช้งานอยู่ 263MB สำหรับแคชหน้า - เกี่ยวกับ สองเท่าของสิ่งที่คาดหวัง. สาเหตุนี้เกิดขึ้นเนื่องจากข้อมูลถูกแคชครั้งแรกโดยแอปพลิเคชันผู้ใช้ที่ออกการเรียก I/O (FUSE) แต่เดิม และครั้งที่สองโดย sdcard daemon (EXT4 FS)
ปัญหา #3 - การใช้งาน FAT32 ที่ไม่สมบูรณ์
มีอีกสองปัญหาที่เกิดจากการใช้ FUSE จำลอง FAT32 ซึ่งไม่ค่อยมีใครรู้จักในชุมชน Android
ประการแรกเกี่ยวข้องกับ การประทับเวลาไม่ถูกต้อง. หากคุณเคยถ่ายโอนไฟล์ (เช่น รูปภาพ) และสังเกตเห็นว่าการประทับเวลาไม่ถูกต้อง นั่นเป็นเพราะการนำ FUSE ของ Android มาใช้ ประเด็นนี้มี มีอยู่เพื่อ ปี. หากจะเจาะจงมากขึ้น ประเด็นนี้เกี่ยวข้องกับ เวลา() การเรียกระบบซึ่งช่วยให้คุณเปลี่ยนการเข้าถึงและแก้ไขเวลาของไฟล์ได้ ขออภัย การเรียกไปยัง sdcard daemon ในฐานะผู้ใช้มาตรฐานไม่มีสิทธิ์ที่เหมาะสมในการดำเนินการเรียกของระบบนี้ มีวิธีแก้ไขชั่วคราวสำหรับสิ่งนี้ แต่พวกเขาต้องการให้คุณทำ มีสิทธิ์เข้าถึงรูท.
หากคุณเคยถ่ายโอนไฟล์ (เช่น รูปภาพ) และสังเกตเห็นว่าการประทับเวลาไม่ถูกต้อง นั่นเป็นเพราะการนำ FUSE ของ Android มาใช้
ปัญหาต่อไปคือเกี่ยวข้องกับธุรกิจที่ใช้บางอย่างเช่น การ์ดสมาร์ท SD. ก่อนที่จะมี FUSE ผู้ผลิตแอปสามารถตรวจสอบได้ ธง O_DIRECT เพื่อสื่อสารกับไมโครคอนโทรลเลอร์ที่ฝังอยู่ในการ์ด ด้วย FUSE นักพัฒนาจะสามารถเข้าถึงไฟล์เวอร์ชันแคชเท่านั้น และไม่สามารถมองเห็นคำสั่งใดๆ ที่ส่งมาจากไมโครคอนโทรลเลอร์ได้ นี่เป็นปัญหาสำหรับแอปขององค์กร/ภาครัฐ/ธนาคารบางแอปที่สื่อสารกับการ์ด microSD ที่มีมูลค่าเพิ่ม
การทิ้ง FUSE สำหรับ SDCardFS
OEM บางรายตระหนักถึงปัญหาเหล่านี้ตั้งแต่เนิ่นๆ และเริ่มมองหาวิธีแก้ปัญหาในเคอร์เนลเพื่อแทนที่ FUSE ยกตัวอย่างซัมซุงที่พัฒนาแล้ว SDCardFS ซึ่งใช้ WrapFS โซลูชันในเคอร์เนลนี้จำลอง FAT32 เช่นเดียวกับที่ FUSE ทำ แต่มองข้ามค่าใช้จ่าย I/O การแคชสองครั้ง และปัญหาอื่น ๆ ที่ฉันกล่าวถึงข้างต้น (ใช่แล้ว ผมขอย้ำประเด็นนี้อีกครั้งว่า โซลูชันที่ Google กำลังดำเนินการอยู่นี้อิงตามงานของ Samsung).
ในที่สุด Google เองก็ได้รับทราบถึงข้อเสียที่เกี่ยวข้องกับ FUSE ซึ่งเป็นสาเหตุที่พวกเขาเริ่มก้าวไปสู่เลเยอร์การจำลอง FAT32 ในเคอร์เนลที่พัฒนาโดย Samsung บริษัทดังที่ได้กล่าวไว้ใน นักพัฒนา Android หลังเวที podcast กำลังดำเนินการเพื่อทำให้ SDCardFS พร้อมใช้งานสำหรับอุปกรณ์ทั้งหมดในเคอร์เนลเวอร์ชันที่กำลังจะมาถึง ขณะนี้คุณสามารถดูความคืบหน้าของพวกเขาได้ ทำงานที่ AOSP.
ในฐานะที่เป็น นักพัฒนาซอฟต์แวร์ของ Google อธิบายไว้ก่อนหน้านี้ความท้าทายที่ใหญ่ที่สุดในการใช้โซลูชันในเคอร์เนลคือวิธีแมปชื่อแพ็กเกจ ID แอปพลิเคชันที่จำเป็นสำหรับแพ็คเกจเพื่อเข้าถึงข้อมูลของตัวเองในที่จัดเก็บข้อมูลภายนอกโดยไม่ต้องมีใดๆ สิทธิ์ แต่คำกล่าวดังกล่าวมีขึ้นเมื่อปีที่แล้ว และเรามาถึงจุดที่ทีมงานเรียก SDCardFS ว่า "สิ่งที่ยิ่งใหญ่ต่อไป" พวกเขาได้ยืนยันแล้วว่า ข้อผิดพลาดการประทับเวลาที่น่ากลัว ได้รับการแก้ไขแล้ว เนื่องจากการย้ายออกจาก FUSE ดังนั้นเราจึงสามารถตั้งตารอที่จะเห็นการเปลี่ยนแปลงทั้งหมดที่เกิดจากการละทิ้ง FUSE
การตรวจสอบข้อเท็จจริงความเข้าใจผิด
หากคุณเข้าถึงบทความนี้ได้ไกลถึงขนาดนี้ ก็ขอชื่นชมที่ติดตามทุกสิ่งจนถึงตอนนี้! ฉันต้องการชี้แจงคำถามสองสามข้อที่ฉันมีเมื่อเขียนบทความนี้:
- SDCardFS มี ไม่เกี่ยวข้องกับการ์ด SD จริง. มันถูกตั้งชื่อเช่นนี้เพราะมันจัดการการเข้าถึง I/O สำหรับ /sdcard และอย่างที่คุณอาจจำได้ /sdcard เป็นป้ายกำกับที่ล้าสมัยซึ่งหมายถึงที่เก็บข้อมูล "ภายนอก" ของอุปกรณ์ของคุณ (ที่แอปจัดเก็บสื่อของพวกเขา)
- SDCardFS คือ ไม่ใช่ระบบไฟล์แบบดั้งเดิม เช่น FAT32, EXT4 หรือ F2FS มันเป็นระบบไฟล์ wrapper ที่วางซ้อนกันได้ซึ่งส่งคำสั่งไปยังระบบไฟล์จำลองระดับล่าง (ในกรณีนี้ จะเป็น FAT32 บน /sdcard)
- จะไม่มีอะไรเปลี่ยนแปลงเกี่ยวกับ MTP. คุณจะใช้ MTP ต่อไปเพื่อถ่ายโอนไฟล์ไปยัง/จากคอมพิวเตอร์ของคุณ (จนกว่า Google จะเลือกใช้โปรโตคอลที่ดีกว่า) แต่อย่างน้อยข้อผิดพลาดในการประทับเวลาจะได้รับการแก้ไข!
- ดังที่ได้กล่าวไว้ก่อนหน้านี้ เมื่อ Google อ้างถึง "ที่จัดเก็บข้อมูลภายนอก" พวกเขากำลังพูดถึง (สำหรับจุดประสงค์ทั้งหมด และ วัตถุประสงค์) ภายใน /sdcard พาร์ติชัน FAT32 เสมือนหรือพวกเขากำลังพูดถึง microSD จริงแบบถอดได้ การ์ด. คำศัพท์ทำให้เกิดความสับสน แต่เป็นสิ่งที่เราประทับใจ
บทสรุป
การย้ายออกจาก FUSE และใช้เลเยอร์การจำลอง FAT32 ในเคอร์เนล (SDCardFS) จะทำให้ Google ลดขนาดลง ค่าใช้จ่าย I/O ที่สำคัญ กำจัดการแคชสองครั้ง และแก้ไขปัญหาที่ไม่ชัดเจนบางประการที่เกี่ยวข้องกับการจำลองของ FUSE FAT32.
เนื่องจากการเปลี่ยนแปลงเหล่านี้จะเกิดขึ้นกับเคอร์เนล จึงสามารถเปิดตัวได้โดยไม่ต้องใช้ Android เวอร์ชันใหม่ที่สำคัญควบคู่ไปด้วย ผู้ใช้บางคนคาดหวังว่าจะเห็นการเปลี่ยนแปลงเหล่านี้ถูกนำมาใช้อย่างเป็นทางการใน Android 8 แต่ก็เป็นไปได้ สำหรับ OTA ในอนาคตบนอุปกรณ์ Pixel เพื่อนำเคอร์เนล Linux เวอร์ชัน 4.1 ที่ Google ใช้งานอยู่ บน.
สำหรับบางท่าน SDCardFS ไม่ใช่แนวคิดใหม่ อันที่จริง อุปกรณ์ Samsung ใช้งานมันมาหลายปีแล้ว (เป็นอุปกรณ์ที่พัฒนามาตลอด) นับตั้งแต่ SDCardFS เปิดตัวใน AOSP เมื่อปีที่แล้ว นักพัฒนา ROM และเคอร์เนลแบบกำหนดเองบางรายได้เลือกที่จะนำไปใช้กับงานของตน มีอยู่ช่วงหนึ่งที่ CyanogenMOD กำลังพิจารณาที่จะใช้งาน แต่ก็ย้อนกลับเมื่อผู้ใช้ประสบปัญหากับรูปถ่ายของพวกเขา แต่หวังว่าเมื่อ Google เข้ามาครอบครองโปรเจ็กต์นี้ ผู้ใช้ Android บนอุปกรณ์ในอนาคตทั้งหมดจะสามารถใช้ประโยชน์จากการปรับปรุงที่นำเสนอพร้อมกับการละทิ้ง FUSE