2 คะแนน โดย GN⁺ 2024-03-11 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Amazon S3 เป็นเทคโนโลยีคลาวด์ยุคแรกที่เปิดตัวในปี 2006 ซึ่งแข็งแกร่งด้านการจัดเก็บไฟล์ แต่ไม่ใช่ ระบบไฟล์ ที่มาแทน Unix file API ได้ตรง ๆ
  • Unix file API เป็นเหมือน โมดูลลึก ที่ซ่อนการบัฟเฟอร์, page cache, สิทธิ์, และการจัดตาราง IO ไว้หลังอินเทอร์เฟซแคบ ๆ อย่าง open, read, write, seek, close
  • S3 ดูเรียบง่ายโดยยึด GetObject และ PutObject เป็นหลัก แต่รองรับแค่อ่านบางส่วนผ่าน Range และ ไม่รองรับการเขียนทับบางส่วน
  • ฐานข้อมูลอย่าง Postgres, SQLite, MySQL, MongoDB, Elasticsearch พึ่งพาการเขียนทับระดับเพจ ดังนั้นการเอาไฟล์ SQLite หรือ DuckDB ไปวางบน S3 ตรง ๆ จึงแทบไม่เหมาะ นอกจากชุดข้อมูลขนาดเล็ก
  • จุดแข็งของ S3 คือแบนด์วิดท์อ่าน·เขียนสูงและภาระการดูแลต่ำ แต่ก็ต้องคำนึงถึงข้อจำกัดอย่างไม่มี rename/move, การไล่รายการช้า, API ที่รองรับเฉพาะ XML, และไม่มีสภาพแวดล้อมทดสอบแบบโลคัล

S3 เก็บไฟล์ได้ แต่ไม่ใช่ระบบไฟล์

  • S3 เป็น เทคโนโลยีคลาวด์ยุคแรก ที่เปิดตัวในปี 2006 และตามคำฮิตในยุคนั้นจึงถูกเรียกว่า “object store”
  • ในทางปฏิบัติมันถูกใช้เป็นที่เก็บไฟล์อย่างแพร่หลาย แต่ถ้าเข้าใจมันเป็น “Amazon Cloud Filesystem” ก็จะถูกแค่บางส่วน
  • มันเก็บไฟล์ได้ดี แต่ไม่สามารถทดแทนพฤติกรรมและความคาดหวังของระบบไฟล์แบบเดิมได้ทั้งหมด

Unix file API และโมดูลลึก

  • แกนหลักของ Unix file API สรุปได้ด้วยคำสั่งห้าตัวดังนี้
    • open(filepath): เปิดไฟล์
    • file.read(size=100): อ่านจากตำแหน่งปัจจุบันและเลื่อนตำแหน่งไปข้างหน้า
    • file.write("hello, world"): เขียนที่ตำแหน่งปัจจุบันและเลื่อนตำแหน่งไปข้างหน้า
    • file.seek(94): ย้ายตำแหน่งไปยังไบต์ที่กำหนด
    • file.close(): ปิดไฟล์
  • คำสั่งเหล่านี้คือส่วนสำคัญของ system call ทั้งหมด และใกล้เคียงกับความสามารถขั้นต่ำที่จำเป็นต่อการอ่านและเขียนไฟล์
  • เพราะมีการประมวลผลมากมายซ่อนอยู่หลังอินเทอร์เฟซแคบ ๆ นี้ Unix file API จึงมองได้ว่าเป็น โมดูลลึก (deep module)
    • การบัฟเฟอร์และ page cache
    • การจัดการ fragmentation
    • การจัดการสิทธิ์
    • การจัดตาราง IO
    • แม้แต่ความสามารถอย่าง wear-levelling ของ SD card ผู้ใช้ก็ได้ประโยชน์โดยไม่ต้องดูแลเอง

โมดูลตื้น, YAML, และ ORM

  • โมดูลตื้นคือสิ่งที่มีพื้นผิว API ค่อนข้างใหญ่เมื่อเทียบกับสิ่งที่มันช่วยจัดการให้
  • ทุกวันนี้ หนึ่งในสัญญาณบอกว่าเป็นโมดูลตื้นคืออินเทอร์เฟซเป็น YAML
    • YAML ดูเหมือนภาษา markup แต่ในความจริงมักถูกใช้เป็นไวยากรณ์ใช้ซ้ำที่ใส่ความหมายได้แทบทุกแบบ
    • ในโลก DevOps หลายครั้ง YAML ทำงานคล้าย “ภาษาโปรแกรม”
    • ถ้า YAML mini-language มีโครงสร้างวนซ้ำ ก็มีโอกาสจะเป็น Turing-complete
  • โมดูลตื้นไม่ได้แปลว่าแย่เสมอไป
    • SQL ORM โดยเนื้อแท้แล้วเป็น abstraction ที่รั่ว และใช้งานได้ยากหากไม่เข้าใจ SQL
    • ในบางกรณี โมดูลตื้นอาจเป็นรูปแบบที่ดีที่สุดเท่าที่ทำได้
  • แต่ถ้าเงื่อนไขเท่ากัน โมดูลที่ลึกกว่าจะดีกว่า

S3 API เรียบง่าย แต่ไม่เหมือนไฟล์ API

  • Unix file API เริ่มลงหลักปักฐานตั้งแต่ต้นทศวรรษ 1970 และแม้อินเทอร์เฟซจะคงเดิมเพื่อความเข้ากันได้ แต่การทำงานภายในถูกเปลี่ยนมาหลายครั้ง
  • Amazon S3 ไม่ได้สร้าง Unix file system API ขึ้นมาใหม่
  • คำสั่งพื้นฐานของ S3 สอดคล้องกับ Unix file API ได้เพียงบางส่วน
    • GetObject(Bucket, Key, Range=None): อ่านทั้งอ็อบเจ็กต์หรือบางส่วน
    • PutObject(Bucket, Key): เขียนทั้งอ็อบเจ็กต์
  • แม้จะมีแนวคิดเพิ่มเติมอย่าง bucket แต่ถ้าดูจากสัดส่วนระหว่างฟังก์ชันกับอินเทอร์เฟซ S3 ก็อาจถือว่าเรียบง่ายกว่า Unix file API
  • ความต่างที่ชี้ขาดคือการไม่มี การเขียนทับบางส่วน
    • อ่านบางส่วนของอ็อบเจ็กต์ได้ผ่านอาร์กิวเมนต์ Range ของ GetObject
    • แต่ไม่สามารถเขียนทับเฉพาะบางส่วนของอ็อบเจ็กต์ได้
    • การเขียนทับต้องทำทั้งไฟล์
  • เพราะความต่างนี้ S3 จึงเหมาะกับกรณีใช้งานไฟล์แบบเดิมเพียงบางส่วนเท่านั้น

