- Quack มอบการสื่อสารระหว่างอินสแตนซ์ของ DuckDB ทำให้สามารถจัดวางแบบไคลเอนต์-เซิร์ฟเวอร์และให้ผู้เขียนหลายคนใช้งานฐานข้อมูลเดียวกันได้พร้อมกัน
- DuckDB ยังคงรักษา สถาปัตยกรรมแบบ in-process ไว้ โดยจัดการการซิงก์สถานะที่จำเป็นเมื่อหลายโปรเซสแก้ไขไฟล์เดียวกันผ่านโปรโตคอลระยะไกล
- Quack เป็นโปรโตคอลแบบ request-response บนพื้นฐานของ HTTP ใช้การซีเรียลไลซ์
application/duckdb และการยืนยันตัวตนด้วยโทเค็น โดยใช้พอร์ตเริ่มต้น 9494
- ในการทดสอบประสิทธิภาพ Quack ส่งข้อมูล 60 ล้านแถว ได้ภายใน 4.94 วินาที และในการทดสอบ append ขนาดเล็กก็ทำได้ราว 5,434 tx/s ที่ 8 เธรด
- Quack มีแผนสำหรับการรวมเข้ากับ DuckLake, Catalog server ระยะไกล, การติดตั้งและโหลดอัตโนมัติ, การขยายโปรโตคอล และโปรโตคอลการจำลองข้อมูล โดยตั้งเป้าออกเวอร์ชัน production ในช่วง DuckDB v2.0
จุดประสงค์และที่มาของ Quack
- Quack เป็นโปรโตคอลระยะไกลที่ทำให้อินสแตนซ์ของ DuckDB สื่อสารกันได้ ช่วยให้ DuckDB ทำงานในรูปแบบไคลเอนต์-เซิร์ฟเวอร์ และเปิดให้ผู้เขียนหลายคนใช้งานฐานข้อมูลเดียวกันได้พร้อมกัน
- ตั้งแต่ปี 2019 DuckDB เน้นย้ำ สถาปัตยกรรมแบบ in-process มาโดยตลอด โดยแนวทางที่ทำงานผ่านการเรียก API ระดับต่ำโดยไม่ต้องมีเซิร์ฟเวอร์หรือโปรโตคอลแยกต่างหากนั้นเหมาะมากกับงาน data science แบบโต้ตอบ เช่น Python notebook และการเพิ่มความสามารถ SQL ภายในแอปพลิเคชัน
- หากต้องการให้หลายโปรเซสแก้ไขไฟล์ฐานข้อมูล DuckDB เดียวกันพร้อมกัน ก็จำเป็นต้องซิงก์สถานะจำนวนมากที่ DuckDB เก็บไว้ในหน่วยความจำหลักระหว่างโปรเซส
- ก่อนหน้านี้มีแนวทางอ้อม เช่น โปรเซส RPC แยกต่างหาก, โปรเจ็กต์ที่ใช้ Arrow Flight SQL protocol, โปรโตคอลเฉพาะของ MotherDuck, หรือการจับคู่ PostgreSQL กับ pg_duckdb ในแบบ “EleDucken”
- หากต้องการขยาย DuckDB ให้เป็น เครื่องมือประมวลผลข้อมูลอเนกประสงค์ โปรโตคอลไคลเอนต์-เซิร์ฟเวอร์ก็สามารถเปิดกรณีการใช้งานใหม่ ๆ เพิ่มเติมจากความสามารถแบบ in-process ได้
วิธีใช้งาน Quack
- ใน Quack อินสแตนซ์ของ DuckDB ตั้งแต่สองตัวขึ้นไปจะสื่อสารกัน โดย DuckDB ทำหน้าที่ได้ทั้ง ไคลเอนต์และเซิร์ฟเวอร์
- อินสแตนซ์ทั้งสองอาจอยู่คนละเครื่อง อยู่คนละสถานที่ หรือแม้แต่อยู่คนละหน้าต่างเทอร์มินัลบนโน้ตบุ๊กเครื่องเดียวกันก็ได้
- ส่วนขยาย Quack อยู่ในรีโพซิทอรี
core_nightly ในตอนนี้ และใช้งานได้กับเวอร์ชันที่ปล่อยอยู่ในปัจจุบันคือ DuckDB v1.5.2
- ฝั่งเซิร์ฟเวอร์ของ DuckDB ต้องติดตั้งและโหลด Quack ก่อน แล้วจึงเรียก
quack_serve โดยในตัวอย่างใช้ quack:localhost และ token = 'super_secret'
INSTALL quack FROM core_nightly;
LOAD quack;
CALL quack_serve(
'quack:localhost',
token = 'super_secret'
);
CREATE TABLE hello AS
FROM VALUES ('world') v(s);
- ฝั่งไคลเอนต์ของ DuckDB ก็ต้องติดตั้งและโหลด Quack เช่นกัน จากนั้นตั้งค่าโทเค็นด้วย
CREATE SECRET แล้วเชื่อมต่ออินสแตนซ์ระยะไกลด้วย ATTACH 'quack:localhost' AS remote;
INSTALL quack FROM core_nightly;
LOAD quack;
CREATE SECRET (
TYPE quack,
TOKEN 'super_secret'
);
ATTACH 'quack:localhost' AS remote;
FROM remote.hello;
- ด้วยการตั้งค่านี้ DuckDB #2 จะสามารถอ่านค่า
world จากตารางระยะไกล hello ได้
- นอกจากนี้ยังสามารถคัดลอกข้อมูลจากอินสแตนซ์ภายในเครื่องไปยังอินสแตนซ์ระยะไกลได้ โดยในตัวอย่าง DuckDB #2 สร้างตาราง
remote.hello2 และ DuckDB #1 ตรวจสอบได้ด้วย FROM hello2;
- สำหรับคิวรีที่ซับซ้อนหรือชุดข้อมูลขนาดใหญ่ สามารถควบคุมได้ชัดเจนขึ้นว่างานใดถูกรันบนฝั่งระยะไกลด้วยฟังก์ชัน
query ที่ส่งคิวรีไปทั้งก้อนไปยังปลายทาง
FROM remote.query(
'SELECT s FROM hello'
);
การออกแบบโปรโตคอล
-
บนพื้นฐานของ HTTP
- Quack ถูกสร้างขึ้นบน HTTP โดยตรง และ HTTP ก็กลายเป็นชั้นโปรโตคอลมาตรฐานโดยพฤตินัยเหนือ TCP และชั้นที่ต่ำกว่านั้นไปแล้ว
- สแตก HTTP ถูกปรับแต่งให้มีประสิทธิภาพสำหรับการส่งสตรีมข้อความ และหากติดตั้งใช้อย่างเหมาะสมก็มี overhead ต่ำ
- วิธีจัดการ HTTP เป็นที่รู้จักอย่างกว้างขวางในเรื่องอย่าง load balancing, authentication, firewall และ intrusion detection
- การใช้ HTTP ยังทำให้ DuckDB-Wasm distribution ใช้ Quack ได้แบบ native
- DuckDB ที่รันในเบราว์เซอร์จึงสามารถเชื่อมต่อไปยังอินสแตนซ์ DuckDB ที่รันอยู่บนเซิร์ฟเวอร์ EC2 ได้โดยตรงผ่าน Quack
-
รูปแบบ request-response
- การโต้ตอบของ Quack ทำงานในรูปแบบ request-response ที่ขับเคลื่อนโดยไคลเอนต์เสมอ
- ข้อความต่าง ๆ ครอบคลุมตั้งแต่คำขอเชื่อมต่อเพื่อยืนยันตัวตนด้วยโทเค็น, คำขอรันคิวรี, การส่งคืนส่วนแรกของผลลัพธ์, ไปจนถึงข้อความ fetch เพิ่มเติมสำหรับดึงผลลัพธ์ขนาดใหญ่
- ผลลัพธ์ขนาดใหญ่สามารถดึงแบบขนานจากหลายเธรดได้
-
การซีเรียลไลซ์
- คำขอและคำตอบถูกเข้ารหัสด้วย MIME type ใหม่คือ
application/duckdb
- การเข้ารหัสนี้ใช้ primitive การซีเรียลไลซ์ภายในของ DuckDB สำหรับโครงสร้างที่ซับซ้อน เช่น data type และ result set
- primitive ชุดเดียวกันนี้ถูกใช้ในไฟล์ WAL ของ DuckDB มาหลายปีแล้ว และผ่านการปรับแต่งกับตรวจสอบมาอย่างมาก
-
การเข้ารหัสและวิธีเปิดใช้งาน
- เมื่อเริ่มเซิร์ฟเวอร์ Quack จะสร้าง โทเค็นยืนยันตัวตนแบบสุ่ม โดยอัตโนมัติ และไคลเอนต์ต้องส่งโทเค็นนี้มา
- โดยค่าเริ่มต้น Quack server จะ bind เฉพาะกับ
localhost เท่านั้น และสามารถ override พฤติกรรมนี้ได้
- โดยค่าเริ่มต้นจะไม่ใช้ SSL เพราะมองว่าการเพิ่มโครงสร้างพื้นฐานและ dependency เหล่านั้นเพื่อการสื่อสารบน
localhost เพียงอย่างเดียวไม่เหมาะสม
- ไม่แนะนำให้เปิด endpoint ของ DuckDB Quack ตรงสู่สาธารณะอินเทอร์เน็ต
- หากจำเป็นต้องเปิด Quack สู่เว็บ แนะนำอย่างยิ่งให้ใช้ endpoint HTTP ทั่วไปอย่าง nginx และให้พร็อกซีดังกล่าว terminate SSL ด้วย Let’s Encrypt หรือโซลูชันลักษณะเดียวกัน
- ไคลเอนต์ Quack จะถือว่าเปิดใช้ SSL สำหรับการเชื่อมต่อที่ไม่ใช่แบบ local อยู่แล้ว และสามารถ override พฤติกรรมนี้ได้
- การตั้งค่าที่เกี่ยวข้องอยู่ใน เอกสาร reverse proxy
-
การลดจำนวนรอบการสื่อสาร
- Quack ถูกออกแบบมาเพื่อลดจำนวน protocol round trip ที่ต้องใช้ต่อคิวรี
- หลังเชื่อมต่อแล้ว คิวรีหนึ่งรายการสามารถประมวลผลได้ในรอบเดียว ซึ่งเหมาะกับสภาพแวดล้อมที่ไวต่อ latency
- การส่งผลลัพธ์ขนาดใหญ่ก็ได้รับการปรับแต่งเช่นกัน และทีม DuckDB มองว่า Quack เป็นวิธีส่งตารางผ่าน socket ที่เร็วที่สุดในตอนนี้
- ผลการทดสอบแสดงให้เห็นว่าสามารถส่งข้อมูลหลายล้านแถวได้ภายในไม่กี่วินาที
-
การยืนยันตัวตนและการกำหนดสิทธิ์
- Quack ออกแบบโมเดล authentication และ authorization ให้สอดคล้องกับแนวคิดเรื่องความ extensible ของ DuckDB
- มีทั้งวิธีการยืนยันตัวตนเริ่มต้นและการกำหนดสิทธิ์เริ่มต้นแบบไม่จำกัด แต่ทั้งสองอย่างสามารถเปลี่ยนเป็นโค้ดที่ผู้ใช้จัดเตรียมเองได้
- เมื่อเซิร์ฟเวอร์เริ่มทำงาน จะสร้างโทเค็นยืนยันตัวตนแบบสุ่ม และไคลเอนต์ต้องส่งสตริงยืนยันตัวตนมาเมื่อเชื่อมต่อ
- เซิร์ฟเวอร์จะเรียก authentication callback โดย callback เริ่มต้นจะเปรียบเทียบโทเค็นที่ไคลเอนต์ส่งมากับโทเค็นที่เซิร์ฟเวอร์สร้างไว้
- สามารถเปลี่ยน authentication callback ผ่านการตั้งค่าได้ จึงรองรับทั้งการตรวจ LDAP directory, การอ่านไฟล์ข้อความ หรือ logic แบบกำหนดเองอื่น ๆ
- ฟังก์ชัน authorization ก็เปลี่ยนได้เช่นกัน โดยฟังก์ชันเริ่มต้นจะอนุญาตทุกคำขอ
- ฟังก์ชัน authorization ที่ผู้ใช้กำหนดเองสามารถตรวจสอบแต่ละคิวรีที่ไคลเอนต์ต้องการรัน และตัดสินใจโดยอ้างอิงกับสตริงยืนยันตัวตนที่ใช้ก่อนหน้านั้นได้
- callback เหล่านี้สามารถเขียนเป็น SQL macro ปกติได้เช่นกัน
-
พอร์ตเริ่มต้น
- โดยค่าเริ่มต้น Quack server จะรอฟังที่ พอร์ต
9494
- เลข
94 สะท้อนปี 1994 ซึ่งเป็นปีที่ Netscape Navigator เปิดตัว เพื่อให้จดจำได้ง่าย
การทดสอบประสิทธิภาพ
- การทดสอบทำบน AWS virtual machine ที่รัน Ubuntu on Arm
- ประเภทอินสแตนซ์คือ m8g.2xlarge ซึ่งมี 8 vCPU, RAM 32GB และแบนด์วิดท์เครือข่าย “สูงสุด 15Gbps”
- การทดสอบจำลองสถานการณ์จริงที่ไคลเอนต์กับเซิร์ฟเวอร์อยู่คนละเครื่อง แต่ยังอยู่ในดาต้าเซ็นเตอร์เดียวกัน
- ทั้งสองอินสแตนซ์ถูกวางไว้ใน availability zone เดียวกัน และมีค่า ping เฉลี่ยราว 0.280ms
-
การส่งข้อมูลปริมาณมาก
- เบนช์มาร์กแรกวัดงาน bulk transfer สำหรับการส่งหลายแถวผ่านโปรโตคอลฐานข้อมูล
- ตัวที่นำมาเปรียบเทียบคือ Quack, PostgreSQL protocol และ Arrow Flight SQL protocol
- Arrow Flight ถูกให้บริการผ่านเซิร์ฟเวอร์ GizmoSQL ที่ใช้ DuckDB ภายใน
- มีการเพิ่มจำนวนแถวจากตาราง TPC-H
lineitem ทีละระดับและวัดไปจนถึง 60 ล้านแถว
- 60 ล้านแถวคิดเป็นข้อมูลรูปแบบ CSV ขนาด 76GB
- แต่ละผลลัพธ์รายงานเป็นค่า median wall-clock time จากการรัน 5 ครั้ง
- ผลลัพธ์หลักมีดังนี้
- 100k แถว: DuckDB Quack
0.07 s, Arrow Flight 0.07 s, PostgreSQL 0.20 s
- 1M แถว: DuckDB Quack
0.24 s, Arrow Flight 0.38 s, PostgreSQL 2.20 s
- 10M แถว: DuckDB Quack
0.89 s, Arrow Flight 2.90 s, PostgreSQL 25.64 s
- 60M แถว: DuckDB Quack
4.94 s, Arrow Flight 17.40 s, PostgreSQL 158.37 s
- Quack ส่ง 60 ล้านแถวได้ในเวลา ต่ำกว่า 5 วินาที แสดงให้เห็นถึงประสิทธิภาพสูงในการส่ง result set ขนาดใหญ่
- แม้ Arrow Flight SQL จะถูกออกแบบมาเฉพาะทาง แต่ในผลลัพธ์นี้ก็ยังตาม Quack ไม่ทัน ขณะที่โปรโตคอลแบบ row-based ของ PostgreSQL เสียเปรียบโดยรวม
- ไคลเอนต์ PostgreSQL มาตรฐานไม่ได้อ่านแบบขนานหลายเธรด แต่ Quack และ Arrow สามารถทำเช่นนั้นได้
- PostgreSQL client ของ DuckDB เองก็อ่านแบบขนานได้ในบางกรณี
-
งานเขียนขนาดเล็ก
- เบนช์มาร์กที่สองวัดงาน append ขนาดเล็ก
- นี่สอดคล้องกับสถานการณ์ที่มีการรวมงานเขียนขนาดเล็กไว้ที่ศูนย์กลาง เช่น การรวบรวมข้อมูล observability ไปยังอินสแตนซ์ DuckDB ส่วนกลาง
- เป็นการทดสอบที่ไม่เป็นประโยชน์ต่อโปรโตคอลที่ต้องใช้การสื่อสารไคลเอนต์-เซิร์ฟเวอร์หลายรอบเพื่อปิดธุรกรรมเดี่ยว
- มีการสร้างตารางว่างที่มีโครงสร้างเหมือน TPC-H
lineitem แล้วแทรกค่าที่สุ่มขึ้นมาทีละหนึ่งแถว โดยแต่ละแถวอยู่ในธุรกรรม INSERT แยกกัน
- ทดสอบเป็นเวลา 5 วินาทีโดยเพิ่มจำนวนเธรดแบบขนาน และทำซ้ำ 5 ครั้งก่อนรายงานค่ามัธยฐานของจำนวนธุรกรรมต่อวินาที
- ผลลัพธ์หลักมีดังนี้
- 1 เธรด: DuckDB Quack
1,038 tx/s, Arrow Flight 469 tx/s, PostgreSQL 839 tx/s
- 2 เธรด: DuckDB Quack
1,956 tx/s, Arrow Flight 799 tx/s, PostgreSQL 1,094 tx/s
- 4 เธรด: DuckDB Quack
3,504 tx/s, Arrow Flight 1,224 tx/s, PostgreSQL 2,180 tx/s
- 8 เธรด: DuckDB Quack
5,434 tx/s, Arrow Flight 1,358 tx/s, PostgreSQL 4,320 tx/s
- Quack ทำได้ดีกว่า PostgreSQL จนถึง 8 เธรดแบบขนาน และแสดง throughput สูงสุดราว 5,500 tx/s
- หากมากกว่านั้นจะเริ่มชนข้อจำกัดปัจจุบันของ DuckDB เองในด้านจำนวนการแทรกพร้อมกันต่อวินาทีบนตารางเดียวกัน
- PostgreSQL ขยายตัวได้ดีกว่าในช่วงนี้ และทีม DuckDB มองว่าเป็นจุดที่ควรตรวจสอบต่อในอนาคตอันใกล้
- Arrow Flight ทำผลงานได้ไม่ดีตามคาด อยู่ที่ประมาณครึ่งหนึ่งของ PostgreSQL
- มีการเปิดเผย สคริปต์เบนช์มาร์ก ให้ใช้งานแล้ว
กรณีการใช้งานและความหมายต่อ DuckDB
- Quack เปิดทางสู่การใช้งาน DuckDB แบบ multiplayer ที่หลายโปรเซสสามารถแก้ไขเนื้อหาของตารางเดียวกันได้แบบขนาน ทั้งในเครื่องและระยะไกล
- ความสามารถบางส่วนเคยทำได้ผ่าน DuckLake แต่ Quack ทำให้สิ่งนี้ง่ายขึ้นและให้ประสิทธิภาพสูงกว่ามาก
- สิ่งนี้ขยายขอบเขตการใช้งานของ DuckDB ในกรณีที่สถานะส่วนกลางสำคัญกว่าการคิวรีแบบ local ที่ใกล้มากเป็นพิเศษ
- การเติบโตของ data lake แสดงให้เห็นแล้วว่าข้อมูลไม่ได้อยู่ในเครื่องเสมอไป และ Quack ก็สอดคล้องกับทิศทางดังกล่าว
- Quack จะถูกรวมเข้ากับ DuckLake และเปิดให้ DuckDB เองทำหน้าที่เป็น Catalog server ที่เข้าถึงจากระยะไกลได้
- การรวมกันนี้อาจเปิดความสามารถใหม่ ๆ เช่น data inlining
- คำถามเพิ่มเติมดูได้ใน Quack FAQ
- DuckDB กำลังขยับออกจากตลาดเฉพาะเดิมในฐานะฐานข้อมูลแบบ in-process สำหรับงานวิเคราะห์เชิงโต้ตอบ ไปสู่การเป็นองค์ประกอบแกนกลางของสถาปัตยกรรมข้อมูลสมัยใหม่มากขึ้น
เหตุผลที่ไม่ใช้ Arrow Flight SQL
- โปรเจ็กต์ที่เกี่ยวข้องอย่าง Arrow และ ADBC มีคุณค่าในฐานะ exchange API ที่ช่วยลดแรงเสียดทานของการแลกเปลี่ยนข้อมูลระหว่างระบบ คล้ายกับ ODBC และ JDBC
- อย่างไรก็ตาม DuckDB ระมัดระวังในการใช้ฟอร์แมตแลกเปลี่ยนอย่าง Arrow ภายในตัวระบบ
- โครงสร้างภายในของผลลัพธ์คั่นกลางจากคิวรีของ DuckDB มีส่วนที่คล้าย Arrow แต่ในอีกหลายส่วนก็แตกต่างกันมาก
- DuckDB มองว่าหากต้องการเดินหน้าสร้างนวัตกรรมด้านระบบข้อมูลต่อไป ก็ไม่ควรถูกจำกัดด้วยฟอร์แมตที่ถูกควบคุมจากภายนอก จึงเลือกใช้การซีเรียลไลซ์ของตนเองใน Quack
- การใช้การซีเรียลไลซ์ของตัวเองยังทำให้สามารถปล่อย data type ใหม่หรือข้อความโปรโตคอลใหม่ได้ทันทีเมื่อจำเป็น
- ใน Arrow Flight SQL คิวรีทุกตัวมีการออกแบบให้ต้องใช้ protocol round trip อย่างน้อยสองครั้ง คือ
CommandStatementQuery และ DoGet
- แนวทางนี้ไม่เหมาะกับงานอัปเดตขนาดเล็ก โดยเฉพาะในสภาพแวดล้อมที่มี latency สูงกว่า
- Quack จึงถูกออกแบบให้คิวรีขนาดเล็กสามารถทั้งรันคิวรีและ fetch ผลลัพธ์ได้ภายในรอบเดียว
แผนในอนาคต
- Quack จะถูกรวมเข้ากับ DuckLake เพื่อให้สามารถใช้เซิร์ฟเวอร์ DuckDB ระยะไกลเป็น DuckLake catalog ได้
- การรวมกันนี้คาดว่าจะช่วยเพิ่มประสิทธิภาพได้มาก โดยเฉพาะในเรื่อง inlining
- ในช่วงไม่กี่เดือนข้างหน้า มีแผนจะปรับแต่ง Quack และออก production release แรกพร้อม DuckDB v2.0 ที่มีกำหนดในฤดูใบไม้ร่วงปีนี้
- มีแผนให้ส่วนขยาย Quack รองรับ การติดตั้งอัตโนมัติและการโหลดอัตโนมัติ เมื่อจำเป็น
- มีแผนปรับปรุงไวยากรณ์สำหรับการสื่อสารกับฐานข้อมูล SQL ระยะไกลจาก DuckDB โดยใช้ parser ใหม่
- ในฝั่ง DuckDB core มีแผนเพิ่มจำนวนธุรกรรมต่อวินาทีอย่างมาก เพื่อให้สเกลธุรกรรมเกินกว่า 8 เธรดแบบขนานได้อีกมาก
- นอกเหนือจาก authentication และ authorization ยังมีการพิจารณาเปิดให้ การขยายโปรโตคอล Quack รองรับการที่ส่วนขยายของ DuckDB เพิ่มข้อความโปรโตคอลและโค้ดจัดการใหม่ได้
- ยังมีการพิจารณาเพิ่มโปรโตคอล replication บน Quack เพื่อจำลองการเปลี่ยนแปลงของอินสแตนซ์ DuckDB ไปยังเซิร์ฟเวอร์อื่น และสร้างคลัสเตอร์ read replica
- Quack และการเปิดตัวระยะแรกจะถูกพูดถึงในงานประชุมชุมชน DuckCon #7 วันที่ 24 มิถุนายนด้วย
- นอกจากนี้ยังมีหน้า Quack project แยกต่างหาก
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
สัปดาห์ที่แล้วเพิ่งคิดเลยว่าอยากได้อะไรแบบนี้ จังหวะมาพอดีมาก
ผมกำลังสตรีมค่าจากเซนเซอร์เข้า DuckDB ผ่านเซิร์ฟเวอร์ Deno แต่ถ้าไม่ปิดเซิร์ฟเวอร์ก็ไม่สามารถใช้
duckdb -uiเพื่อตรวจดูข้อมูลได้ไม่อยากเพิ่มฟีเจอร์เข้าไปในเซิร์ฟเวอร์แค่เพื่อดูเนื้อหาใน DB ก็เลยกะว่าจะทนใช้แบบนั้นไปก่อน แต่สิ่งนี้แก้ปัญหานั้นรวมถึงปัญหาคล้าย ๆ กันที่เคยเจอกับ DuckDB ได้อย่างเรียบร้อย
DuckDB คือเทคโนโลยีที่ชอบที่สุดในปี 2025/26 และมันเข้าไปอยู่ลึกมากในหลายเวิร์กโฟลว์ ทั้งงาน LLM, การเก็บข้อมูล, การวิเคราะห์, data pipeline ฯลฯ
สนใจมาก แต่ยังแทรก DuckDB เข้าไปในวิธีแก้ปัญหาของตัวเองแบบเป็นธรรมชาติไม่ได้ เลยยังไม่ค่อยเห็นว่าจะแมปกับ use case แบบไหนได้บ้าง
เจ๋งมาก ผมกำลังดูอยู่ว่าจะใช้ DuckDB กับเฟรมเวิร์กแอปภายในบริษัทดีไหม แล้วนี่ก็ช่วยตอบโจทย์ปัญหา "แล้วจะ scale แนวนอนยังไง" ได้พอดี
ขอปรบมือให้ทีม DuckDB และก็ชอบที่ตั้งชื่อโปรโตคอลว่า Quack ด้วย
ผมกำลังทำโอเพนซอร์สโปรเจกต์ที่เก็บและ query ข้อมูล observability คือ metrics, logs, traces ลงใน Parquet และถึงจะเห็นด้วยมากกับแนวคิดเรื่อง open storage format และ catalog แต่ก็อึดอัดกับ usability ของ Apache Iceberg อยู่
พอเห็นอันนี้แล้ว DuckLake ดูน่าสนใจกับ use case ของผมมากขึ้นเยอะ และตื่นเต้นว่าจะไปต่อทางไหน
https://github.com/smithclay/duckdb-otlp
ผมชอบ DuckDB แต่ไม่ค่อยแน่ใจว่ามันอยากเป็นอะไรกันแน่
วิธีใช้งานใหม่ ๆ โผล่มาเรื่อย ๆ จนมองทีเดียวแล้วไม่ค่อยง่ายว่าจะควรใช้แบบไหน
ความพยายามครั้งนี้ค่อนข้างสอดคล้องดี และในแง่หนึ่งก็เป็นการพากลับไปสู่โมเดลการใช้งานที่คุ้นเคยของฐานข้อมูลเชิงสัมพันธ์แบบ client-server ดั้งเดิม
เดิมที relational DBMS ก็คือระบบที่รองรับหลายผู้ใช้พร้อมกันอยู่แล้ว และ DuckDB ก็เป็น local engine ที่เร็วมากซึ่งฝังเข้าไปในระบบอื่นได้ จึงมี use case หลากหลาย
มันคล้ายกับการถามว่า SQLite อยากเป็นอะไร โทรศัพท์, เบราว์เซอร์, แอปเดสก์ท็อป, อุปกรณ์ IoT ต่างก็มีมันอยู่ข้างใน และผู้คนก็ขยายมันไปหลายทิศทาง ความต่างคือกรณีนี้ไม่ใช่ third-party แต่เป็น first-party ซึ่งสำหรับผมเป็นการขยับที่เข้าใจง่ายมาก
แอปจะคอยดู asset บน S3 แล้วถ้า etag เปลี่ยนก็จะดึงมา
มันทำให้เข้าถึงประสิทธิภาพระดับ BigQuery หรือ ClickHouse ได้ง่าย โดยไม่ต้องมารันโครงสร้างพื้นฐานพวกนั้นเองหรือจ่ายค่าใช้จ่ายแบบนั้น
อาจไม่ได้เหมาะกับทุกกรณี แต่รองรับอะไรได้มากกว่าที่คาดไว้เยอะ
ตอนนี้ตัวเอนจินเองไม่ใช่จุดที่เจ็บปวดเสมอไปแล้ว แต่สิ่งรอบข้างต่างหากที่เป็นปัญหา ไม่ว่าจะเป็น live DB, S3 path, ไฟล์ Parquet, credentials, การรันซ้ำได้แบบกำหนดได้, การ export, การตรวจสอบความถูกต้อง, และช่วงเวลาที่สคริปต์ใช้ครั้งเดียวค่อย ๆ กลายเป็นโครงสร้างพื้นฐานโดยไม่รู้ตัว
Quack ทำให้ส่วน remote/server สะอาดขึ้น แต่ภาพใหญ่กว่านั้นดูเหมือน DuckDB กำลังกลายเป็นชั้น SQL ภายในเครื่องมือ มากกว่าจะเป็นเครื่องมือปลายทางสำหรับผู้ใช้โดยตรง
เขาไม่ได้อธิบายว่า "ผู้เขียนพร้อมกัน" หมายถึงอะไร
เท่าที่ดูเหมือนแค่ว่า ทำให้การเขียนถูก serialize ฝั่งเซิร์ฟเวอร์
ไม่เห็นเหตุผลว่าฟีเจอร์นี้จะจู่ ๆ มาทำให้ทุกการเขียนต้อง serialize
ดูมีประโยชน์สำหรับชุดข้อมูลวิเคราะห์ภายในขนาดเล็กที่อยากวางไว้บนเซิร์ฟเวอร์ทีมที่แชร์กันใช้
สำหรับ homelab ก็น่าลองดูได้สบาย ๆ
ข้อดีใหญ่ของโปรโตคอลเซิร์ฟเวอร์นี้คือสามารถแชร์เซิร์ฟเวอร์ที่มีหน่วยความจำมาก และใช้ shared cache สำหรับข้อมูลล่าสุดได้
ผมมีแอปพลิเคชัน C++ ซึ่งระหว่างรันทุกอย่างอยู่ในหน่วยความจำ
ระหว่างเซสชันจะบันทึกลงดิสก์เป็น XML และมันก็ทำงานได้ดี แต่โดยเคร่งครัดแล้วออกแบบมาสำหรับผู้ใช้คนเดียว และลูกค้าบางรายอยากให้ขยายไปเป็นแบบที่หลายคนอ่านและเขียนพร้อมกันได้
ความต้องการด้านประสิทธิภาพไม่สูง แค่ประมาณ 2-3 คนอัปเดตรายการหลักพันพร้อมกัน แบบนี้ DuckDB + Quack จะเป็นตัวเลือกที่ดีไหม หรือมีตัวเลือกอื่นที่ดีกว่า? ผมดู SQLite ไว้เหมือนกัน แต่เข้าใจว่ามันไม่ได้ทำงานแบบ client-server
ถ้าจะใช้ฐานข้อมูลที่รองรับผู้ใช้พร้อมกันได้ โดยไม่โฮสต์ DB ฝั่งเซิร์ฟเวอร์ในรูปแบบใดรูปแบบหนึ่ง ก็ดูยากที่จะมีตัวเลือกที่เหมาะ
แน่นอนว่าในทางเทคนิคก็ทำได้ เหมือนบางเกมที่สร้าง client server สำหรับ multiplayer ขึ้นมาเอง แต่พูดตรง ๆ คือการโฮสต์ Postgres หรือ SQLite นั้นถูกและง่ายแบบเหลือเชื่อ และที่สำคัญคือเป็นแนวทางมาตรฐานสำหรับปัญหานี้
ยอดเยี่ยมมาก ผมกำลังใช้ DuckDB ทำ แอปสเปรดชีตแบบคอลัมน์คล้าย Excel อยู่ แต่ต้องสร้าง "client" ขึ้นมาใหม่ผ่านชั้น HTTP แบบดั้งเดิม
คำถามว่า "DuckDB อยากเป็นอะไร" โผล่มาเรื่อย ๆ แต่ผมว่าคำตอบชัดอยู่แล้ว
มันอยากเป็น SQLite สำหรับงานวิเคราะห์ ฝังได้ ไม่ต้องตั้งค่า และรันได้ทุกที่
Quack ก็เป็นแค่ส่วนที่ทำให้คำว่า "ทุกที่" รวมถึงระยะไกลเข้าไปด้วย
มีคำถามว่า "สามารถใช้ DuckDB กับ Quack เป็นฐานข้อมูล catalog ของ DuckLake ได้ไหม?" ซึ่งคำตอบคือ "ยังไม่ได้ แต่กำลังทำอยู่!"
มันอาจดูเป็น use case เฉพาะทาง แต่กลับเป็นส่วนที่ผมสนใจที่สุด
lakehouse ของเราใช้ DuckLake และใช้ Postgres เป็น catalog อยู่ แต่ DuckDB / Quack catalog ดูเหมือนจะเป็นทางเลือกที่ยอดเยี่ยม
มีหลายเหตุผล อย่างแรกคือไม่มีปัญหา type mismatch ในการประมวลผลแบบ inline ถ้าใช้ catalog ที่ไม่ใช่ DuckDB จะมีหลาย type ที่แมปกันแบบ 1:1 ไม่ได้ ทำให้มี overhead เพิ่มตอนจัดการ data type พวกนั้น
อย่างที่สองคือคุณจะได้ทั้งประสิทธิภาพการวิเคราะห์ของ DuckDB และตอนนี้รวมถึงประสิทธิภาพด้าน transaction บน catalog ด้วย การที่ DuckDB อ่าน DuckDB เองนั้นเร็วกว่า scanner ของ Postgres/SQLite ของเราอย่างชัดเจน
อย่างที่สามคือไม่มี round trip สำหรับ retry ทั้งก้อนของ logic การ retry สามารถรันอยู่ฝั่งเซิร์ฟเวอร์ DuckDB ได้ง่าย(tm) ตอนนี้ retry แบบนี้ทำให้เกิดการไปกลับกับ Postgres หลายรอบ และกลายเป็นคอขวดด้านประสิทธิภาพเมื่อมี workload ที่ contention สูง
เผื่อไว้ก่อน ผมเป็นนักพัฒนาของ duckdb/ducklake
น่าจะได้ลองทดสอบกันภายในไม่กี่วัน