9 คะแนน โดย GN⁺ 2024-04-22 | 3 ความคิดเห็น | แชร์ทาง WhatsApp
  • SQLite เร็วมาก สามารถรองรับการอ่านพร้อมกันได้ราว ~168,000 ครั้งและการเขียน ~8000 ครั้งอย่างต่อเนื่องบนเซิร์ฟเวอร์ทั่วไปเครื่องเดียวระดับ ~40€/m
  • เนื่องจากเป็นไลบรารีแบบฝังตัวที่ออกแบบมาสำหรับแอปพลิเคชันฝั่งไคลเอนต์ เช่น ระบบฝังตัว โทรศัพท์ และแอปเดสก์ท็อป ฐานข้อมูล SQLite จึงต้องอยู่ร่วมกับแอปพลิเคชันเซิร์ฟเวอร์ และไม่สามารถเข้าถึงผ่านเครือข่ายได้
  • แล้วจะใช้ SQLite อย่างไรในสถานการณ์ที่ต้องมีมากกว่าหนึ่งเครื่อง?
    • โปรเจกต์ทำเล่นช่วงสุดสัปดาห์อาจได้รับความนิยมแบบถล่มทลายจนต้องขยายระบบอย่างรวดเร็ว
    • หนึ่งในข้อกำหนดของ CTO อาจเป็นการต้องดีพลอยบริการที่มีความพร้อมใช้งานสูงไปยังอย่างน้อย 2 ดาต้าเซ็นเตอร์ที่ต่างกัน
  • ในช่วงไม่กี่ปีที่ผ่านมา มีหลายโปรเจกต์ที่พยายามดัดแปลง SQLite ให้เป็นฐานข้อมูลฝั่งแบ็กเอนด์สำหรับแอปพลิเคชันแบ็กเอนด์
  • บทความนี้พยายามหาคำตอบว่านี่คือการเปลี่ยนกระบวนทัศน์ที่ช่วยให้องค์กรส่งมอบประสบการณ์ผู้ใช้ที่ดีกว่าได้เร็วขึ้น หรือเป็นเพียงกระแสการตลาดที่บริษัทต่าง ๆ ผลักดันเพื่อขยาย "จุดขายเฉพาะตัว (Unique Selling Proposition)" ของตน

การใช้ SQLite เป็นฐานข้อมูลที่เอดจ์

  • SQLite กำลังถูกโปรโมตไม่ใช่แค่ในฐานะฐานข้อมูลแบ็กเอนด์ธรรมดา แต่ในฐานะฐานข้อมูลที่เอดจ์
  • ผู้เล่นที่เด่นที่สุดคือ Cloudflare D1, fly.io ที่ใช้ LiteFS และ Turso
  • ผลิตภัณฑ์ต่อยอดจาก SQLite ส่วนใหญ่ทำงานในลักษณะคล้ายกัน
    • มีฐานข้อมูลหลักที่รับการเขียนอยู่ที่ใดที่หนึ่ง แล้วค่อยทำ replication แบบ asynchronous ไปยังภูมิภาคอื่น
    • การทำ replication มักเกิดขึ้นโดยการสตรีมล็อกของทุกทรานแซกชันที่รันบนฐานข้อมูล หรือสตรีม Write-Ahead Log ของ SQLite
    • ในสถาปัตยกรรมแบบนี้ ตามทฤษฎีแล้วการอ่านสามารถให้ศูนย์ข้อมูลเอดจ์จัดการได้ แต่การเขียนยังคงต้องถูกส่งกลับไปยังตำแหน่งศูนย์กลาง
  • ในทางปฏิบัติ ลูกค้าคงไม่อยากเจอสถานการณ์ที่สั่งซื้อสินค้าในแอปอีคอมเมิร์ซสำเร็จแล้ว ฐานข้อมูล SQLite หลักอนุมัติคำสั่งซื้อเรียบร้อย แต่รีพลิกาสำหรับการอ่านในภูมิภาคยังตามไม่ทันและยังไม่ได้รับข้อมูลอัปเดต จนแสดงข้อความว่าไม่พบรายการ
  • ยินดีต้อนรับสู่ "โลกอันเจ็บปวดของ Eventual Consistency"