ฐานข้อมูลย้ายมาบน S3 ตรง ๆ ได้ยาก

  • ฐานข้อมูลหลายตัวเก็บข้อมูลไว้ในไฟล์บนระบบไฟล์
    • Postgres เก็บ 2–3 ไฟล์ต่อหนึ่งตาราง พร้อมไฟล์สำหรับจัดการอีกหลายไฟล์
    • SQLite เป็นที่รู้จักกันดีว่าเก็บข้อมูลทั้งหมดไว้ในไฟล์เดียว
    • MySQL, MongoDB, Elasticsearch ก็เก็บข้อมูลลงไฟล์เช่นกัน
  • ปัญหาคือฐานข้อมูลโดยทั่วไปพึ่งพา การเขียนทับบางส่วนระดับเพจ
    • ข้อมูลมักถูกเก็บเป็นเพจขนาด 4KB หรือ 8KB
    • ใน heap file หนึ่งไฟล์อาจมีเพจนับพัน
    • เพจจะถูกเขียนทับบางส่วนเพื่อเก็บข้อมูลที่ต้องการ
  • ถ้าวางฐานข้อมูล SQLite ไว้บน S3 ทุกครั้งที่เขียนจะต้องเขียนไฟล์ฐานข้อมูลทั้งก้อนใหม่
  • S3 เขียนข้อมูลก้อนใหญ่ได้เร็ว แต่หากไม่ใช่ชุดข้อมูลเล็กมาก กลยุทธ์ที่ต้องเขียนทับทั้งไฟล์ทุกครั้งย่อมรับภาระไม่ไหว
  • เมื่อเขียนไฟล์ฐานข้อมูลใหม่ทั้งก้อนทุกครั้ง ก็ใช้ประโยชน์จาก ความถูกต้องสมบูรณ์ของทรานแซกชัน ที่ผู้พัฒนาฐานข้อมูลสร้างไว้ได้ยาก
  • บน S3 การเขียนครั้งสุดท้ายคือผู้ชนะ

สิ่งที่ S3 ทำได้ดีและทำได้ไม่ดี

  • จุดแข็งของ S3 คือ แบนด์วิดท์ การอ่านและเขียนที่สูงมาก
    • หาได้ไม่ยากว่ามีกรณีที่เขียนหรืออ่านจาก S3 ได้เกิน 10GB ต่อวินาทีบนอินเทอร์เน็ต
    • ผู้เขียนยังเคยทำให้เครือข่ายออฟฟิศของลูกค้าฝั่งการเงินอิ่มตัวด้วยงานเขียนไปยัง S3
  • นอกจากการไม่มีการเขียนทับบางส่วนแล้ว ยังมีข้อจำกัดอื่นที่ต่างจากระบบไฟล์
  • S3 ไม่มีคำสั่ง rename หรือ move
    • การเปลี่ยนชื่อทำโดย CopyObject แล้วตามด้วย DeleteObject
    • CopyObject ใช้เวลาเพิ่มขึ้นเป็นเส้นตรงตามขนาดไฟล์
    • ถ้าเขียนไฟล์ผิดที่ไปจำนวนมากแล้วต้องย้อนกลับ จะช้ามาก
  • การไล่รายการไฟล์ก็ช้า
    • แม้แบนด์วิดท์อ่าน·เขียนจะสูงมาก แต่การแสดงรายการสิ่งที่เก็บไว้กลับช้ากว่ามาก
    • อาจช้ากว่าระบบไฟล์โลคัลที่ช้าอยู่แล้วด้วยซ้ำ
  • ในทางกลับกัน ภาระด้าน การดูแลระบบ ต่ำกว่าระบบไฟล์
    • แค่กำหนดชื่อ bucket และ key ที่เหลือคลาวด์จัดการให้
    • ลดภาระงานซ้ำ ๆ อย่างการสำรองข้อมูล, การทำสำเนาไว้นอกสถานที่, และ provisioning
    • provisioning ครอบคลุมไม่ใช่แค่ความจุ แต่รวมถึงงาน IO ด้วย

ในอินเทอร์เฟซระหว่างองค์กร โมดูลลึกยิ่งสำคัญ

  • การที่ S3 เป็นคลาวด์ API ตัวแรก ๆ ที่ได้รับความนิยม เชื่อมโยงกับข้อดีของ API แบบลึก
  • API แบบลึกมีประโยชน์ในการซ่อนความซับซ้อนระหว่างโมดูลภายในระบบเดียว และยิ่งสำคัญกว่าเมื่อเป็นความสัมพันธ์ที่มีต้นทุนสูง เช่น การโต้ตอบระหว่างสองบริษัท
  • การเชื่อมระบบคอมพิวเตอร์ระหว่างองค์กรแต่เดิมเรียกว่า integration และมักถูกมองเป็นคำพ้องของความเจ็บปวด
  • ซอฟต์แวร์องค์กรขนาดใหญ่อย่าง SAP ไม่ใช่โมดูลลึก
    • คนเกือบทั้งองค์กรต้องเข้าใจ SAP
    • ต้องปรับให้เข้ากับวิธีทำงานเดิมอยู่ตลอด
    • โปรเจ็กต์ผสานรวม SAP มีราคาแพง ใหญ่โต และมีตัวอย่างความล้มเหลวซ้ำ ๆ
  • ความซับซ้อนภายในของ S3 ไม่ได้ต่ำกว่าการติดตั้ง SAP แบบมีนัยสำคัญ
    • Amazon เรียก S3 ว่า “Simple Storage Service” แต่ในความจริง S3 มีความซับซ้อนสูง
    • เกี่ยวข้องกับ queueing theory, การแย่งกันใช้ IO, sharding, และปัญหาอีกมากที่ระบบไฟล์ต้องจัดการ
  • คำว่า “simple” ของ S3 จึงใกล้เคียงกับ อินเทอร์เฟซที่ลึก มากกว่าความเรียบง่ายจริง ๆ

ข้อยกเว้นที่เหมาะกับ S3 และข้อจำกัดที่ยังเหลือ

  • ไม่ได้หมายความว่าจะตัดประเด็นที่ว่า S3 อาจแพงเกินไปเมื่อเทียบกับบางกรณีใช้งาน
  • แนวคิดเรื่องโมดูลลึกและโมดูลตื้นมาจาก A Philosophy of Software Design ของ John Ousterhout
  • มีฐานข้อมูลที่ถูกออกแบบมาตั้งแต่แรกให้ใช้ S3 API เป็นชั้นจัดเก็บข้อมูล
    • Snowflake เป็นตัวอย่างหนึ่ง
    • แต่ไม่ใช่การย้ายระบบแบบโปร่งใส ต้องตัดสินใจตั้งแต่ขั้นออกแบบ
    • Snowflake เป็นกรณีที่อย่างน้อยจนถึงปี 2016 ได้ตัดสินใจเรื่องนี้ตั้งแต่เนิ่น ๆ มาก
  • ไม่ใช่แค่ฐานข้อมูลที่มีปัญหาบน S3
    • ไฟล์ฟอร์แมตจำนวนมากตั้งสมมติฐานว่ามี seek ราคาถูก
    • ไฟล์ Zip เป็นตัวอย่างชัดเจนที่ทำงานบนดิสก์ได้ดีกว่าบน S3

