• อนาคตของบริการข้อมูลบนคลาวด์คือสถาปัตยกรรมแบบ "ขนาดใหญ่, หลายเทนแนนต์"
    • เหตุผลที่บริการ SaaS ระดับบนอย่าง S3 มอบทั้งความเรียบง่าย ความน่าเชื่อถือ ความทนทาน ความสามารถในการขยาย และราคาที่ต่ำได้ เป็นเพราะเทคโนโลยีของบริการเหล่านี้ถูกออกแบบเชิงสถาปัตยกรรมมาเพื่อมอบคุณสมบัติเหล่านี้โดยตรง
    • การให้บริการลูกค้าผ่าน resource pool ขนาดใหญ่ช่วยรับประกันทั้งประสิทธิภาพจากขนาดและความน่าเชื่อถือ

[นิยามของระบบ Serverless Multi-Tenant]

นิยามของ "Multi-Tenancy"

  • Multi-tenancy คือการแชร์ทรัพยากรโดยวาง workload หลายชุดร่วมกันบนฮาร์ดแวร์ที่ใช้ร่วมกัน
  • การสร้างระบบบนคลาวด์หมายถึงการที่หลายเทนแนนต์ได้รับบริการจาก compute instance ที่ใช้ร่วมกัน (เช่น Amazon EC2 หรือ Google Compute) หรือจากบริการ PaaS ที่ใช้ร่วมกัน (เช่น cloud object storage)
  • นิยามของ multi-tenancy คือ "การให้บริการหลายเทนแนนต์บนทรัพยากรที่ใช้ร่วมกัน (เช่น virtualized server, drive และบริการ building block ของ PaaS)"
  • มีโมเดลการแชร์ทรัพยากรได้หลายแบบ และบางระบบก็ผสมหลายโมเดลเข้าด้วยกันตลอดทั้งคอมโพเนนต์
    • Shared process: software process เดียวกันให้บริการหลายเทนแนนต์ โดยการแยกข้อมูลและความปลอดภัยเป็นแบบเชิงตรรกะ
    • Container: รันโหนดแบบ single-tenant แล้วแพ็กหลายคอนเทนเนอร์ไว้ต่อโฮสต์หนึ่งเครื่อง โดยทั่วไปทำผ่าน Kubernetes ที่โหนด K8s หนึ่งตัวอาจโฮสต์พ็อดของเทนแนนต์จำนวนมาก
    • Virtualization: รันโหนดแบบ single-tenant ใน VM (เช่น QEMU) หรือ microVM (เช่น Firecracker) แล้วแพ็กหลาย VM ต่อโฮสต์หนึ่งเครื่อง โดย Kubernetes ก็สามารถใช้งานร่วมกับ VM ผ่าน Kata Containers ได้
  • ยังมีวิธีการ isolate ของ V8 ที่ให้เทนแนนต์ใช้ V8 process เดียวกันได้ภายใต้ lightweight context ที่แยกจากกัน แต่ยังไม่เคยเห็นสิ่งนี้ในระบบข้อมูล

นิยามของ Serverless

  • ลูกค้าไม่ได้เลือกประเภทเซิร์ฟเวอร์หรือระบุฮาร์ดแวร์โดยตรง
  • ระบบเหล่านี้อาศัยความยืดหยุ่นและความสามารถในการย้ายงานในระดับหนึ่ง เพื่อรองรับความต้องการของทุก workload โดยที่ลูกค้าไม่ต้องปรับขนาดฮาร์ดแวร์เองโดยตรง
    • ความยืดหยุ่น: ความสามารถของบริการในการ scale up/down และหดหรือขยายตามความต้องการของ workload
    • ความสามารถในการย้ายงาน: ความสามารถของบริการในการย้ายและปรับสมดุล workload ภายใน เพื่อให้ตอบโจทย์ด้านประสิทธิภาพและเสถียรภาพ
  • โมเดล serverless ใช้การคิดค่าบริการตามการใช้งาน ซึ่งมีความสำคัญต่อผู้ใช้มากขึ้นเรื่อย ๆ
    • ลูกค้าจำนวนมากไม่ต้องการ commit ล่วงหน้าในปริมาณมาก และต้องการเพียงจ่ายตามที่ใช้จริง
    • การคิดค่าบริการตามการใช้งานมีหลายรูปแบบ ซึ่งแตกต่างกันมากตามลักษณะ workload และการออกแบบระบบเบื้องหลัง
      • จ่ายตามจำนวน operation (ระดับล้านครั้ง)
      • จ่ายตามการใช้ CPU และหน่วยความจำของ workload
      • จ่ายตาม GB ของ storage
      • จ่ายตามหน่วยประสิทธิภาพ/ความจุเสมือนที่เกี่ยวข้องกับทรัพยากรและอัตราการทำงาน (เช่น RCU/WCU ของ DynamoDB)
      • โมเดลไฮบริดที่ลูกค้าจ่ายสำหรับความจุพื้นฐานบางส่วน และจ่ายเพิ่มเมื่อใช้เกินกว่านั้น ("จ่ายฐาน แล้วจ่ายช่วงพีค")