วิธีแก้และข้อจำกัดของ LiteFS

  • LiteFS เสนอวิธีแก้แบบกึ่งแฮ็ก โดยให้แอปพลิเคชันตั้งค่า __txid cookie เพื่อติดตามทรานแซกชันล่าสุดที่รีพลิกาในภูมิภาคมีอยู่ และถ้ามันล้าหลังเกินไปก็ส่งคำสั่งอ่านไปยังฐานข้อมูลหลัก
  • ตอนนี้แอปพลิเคชันจึงถูกผูกแน่นกับฐานข้อมูลและ reverse proxy
  • LiteFS ไม่ได้พูดถึงข้อเท็จจริงที่ว่ามันรองรับการเขียนได้เพียงประมาณ 100 ครั้งต่อวินาที

ข้อเสียหลักของระบบ SQLite แบบกระจายส่วนใหญ่

  • ระบบ SQLite แบบกระจายส่วนใหญ่ไม่รองรับ interactive transaction ที่มีการคำนวณบางอย่างระหว่างคำสั่ง query ต่าง ๆ ภายในทรานแซกชัน
  • สามารถมี write transaction ที่ active ได้เพียงหนึ่งรายการในเวลาเดียวกัน ในฐานข้อมูล SQLite ปกติ นี่มักไม่ใช่ปัญหาเพราะการเขียนส่วนใหญ่ใช้เวลาไม่เกินหลายสิบไมโครวินาที
  • แต่เมื่อเพิ่ม latency ของเครือข่ายระหว่างแอปพลิเคชันกับฐานข้อมูล SQLite ระบบจะเริ่มพัง ฐานข้อมูลจะถูกล็อกตลอดช่วงเวลา round trip ของทรานแซกชัน และสุดท้ายจะถูกจำกัดเหลือการเขียนเพียงไม่กี่ครั้งต่อวินาที
  • Turso "แก้" ปัญหานี้ด้วย batch โดยสามารถรวมหลาย query เข้าเป็น batch แล้วรันเป็นทรานแซกชันเดียว ส่วน Cloudflare D1 "แก้" ปัญหาด้วย batch และ stored procedure

ถ้ามีวิธีที่ง่ายกว่านี้ล่ะ?

  • สำหรับเว็บแอปพลิเคชัน มีวิธีที่เรียบง่ายและทรงพลังมากซึ่งทำให้ระบบเร็วทั่วโลกได้อยู่แล้ว นั่นคือ HTTP caching ด้วย header Cache-Control และ ETag
  • การใช้ HTTP caching ช่วยหลีกเลี่ยงการต้องใช้เทคนิคคล้ายฐานข้อมูลแบบ weak consistency ซึ่งอาจทำให้เว็บแอปพลิเคชันซับซ้อนเกินไปหรือเสี่ยงต่อ race condition
  • ผู้เขียนบทความนี้ใช้เวลาอย่างมากในหนังสือเล่มใหม่ "Cloudflare for Speed and Security" เพื่ออธิบายกลยุทธ์การแคชหลากหลายแบบที่ไม่เพียงทำให้เว็บแอปเร็วขึ้น แต่ยังรองรับผู้ใช้พร้อมกันจำนวนมากได้ด้วยทรัพยากรน้อยที่สุด