สิ่งที่น่าเสียดายเกี่ยวกับ S3

  • S3 API รองรับเฉพาะ XML
    • JSON ก็มีอยู่แล้วในปี 2006 แต่ตอนนั้น XML ยังเหนือกว่า
    • จึงน่าเสียดายที่ตอน Amazon เปลี่ยนจาก SOAP ไปเป็น REST ไม่ได้ออกเวอร์ชัน JSON มาด้วย
  • Amazon ยังเลิกดูแล XSD schema แล้ว
    • ทั้งที่หนึ่งในข้อดีสำคัญของ XML API คือ schema แต่ตอนนี้เอกสารมาตรฐานกลับเป็นเว็บไซต์
  • Amazon ไม่มีสภาพแวดล้อมทดสอบแบบโลคัลให้
    • ใน Python ผู้คนมักใช้ไลบรารี moto เพื่อการทดสอบที่จริงจัง
    • ทั้งที่ moto เป็นเครื่องมือทดสอบสำหรับบริการเชิงพาณิชย์ แต่กลับดูแลโดยอาสาสมัคร
  • Amazon S3 รองรับ checksum แต่ไม่ได้เปิดใช้เป็นค่าเริ่มต้น
    • Amazon มีคำกล่าวอ้างหลายอย่างเรื่องความทนทาน
    • แม้จะไม่เคยได้ยินว่ามีปัญหาจริง แต่ก็ไม่เคยเห็นตัวอย่างที่คำกล่าวอ้างเหล่านั้นถูกทดสอบเช่นกัน
  • ในอดีต S3 เคยมีหลุมพรางเรื่อง eventual consistency
    • ถ้าอ่านไฟล์ เขียนทับ แล้วอ่านอีกครั้ง อาจยังเห็นข้อมูลเก่าที่ยังไม่เปลี่ยน
    • มันเกิดขึ้นเป็นครั้งคราวในช่วงเวลาสั้น ๆ และสร้างความสับสน
    • ผู้ให้บริการ S3 implementation รายอื่นไม่ได้ลอกพฤติกรรมนี้ และ Amazon ก็แก้ไขเมื่อไม่กี่ปีก่อนด้วย strong read-after-write consistency