[ความท้าทายร่วมกัน]

ทำงานภายใต้ข้อจำกัดที่ workload กำหนด

  • ข้อจำกัดจำนวนมากที่เกิดจาก workload ของระบบข้อมูลแต่ละแบบ เป็นตัวขับเคลื่อนสำคัญของสถาปัตยกรรมพื้นฐาน
    • ข้อกำหนดด้าน latency/availability
    • ข้อกำหนดด้าน consistency
    • ความสัมพันธ์/การพึ่งพากันระหว่าง request และข้อมูล
    • รูปแบบการเข้าถึงแบบลำดับเทียบกับแบบสุ่ม
    • ความหลากหลายของงานที่ทำต่อหนึ่ง request
    • ขนาดข้อมูล
    • โปรโตคอลแบบ session เทียบกับแบบ request-oriented, กลไกแบบ push เทียบกับ pull
    • ความเข้มข้นของงานด้านการคำนวณ
  • หากข้อกำหนดด้าน latency และ consistency ผ่อนคลาย วิศวกรก็จะมีอิสระมากขึ้น
    • ตัวอย่างที่ดีคือการใช้ประโยชน์จาก cloud object storage ซึ่งมีต้นทุนต่ำและความทนทานสูง ในระบบที่ไม่ได้ต้องการ latency ต่ำมาก เพราะระบบที่ latency ต่ำมีข้อจำกัดในการเพิ่มคอมโพเนนต์ที่มี latency สูง
    • ระบบที่เป็น eventually consistent สามารถหลีกเลี่ยงภาวะกลืนไม่เข้าคายไม่ออกนี้ได้ โดยเขียนข้อมูลไปยัง object storage แบบ asynchronous แทนที่จะใส่ไว้ใน hot path แบบ synchronous ของข้อมูล
    • แต่ระบบที่ต้องการทั้ง latency ต่ำและ strong consistency ไม่มีทางลัดแบบนี้
  • เมื่อข้อจำกัดอย่าง latency ต่ำมารวมกัน spatial locality และ temporal locality ของ workload อาจมีผลต่อการเลือกสถาปัตยกรรม
    • ตัวอย่างเช่น workload ที่มีลักษณะเด่นเป็น sequential scan ควรเก็บช่วงข้อมูลที่ต่อเนื่องกันไว้ด้วยกัน เพื่อให้สแกนจากดิสก์ได้เร็วและมีประสิทธิภาพ
    • การแยกช่วงเหล่านี้ออกเป็นช่วงย่อยขนาดเล็กช่วยจัดการ hotspot ได้ดีขึ้น แต่ทั้งสองอย่างนี้เป็นสิ่งที่ขัดแย้งกัน จึงต้องหาสมดุลระหว่างกัน
    • ส่วนรูปแบบการเข้าถึงแบบสุ่มที่แทบไม่มีความสัมพันธ์ระหว่าง request แต่ละรายการ สามารถใช้ประโยชน์จาก flat address space ที่กระจายแบบบางและสม่ำเสมอไปยังหลายเซิร์ฟเวอร์ได้
  • โปรโตคอลแบบ session-oriented ที่สร้าง persistent connection มักยากกว่าโปรโตคอลแบบ request-oriented ซึ่งแต่ละ request เป็นอิสระจาก request ก่อนหน้า
    • persistent connection อาจต้องมี connection pooling และเมื่อเกิดการเปลี่ยนแปลงอย่าง rolling node หรือ data balancing ก็อาจส่งผลกระทบที่ผู้ใช้สังเกตได้จากฝั่ง client
  • มีทั้งระบบที่เป็น storage API แบบเรียบง่าย เช่น object storage หรือ Kafka API และระบบที่ใช้การคำนวณหนักอย่างฐานข้อมูล SQL
    • สิ่งนี้นำไปสู่ประเด็นเรื่องความสามารถในการคาดการณ์และความแปรผันของปริมาณงานที่ต้องใช้ในการประมวลผลแต่ละ request
    • ตัวอย่างสุดขั้วด้านหนึ่งคือ data streaming API อย่าง Kafka ที่เพียงดึงบล็อกของเรคคอร์ดที่ต่อเนื่องกัน ส่วนอีกด้านคือ SQL ซึ่งงานที่ต้องใช้ต่อ query อาจแตกต่างกันอย่างมาก