ฐานข้อมูลในฐานะ abstraction

  • Latency ไม่ใช่ปัญหาเดียวที่ distributed SQLite พยายามแก้ อีกปัญหาคือความซับซ้อนด้านการปฏิบัติการ
  • การดูแลคลัสเตอร์ของเซิร์ฟเวอร์ที่เชื่อมต่อกันผ่านเครือข่ายนั้นยาก และมักนำไปสู่ downtime กับการสูญเสียรายได้ ยังไม่รวมถึงการดูแลฐานข้อมูลซึ่งต้องอาศัยการบริหารจัดการอย่างต่อเนื่องและวัฒนธรรมด้านความปลอดภัยที่ดีเพื่อหลีกเลี่ยงหายนะอย่างที่ GitLab เคยเจอในปี 2017
  • ดังนั้นแนวคิดก็คือการ bundle ฐานข้อมูลไปกับแอปพลิเคชันและวางทุกอย่างไว้บนเซิร์ฟเวอร์เครื่องเดียว
  • แนวทางนี้ดีเมื่อมีนักพัฒนาเพียงคนเดียว แต่ในองค์กรขนาดใหญ่ก็มักจะมีคนหรือทีมที่รับผิดชอบการดูแลเซิร์ฟเวอร์ฐานข้อมูลโดยเฉพาะ
  • นี่จึงเป็นเหตุผลที่ฐานข้อมูลซึ่งเข้าถึงผ่าน socket แทนที่จะเป็นไลบรารีแบบฝังตัว จึงเป็น abstraction ที่ยอดเยี่ยม เพราะจริง ๆ แล้วมันไม่ใช่ abstraction ทางเทคนิค แต่เป็น abstraction ทางองค์กร ระหว่างพัฒนา มันอาจเป็นแค่คอนเทนเนอร์ง่าย ๆ ที่รันบนเครื่องนักพัฒนา แต่ใน production มันอาจเป็นอะไรก็ได้ตั้งแต่คอนเทนเนอร์ที่รันบนเซิร์ฟเวอร์เดียวกับแอปพลิเคชัน ไปจนถึงคลัสเตอร์แบบกระจายที่เข้าถึงผ่านเครือข่าย นักพัฒนาเพียงสลับค่าคอนฟิกตัวเดียวคือ DATABASE_URL แล้วทีมปฏิบัติการจะจัดการที่เหลือทั้งหมด
  • ในทางกลับกัน ระบบไฟล์ Unix แบบดั้งเดิมเป็น abstraction ที่ไม่เหมาะกับการประมวลผลแบบกระจาย แน่นอนว่ามี NFS (Network File System) แต่เนื่องจากระบบไฟล์ Unix ถูกออกแบบมาสำหรับการเข้าถึงจากเครื่องเดียว ประสิทธิภาพจึงไม่ดีนัก ตรงกันข้าม โปรโตคอล S3 เป็น abstraction ที่ค่อนข้างดีสำหรับการจัดเก็บข้อมูลไร้โครงสร้างจำนวนมากอย่างมีประสิทธิภาพ ขยายขนาดได้ และเชื่อถือได้ นักพัฒนาเพียงใช้ S3-compatible SDK แล้วก็แทบไม่ต้องคิดอะไรต่อ โดยทีมปฏิบัติการหรือผู้ให้บริการคลาวด์จะดูแลทุกอย่างให้ ไม่ว่าจะเป็นประสิทธิภาพ ความทนทาน หรือความเสถียร