1 ความคิดเห็น

 
GN⁺ 2024-03-11
ความคิดเห็นบน Hacker News
  • มองว่า ความทนทานของ S3 แม้จะฟังดูโอ้อวดแต่ก็เชื่อถือได้ และเทียบกับระบบไฟล์แบบดั้งเดิมได้ยาก
    ความต่างไม่ได้มีแค่ซอฟต์แวร์ แต่รวมถึงโครงสร้างพื้นฐานทางกายภาพและวัฒนธรรมด้านความปลอดภัยด้วย และรู้สึกว่า การแยก Availability Zone ของ AWS ดีกว่าคลาวด์รายอื่น
    ตอนทำงานกับ S3 มักถูกนำไปเทียบราคากับ GCP Blob Storage แต่ Google อาจวางข้อมูลไว้ในอาคารเดียวกันหรือแม้แต่คนละห้องในอาคารเดียวกัน จึงไม่ใช่การเปรียบเทียบที่ยุติธรรมกับการแยกแบบ AWS
    ทั้งองค์กรหมกมุ่นกับความถูกต้องสมบูรณ์ของข้อมูลอย่างมาก ใส่ checksum ให้ทุกอย่าง และเตรียมรับมือแม้กระทั่งเหตุการณ์ใหญ่ระดับภัยพิบัติทางธรรมชาติ
    ในสเกลของ S3 ยังตรวจจับ bit rot อย่างการพลิกบิตแบบสุ่มจากรังสีคอสมิกที่กระทบจานฮาร์ดดิสก์ได้ด้วย และยังวัดอัตราความล้มเหลวแยกตามผู้ผลิตดิสก์และช่วงเวลาการผลิต เพื่อลดโอกาสข้อมูลสูญหายแม้แบตช์ใดแบตช์หนึ่งจะเสียหาย
    ถึงขั้นบอกว่าไม่อยากเก็บข้อมูลสำคัญไว้ที่อื่น และได้สร้างระบบ deployment สำหรับ S3 ขึ้นมาเอง

    • อยากรู้ว่าประสบการณ์จากผู้ให้บริการสตอเรจรายอื่นเป็นอย่างไร
      คำอธิบายนี้ฟังคล้ายการชมว่า Cinnabon ทำแป้งเอง ทั้งที่สิ่งที่กล่าวมาคือเรื่องปกติที่บริษัทสตอเรจทั่วไปก็มักทำ
      การใส่ checksum ให้ทุกอย่างเป็นความสามารถพื้นฐานของหลายไฟล์ซิสเต็มอยู่แล้ว และถ้าคอมที่บ้านยังตรวจจับ bit rot แล้วแจ้งเตือนได้ ผู้ให้บริการสตอเรจรายใหญ่ก็ยิ่งต้องทำเป็นธรรมดา
      การติดตามอัตราความเสียหายแยกตามผู้ผลิตดิสก์ก็พบได้ทั่วไป บริษัทสตอเรจหลายแห่งยังเผยแพร่รายงานด้วย และแม้แต่องค์กรไอที 6 คนก็ยังเคยจัดการด้วยสเปรดชีต
      นอก AWS ก็มีคนเก่งด้านสตอเรจทำงานกันมานานมากแล้ว ตั้งแต่ก่อน AWS จะเกิดขึ้นเสียอีก
    • การแยก Availability Zone ของ AWS ไม่ได้ดีกว่าทุกรายเสมอไป
      ตัวอย่างเช่น บัญชี geo-redundant ของ rsync.net มีที่เก็บหลักอยู่ Fremont และที่เก็บสำรองอยู่ Denver ซึ่งอยู่กันคนละรัฐหรืออาจคนละประเทศ
      และที่บอกว่า S3 ตรวจจับ bit rot ได้เพราะมีสเกลใหญ่ก็ไม่จริงนัก เพราะแค่รัน ZFS บนเซิร์ฟเวอร์ส่วนตัวก็ตรวจจับ bit rot ในสเกลเล็กได้ดีเหมือนกัน
      [1] สำนักงานใหญ่ he.net
    • การใส่ checksum ให้ข้อมูลไม่ใช่เพราะหวาดระแวง แต่เป็นสิ่งจำเป็นตามธรรมชาติเพื่อให้รัน อัลกอริทึม Reed-Solomon ได้ โดยต้องรู้ก่อนว่าบล็อกไหนใช้การไม่ได้
      ถ้าเหตุการณ์ความเสียหายแบบนี้เกิดมากพอ ก็น่าจะใช้เป็นสัญญาณให้ย้ายบล็อกข้อมูลแต่ละก้อนไปยังเครื่องอื่นเพื่อ “รักษา” ระบบได้ด้วย
      โดยรวมแล้วสิ่งที่กล่าวมาถือว่าค่อนข้างปกติในระบบสตอเรจ และไม่ใช่ลักษณะเฉพาะของ S3
    • เรื่องที่ว่า Google เก็บข้อมูลไว้ในอาคารเดียวกันไม่น่าจะเป็นความจริง
      ตาม เอกสาร Google Cloud Storage ข้อมูลจะถูกทำสำเนาข้ามหลายโซน และแต่ละโซนจะถูกแมปไปยังคลัสเตอร์คนละชุด
      https://cloud.google.com/compute/docs/regions-zones/zone-vir...
    • มากกว่าจะเชื่อคำว่า “เชื่อเถอะ” ผมอยากเชื่อ ผลการทดสอบ
      สงสัยว่ามีบุคคลที่สามที่เป็นกลางซึ่งตรวจสอบความทนทาน ความถูกต้องสมบูรณ์ และความสอดคล้องของ S3 อย่างเข้มงวดระดับเดียวกับ Jepsen หรือไม่
      ถ้ามีใครเปรียบเทียบคลาวด์สตอเรจที่เข้ากันได้กับ S3 อย่างจริงจัง อาจพบปัญหาใหญ่ ๆ ที่น่ากลัว หรือบางทีอาจมีการเปรียบเทียบแบบนั้นอยู่แล้วก็ได้
  • สิ่งที่มีประโยชน์จริงใน S3 ไม่ใช่ความเร็วอ่าน/เขียน แต่คือ การ list รายการ
    ในบักเก็ตที่ไม่มีเวอร์ชันหรือไม่มี delete marker การ list ด้วย prefix หนึ่ง ๆ ทำงานได้แทบเหมือนเวลา คงที่ ทำให้สามารถขอคีย์ 1000 รายการที่เรียงตามตัวอักษรถัดจากสตริงใดก็ได้ แม้ในบักเก็ตที่มีออบเจ็กต์ 1 แสนล้านชิ้น
    การใช้ / เป็นตัวคั่นเป็นเพียงค่าเริ่มต้นเท่านั้น จะใช้ตัวอักษรใดก็ได้เพื่อให้ได้ชุดของ common prefix และไดเรกทอรีไม่ได้มีอยู่จริง แต่เพียงแสดงผลเหมือนถูกสร้างขึ้นเมื่อจำเป็น
    คุณสมบัตินี้ทำให้สามารถแบ่งข้อมูลได้หลายแบบตามตัวระบุที่ต้องการ โดยไม่ต้องกังวลเรื่องประสิทธิภาพ
    ถ้าการ list ช้าเฉย ๆ ทำการค้นหาตาม prefix ของชื่อไฟล์ไม่ได้ และช้าลงตามจำนวนคีย์เหมือนไฟล์ซิสเต็ม Unix แบบดั้งเดิม S3 ก็คงไม่มีประโยชน์อะไรเลย

    • ยังไม่ค่อยน่าเชื่อเท่าไร
      ความสามารถในการดึงคีย์ก่อนหรือหลัง prefix เป็นพื้นฐานของ ดัชนีฐานข้อมูล มาตั้งแต่ยุค 1970 แล้ว จึงไม่ใช่เรื่องที่น่าประทับใจเป็นพิเศษ
      แม้กรณีใช้งานอาจต่างกัน แต่หลายครั้งการ list บักเก็ตก็ช้าจนเป็นอุปสรรค และพอบักเก็ตใหญ่ขึ้นหน่อย เวลาที่ใช้ไล่คีย์ก็มากกว่าเวลาอ่านข้อมูลเสียอีก
      เท่าที่จำได้ throughput ของการ list ต่ำกว่า 1Mbps แต่ตอนนี้ไม่มีบักเก็ตใหญ่พอจะทดสอบทันที
    • ความต่างระหว่าง ลำดับชั้นคีย์แบบแบนตามลำดับพจนานุกรม กับลำดับชั้นไฟล์ซิสเต็มที่ซ้อนด้วยไดเรกทอรีนั้นเห็นชัดจากตัวอย่าง
      ถ้ามี dir1/a/000000 ถึง dir1/a/999999 และมี dir1/b อยู่ด้วย ในไฟล์ซิสเต็มแบบลำดับชั้นจริง ๆ คำสั่ง ls dir1/ เพียงเดินดูและคืนค่า 2 รายการคือ "a" กับ "b" ก็พอ
      แต่ใน key-value store ที่ใช้ดัชนีสตริงแบบแบนโดยไม่จัดการตัวคั่น ต้องไล่ผ่านรายการไดเรกทอรี 1 ล้านรายการตั้งแต่ "a/00000" ถึง "a/999999" ก่อนจะไปถึง "b"
      ดังนั้นลำดับชั้นแบบแบนอย่างง่ายจึงทำให้การแสดงรายการในไดเรกทอรีหนึ่งเป็น O(ลูกหลานทั้งหมดแบบ recursive) แทนที่จะเป็น O(ลูกโดยตรง) แบบไฟล์ซิสเต็มจริง และจึงช้ากว่ามาก
      อย่างไรก็ตาม ถ้าอัลกอริทึมการ list รู้จัก อักขระตัวคั่น อย่าง / ต้นไม้ prefix ตามลำดับพจนานุกรมก็สามารถข้าม subtree ที่ระดับ / ถัดไปได้อย่างมีประสิทธิภาพ
      เอกสารของ Amazon S3 ก็ระบุชัดว่าในฟิลด์ CommonPrefixes จะสรุปและข้ามคีย์หลายล้านรายการที่ซ้อนอยู่ลึกลงไป
      https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-...
      ยังไม่ได้ทดสอบว่าการติดตั้งใช้งานจริงช่วยลดการเดินข้อมูลได้จริง หรือแค่เดินครบแล้วค่อยลดผลลัพธ์ตอนท้าย แต่หวังว่าน่าจะลดได้จริง
    • ตั้งแต่ XFS ในปี 1993 เป็นต้นมา ไฟล์ซิสเต็ม UNIX ที่ดีซึ่งได้รับอิทธิพลจาก HPFS ต่างก็ใช้ B-tree รูปแบบหนึ่งในการทำไดเรกทอรี
      ดังนั้นจึงไม่ได้ช้าลงตามจำนวนรายการ และการ list ตาม prefix ของชื่อไฟล์ก็เร็วมาก
    • การใช้งาน S3 99% น่าจะเป็นการดึงออบเจ็กต์ด้วยคีย์ที่รู้อยู่แล้ว
      การมองว่าการ list ตาม prefix เป็นฟีเจอร์หลักจึงรู้สึกแปลก ๆ
    • ไม่แน่ใจว่าเรานิยามคำว่า “เวลา คงที่” ตรงกันหรือเปล่า
      การได้คีย์ 1000 รายการจากการเรียกผ่านเครือข่ายหนึ่งครั้ง ไม่ได้การันตีอะไรเลยเกี่ยวกับความซับซ้อนของฝั่ง backend
  • ไม่นานมานี้ตอนกำลังปรับสคริปต์จัดการทรัพยากร S3 ก็แปลกใจกับความเร็วในการดึงรายการ
    เพื่อนร่วมงานบอกว่าจำเป็นต้องมีแคชรายการไฟล์ เลยส่งแคชที่เติมไว้ล่วงหน้ามาให้ ตอนแรกคิดว่าไม่น่าจะจำเป็นจริง แต่พอลองตรวจเองแล้วกลับไม่ใช่แบบนั้น
    มีรูทไดเรกทอรีสำหรับทรัพยากรแต่ละรายการราว 1 แสนรายการ แต่ละอันมีไดเรกทอรี 5~6 อันและไฟล์จำนวนไม่มาก โดยรวมแล้วไฟล์ทั้งหมดน่าจะไม่ถึง 1 ล้านไฟล์ และความลึกมากสุดประมาณ 3 ชั้น
    การไล่รายการไฟล์เหล่านี้แบบ recursive ใช้เวลาถึง 15 นาทีตามตัวอักษร
    ลองข้อเสนอปรับปรุงความเร็วจาก Stack Overflow และ ChatGPT ไปหลายอย่างแล้ว แต่ไม่มีผลที่มีนัยสำคัญ และไม่เข้าใจว่าทำไมมันถึงช้าขนาดนี้
    ไม่รู้ว่า Amazon ทำไมถึงยังไม่แก้ และจากมุมคนนอกมันดูเหมือนแค่เอา B-tree สักสองสามตัวไปแปะในแต่ละบักเก็ตก็น่าจะจบ
    ถ้ามันเป็นปัญหาที่ยาก เหตุผลก็น่าจะน่าสนใจ เลยอยากฟัง

    • โดยพื้นฐานแล้ว S3 คือคีย์-แวลูสโตร์
      ที่มองอ็อบเจ็กต์เหมือนเป็น “ไดเรกทอรี” ได้ ก็เป็นแค่การกรองด้วย prefix เท่านั้น มันไม่ใช่ไฟล์ซิสเต็ม และไม่มีแนวคิดเรื่องไดเรกทอรีด้วย
    • คำว่า “recursive” และส่วนที่อธิบายเรื่อง “ไดเรกทอรี”, “ชั้น” ไว้ยืดยาวชวนให้กังวล
      วิธีที่เร็วที่สุดในการไล่รายการอ็อบเจ็กต์ใน S3 ไม่ต้องใช้ recursion เลย แค่ไล่รายการอ็อบเจ็กต์ทั้งหมดใต้ prefix นั้นก็พอ
      ถ้าใช้ตัวคั่นพาธทำให้คีย์ของ S3 ดูเหมือนโครงสร้างโฟลเดอร์ แล้ววน “ทีละโฟลเดอร์” จะช้ากว่ามาก
      ตอนเรียก ListObjectsV2 ไม่ควรส่ง delimiter ไป และถ้าไม่ใช้ฟังก์ชันตัวคั่น “ไดเรกทอรี” กับ “ชั้น” ก็จะไม่กระทบประสิทธิภาพ
      ถ้าจะให้ได้เวลารวมตามที่ต้องการ ก็ให้แบ่งงาน list เดียวออกเป็นการดึงรายการแบบขนานสำหรับหลาย ๆ prefix
    • ผลสืบเนื่องที่น่าสนใจของปัญหานี้คือการลบ S3 bucketไม่ใช่เรื่องง่าย
      บักเก็ตที่มีอ็อบเจ็กต์อยู่จะลบไม่ได้ และก็ไม่สามารถบอก S3 ทีเดียวให้ลบอ็อบเจ็กต์ทั้งหมดได้
      ต้องส่งคำขอ API สำหรับลบแยกทีละอ็อบเจ็กต์ และก่อนหน้านั้นก็ต้องส่งคำขอ list อ็อบเจ็กต์ครั้งละ 1000 รายการด้วย ซึ่งการเรียก list นี้ทั้งใช้เวลาและมีค่าใช้จ่าย
      บทความนี้สรุปสถานการณ์ได้ดี: https://cloudcasts.io/article/deleting-an-s3-bucket-costs-mo...
      สุดท้ายแล้ว วิธีที่เร็วที่สุดในการเก็บกวาด S3 bucket ก็คือการลบบัญชี AWS ที่บักเก็ตนั้นสังกัดอยู่
    • เหตุผลอาจธรรมดากว่านั้นมาก
      ในหนึ่งคำขอสามารถไล่รายการอ็อบเจ็กต์ได้ 1 หมื่นรายการ และการเอา 1 หมื่นรายการถัดไปต้องอาศัยผลลัพธ์จากคำขอก่อนหน้า จึงเป็นงานแบบลำดับต่อกันทั้งหมด
      ถ้าจะไล่รายการ 1 ล้านไฟล์ ก็ต้องใช้คำขอต่อเนื่อง 100 ครั้ง และถึงแม้ round-trip time จะมีแค่ 50ms แค่เวลาไปกลับก็กินไป 5 วินาทีแล้ว ยังไม่รวมต้นทุนในการสร้างรายการเองในลูปแบบแบน
      ค่าใช้จ่ายของการดึงรายการ 1 หมื่นรายการใกล้เคียงกับต้นทุนการเขียน และตัวมันเองก็ค่อนข้างช้าอยู่แล้ว อีกทั้งการดึงรายการแต่ละครั้งอาจเป็นสแนปช็อตที่มี strong consistency จึงยิ่งมีต้นทุนเพิ่ม
      B-tree ดูจะช่วยได้ไม่มาก เว้นแต่เป็นกรณีเดินไดเรกทอรี แต่ถึงอย่างนั้นคอขวดก็น่าจะเป็นงานเครือข่ายและ API ที่เปิดให้ใช้งานจากภายนอก
      สุดท้ายแล้วการดึงรายการไฟล์ไม่ใช่กรณีใช้งานที่สำคัญขนาดนั้น โดยทั่วไปมักให้ S3 จัดการงานที่ต้องการผ่านความสามารถอย่าง object lifecycle แล้วให้มันประมวลผลอย่างมีประสิทธิภาพในชั้นไฟล์ซิสเต็มภายใน
    • การคิดว่ามีไดเรกทอรีอยู่ใน S3 bucket ไม่ใช่โมเดลที่ดีนัก
      ทั้งหมดคืออ็อบเจ็กต์ และเว็บอินเทอร์เฟซแค่แสดง prefix ที่คั่นด้วย slash ให้อ่านง่ายขึ้น
      อ็อบเจ็กต์แต่ละตัวมีคีย์ และคีย์นั้นอาจมี slash อยู่ได้ คุณจะคิดแต่ละช่วงว่าเป็นไดเรกทอรีเพื่อความสบายใจก็ได้
      แต่พอลองทำงานแบบที่ปกติทำกับไดเรกทอรี ภาพลวงนั้นก็จะพังลง
  • คนที่สร้าง S3 รู้มาตั้งแต่แรกว่านี่ไม่ใช่ไฟล์ซิสเต็ม และชื่อว่าอ็อบเจ็กต์สตอเรจก็ตั้งขึ้นมาเพื่ออธิบายความต่างที่บทความชี้ไว้
    การที่ “อ็อบเจ็กต์เคยได้รับความนิยม” หมายถึงอ็อบเจ็กต์ในฐานะองค์ประกอบซอฟต์แวร์ที่รวมโค้ดที่รันได้กับสถานะภายในไว้ด้วยกัน แต่ตัวอย่างยุคแรกของ S3 ไม่ได้เป็นแนว “serialize live object แล้วไป deserialize ในอีกโปรเซสหนึ่ง”
    ตัวอย่างทั้งหมดเป็นพวกทรัพยากรสแตติกของเว็บไซต์ และในฝั่งฐานข้อมูลเอง คำว่าอ็อบเจ็กต์ก็ถูกใช้ในความหมายจาก “binary large object” หรือ “blob” อยู่แล้ว
    S3 ใกล้เคียงกับที่เก็บสิ่งที่เอาไปใส่ฐานข้อมูลไม่ค่อยเหมาะมากกว่า และ use case ตอนเปิดตัวในการออกแบบช่วงแรกก็สมมติว่าดัชนีเนื้อหาอยู่ที่อื่นสักแห่ง ดังนั้นการที่การดึงรายการช้าก็อธิบายธรรมชาติแบบนั้นได้ตรงตัว

    • ดูเหมือนผู้เขียนจะไม่รู้ว่า “อ็อบเจ็กต์สตอเรจ” เป็นคำศัพท์ของระบบจัดเก็บข้อมูลที่ไม่เกี่ยวกับการเขียนโปรแกรมเชิงวัตถุ
      https://en.wikipedia.org/wiki/Object_storage
    • กังวลว่าผู้เขียนจะสับสนระหว่างการเขียนโปรแกรมเชิงวัตถุกับอ็อบเจ็กต์สตอเรจ
      ตามคำอธิบายของ GCP อ็อบเจ็กต์สตอเรจคือสถาปัตยกรรมที่เก็บข้อมูลไม่มีโครงสร้างโดยแบ่งเป็นอ็อบเจ็กต์ในสภาพแวดล้อมข้อมูลแบบแบนที่มีโครงสร้างเรียบง่าย
      https://cloud.google.com/learn/what-is-object-storage
      กล่าวคือ หัวใจสำคัญคือข้อมูลไม่มีโครงสร้าง การจัดวางแบบแบน และการอ่านเขียนในระดับทั้งรายการ
  • S3 ไม่ใช่ไฟล์ และยิ่งไม่ใช่ระบบไฟล์
    สิ่งที่คาดหวังจากนามธรรมแบบไฟล์คือความสามารถในการแก้ไขได้ ต้องสามารถแก้ไขบางส่วนของไฟล์ ขยาย ย่อ และอ่านเขียนที่ออฟเซ็ตใดก็ได้แบบสุ่ม
    เมื่อเปิดไฟล์แล้วก็ไม่ควรต้องย้อนกลับไปที่รากหรือแนวคิดระดับบนอีก แต่ S3 มีเพียงอ็อบเจ็กต์ที่เปลี่ยนไม่ได้บนรายการที่เปลี่ยนได้เท่านั้น และถ้าจะเปลี่ยนก็ต้องคัดลอกแล้วอัปโหลดใหม่
    นามธรรมแบบไฟล์ดั้งเดิมคือการค้นหาเซกเตอร์ของดิสก์แล้วแสดงให้ไคลเอนต์เห็นเป็นบัฟเฟอร์ต่อเนื่อง ส่วน S3 แก้คนละปัญหา
    หลายคนเข้าใจผิดว่าแนวคิดดี ๆ ของ UNIX ที่ว่า “ทุกอย่างคือไฟล์” หมายความว่าทุกอย่างควรถูกมองเป็นบัฟเฟอร์เสมือนต่อเนื่อง
    แก่นจริง ๆ คือไม่ว่าจะเป็นไฟล์หรืออ็อบเจ็กต์ชนิดอื่นที่ระบบอยากแสดงให้โปรเซสเห็น ก็มี leaf node พื้นฐานอยู่ และทุกอย่างรวมถึงไดเรกทอรีสามารถถูกลิสต์อยู่ในไดเรกทอรีได้ ทำให้เกิดต้นไม้แบบเรียกซ้ำ
    สิ่งที่ทำให้เป็นระบบไฟล์ไม่ใช่ชนิดของ leaf node ใดชนิดหนึ่ง แต่คือ ไดเรกทอรี
    การเพิ่ม leaf type ใหม่อย่าง socket หรือ framebuffer แทบจะเป็นเรื่องเล็กน้อยและไม่ทำลายแนวคิดนี้ แต่ถ้าเพิ่มคอนเทนเนอร์อีกชนิดอย่าง list โครงสร้างระบบไฟล์จะซับซ้อนขึ้นและความสอดคล้องเชิงแนวคิดจะพัง
    S3 ไม่ได้ทำสิ่งเหล่านี้ แต่ก็ไม่เป็นไร
    แค่เอาสิ่งที่ไม่เข้ากับฐานข้อมูลไปใส่ไว้ แล้วหวังว่าระหว่างที่ไม่มองมันจะไม่เกิด bit rot
    ความอยากทำให้ S3 ดูเหมือนระบบไฟล์น่าจะมาจากการที่ลูกค้าเข้าใจผิดว่า S3 เก่งเรื่องอะไร และฝ่ายจัดการผลิตภัณฑ์ก็ไม่ขัดความเข้าใจผิดนั้นแต่กลับรับมันไว้

    • เห็นด้วยว่า S3 ไม่ใช่ระบบไฟล์
      อุปมาที่ถูกกว่าคือ อุปกรณ์จัดเก็บแบบบล็อก เพียงแต่เป็นอุปกรณ์บล็อกที่ประหลาดมาก ซึ่งขนาดบล็อกเป็นเท่าไรก็ได้และอาจมีคีย์กำกับได้
      ระบบไฟล์เป็นนามธรรมที่วางอยู่บนอุปกรณ์จัดเก็บแบบบล็อก ดังนั้น “ระบบไฟล์ S3” ก็ควรเป็นนามธรรมที่วางอยู่บน S3 โดยมอง S3 เป็นที่เก็บบล็อกพื้นฐาน
    • สงสัยว่าระบบไฟล์แบบอ่านอย่างเดียวเข้ากับคำนิยามนี้อย่างไร
  • ระบบไฟล์คือนามธรรมที่สร้างอยู่บน อุปกรณ์บล็อก
    อุปกรณ์บล็อกให้ไบต์อาร์เรย์ขนาดมหาศาล และเปิดให้ทำการอ่าน/เขียนเป็นบล็อก เช่น “เขียน 300 ไบต์นี้ที่ตำแหน่ง 273041”
    ตัวอุปกรณ์บล็อกเองก็เป็นนามธรรมที่สร้างอยู่บนฮาร์ดแวร์จริงอีกที ดังนั้นคำสั่งว่า “เขียน 300 ไบต์นี้” ในความเป็นจริงจะนำไปสู่การทำงานอย่าง “ย้ายหัวอ่านของจานที่ 2 ไปยังตำแหน่งที่ 6”
    S3 ก็เป็นเพียงอีกนามธรรมหนึ่งที่สร้างอยู่บนสตอเรจดิบ และเป็น คีย์-อ็อบเจ็กต์สโตร์ แบบแบนอย่างเคร่งครัด
    ถ้าต้องการความสามารถแบบระบบไฟล์ ก็ไปทำในแอปหรือใช้ระบบไฟล์ไปเลย
    ถ้าต้องการแค่ append ก็ให้ฐานข้อมูลติดตาม append chain แล้วเก็บ chunk ไว้ใน S3; ถ้าไม่เข้ากันก็ใช้สิ่งอื่น
    ถ้าต้องการ copy ก็สร้างรีเฟอเรนซ์ใหม่ไปยังอ็อบเจ็กต์เดิมในฐานข้อมูล; ถ้าไม่เข้ากันก็ใช้สิ่งอื่น
    S3 เหมาะกับคนจำนวนมากอยู่แล้ว จึงไม่ควรพยายามเปลี่ยนมันให้เป็นอย่างอื่น
    และควรเลิกพยายามเปลี่ยนความหมายของคำศัพท์เฉพาะที่มีใช้กันมานานแล้วด้วย ระบบไฟล์เป็นแนวคิดที่อธิบายอยู่ในตำรา และ S3 ก็ไม่เคยอ้างว่าตัวเองเป็นระบบไฟล์
    การศึกษาเรื่องการออกแบบระบบปฏิบัติการสักหน่อยช่วยได้มากและก็สนุกจริง ๆ

  • มีการพูดคุยเปรียบเทียบ API ของ object_store ใน Apache Arrow กับ Apache OpenDAL ที่ https://github.com/apache/arrow-rs/issues/3888
    Apache OpenDAL เป็นไลบรารีที่ให้ API คล้ายระบบไฟล์บนแบ็กเอนด์หลายชนิด รวมถึง S3 และคลาวด์สตอเรจอีกหลายเจ้า
    ระบบฐานข้อมูลบางตัว เช่น GreptimeDB และ Databend ใช้ OpenDAL เหมือนเป็น S3 SDK ที่ดีกว่าสำหรับเข้าถึงข้อมูลในคลาวด์สตอเรจ
    ยังมี Alluxio และ JuiceFS เป็นอีกทางแก้สำหรับจัดการอินเทอร์เฟซคล้ายระบบไฟล์บน S3 แต่ต่างจาก Apache OpenDAL ตรงที่ต้องมีการดีพลอยแยกและมีบริการเมทาดาทาภายในเฉพาะ

    • ไม่แน่ใจว่าจะใช้ OpenDAL แทน Alluxio เป็นเลเยอร์แคชภายในเครื่องสำหรับ TrinoDB ได้หรือไม่
  • เมื่อพูดถึง S3 ก็ควรพูดถึง Backblaze B2 ด้วย
    ราคาถูกกว่า S3 3 เท่าเลยชอบมาก และไม่ได้เกี่ยวข้องอะไรกับ Backblaze

    • Backblaze B2 ราคาถูกก็จริง แต่ถ้าจะใช้ในโปรดักชันก็มีต้นทุนบางอย่างที่ต้องนับรวม
      มี maintenance window 2 ชั่วโมงทุกสัปดาห์ช่วง 11:30~13:30 PST โดยปกติจะไม่ล่ม แต่บางครั้งก็เกิด outage ทั้งระบบกลางชั่วโมงทำงานของสหรัฐฯ
      ถ้าอัตราความผิดพลาดสูงจนใช้งานไม่ได้ ก็ต้องเปิด support ticket และในช่วงหลายปีที่ผ่านมาเจอแบบนี้ประมาณปีละครั้ง
      ฝั่งซัพพอร์ตเอาแต่ถามคำถามมากมายราวกับไม่มี error log หรือ visibility ฝั่งตัวเอง และไม่ได้ตรวจปัญหาอย่างจริงจัง
      ยังมี ความสำเร็จลวง ที่ตอบกลับว่าอัปโหลดสำเร็จ แต่ในระบบ B2 กลับถูกเก็บเป็น 0 ไบต์จริง ๆ ดังนั้นแม้ได้ success code ก็ต้องตรวจสอบไฟล์ที่อัปโหลดเสมอ
      ถ้ามีช่องโหว่ความรุนแรงสูงอย่าง Log4j2 CVE ก็อาจเกิดการหยุดชะงักยาว เช่น 10 ชั่วโมง
      ราคาเยี่ยมมาก แต่ไม่ใช่ผลิตภัณฑ์ที่เทียบตรงกับบริการคลาวด์สตอเรจที่ mature กว่าได้
    • ประเด็นสำคัญของบริการทางเลือกคือข้อมูลจะปลอดภัยได้เท่ากับที่คุณเชื่อถือบริษัทนั้นเท่านั้น
      แต่ก็คิดว่าสามารถบรรเทาได้ระดับหนึ่งด้วยแบ็กอัปภายนอกสองชั้น
    • B2 ก็ดีอยู่ แต่ไม่ถึงขั้นดีพอให้ยอมจ่าย ค่า IPv4 address เพื่อใช้มัน
      การโฆษณาว่าเป็นโซลูชันมัลติคลาวด์ แต่ในความเป็นจริงกลับมีค่าบริการ NAT gateway และ IPv4 แปะอยู่ทุกที่ จนแทบตัดความเป็นไปได้ในการนำไปใช้ทิ้ง น่าขันมาก
      เวิร์กโหลดเป็นแบบอ่านเยอะเขียนน้อย จึงยังประหยัดเงินได้แม้ต้องจ่ายค่าแบนด์วิดท์ของ B2 แต่ถ้าต้องผ่าน NAT64 gateway หรือต้องจ่ายค่าบริการรายชั่วโมงเพื่อเข้าถึง B2 ก็ไม่คุ้มอีกต่อไป
  • เป็นบทความที่ดี และคงจะมีประโยชน์มากถ้าได้อ่านก่อนเริ่มต้นเส้นทางการเมานต์ cloud storage ด้วย FUSE ผ่าน rclone mount
    หลังจากลองผิดลองถูกอยู่หลายครั้ง ในที่สุด rclone ก็มีชั้น VFS ที่ปรับสตอเรจอย่าง S3, Google Cloud Storage, Azure Blob, OpenStack Swift และ Oracle Object Storage ให้กลายเป็นชั้นไฟล์ซิสเต็มที่คล้าย POSIX และโค้ด rclone mount ที่แท้จริงก็เป็นเพียงชั้นบาง ๆ ที่อยู่ด้านบนของมัน
    ชั้น VFS มีระดับความเข้ากันได้หลายขั้น โดยในโหมด off จะทำเพียงแคชไดเรกทอรี
    ในโหมดนี้ ตามที่บทความกล่าวไว้ จะไม่สามารถอ่านและเขียนไฟล์เดียวกันพร้อมกันได้, เขียนกลางไฟล์ก็ไม่ได้, และไฟล์จะเขียนได้แบบลำดับต่อเนื่องเท่านั้น
    น่าแปลกที่ถึงจะมีข้อจำกัดแบบนี้ หลายอย่างก็ยังทำงานได้ค่อนข้างดี
    ขั้นถัดไปคือ writes ซึ่งรองรับความสามารถแบบ POSIX ส่วนใหญ่ที่แอปต้องการ เช่น การอ่านและเขียนไฟล์เดียวกันพร้อมกัน หรือการเขียนกลางไฟล์ แต่ต้องแลกกับการสร้างสำเนาไฟล์ไว้ในเครื่องแล้วอัปโหลดแบบ asynchronous ตอนปิดไฟล์
    เอกสารโหมดแคชของ VFS สะท้อนข้อจำกัดที่บทความพูดถึงได้ดี: https://rclone.org/commands/rclone_mount/#vfs-file-caching
    โดยพื้นฐานแล้ว S3 ไม่มีไดเรกทอรีจริง ๆ ด้วยซ้ำ จึงไม่สามารถมีไดเรกทอรีที่ไม่มีไฟล์ได้ และไดเรกทอรีก็ไม่มีเมทาดาทาที่ใช้ได้จริงอย่างเวลาแก้ไข
    สามารถสร้าง directory marker ซึ่งเป็นไฟล์ขนาด 0 ไบต์ที่ลงท้ายด้วย / ได้ และเครื่องมือจำนวนมากรวมถึง rclone ก็รองรับสิ่งนี้
    ปกติการไม่มีไดเรกทอรีว่างเปล่ามักไม่ใช่ปัญหาใหญ่นัก เพราะชั้น VFS จะสร้างของปลอมขึ้นมาให้ และแอปส่วนใหญ่ก็มักจะเขียนอะไรบางอย่างลงไปในนั้นในไม่ช้า
    ท้ายที่สุดแล้ว การเปลี่ยนสิ่งที่ดูเหมือน S3 ให้ดูเหมือนไฟล์ซิสเต็มแบบ POSIX ต้องอาศัยงานจำนวนมาก และเบื้องหลังพฤติกรรมอย่างการเปลี่ยนชื่อไฟล์ที่เปิดอยู่รวมถึงกรณียกเว้นชวนปวดหัวต่าง ๆ ก็มีการเล่นกลอยู่มาก
    คำสั่งระดับล่างของ rclone อย่าง move/sync/copy ไม่ได้ทำการจัดการแบบนั้น และใช้ S3 API แทบจะตรง ๆ
    ถ้าจะเปลี่ยนอะไรได้สักอย่างใน S3 API ก็อยากให้มีตัวเลือกอ่านเมทาดาทาพร้อมกับการ list
    rclone เก็บเวลาแก้ไขไฟล์ไว้ใน object metadata แต่ไม่มีวิธีอ่านมันแบบครั้งละมาก ๆ จึงต้อง HEAD ทีละอ็อบเจ็กต์
    หรือถ้าตั้งค่า Last-Modified ของอ็อบเจ็กต์ตอนอัปโหลดได้ก็คงดี

    • สงสัยว่าน่าจะอ้อมไปได้ด้วยการ เก็บเมทาดาทาไว้ในชื่อตัวคีย์เอง
      ข้อจำกัดความยาวคีย์คือ 1024 จึงจำกัดปริมาณเมทาดาทาที่เก็บได้ แต่ต่อให้คิดรวมพาธไฟล์เข้าไปด้วยก็ยังเหลือค่อนข้างมาก
      อาจใช้ตัวคั่นอย่าง // ที่ใช้ไม่ได้ในพาธที่ normalize แล้ว แล้วเก็บเป็น /path/to/file.txt//mtime=1710066090
      แบบนี้ก็ยังดึง “ไดเรกทอรี” ตาม prefix ได้ และดึงไฟล์โดยตรงโดยใช้ // เป็นเหมือน prefix ได้ด้วย
      แต่รูปแบบแบบนี้ก็น่าจะทำลายความเข้ากันได้กับซอฟต์แวร์อื่นอย่างมาก
    • เห็นด้วยว่าควรมีตัวเลือกให้รวมเมทาดาทาในการ list
      ใน MinIO มีการเพิ่มพารามิเตอร์ “ลับ” ชื่อ metadata=true เพื่อให้รวมเมทาดาทาและแท็กในการ list เมื่อมีสิทธิ์ที่เหมาะสม
      เพราะเป็น extension จึงไม่ใช่สิ่งที่ใช้ได้อย่างเสถียรเสมอไป แต่ rclone สามารถลองใช้ทุกครั้งและใช้เมื่อทำได้
      ไฟล์ขนาด 0 ไบต์ที่ลงท้ายด้วย / ก็ทำได้เช่นกัน แต่จะมอง common prefix ในการ list ว่าเป็นไดเรกทอรีเลยก็ได้
      แบบนั้นไดเรกทอรีจะไม่มีสถานะของตัวเอง และจะไม่มีทางมีอยู่ได้ถ้าไม่มีอ็อบเจ็กต์อยู่ข้างใน ซึ่งก็มีทั้งข้อดีและข้อเสีย
      ถ้าตั้งค่า Last-Modified ได้ตอนอัปโหลด ข้อจำกัดฝั่งไคลเอนต์ก็จะลดลง แต่การใช้เวลาเซิร์ฟเวอร์เป็นเกณฑ์ก็มีข้อดีเหมือนกัน
      ในการทำ replication หรือ mirroring ฝั่งไคลเอนต์เองก็ต้องจัดการข้อจำกัดแบบเดียวกัน
      สำหรับผม สิ่งที่น่าหงุดหงิดที่สุดคือไม่มี HeadObjectVersions ที่คืนข้อมูลเวอร์ชันของอ็อบเจ็กต์เดี่ยวได้
      ListObjectVersions ไม่สามารถรู้ได้ว่า prefix ที่ให้มาคือ prefix จริงหรือเป็น object key จึงหลีกเลี่ยงไม่ได้ที่จะกลายเป็นงานระดับทั้งคลัสเตอร์เสมอ
      แม้ AWS จะเพิ่งเพิ่ม GetObjectAttributes มาไม่นาน แต่ข้อมูลเวอร์ชันที่น่าจะเข้ากับมันได้ดีกลับไม่ได้ถูกรวมไว้
  • “Simple” ใน S3 ไม่ได้หมายถึง “ไม่ลึก” แต่หมายถึงมีชิ้นส่วนให้น้อยที่สุดเท่าที่จำเป็นต่อการบรรลุข้อกำหนด
    ถ้าต้องการ object storage ที่เป็นแบบ distributed, centralized, replicated, high availability, high durability, high bandwidth, low latency, strongly consistent, synchronous, scalable พร้อม HTTP REST API ด้วย ผมคิดว่ายากที่จะทำอะไรให้ ง่ายกว่า S3
    แม้ AWS S3 จะมีฟีเจอร์เพิ่มเข้ามามากมายตลอดเวลานาน แต่พฤติกรรมพื้นฐานยังคงเดิม

    • ถ้าใช้คำตามที่บทความใช้ “มีชิ้นส่วนเท่าที่จำเป็นขั้นต่ำ” นี่แหละคือความหมายของ ลึก
      ตามเกณฑ์ของ Ousterhout ใน 『A Philosophy of Software Design』 คำว่า simple หมายถึงไม่ซับซ้อน และ “Simple Made Easy” ของ Rich Hickey ก็อยู่ในบริบทเดียวกัน
      ส่วน “ลึก” หมายถึงมีอินเทอร์เฟซเล็ก แต่ให้ความสามารถภายในที่ซับซ้อนและมากมาย ดังนั้นกับ S3 คำนี้เหมาะกว่า “เรียบง่าย”
      มันต่างจากความเรียบง่ายในความหมายว่า S3 ไม่มีอะไรเท่าไร
      https://www.infoq.com/presentations/Simple-Made-Easy/
    • ถ้าตามถ้อยคำของบทความ ก็อาจมองได้ว่าความเรียบง่ายแทบจะสื่อถึงความลึกและอินเทอร์เฟซที่แคบอยู่แล้ว