การแยกเทนแนนต์ออกจากกัน

  • การแชร์ทรัพยากรช่วยเพิ่มการใช้งานฮาร์ดแวร์ให้คุ้มขึ้น แต่ก็อาจทำให้เกิด resource contention ที่ workload ของเทนแนนต์หนึ่งไปกระทบอีกเทนแนนต์หนึ่งได้
  • ในระบบ multi-tenant ต้องทำให้แน่ใจว่าเทนแนนต์ที่ใช้บริการบนทรัพยากรฮาร์ดแวร์ร่วมกัน จะได้รับการรับประกันเสมือนกำลังใช้บริการแบบเฉพาะของตนเอง

การแยก storage ออกจาก compute

  • การแยก storage ออกจาก compute เป็นหลักการออกแบบสำคัญที่ทุกระบบที่สำรวจมาล้วนทำในระดับใดระดับหนึ่ง
  • แนวโน้มของฮาร์ดแวร์ทำให้การแยก storage กับ compute เป็นจริงได้มากขึ้นเรื่อย ๆ ส่วนหนึ่งเพราะเครือข่ายไม่ใช่คอขวดแบบเดิมอีกต่อไป
  • แม้ network throughput จะเพิ่มขึ้น แต่ก็ยังมีความท้าทายใหม่จากการแยกแบบนี้ โดยเฉพาะเมื่อ cloud object storage เข้ามามีบทบาทหลัก
    • cloud object storage ยังมี latency ค่อนข้างสูง แต่มีความทนทานสูงและต้นทุนต่ำ
    • แต่ก็อาจยากที่จะนำไปใช้กับ workload ที่โดยทั่วไปต้องการ latency ต่ำ เช่นฐานข้อมูล OLTP
    • นอกจากนี้ โมเดลด้านเศรษฐศาสตร์ของ cloud object storage ยังไม่เอื้อต่อการออกแบบที่พึ่งพา object ขนาดเล็กจำนวนมาก และบังคับให้ต้องสะสมข้อมูลลงใน object ขนาดใหญ่ขึ้นด้วยจำนวน request ที่น้อยลง ซึ่งยิ่งทำให้ชีวิตของระบบ low-latency ซับซ้อนกว่าเดิม
  • วิศวกรสามารถรวม object storage เข้าไปในระบบที่ latency ต่ำได้ โดยรับมือกับปัญหา latency ของ object storage ผ่านการวาง durable, fault-tolerant write cache และ predictive read cache ไว้ด้านหน้า object storage ที่ช้า
    • durable write cache นี้โดยพื้นฐานคือคลัสเตอร์ของเซิร์ฟเวอร์ที่ทำ replication protocol และเขียนข้อมูลลง block storage
      • ในเบื้องหลัง คลัสเตอร์จะอัปโหลดข้อมูลไปยัง object storage แบบ asynchronous ตามรูปแบบที่คุ้มค่ากว่า ซึ่งใช้การเขียนไฟล์ขนาดใหญ่จำนวนน้อย
      • write cache ที่ทนต่อความขัดข้องรองรับการเขียนที่มี latency ต่ำได้ดี
    • จุดที่อาจเป็นปัญหาในสถาปัตยกรรมนี้คือ read cache
      • workload แบบลำดับอย่าง event streaming เป็นกรณีที่ง่ายและได้ผลมาก
      • ตราบใดที่ Aggregate Prefetching ยังตามความต้องการทัน การอ่านก็ควรไปโดน read cache ในเครื่องเสมอ
      • ส่วนฐานข้อมูลเจอปัญหาที่ยากกว่าเพราะมีรูปแบบการเข้าถึงแบบสุ่มที่คาดเดายาก แต่ table scan ก็ยังได้ประโยชน์จาก read-ahead อยู่ดี
  • การทำ distributed fault-tolerant write cache ด้วย replication protocol ไม่ใช่เรื่องง่ายนัก และในสภาพแวดล้อมแบบ multi-AZ ก็อาจมีต้นทุนอื่น เช่นค่าบริการข้าม AZ เพิ่มเข้ามา
    • แต่ในตอนนี้ยังไม่มีทางเลือกอื่น สำหรับระบบที่ต้องการ latency ต่ำและอยากใช้ object storage ที่ราคาถูกและทนทานเป็นที่เก็บข้อมูลหลัก
    • ระบบ latency ต่ำอื่น ๆ ควรหลีกเลี่ยงการใช้ cloud object storage ไปเลย และให้ความสำคัญกับ latency ต่ำที่คาดการณ์ได้มากกว่า
    • แม้ cloud storage จะถูกใช้อย่างแพร่หลาย แต่ก็ไม่ได้ใช้ได้กับทุกกรณี เพราะมี trade-off ด้าน latency