บทสรุป

  • SQLite เป็นฐานข้อมูลที่น่าทึ่งจริง ๆ แต่สำหรับทีมส่วนใหญ่ ควรหลีกเลี่ยง SQLite และเลือก PostgreSQL แทนจะดีกว่า
  • มีชั่วโมงวิศวกรรมจำนวนมหาศาลที่ถูกใช้ไปกับการทำให้ PostgreSQL กลายเป็นฐานข้อมูลแบ็กเอนด์ที่ยอดเยี่ยมที่สุด หากเลือก SQLite คุณก็แทบเลี่ยงไม่ได้ที่จะต้องประดิษฐ์สิ่งที่ PostgreSQL มีมานานแล้วขึ้นใหม่ในแบบที่เปราะบางและเต็มไปด้วยบั๊ก
  • ในตอนนี้ กระแสที่พยายามทำให้ SQLite เป็นฐานข้อมูลแบ็กเอนด์ ดูเป็นเพียงรัฐประหารทางการตลาดของบริษัทที่ขายโครงสร้างพื้นฐาน edge computing ซึ่งตระหนักว่าการประมวลผลนั้นไร้ความหมายหากไม่มี data store คำแนะนำแบบไม่ได้ร้องขอสำหรับพวกเขาคือ แทนที่จะสร้าง CDN แล้วผลักภาระความซับซ้อนไปให้แอปพลิเคชัน ควรลงทุนกับ HTTP caching ซึ่งให้ผลลัพธ์ที่ดีกว่ามาก
  • เพราะความซับซ้อนที่ถูกเหนี่ยวนำขึ้น แอปพลิเคชันแบ็กเอนด์ 99.9% จะไม่ได้ประโยชน์อะไรจากการย้ายไปอยู่ที่เอดจ์ และควรโฟกัสกับการวางกลยุทธ์การแคชที่ดีเพื่อมอบประสบการณ์ระดับยอดเยี่ยมทั่วโลกด้วย latency ต่ำกว่า 100ms มากกว่า
  • และนี่คือจุดสิ้นสุดของการทดลองใช้ SQLite สำหรับแอปพลิเคชันฝั่งเซิร์ฟเวอร์ ชัยชนะเป็นของ PostgreSQL
  • "มือสมัครเล่นคุยเรื่องยุทธวิธี มืออาชีพคุยเรื่องลอจิสติกส์ (Amateurs discuss tactics. Professionals discuss logistics.)"
    ความหมายคือ เพื่อความสำเร็จ สิ่งที่สำคัญกว่าการตัดสินใจเชิงยุทธวิธีในภาคสนาม คือระบบและกระบวนการสนับสนุนที่ทำให้การตัดสินใจเหล่านั้นเกิดขึ้นได้ หรือก็คือลอจิสติกส์และการบริหารจัดการ

ความเห็นของ GN⁺

  • ตามที่ผู้เขียนโต้แย้ง การใช้ SQLite ในแอปพลิเคชันแบ็กเอนด์ส่วนใหญ่ดูจะเพิ่มแต่ความซับซ้อนโดยแทบไม่มีประโยชน์ที่จับต้องได้ การใช้ฐานข้อมูลที่ผ่านการพิสูจน์และสุกงอมแล้วอย่าง PostgreSQL น่าจะเป็นทางเลือกที่ดีกว่า
  • การที่ผู้ให้บริการโครงสร้างพื้นฐาน edge computing ผลักดัน SQLite ดูเหมือนเป็นส่วนหนึ่งของกลยุทธ์การตลาดมากกว่าข้อได้เปรียบทางเทคนิค การที่พวกเขาลงทุนกับ HTTP caching และ CDN มากกว่าน่าจะเป็นประโยชน์ต่อผู้พัฒนาแอปพลิเคชันมากกว่า
  • แอปพลิเคชันแบ็กเอนด์ส่วนใหญ่สามารถให้บริการที่เร็วและขยายขนาดได้เพียงพออยู่แล้วด้วยกลยุทธ์การแคชที่เหมาะสม หากไม่ได้มีความจำเป็นต้องใช้ edge computing จริง ๆ ก็ควรหลีกเลี่ยงความซับซ้อนที่เกินจำเป็น
  • distributed SQLite อาจมีประโยชน์ในบาง use case เฉพาะทาง แต่ยังดูมีข้อจำกัดหากจะใช้เป็นโซลูชันอเนกประสงค์ การตอบโจทย์ทั้งความสะดวกในการพัฒนา ประสิทธิภาพ และความสอดคล้องของข้อมูลไปพร้อมกันนั้นไม่ง่าย
  • ท้ายที่สุด สิ่งที่สำคัญที่สุดคือการเลือกเทคโนโลยีให้เหมาะกับความต้องการของแอปพลิเคชันและศักยภาพของทีม แทนที่จะไหลไปตามกระแส ควรวิเคราะห์ข้อดีข้อเสียอย่างรอบคอบและตัดสินใจอย่างระมัดระวัง
  • ผู้เขียนเน้นย้ำว่า SQLite ยังมีข้อบกพร่องหลายด้านสำหรับการใช้งานเป็นฐานข้อมูลแบ็กเอนด์ แต่ก็ไม่ได้หมายความว่าต้องตัดทิ้งทั้งหมด เพราะอาจยังมี use case อื่นที่สามารถใช้ประโยชน์จากจุดแข็งของ SQLite ได้

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

 
aer0700 2025-03-03

