วิธีที่ Discord จัดเก็บข้อความนับล้านล้านรายการ (2023)
(discord.com)- เมื่อปริมาณการจัดเก็บข้อความของ Discord เติบโตจากหลักหลายพันล้านเป็น หลายล้านล้าน รายการ ภาระการปฏิบัติการของคลัสเตอร์ Cassandra 177 โหนดในช่วงต้นปี 2022 และ latency ที่คาดเดายากก็เริ่มรับมือไม่ไหว
- การออกแบบ Cassandra ที่อิง
channel_idและ bucket ตามเวลา ทำให้เกิด hot partition เมื่อมีทราฟฟิกอ่านจำนวนมากกระจุกตัวจากเซิร์ฟเวอร์ขนาดใหญ่ และด้วยการอ่าน/เขียนแบบ quorum latency จึงลุกลามเป็นผลกระทบต่อผู้ใช้ในวงกว้างขึ้น - วาง data service ที่ใช้ Rust ไว้ระหว่าง API กับฐานข้อมูล เพื่อรวมคำขอพร้อมกันที่อ่านแถวเดียวกัน และลดภาระฐานข้อมูลด้วยการ route แบบ consistent hashing ตาม channel ID
- การย้ายไป ScyllaDB ดำเนินผ่านการตั้งค่าคลัสเตอร์ใหม่และ migrator ที่เขียนด้วย Rust ลดงานที่คาดว่าจะใช้ 3 เดือน ด้วย Spark เหลือราว 9 วัน และย้ายข้อความได้สูงสุด 3.2 ล้านรายการต่อวินาที
- หลัง cutover ในเดือนพฤษภาคม 2022 จำนวนโหนดลดจาก Cassandra 177 โหนดเหลือ ScyllaDB 72 โหนด, p99 ของการค้นหาข้อความเก่าดีขึ้นจาก 40~125ms เป็น 15ms และ p99 ของการ insert ข้อความดีขึ้นจาก 5~70ms เป็น 5ms
ภาระการปฏิบัติการที่เพิ่มขึ้นใน Cassandra
- ในปี 2017 Discord เผยแพร่บทความ วิธีจัดเก็บข้อความหลายพันล้านรายการ โดยเล่ากระบวนการย้ายจาก MongoDB ไป Cassandra
- เป้าหมายในตอนนั้นคือฐานข้อมูลที่ขยายได้ ทนทานต่อความขัดข้อง และต้องบำรุงรักษาค่อนข้างน้อย แต่เมื่อปริมาณข้อมูลเพิ่มขึ้น คลัสเตอร์ Cassandra เองก็กลายเป็นภาระการปฏิบัติการขนาดใหญ่
- คลัสเตอร์
cassandra-messagesสำหรับจัดเก็บข้อความ เติบโตจาก 12 โหนดในปี 2017 เป็น 177 โหนด ในช่วงต้นปี 2022 และเก็บข้อความหลายล้านล้านรายการ - ทีมปฏิบัติการถูกเรียกตัวบ่อยครั้งจากปัญหาฐานข้อมูล, latency คาดเดาได้ยาก และจำเป็นต้องลดงานบำรุงรักษาที่มีต้นทุนสูงเกินไป
สคีมาข้อความและ hot partition
- สคีมาข้อความแบบย่อประกอบด้วย
channel_id,bucket,message_id,author_id,contentและ primary key คือ((channel_id, bucket), message_id) - ID ของ Discord อิง Snowflake จึงเรียงตามเวลาได้ และข้อความถูก partition ตาม channel กับ bucket ซึ่งเป็นหน้าต่างเวลาคงที่
- ใน Cassandra ข้อความทั้งหมดของ channel และ bucket หนึ่ง ๆ จะถูกเก็บไว้ด้วยกัน และถูกจำลองไปยังหลายโหนดตาม replication factor
- เซิร์ฟเวอร์กลุ่มเพื่อนขนาดเล็กกับเซิร์ฟเวอร์ที่มีสมาชิกหลายแสนคนมีปริมาณข้อความต่างกันหลายลำดับขั้น และความต่างนี้นำไปสู่ความต่างของภาระในระดับ partition
- การเขียนจะถูก append ลง commit log และ memtable ซึ่งเป็นโครงสร้างในหน่วยความจำ แล้วจึง flush ลงดิสก์ แต่การอ่านอาจต้องค้นทั้ง memtable และ SSTable หลายตัว ทำให้มีต้นทุนสูงกว่า
- เมื่อมีการอ่านพร้อมกันหลั่งไหลเข้ามาในเซิร์ฟเวอร์ขนาดใหญ่ partition เฉพาะจุดจะกลายเป็น hot partition ทำให้ latency ของโหนดนั้นเพิ่มขึ้นและกระทบ query อื่น ๆ ด้วย
- เนื่องจากใช้ quorum consistency level ทั้งในการอ่านและเขียน latency ที่เพิ่มขึ้นของโหนดที่รับผิดชอบ hot partition จึงลุกลามเป็นผลกระทบต่อผู้ใช้ในวงกว้างขึ้น
คอขวดในการบำรุงรักษา Cassandra
- compaction ของ Cassandra ก็เป็นอีกสาเหตุของการรับมือเหตุขัดข้องซ้ำ ๆ
- ต้อง compact SSTable บนดิสก์เพื่อให้ประสิทธิภาพการอ่านดีขึ้น แต่ถ้า compaction ค้างสะสม ต้นทุนการอ่านจะสูงขึ้น
- ระหว่างที่โหนดทำ compaction latency อาจเพิ่มขึ้นต่อเนื่องเป็นลูกโซ่
- Discord มักทำงานที่เรียกว่า “gossip dance” อยู่บ่อยครั้ง
- นำโหนดออกจากทราฟฟิกเพื่อทำ compaction
- ใส่กลับเข้าไปเพื่อให้ตาม hint ของ Cassandra hinted handoff ทัน
- ทำขั้นตอนนี้ซ้ำจนกว่า compaction backlog จะหมด
- ยังใช้เวลามากกับการจูน JVM garbage collector และการตั้งค่า heap และ GC pause ก็สร้าง spike ของ latency ขนาดใหญ่
เหตุผลที่ย้ายไป ScyllaDB
- นอกจากข้อความแล้ว Discord ยังดำเนินงานคลัสเตอร์ Cassandra อีกหลายชุด และแต่ละคลัสเตอร์ก็พบปัญหาคล้ายกัน
- ScyllaDB ที่เคยแสดงความสนใจไว้ในบทความก่อนหน้า เป็นฐานข้อมูลที่เข้ากันได้กับ Cassandra เขียนด้วย C++ และให้ประสิทธิภาพที่ดีกว่า, repair ที่เร็วขึ้น, การแยก workload ตามสถาปัตยกรรม shard-per-core และโครงสร้างที่ไม่มี garbage collection
- แม้ ScyllaDB จะไม่ได้ไร้ปัญหา แต่การเขียนด้วย C++ แทน Java ทำให้ไม่มี garbage collector ซึ่งตัดกันโดยตรงกับปัญหาการปฏิบัติการของ Cassandra
- หลังยืนยันการปรับปรุงจากการทดลองและทดสอบ Discord ตัดสินใจย้ายฐานข้อมูลทั้งหมดไป ScyllaDB และภายในปี 2020 ก็ย้ายฐานข้อมูลทั้งหมดแล้ว ยกเว้น
cassandra-messages - คลัสเตอร์ข้อความเหลือไว้เป็นลำดับสุดท้าย เพราะเป็นคลัสเตอร์ขนาดใหญ่ที่มีข้อความหลายล้านล้านรายการและเกือบ 200 โหนด
- ประสิทธิภาพของ reverse query ใน ScyllaDB ยังไม่เพียงพอต่อข้อกำหนดในการทดสอบช่วงแรก
- reverse query คือกรณีสแกนในทิศทางตรงข้ามกับการเรียงของตาราง เช่น งานสแกนข้อความแบบเรียงจากน้อยไปมาก
- เมื่อทีม ScyllaDB ให้ความสำคัญและ implement การปรับปรุงประสิทธิภาพ ปัจจัยที่ขวางการ migration ฐานข้อมูลสุดท้ายก็หมดไป
Data service ที่ใช้ Rust
- Discord มองว่าการเปลี่ยนเฉพาะฐานข้อมูลไม่ได้แก้ทุกปัญหาโดยอัตโนมัติ จึงเปลี่ยนชั้นที่อยู่เหนือฐานข้อมูลไปพร้อมกัน
- วาง data service ระหว่าง API monolith กับคลัสเตอร์ฐานข้อมูล เพื่อควบคุมคำขอพร้อมกันที่มุ่งไปยังฐานข้อมูล
- Data service เขียนด้วย Rust
- Discord เคยใช้ Rust ในบางโปรเจกต์มาก่อนแล้ว
- Rust ให้ความเร็วระดับ C/C++ โดยไม่ต้องละทิ้งความปลอดภัย
- Tokio ecosystem ถูกใช้เป็นฐานสำหรับสร้างระบบ async I/O และยังมีการรองรับ driver สำหรับ Cassandra และ ScyllaDB
- Data service มี gRPC endpoint ประมาณหนึ่ง endpoint ต่อ query ฐานข้อมูลหนึ่งรายการ และตั้งใจไม่ใส่ business logic ลงไป
- แกนหลักคือ request coalescing
- หากผู้ใช้หลายคนขอ row เดียวกันพร้อมกัน ฐานข้อมูลจะถูก query เพียงครั้งเดียว
- คำขอแรกสร้าง worker task ภายใน service และคำขอถัด ๆ ไปตรวจพบ task นั้นแล้ว subscribe
- worker task query ฐานข้อมูลและส่ง row ผลลัพธ์กลับให้ subscriber ทุกคน
เพิ่มประสิทธิผลของการรวมคำขอด้วย routing
- ด้านหน้า data service ใช้ routing แบบ consistent hash
- คำขอแต่ละรายการของ data service จะมี routing key และในกรณีข้อความ routing key คือ channel ID
- เพราะคำขอทั้งหมดของ channel เดียวกันถูกส่งไปยัง service instance เดียวกัน request coalescing จึงทำงานได้ดีขึ้น
- ตัวอย่างเช่น เมื่อมีการแจ้งเตือน
@everyoneในเซิร์ฟเวอร์ขนาดใหญ่ ผู้ใช้จำนวนมากอาจเปิดแอปและอ่านข้อความเดียวกัน ทำให้ทราฟฟิกฐานข้อมูลพุ่งขึ้น - ในโครงสร้างเดิม สถานการณ์แบบนี้อาจนำไปสู่ hot partition และต้องเรียกทีมปฏิบัติการ แต่ data service ลด traffic spike ที่มุ่งไปยังฐานข้อมูลได้อย่างมาก
- การปรับปรุงนี้ไม่ได้กำจัด hot partition และ latency ของคลัสเตอร์ Cassandra ไปทั้งหมด แต่ช่วยซื้อเวลาให้เตรียมคลัสเตอร์ ScyllaDB ใหม่และดำเนินการ migration
การ migration ข้อความหลายล้านล้านรายการ
- ข้อกำหนดของ migration ชัดเจน
- ต้องย้ายข้อความหลายล้านล้านรายการ
- ต้องไม่มี downtime
- ต้องจบให้เร็ว เพราะ Cassandra ยังสร้างเหตุขัดข้องให้ต้องรับมือบ่อยครั้ง
- Discord ตั้งค่าคลัสเตอร์ ScyllaDB ใหม่ก่อน โดยใช้ super-disk storage topology
- ใช้ Local SSD เพื่อให้ได้ความเร็ว
- ใช้ RAID เพื่อ mirror ข้อมูลไปยัง persistent disk
- เป็นโครงสร้างที่ได้ทั้งความเร็วของดิสก์ local และความทนทานของ persistent disk
- แผนแรกคือให้ข้อมูลใหม่ใช้ ScyllaDB นับจาก cutover time และย้ายข้อมูลเก่าอยู่เบื้องหลัง
- เริ่ม dual write ข้อมูลใหม่ไปยังทั้ง Cassandra และ ScyllaDB พร้อมกับเตรียม Spark migrator ของ ScyllaDB
- Spark migrator ต้องจูนจำนวนมาก และหลังตั้งค่าแล้ว เวลาคาดการณ์จนเสร็จคือ 3 เดือน
- จากนั้น Discord ขยายไลบรารีฐานข้อมูลความเร็วสูงที่มีอยู่ และเขียน data migrator ใหม่ด้วย Rust
- อ่าน token range จากฐานข้อมูล
- บันทึก checkpoint ภายในเครื่องด้วย SQLite
- ส่งข้อมูลจำนวนมากไปยัง ScyllaDB
- เวลาคาดการณ์จนเสร็จของ Rust migrator ใหม่ลดเหลือ 9 วัน และความเร็วนี้ทำให้สามารถทำ cutover ทั้งหมดในครั้งเดียว แทนแนวทางซับซ้อนที่อิงเวลา
Cutover และการตรวจสอบความถูกต้อง
- Migration ดำเนินที่ความเร็วสูงสุด 3.2 ล้านข้อความต่อวินาที
- ความคืบหน้าหยุดที่ 99.9999% เพราะ token range สุดท้ายไม่กี่ช่วงมีช่วง tombstone ขนาดใหญ่ที่ยังไม่ได้ compact อยู่ใน Cassandra
- เมื่อ compact token range ดังกล่าวแล้ว migration ก็เสร็จในไม่กี่วินาทีต่อมา
- Discord ทำ การตรวจสอบข้อมูลอัตโนมัติ โดยส่งคำขออ่านสัดส่วนเล็ก ๆ ไปยังฐานข้อมูลทั้งสองและเปรียบเทียบผลลัพธ์ ซึ่งผลออกมาไม่มีปัญหา
- คลัสเตอร์ ScyllaDB รับทราฟฟิก production ทั้งหมดได้ดี ขณะที่ Cassandra ประสบปัญหา latency บ่อยขึ้นเรื่อย ๆ
- ทีมจึงเปลี่ยน ScyllaDB ให้เป็น primary database ณ ตอนนั้น
ประสิทธิภาพและขนาดหลัง cutover
- การเปลี่ยนฐานข้อมูลข้อความเกิดขึ้นในเดือนพฤษภาคม 2022
- หลังจากนั้นการปฏิบัติการเงียบและเสถียร ไม่ต้องรับมือเหตุขัดข้องตลอดสุดสัปดาห์หรือปรับโหนดคลัสเตอร์ต่อเนื่องเพื่อรักษา uptime อีก
- จำนวนโหนดลดจาก Cassandra 177 โหนด เหลือ ScyllaDB 72 โหนด
- พื้นที่ดิสก์ต่อโหนดของ ScyllaDB คือ 9TB มากกว่าค่าเฉลี่ย 4TB ของโหนด Cassandra
- tail latency ก็ดีขึ้นอย่างมาก
- p99 ของการค้นหาข้อความเก่า: Cassandra 40~125ms → ScyllaDB 15ms
- p99 ของการ insert ข้อความ: Cassandra 5~70ms → ScyllaDB 5ms
- ด้วยประสิทธิภาพที่ดีขึ้น Discord จึงสามารถเปิด use case ของผลิตภัณฑ์ใหม่ ๆ โดยอาศัยความเชื่อมั่นต่อฐานข้อมูลข้อความ
ยืนยันการรองรับภาระจากทราฟฟิก World Cup
- ช่วงปลายปี 2022 ระหว่าง World Cup ผู้ใช้ทั่วโลกชมการแข่งขัน และกราฟการส่งข้อความของ Discord ก็ปรากฏจังหวะที่มีประตูเกิดขึ้นด้วย
- กราฟการส่งข้อความของ World Cup Final มี spike หลายจุดที่สอดคล้องกับเหตุการณ์ในการแข่งขัน
- ลูกจุดโทษของ Messi และการขึ้นนำ 1-0 ของ Argentina
- ประตูเพิ่มเติมของ Argentina
- plateau 15 นาทีที่ต่อเนื่องตลอดช่วงพักครึ่ง
- spike จากการที่ Mbappe ทำประตูให้ France และทำอีกประตูใน 90 วินาทีถัดมาเพื่อตีเสมอ
- จบเวลาปกติและเข้าสู่ช่วงต่อเวลาพิเศษ
- การแชตช่วงพักครึ่งแรกของการต่อเวลาพิเศษ
- ประตูเพิ่มเติมของ Messi
- ประตูตีเสมอของ Mbappe
- จบช่วงต่อเวลาพิเศษและเข้าสู่การดวลจุดโทษ
- France ยิงพลาดและ Argentina คว้าแชมป์
- แม้ปริมาณการส่งข้อความเพิ่มขึ้นมาก data service ที่ใช้ Rust และ ScyllaDB ก็รองรับทราฟฟิกได้
- ระบบสุดท้ายถูกจัดระเบียบเป็นโครงสร้างที่สามารถรองรับ ข้อความหลายล้านล้านรายการ ได้
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
บทความนี้ดูเหมือนจะโทษ garbage collection อย่างหนัก แต่ถ้าดูบทความก่อนหน้า [0] จะดูใกล้เคียงกับข้อจำกัดของวิธีใช้งาน Cassandra หรือการจัดการการลบจำนวนมากของ Cassandra หรือทั้งสองอย่างมากกว่า
ผู้ใช้ลบข้อความหลายล้านข้อความผ่าน API จนเหลือข้อความในช่องเพียง 1 ข้อความ และเนื่องจาก Cassandra จัดการการลบเป็น tombstone เมื่อผู้ใช้เปิดช่องนั้น แม้ข้อความจริงจะมีเพียง 1 ข้อความ แต่ก็ต้องสแกน tombstone หลายล้านรายการ คำอธิบายคือในกระบวนการนั้นมี garbage เกิดขึ้นเร็วกว่าที่ JVM จะเก็บกวาดได้
นอกจากนี้ยังมีพูดถึงการปรับแต่ง GC แต่ดูจาก [1] แล้วก็ไม่ได้ปรับแต่งมากนัก และดูเหมือนจะใช้ Cassandra รวมถึงอาจจะ JVM เวอร์ชันเก่าอยู่ด้วย จุดที่สำคัญอีกอย่างคือเพิ่งย้ายมาจาก CMS
0) https://discord.com/blog/how-discord-stores-billions-of-messages
ต่อให้เดิมทีใช้วิธีแก้ปัญหาผิดทาง ผมก็ยังคิดว่าวิธีแก้ที่ใช้งานผิดได้ยากกว่านั้นดีกว่า
ถ้าในปี 2022 ใช้ Java 11 ก็เท่ากับใช้ runtime ที่เก่า 4 ปี หรือถ้าใช้ Java 8 ก็เท่ากับใช้ runtime ที่เก่า 8 ปี จึงมีความเป็นไปได้สูงว่าพลาดประสิทธิภาพไปค่อนข้างมาก
Needs (2023)
เลเยอร์บริการนี้ดูเหมือน Varnish Cache แบบกระจายขนาดใหญ่และหรูหรา เห็นเลือกใช้คำว่า “coalesce” โดยไม่พูดถึง caching ก็ทำให้ดูเหมือนว่าไม่ได้ทำ caching จริง ๆ มากนัก แต่ทำให้นึกถึง “grace mode” ของ Varnish และการใช้เพื่อป้องกัน stampede หรือบริบทที่ผมได้ยินคำว่า ‘request coalescing’ เป็นครั้งแรก https://varnish-cache.org/docs/6.1/users-guide/vcl-grace.htm...
อีกอย่างที่น่าดีใจคือ consistent hashing โผล่มาอยู่เรื่อย ๆ เป็นเทคนิคที่เหมือนเทปกาวสารพัดประโยชน์ชั้นดี ซึ่งพิสูจน์แล้วว่ามีประโยชน์ในสถานการณ์คล้ายกัน ถ้ารู้ว่าสิ่งใดควรอยู่ที่ไหน ทุกคนก็จะรู้ด้วยว่าควรไปหาที่ไหน
proxy_cache_use_stale updating;ผู้ร่วมก่อตั้ง ScyllaDB ได้เสริมไว้หลายอย่าง: Discord ไม่สามารถทำ repair ให้เสร็จบน Cassandra ได้ แต่บน Scylla ไม่เป็นเช่นนั้น และแม้ Scylla จะมีหลายอย่างเหมือน Cassandra เช่น LSM tree และ compaction แต่มี CPU/IO scheduler ของตัวเองที่สามารถให้ priority กับ query สูงกว่า compaction ได้
เขาบอกว่าสามารถเลื่อน compaction ไปไว้ในช่วงครึ่งมิลลิวินาทีที่มี bandwidth ว่างเพียงพอได้ และมีบทความที่เกี่ยวข้องอยู่มากมาย ใน Scylla มีโหมดที่ปลอดภัยกว่าชื่อ
tombstone_gc=repairซึ่งมีอายุ 1.5 ปีแล้ว และสถาปัตยกรรมใหม่ที่ใช้ Raft กับ tablets ซึ่งเพิ่งออกล่าสุดจะเป็นการเปลี่ยนแปลงครั้งใหญ่ถัดไปสำหรับผู้ใช้ปัญหาแบบนี้คงไม่มีตั้งแต่แรก ถ้าใช้ IRC ซึ่งเป็น โปรโตคอลแชตแบบกระจายศูนย์ ที่มีมานานกว่า 40 ปีแล้ว
ยังมีข้อดีคือมีสเปกเปิดและมีอิมพลีเมนเทชันหลายตัวด้วย ไม่ใช่สวนปิดที่มีกำแพงล้อม ถ้าคิดว่า IRC ล้าสมัยเกินไปสำหรับยุคนี้ ก็ลองดู Matrix หรือ XMPP ได้ ผมเข้าใจยากว่า Discord เข้ายึดตลาดได้อย่างไร และค่อนข้างจะเป็นโศกนาฏกรรมเสียด้วยซ้ำ
ถ้าจะติดตามบทสนทนาบนหลายอุปกรณ์ IRC แทบจะบังคับให้ต้องใช้ bouncer อยู่แล้ว มันไม่ได้เข้ารหัสข้อความ และเข้ารหัสได้แค่การเชื่อมต่อระหว่างไคลเอนต์กับเซิร์ฟเวอร์แบบเลือกใช้ได้เท่านั้น หากไม่มี การเข้ารหัสแบบต้นทางถึงปลายทาง ก็ไม่มีความเป็นส่วนตัวจากเซิร์ฟเวอร์หรือผู้ดูแล และเซิร์ฟเวอร์นั้นก็เป็นจุดล้มเหลวเดี่ยวที่ตกเป็นเป้าได้ง่าย
โปรโตคอล Matrix ยังอยู่ระหว่างเปลี่ยนแปลง และอิมพลีเมนเทชันก็ตามสเปกไม่ทัน ถ้าไม่ได้ใช้ Element ก็จะตามหลังทั้งด้านฟีเจอร์และความปลอดภัย XMPP ก็เหมือน IRC ที่ฟีเจอร์พื้นฐานอย่างการเข้ารหัสแบบต้นทางถึงปลายทางต้องพึ่งส่วนขยายแบบเลือกใช้ และไคลเอนต์อาจไม่ได้รองรับอย่างครบถ้วนและถูกต้อง
แนะนำให้อ่านบทวิเคราะห์ของ soatok: https://soatok.blog/2024/08/04/against-xmppomemo/ https://soatok.blog/2024/08/14/security-issues-in-matrixs-ol...
เหตุการณ์ Snowden ปี 2013 เกิดขึ้นเมื่อ 11 ปีก่อนแล้ว ตอนนี้การเข้ารหัสแบบต้นทางถึงปลายทางควรเป็นฟีเจอร์พื้นฐานและถูกมองเหมือนสินค้าโภคภัณฑ์ และควรเรียกร้องอย่างเหนียวแน่นพอ ๆ กับที่เราเคยเรียกร้อง HTTPS แน่นอนว่า Discord ไม่ได้ทำการเข้ารหัสแบบต้นทางถึงปลายทาง
เมื่อไม่นานมานี้ กลุ่มที่ผมอยู่ซึ่งเป็นกลุ่มสายเทคนิคมาก ๆ ย้ายจาก Telegram ไป Matrix แต่ประสบการณ์ผู้ใช้ไม่ดี แอปมีบั๊ก หน้าตาก็ไม่ค่อยดี และในแอป “Element” ตัวใหม่ไม่รองรับ SSO จนใช้บัญชีไม่ได้ สำหรับคนที่ชอบลงไปขุดเองอย่างผม นี่เป็นความไม่สะดวกเล็ก ๆ ที่พอรับได้ แต่คงโน้มน้าวให้เพื่อน ๆ ใช้ไม่ได้
ดาวน์โหลด exe ติดตั้ง สร้างบัญชี แล้วก็รันได้ทันที ใคร ๆ ก็ทำได้ มีซอฟต์แวร์ที่มีประโยชน์และยอดเยี่ยมอยู่มากมาย แต่ส่วนใหญ่ไม่ง่ายสำหรับคนทั่วไป และบางตัวหรือส่วนใหญ่ไม่มีแม้แต่ GUI ผู้คนเลือกที่จะขายตัวตนของตัวเอง และถึงขั้นยอมจ่ายเงินด้วย แทนที่จะทนกับขั้นตอนที่มากเกินไป
ข้อสรุปที่ผมได้จากบทความนี้อาจต่างจากเจตนาของผู้เขียนเล็กน้อย
“ตัวสุดท้ายหรือ? เพื่อนของเรา cassandra-messages. [...] มันเป็นคลัสเตอร์ขนาดใหญ่มาตั้งแต่เริ่ม มีข้อความหลายล้านล้านรายการและเกือบ 200 โหนด ดังนั้นการย้ายระบบใด ๆ ก็ย่อมเป็นงานที่ซับซ้อน”
เมื่อคิดถึงขนาดของ Discord แล้ว ที่เก็บข้อความมี น้อยกว่า 200 โหนด ดูเล็กจนน่าประหลาดใจ ผมคาดไว้ว่าจะเป็นสถาปัตยกรรมซับซ้อนที่ตั้งเป้าขยายได้เร็วกว่าเยอะและมีชิ้นส่วนเคลื่อนไหวมากกว่านี้ ความซับซ้อนจริงคงสูงกว่าที่บทความเล่า แต่เมื่อนึกถึงประสบการณ์ที่ผมเคยรับผิดชอบบางส่วนกับโหนดจริงมากกว่า 200 เครื่องซึ่งทำงานน้อยกว่านี้ ก็อดสงสัยไม่ได้ว่าสถาปัตยกรรมคลาวด์ยุคใหม่ถูกออกแบบเกินจำเป็นแค่ไหน
ในฐานะคนที่เคยเก็บเรคคอร์ดหลายพันล้านรายการด้วยชุดโหนด Cassandra ที่เล็กกว่านี้มาก Cassandra เป็นสิ่งที่ทรมานมากเวลา on-call และเคยเป็นสาเหตุของเหตุขัดข้องใหญ่หลายครั้ง
[0] https://news.ycombinator.com/item?id=34950843
บทความเขียนได้ดีมาก ดีที่ส่วนหนึ่งของแนวทางแก้ไม่ได้เป็นการนำสิ่งที่ต่างไปโดยสิ้นเชิงมาใช้ แต่เป็นการเปลี่ยนไปใช้ ScyllaDB ซึ่งใช้ได้เหมือนเป็นตัวแทนของ Cassandra
Discord ทำให้การลบข้อความเก่าแทบเป็นไปไม่ได้ นี่คือ ฝันร้ายด้านความเป็นส่วนตัว และน่าสงสัยว่าทำไม EU ถึงยังไม่เข้ามาแทรกแซง
คำถามหลักย่อได้ว่า ควรมอง Matrix ว่าใกล้เคียงกับอีเมลมากกว่า หรือใกล้เคียงกับ Facebook มากกว่า ถ้าเป็นอีเมล ผู้คนคงตกใจหากผู้ส่งสามารถลบข้อความของตัวเองออกจากสพูลเมลของผมได้ แต่ถ้าเป็น Facebook ผู้คนก็คงตกใจหากหลังจากใช้สิทธิ์ลบแล้ว โพสต์ยังไปปรากฏอยู่ที่ไหนสักแห่ง
คำอธิบายคือ การแก้เรื่องนี้ต้องอาศัยการตัดสิน และพวกเขาเข้าหาปัญหาโดยพิจารณาก่อนว่าเจตนารมณ์ของ GDPR ต้องการบรรลุอะไรจริง ๆ
https://matrix.org/blog/2018/05/08/gdpr-compliance-in-matrix...
ปัญหาในมุม GDPR คือ Discord ทำให้การลบสิ่งเหล่านี้ยาก เมื่อระบบตรวจพบเจตนาจะลบข้อมูลบัญชี ก็จะชี้นำไปทาง “ทำให้เป็นนิรนาม” และในที่สาธารณะชื่อผู้ใช้จะถูกแยกออกจากข้อความ แต่ก็ยังสามารถตามรอยไปถึงบุคคลเฉพาะได้ หากฝั่งเซิร์ฟเวอร์ก็จัดการแบบนี้เช่นกัน การบังคับใช้คำขอลบข้อมูลที่ระบุตัวบุคคลได้ของผู้ใช้จะกลายเป็นสถานการณ์ที่ต้องไล่ตรวจข้อความจำนวนมหาศาล หรือลบข้อความเก่าเป็นจำนวนมาก
รัฐสภา EU ไม่ใช่รัฐสภาจริง ๆ ในแง่ที่ว่ากฎหมายใหม่เสนอได้โดยคณะกรรมาธิการเท่านั้น ส่วนรัฐสภาที่มาจากการเลือกตั้งส่วนใหญ่ทำได้แค่ลงคะแนน และมองว่าผู้ที่ควบคุมคณะกรรมาธิการไม่ใช่สาธารณชน แต่เป็นกระทรวงการต่างประเทศสหรัฐฯ Newsguard และ Big Tech สหรัฐฯ ที่ไม่ใช่ Musk รวมถึง Discord ต่างก็อยู่ในเครือข่ายอำนาจทางการเมืองและการเงินเดียวกัน และมีอดีตบุคลากรกระทรวงการต่างประเทศอยู่จำนวนมาก
หากไม่มีความโกรธแค้นของสาธารณชน สถาบันระดับ EU ก็มีแนวโน้มสูงที่จะถูกยึดกุม และมองว่ากระแสสาธารณะก็ถูกกลุ่มอภิสิทธิ์แบบไซเบอร์พังก์ที่ใช้ข้อมูล Discord ผิดกฎหมายไปฝึก LLM และเล็งโฆษณาเลือกตั้งควบคุมอยู่ด้วย ท้ายที่สุดควรกังวลว่าอาจมาถึงสภาพแบบ Orwell ที่ไม่อาจหลุดพ้นจากกลุ่มอภิสิทธิ์ถาวรได้
อย่างไรก็ตาม ส่วนใหญ่ของเรื่องนี้ผมให้ความน่าจะเป็นว่า “ถูกในความหมายกว้าง ๆ” แค่ราว ๆ มากกว่า 50% เท่านั้น จึงควรฟังอย่างมีวิจารณญาณมาก ๆ
โดยแก่นแล้ว Cassandra ใกล้เคียงกับ ตารางแฮชแบบกระจายที่ทนทานต่อความผิดพลาด ซึ่งส่วนใหญ่เป็นการเพิ่มข้อมูลเข้าไปอย่างเดียว ถ้าต้องการสิ่งแบบนั้นจริง ๆ พร้อม throughput การเขียนสูง ก็เป็นตัวเลือกที่ดี
ไม่เข้าใจว่าทำไมผู้คนถึงใช้มันเหมือนเป็นฐานข้อมูล จะชนข้อจำกัดทันที และความเจ็บปวดจากการพยายามใช้ให้เหมือนฐานข้อมูลจะยิ่งหนักขึ้นเมื่อสเกลใหญ่ขึ้น
ถ้าเป็นแบบนี้ ผมคิดว่าไม่สมเหตุสมผลในฐานะที่เก็บข้อความของเซิร์ฟเวอร์แชต ดูเหมาะกับปลายทางสำหรับรวบรวมล็อกของระบบกระจายมากกว่า คือมีไคลเอนต์จำนวนมากเทข้อมูลเข้าไป แต่ส่วนใหญ่แทบไม่จำเป็นต้องตรวจสอบล็อก จนจำนวนครั้งที่อ่านข้อความเฉพาะรายการหนึ่งน้อยกว่า 1 กรณีข้อความ Discord เห็นได้ชัดว่าไม่ใช่แบบนั้น
จากประสบการณ์ของผม ไม่เคยเห็นโปรเจกต์ที่เริ่มใช้ Cassandra แล้วยังใช้ต่อหลังผ่านไปประมาณ 1 ปี ต้องใช้เวลาราวหนึ่งปีถึงจะชนข้อจำกัด และสุดท้ายก็เปลี่ยนไปใช้ฐานข้อมูลอย่าง Postgres
ไม่เข้าใจว่าทำไมถึงไม่ทำชาร์ดดิ้งไปเลย แต่ละ ‘เซิร์ฟเวอร์’ ของ Discord ก็แยกจากกันไม่ใช่หรือ? ถ้าส่งข้อความหากันไม่ได้ ก็สงสัยว่าทำไมไม่แบ่ง ข้อความหลายล้านล้านรายการ ออกเป็นชาร์ดหลายพันชุด ให้แต่ละชาร์ดจัดการชุดละหลายพันล้านรายการ
มีข้อความว่า “ทีม ScyllaDB จัดลำดับความสำคัญให้กับงานปรับปรุง และนำการคิวรีแบบย้อนกลับที่มีประสิทธิภาพมาใช้ จึงขจัดอุปสรรคด้านฐานข้อมูลสุดท้ายของแผนการไมเกรตได้”
สงสัยว่าพวกเขาจ่ายไปเท่าไรเพื่อให้ทำสิ่งนี้ให้ ก่อนที่จะได้ใช้ ScyllaDB เสียอีก