การจัดการความร้อน

  • การจัดการความร้อนคือการกระจายโหลดให้สม่ำเสมอที่สุดเท่าที่เป็นไปได้ไปยังหลาย storage node เพื่อหลีกเลี่ยง hotspot ที่อาจทำให้เกิดปัญหาด้านประสิทธิภาพที่ผู้ใช้สังเกตได้ เช่น latency พุ่งหรือจำนวนงานต่อวินาทีลดลง
  • จะเรียกว่า load balancing ก็ได้ แต่โดยทั่วไปคำว่า load balancer มักใช้กับโหนดแบบ stateless
  • ในระบบ stateful อาจเกิด hotspot ที่ object ซึ่งมีความต้องการสูงถูกจับกลุ่มอยู่บน storage node บางตัว จนเกิดการแย่งใช้ทรัพยากร
  • load balancer สามารถกระจายโหลดไปยังชุดโหนด stateless ได้ค่อนข้างง่ายด้วยกลยุทธ์อย่างสุ่ม, least connection หรือรูปแบบ FIFO บางอย่าง แต่ระบบ stateful ต้อง route request ไปยังโหนดตามตำแหน่งที่ข้อมูลอยู่
  • การย้ายข้อมูลเพื่อกระจายโหลดใหม่มักเรียกว่า rebalancing
  • ปัญหาที่ซับซ้อนกว่านั้นคือการกระจายโหลดอาจเปลี่ยนไปตามเวลา
    • การกระจายข้อมูลจึงกลายเป็นกระบวนการแบบไดนามิกที่ต้องรับมือได้ตั้งแต่พีคระยะสั้นซึ่งกระทบข้อมูลเพียงบางส่วน ไปจนถึงการเปลี่ยนแปลงโหลดขนาดใหญ่จากรูปแบบรายวันหรือเหตุการณ์ตามฤดูกาลที่เกิดข้ามหลายเทนแนนต์
  • ชุดข้อมูลขนาดใหญ่ เช่นฐานข้อมูลขนาดใหญ่หรือ event stream ที่มี throughput สูง จำเป็นต้องทำ sharding เพื่อกระจายโหลดอย่างมีประสิทธิภาพ
    • rebalancing จึงกลายเป็นการ rebalance shard และระบบอาจต้อง split หรือ merge shard ด้วยเมื่อการกระจายโหลดเปลี่ยนไป
    • อย่างไรก็ตาม อาจมี trade-off กับเรื่องอย่าง data locality ที่เกี่ยวข้องกับจำนวนและขนาดของ shard
    • ด้านหนึ่ง ยิ่งมีการจัดวางข้อมูลที่เกี่ยวข้องไว้ใกล้กันมาก การค้นคืนก็ยิ่งมีประสิทธิภาพ
    • แต่อีกด้านหนึ่ง ต้นทุนของงานคำนวณที่ต้องดึงข้อมูลจาก shard มากเกินไป อาจมากกว่าประโยชน์ที่ได้จากการกระจายโหลดไปยังเซิร์ฟเวอร์มากขึ้นก็ได้
  • การจัดการความร้อนอาจจำเป็นแม้ในระบบ single-tenant จึงไม่ใช่ปัญหาเฉพาะของ multi-tenant
    • แต่ในระบบข้อมูลแบบ MT การจัดการความร้อนมีความสำคัญยิ่งขึ้น เพื่อไม่ให้เทนแนนต์เผชิญกับความผันผวนของคุณภาพบริการ