แทนที่จะถามว่าอะไรดีที่สุดระหว่าง Postgres กับ sqlite
ลองคิดดีกว่าไหมว่าในสองตัวนี้ อะไรเหมาะกับสถานการณ์ของเรามากกว่า
เพราะสิ่งที่ดีที่สุดย่อมเปลี่ยนไปตามสถานการณ์

 
[ความคิดเห็นนี้ถูกซ่อน]
 
GN⁺ 2024-04-22

ความคิดเห็นจาก Hacker News

  • ตามผู้เขียน LiteFS ระบุว่า Distributed SQLite สำหรับนักพัฒนาอาจมองได้ว่าเป็นการต่อยอดหรือ "ก้าวถัดไป" มากกว่าจะเป็นการเปลี่ยนกระบวนทัศน์หรือกระแสโฆษณาเกินจริง
    • ช่วยแก้ข้อกังวลเรื่องการขยายระบบในแนวนอนของ SQLite
  • การเปลี่ยนกระบวนทัศน์ที่คาดว่าจะเกิดขึ้นผ่าน Distributed SQLite น่าจะมุ่งไปที่อุปกรณ์ของผู้ใช้
    • ทำให้เกิดแอปแบบ local-first ที่มีการโต้ตอบ UI รวดเร็วและมีความสอดคล้องในท้ายที่สุดผ่านการซิงก์
  • การใช้ LiteFS ในสภาพแวดล้อม production สามารถตอบคำถามฐานข้อมูลได้ทันที ทำให้ตัดสถานะการโหลดในเว็บแอปออกไปและช่วยให้โหลดได้รวดเร็ว
  • มีความต้องการโซลูชันสตอเรจแบบโอเพนซอร์สที่เรียบง่ายและกระจายศูนย์สำหรับการโฮสต์เอง
    • โซลูชันที่มีอยู่ เช่น Ceph, SeaweedFS, MinIO ต่างก็มีความท้าทายและความซับซ้อน
  • แนวคิดของ LiteFS คือการใช้ประโยชน์จากข้อได้เปรียบด้านประสิทธิภาพของ SQLite โดยแทนที่สถาปัตยกรรมเครือข่ายแบบ n-tier สำหรับแอปพลิเคชันที่เน้นการอ่าน
    • แต่อาจไม่ได้เหมาะอย่างสมบูรณ์แบบกับทุกแอปพลิเคชัน
  • ข้ออ้างในบทความที่ว่า การใช้ SQLite จะ "ประหยัดได้แค่ไม่กี่มิลลิวินาที" ถูกมองว่าเป็นการประเมินต่ำเกินไป
    • การรันแอปพลิเคชันให้ใกล้ผู้ใช้มากขึ้นสามารถลดเวลาแฝงของคิวรีได้อย่างมาก
  • SQLite และ PostgreSQL มีกรณีการใช้งานและจุดเด่นที่ต่างกัน
    • ไม่ได้เป็นการแข่งขันกันโดยตรง
  • มีการตั้งคำถามต่อข้ออ้างในบทความที่ว่า PostgreSQL คือฐานข้อมูลแบ็กเอนด์ที่ดีที่สุด และการใช้ SQLite จะทำให้ต้องสร้างฟีเจอร์ขึ้นมาใหม่ในแบบที่เปราะบาง
    • ข้ออ้างลักษณะเดียวกันนี้ก็สามารถใช้กับฐานข้อมูลอื่นได้เช่นกัน
  • การแบ่ง SQLite โดยสร้างฐานข้อมูลแยกตามผู้ใช้เป็นแนวทางหนึ่งที่มีความเป็นไปได้
    • แต่ต้องเป็นกรณีที่ผู้ใช้ไม่จำเป็นต้องโต้ตอบกับข้อมูลของกันและกัน