การบรรลุการใช้ทรัพยากรให้สูง

  • หนึ่งในแรงจูงใจหลักของการสร้างสถาปัตยกรรม serverless multi-tenant คือการใช้ทรัพยากรฮาร์ดแวร์พื้นฐานให้มีประสิทธิภาพมากขึ้น เพื่อให้ได้ประสิทธิภาพเชิงเศรษฐศาสตร์ที่ดีกว่า
  • การเพิ่มการใช้ทรัพยากรผ่าน resource pooling เป็นสิ่งสำคัญที่สุด แต่การทำเช่นนั้นพร้อมกับ tenant isolation และประสิทธิภาพที่คาดการณ์ได้ยังเป็นโจทย์ที่ยาก

Cold start

  • ระบบ serverless ที่ลดทรัพยากรต่อเทนแนนต์ลงจนเป็นศูนย์ อาจต้องเผชิญกับปัญหา cold start เมื่อเทนแนนต์กลับมาเริ่ม workload อีกครั้ง
  • cold start เป็นประเด็นสำคัญของ serverless มาตั้งแต่แรก และอาจกระทบกับบางระบบข้อมูลแบบ serverless ได้ด้วย
  • บางระบบไม่มี cold start เลย ขณะที่บางระบบก็หลีกเลี่ยงไม่ได้เนื่องจากสถาปัตยกรรมและการออกแบบผลิตภัณฑ์แบบ scale-to-zero
  • จากทุกกรณีที่เห็น ปัญหา cold start เป็นเรื่องของการตัดสินใจด้านผลิตภัณฑ์ และระดับการลดทรัพยากรอาจต่างกันไปตามแพ็กเกจและวิธีคิดราคา
  • ท้ายที่สุด ลูกค้าและผู้ให้บริการสามารถเลือก trade-off ให้เหมาะกับความต้องการของตนเองได้

ระบบที่สำรวจ

  • Group 1 - Storage APIs (compute-light)
    • Amazon DynamoDB (chapter 1)
    • Kora - Serverless Kafka engine inside Confluent Cloud (chapter 2)
    • Backblaze B2 (planned)
  • Group 2 - SQL OLTP databases (compute-heavy)
    • Neon - serverless PostgreSQL (chapter 3)
    • CockroachDB’s serverless multi-tenant architecture. (in progress)
    • Planetscale (planned)
  • Group 3 - SQL OLAP databases and data warehouses (compute-heavy)
    • Google BigQuery (planned)
    • ClickHouse Cloud (in progress).
  • งานนี้จะดำเนินต่อไป แต่มีแผนจะโพสต์บทสรุปในช่วงเดือนมกราคม/กุมภาพันธ์ 2024

ยังไม่มีความคิดเห็น

ยังไม่มีความคิดเห็น