Ceph: เส้นทางสู่ 1 TiB/s
(ceph.io)- Clyso ได้ทำการทดสอบ burn-in ก่อนเปลี่ยนคลัสเตอร์ Ceph แบบใช้ HDD ไปเป็น การติดตั้ง NVMe ขนาด 10PB และทำได้ 1.0 TiB/s read บนคลัสเตอร์เดี่ยวที่มี 630 OSD
- ฮาร์ดแวร์สุดท้ายคือ Dell PowerEdge R6615 จำนวน 68 เครื่อง พร้อม NVMe 10 ตัวต่อโหนด แต่การทดสอบสมรรถนะสูงสุดทำบนเครื่องที่พร้อมใช้งาน 63 เครื่องและ 630 OSD
- คอขวดช่วงแรกถูกแก้โดยปรับ BIOS CPU c-state, แก้ IOMMU mapping contention ในเคอร์เนล และปัญหา compile flags ของ RocksDB ในแพ็กเกจ upstream Ceph Ubuntu Deb ทำให้เวลา compaction ลดลงราว 3 เท่า และ 4KB random write ดีขึ้น 2 เท่า
- ค่าสูงสุดของคอนฟิก 3X replication คือ 4MB read 1025GiB/s, 4MB write 270GiB/s, 4KB random read 25.5M IOPS, 4KB random write 4.9M IOPS ส่วน 6+2 erasure coding ทำได้ 4MB read 547GiB/s และ write 387GiB/s
- ความเสี่ยงที่เหลือคือปรากฏการณ์ที่ PG บางส่วนเข้าสู่สถานะ active+clean+laggy ระหว่างการเขียนขนาดใหญ่จน throughput ตกฮวบ และหากต้องการ throughput สูงขึ้นเมื่อใช้ NVMe มากกว่า 10 ตัวต่อโหนด จำเป็นต้องมีเครือข่าย 200GbE ขึ้นไป
การออกแบบคลัสเตอร์ NVMe Ceph ขนาด 10PB
- ลูกค้าต้องการเปลี่ยนคลัสเตอร์ Ceph เดิมที่ใช้ HDD ไปเป็น การติดตั้ง NVMe ขนาด 10PB และไม่มีข้อกำหนดเฉพาะสำหรับ RBD, RGW, CephFS
- เงื่อนไขการออกแบบรวมถึงการกระจายข้าม 17 แร็ก, พื้นที่ 4U ต่อแร็ก, พลังงาน, การระบายความร้อน, ความหนาแน่น และความชอบด้านผู้ขาย
- โหนดใหม่ต้องผสานเข้ากับคลัสเตอร์เดิมได้ โดยไม่หยุดให้บริการ และเครือข่ายเป็น Ethernet ความเร็วสูงที่ติดตั้งไว้แล้ว
- ข้อเสนอแรกคือวางโหนด 2U แบบ dual-socket จำนวน 34 เครื่องใน 17 แร็ก แต่สุดท้ายเลือกคอนฟิกบน Dell ที่ Clyso ออกแบบ
- ใบเสนอราคาสุดท้ายถูกกว่าคอนฟิกเดิมราว 13%
- หน่วยความจำต่อ OSD ลดลง แต่ยังอยู่ราว 12GiB ต่อ OSD และ memory throughput เร็วกว่า
- ใช้คอนฟิก single-socket, ทรัพยากร CPU รวมมากขึ้น, network throughput รวมมากขึ้น, โปรเซสเซอร์ AMD รุ่นใหม่กว่า และ DDR5 RAM
- ใช้โหนดที่เล็กลงเพื่อลดผลกระทบของความล้มเหลวของโหนดต่อการกู้คืนคลัสเตอร์ลงครึ่งหนึ่ง
ฮาร์ดแวร์และคอนฟิกพื้นฐาน
- สเปกระบบมีดังนี้
- Nodes: 68 × Dell PowerEdge R6615
- CPU: 1 × AMD EPYC 9454P 48C/96T
- Memory: 192GiB DDR5
- Network: 2 × 100GbE Mellanox ConnectX-6
- NVMe: 10 × Dell 15.36TB Enterprise NVMe Read Intensive AG
- OS: Ubuntu 20.04.6 Focal
- Ceph: Quincy v17.2.7 upstream Deb packages
- ลูกค้าต้องการจำกัดการใช้พลังงานเพิ่มเติมต่อแร็กไว้ราว 1000~1500W
- TDP รวมของโหนด 4 เครื่องต่อแร็กคาดว่าอย่างน้อย 1120W บวกกับพลังงานพื้นฐาน, peak ของ CPU และความไม่มีประสิทธิภาพของ power supply
- หากจำเป็น ประเมินว่าสามารถลด cTDP ของโปรเซสเซอร์เพื่อลดได้ราว 100W ต่อแร็ก
- เซิร์ฟเวอร์ Dell แบบ 1U มีคอนฟิกใกล้เคียงกับรุ่นล่าสุดของระบบที่ใช้ใน upstream Ceph performance lab
- ระหว่างทดสอบพบ ปัญหาด้านสมรรถนะ ที่ไม่มีในฮาร์ดแวร์รุ่นก่อน แต่ส่งผลกับฮาร์ดแวร์ชุดนี้
วิธีทดสอบและการเลือก benchmark
- การทดสอบ burn-in ทำโดยใช้ CBT เพื่อ deploy คลัสเตอร์ Ceph ชั่วคราวและรันการทดสอบ FIO
- ตั้งค่า
osd_memory_targetเป็น 8GB สำหรับ OSD- คาดว่าในการใช้งาน production อาจใช้
osd_memory_targetที่สูงกว่านี้ได้
- คาดว่าในการใช้งาน production อาจใช้
- ลูกค้าไม่จำเป็นต้องทดสอบ workload แบบ block หรือ S3 แต่ใช้ engine
librbdของ FIO แทนRADOS benchRADOS benchขนาดใหญ่ตัดสินจำนวน instance ที่ต้องใช้เพื่อทำให้คลัสเตอร์เต็มกำลังได้ยาก และเคยมีประสบการณ์ว่าต้องใช้ pool พร้อมกันหลายชุด- ใช้ การทดสอบ FIO บน librbd แบบเดียวกันเพื่อเทียบกับผลจาก upstream lab เดิม
- ยังพิจารณาด้วยว่า FIO เป็นเครื่องมือที่รู้จักกันดีและได้รับความเชื่อถือ
- ข้ามการทดสอบ kernel RBD
- engine
librbdช่วยเลี่ยงปัญหาที่ mount point เก่าทำให้ต้อง reboot ระบบ - คลัสเตอร์นี้ไม่มีการเข้าถึง IPMI และเส้นตายการทดสอบก็กระชั้น
- จากเกณฑ์ทดสอบเดิม คาดว่าหากมี client เพียงพอ สมรรถนะรวมโดยทั่วไปจะใกล้เคียงกัน
- engine
- เป้าหมายการทดสอบรวมถึง 3X replication และ 6+2 erasure coding
- msgr V2 ถูกทดสอบทั้งโหมดไม่เข้ารหัสและโหมด secure
ms_client_mode = securems_cluster_mode = securems_service_mode = securems_mon_client_mode = securems_mon_cluster_mode = securems_mon_service_mode = secure
- FIO จะเติม RBD volume ด้วยการเขียนขนาดใหญ่ก่อน จากนั้นรันการทดสอบ IO ขนาด 4MB และ 4KB อย่างละ 300 วินาที
- ในการรันเพื่อ debug ลดเหลือ 60 วินาที
- ปิด background process เช่น scrub, deep scrub, PG autoscaling, PG balancing
ผลของจำนวน PG ต่อสมรรถนะ
- การทดสอบ upstream lab ก่อนหน้านี้ยืนยันว่า จำนวน PG อาจส่งผลต่อสมรรถนะอย่างมาก
- เมื่อจำนวน PG ต่ำ clumpiness ของการกระจายแบบสุ่มอาจส่งผลต่อสมรรถนะ และบางส่วนบรรเทาได้ด้วย balancing เพิ่มเติม
- ในคลัสเตอร์ที่เร็ว PG lock contention ภายใน OSD ก็อาจมีบทบาทสำคัญต่อสมรรถนะรวม
- ปัญหานี้บรรเทาได้ไม่ง่ายนักนอกจากเพิ่มจำนวน PG
- แม้ในการทดสอบที่ใช้เพียง 60 OSD สมรรถนะ random read ของ RBD pool แบบ 3X replication ก็ยัง scale ได้ถึง 16384 PG
- การเขียนถึงจุดสูงสุดเร็วกว่านั้น แต่ยังได้ประโยชน์จนถึง 2048 PG
- ไม่ควรนำจำนวน PG สูง ๆ ไปใช้กับ production แบบไม่พิจารณา
- ค่าเริ่มต้นของ Ceph เช่นความยาว PG log และ PG stat update อาจส่งผล
- จำเป็นต้องทบทวนว่าธรรมเนียมเดิมที่ใช้ 100 PG ต่อ OSD ยังเหมาะสมอยู่หรือไม่
ปัญหาสมรรถนะช่วงแรกและพฤติกรรมแปลก ๆ
- สามารถล็อกอินเข้าไปยังฮาร์ดแวร์ใหม่ได้ครั้งแรกในสัปดาห์ถัดจาก Thanksgiving ของสหรัฐฯ และแผนเดิมคือทดสอบ burn-in 1~2 สัปดาห์ก่อนผสานเข้าคลัสเตอร์เดิม
- การทดสอบสมรรถนะระดับล่างในตอนแรกดูดี
- การทดสอบเครือข่ายด้วย iperf เข้าใกล้ 200Gb/s ต่อโหนด
- สมรรถนะพื้นฐานของ NVMe drive ในบางโหนดก็ดูสมเหตุสมผล
- ระบบปฏิบัติการของโหนดทั้ง 68 เครื่องถูก deploy ผิดไปอยู่บน OSD drive 2 ตัว แทนที่จะเป็น Dell BOSS m.2 boot drive ภายใน
- จึงต้องทดสอบโดยใช้ NVMe เพียง 8 ตัวต่อโหนด แทนการทดสอบ 3 โหนด 30 OSD ตามแผน
- ผล Ceph แรกต่ำกว่าคาดมาก แม้คิดเผื่อจำนวน OSD ที่ลดลงแล้ว
- มีเพียง random read ที่พอเข้าใกล้ระดับยอมรับได้ แต่ก็ยังไม่พอ
- เมื่อจำกัดวงไปที่การทดสอบโหนดเดียวและ OSD เดียว พบ รูปแบบผิดปกติ
- ระบบที่ทำงานดีในการทดสอบ OSD เดียว กลับสมรรถนะตกหลังการทดสอบ 8 OSD
- หลังจากนั้น แม้ทดสอบ OSD เดียวก็ยังมีสมรรถนะไม่ดีต่อเนื่องหลายชั่วโมงก่อนฟื้นตัว
- หากไม่แทรกการทดสอบ multi-OSD สมรรถนะจะยังคงสูงต่อไป
- เมื่อรัน FIO กับ drive โดยตรง ไม่สามารถทำซ้ำปัญหาเดียวกันได้
- ระหว่างการทดสอบ 8 OSD มี OSD หนึ่งตัวใช้ CPU มากกว่า OSD อื่นมาก
- OSD wallclock profile แสดงว่ามีการใช้เวลามากที่
io_submitซึ่งมักเป็นรูปแบบที่เห็นเมื่อ drive queue เต็มและเคอร์เนลถูก block
การแก้ไขสามอย่าง
-
โหมด performance ใน BIOS และ c-state
- การแก้ไขแรกคือ BIOS ไม่ได้อยู่ในโหมด maximum performance ทำให้ CPU c-state เปิดใช้งานอยู่
- Ceph ไวต่อ latency ที่เกิดจากการสลับ CPU c-state มาก
- เมื่อปิด c-state ด้วยโหมด maximum performance สมรรถนะ ดีขึ้น 10~20% แต่ยังไม่พอถึงเป้าหมาย
-
IOMMU contention
- ปัญหาที่สองปรากฏใน perf profile ฝั่งเคอร์เนล
- ระหว่างการรันที่แย่ มีการใช้เวลามากใน
native_queued_spin_lock_slowpathและเส้นทาง IOMMU DMA mapping alloc_iovaiommu_dma_alloc_iovaiommu_dma_map_sgnvme_map_datanvme_queue_rq- เมื่อ ปิด IOMMU ในเคอร์เนล สมรรถนะ 4MB read/write ของการทดสอบ 8 โหนดดีขึ้นมาก
- หลังแก้จุดนี้ ปัญหา 4KB random write ยังเหลืออยู่
-
RocksDB compile flags
- ปัญหาที่สามคือสมรรถนะ 4KB random write และ RocksDB compaction ต่ำกว่าคาด
- อาการคล้ายกันใน Ceph ในอดีตเกี่ยวข้องกับสาเหตุสองอย่าง
- ถูก compile โดยไม่มีการรองรับ TCMalloc
- ถูก compile โดยไม่มี cmake flags และ compiler optimization ที่เหมาะสม
- แพ็กเกจ upstream Ceph Ubuntu มี TCMalloc รวมอยู่แล้ว
- ตรวจพบจาก build log ของแพ็กเกจ Ubuntu 17.2.7 ว่า RocksDB ไม่ได้ถูก build ด้วย compile flags ที่ถูกต้อง
- Canonical และ Gentoo แก้ปัญหานี้ใน build ของตนเองแล้ว
- ผู้ใช้ Debian/Ubuntu cephadm ที่ใช้ upstream container ดูเหมือนไม่ได้รับผลกระทบ
- เมื่อ build แพ็กเกจ custom 17.2.7 ที่แก้แล้ว เวลา compaction ลดลงราว 3 เท่า และสมรรถนะ 4KB random write เพิ่มขึ้น 2 เท่า
การทดสอบขยายในสัปดาห์แรกของปี 2024
- วันที่ 2 มกราคม การทดสอบสมรรถนะล่าช้าเพราะต้องรับมือเหตุขัดข้องขนาดใหญ่ของอีกคลัสเตอร์ที่เกี่ยวข้อง
- ตั้งแต่วันศุกร์จึงกลับมากำหนดค่า CBT และการทดสอบใหม่ คราวนี้สามารถใช้ drive ครบ 10 ตัวต่อโหนดได้
- เพิ่มจำนวน FIO client ให้โดยเฉลี่ยมี FIO client ประมาณ 1 ตัวที่
io_depth128 ต่อ OSD - การทดสอบ 3 โหนดทำได้ 63GiB/s ใน 4MB random read
- การทดสอบ 10 โหนดทำได้ 213.5GiB/s
- scale เกือบเป็นเส้นตรงเมื่อเทียบกับ 3 โหนด อยู่ที่ระดับ 98.4%
- ตอนนั้นจาก 68 โหนด มีเพียง 63 โหนดที่ใช้งานได้
- วาง 32 โหนด, 320 OSD ไว้ฝั่งหนึ่ง
- รัน FIO process 10 ตัวต่อโหนดบน client node 31 เครื่อง
- ที่ขนาด 320 OSD ทำได้ 635GiB/s read และ 4KB random read เกิน 15 ล้าน IOPS
- latency เฉลี่ยและ tail latency ดูสม่ำเสมอในการทดสอบขยาย
- คาดว่าเกิดจากการเพิ่มจำนวน PG และ FIO client พร้อมกับ OSD
- การทดสอบอยู่ในสภาวะ IO หนักมาก และน่าจะเข้าสู่จุดที่เพิ่ม IO เข้าไปอีกก็ไม่เพิ่มสมรรถนะ มีแต่ latency เพิ่มขึ้น
ทำได้ 1 TiB/s บน 630 OSD
- เนื่องจากไม่มี client node แยกต่างหากเพิ่มเติมสำหรับการทดสอบเต็มความจุ จึงวาง FIO process ร่วมบน OSD node
- มีโอกาส 1/63 ที่ client จะสื่อสารกับ OSD ในเครื่องเดียวกัน จึงได้ประโยชน์ด้านเครือข่ายเล็กน้อย
- ในทางกลับกัน การวาง FIO client ร่วมบน OSD node อาจทำให้เสียสมรรถนะได้
- การ deploy ด้วย CBT ที่สร้าง 630 OSD บน 63 โหนดใช้เวลาราว 15 นาที
- ความพยายามครั้งแรกได้ราว 950GiB/s ใกล้ 1 TiB/s มาก
- จากนั้นลด OSD shard และ async messenger thread และใช้ Reef RocksDB tuning
- สมรรถนะ read ลดลงเล็กน้อย และสมรรถนะ write ดีขึ้น
- สมรรถนะ random write ดีขึ้นเกือบ 20%
- ดูเหมือนผลที่ใหญ่กว่ามาจากการเปลี่ยน shard/thread
- ยังทดลองเพิ่มจำนวน PG เป็นสองเท่าและเพิ่มจำนวน client อีกครั้ง
- 4MB random read ดีขึ้นเล็กน้อยตามจำนวน client ที่เพิ่มขึ้น
- IOPS ของ small random read แย่ลง
- ที่ FIO 8 ตัวต่อโหนด รวม 504 process สมรรถนะ sequential write ลดลงมาก
- เมื่อ FIO process 504 ตัวทำ 4MB write, PG บางส่วนเข้าสู่สถานะ active+clean+laggy
- แม้ throughput จะเป็นเพียงส่วนหนึ่งของความสามารถของคลัสเตอร์ แต่ laggy PG เพิ่มขึ้นตามเวลา
- คลัสเตอร์ไม่ฟื้นจากสถานะดังกล่าวจนกว่า workload จะจบ
- ตามเอกสาร Ceph ในสถานะ laggy, replica ไม่สามารถ acknowledge lease ใหม่จาก primary ได้ทัน ทำให้ IO หยุดชั่วคราว
- สุดท้าย ค่าเริ่มต้นของ Ceph คือ 8 shards, 2 threads ต่อ shard, 3 msgr threads เหมาะกับ 4MB read ที่สุด
- ภายใต้เงื่อนไข 256K PG, 630 OSD, FIO client process 504 ตัว
ceph -sแสดง 1.0 TiB/s read- OSD ทั้ง 630 ตัวอยู่ในสถานะ up/in
- PG ทั้ง 262145 ตัวอยู่ในสถานะ active+clean
- งาน read ที่แสดงคือ 266.15k op/s
ผลลัพธ์ 6+2 erasure coding
- คลัสเตอร์ปลายทางเดิมจริงของลูกค้าเป็นคอนฟิก 6+2 erasure coding จึงต้องทดสอบแยกต่างหาก
- เลือกค่า PG, shard และ client ที่ทำงานได้ดีในการทดสอบก่อนหน้าเพื่อทดสอบ EC
- เห็นว่า async messenger thread ทำงานหนัก จึงทดลองเพิ่มจากค่าเริ่มต้น
- ที่ async msgr thread 4~5 ตัว ได้สมรรถนะดังนี้
- อ่าน: เกิน 500GiB/s
- เขียน: เกือบ 400GiB/s
- เหตุที่ 6+2 EC read ช้ากว่า 3X replication คือความต่างของ network overhead
- ใน replication, primary OSD เพียงอ่านข้อมูล local แล้วส่งให้ client ทำให้ network overhead โดยพฤตินัยเป็น 1X
- ใน 6+2 EC, primary ต้องอ่าน 5 จาก 6 chunk จาก replica เพื่อประกอบ object แล้วจึงส่งให้ client
- network overhead รวมของ request อยู่ราว
(1 + 5/6)X
- สำหรับ write ภาพกลับกัน
- 3X replication มี network overhead รวม 3X เพราะ client ส่ง object ให้ primary แล้ว primary ส่งต่อไปยัง secondary อีกสองตัว
- ใน EC แค่ส่ง 7/8 chunk ไปยัง secondary จึงให้สมรรถนะดีกว่าสำหรับการเขียนขนาดใหญ่
- IOPS ของ IO ขนาดเล็กเป็นอีกประเด็นหนึ่ง
- ในการอ่าน/เขียนขนาดเล็กมาก Ceph จะเข้าถึง OSD ทั้งหมดที่เข้าร่วมใน PG ของ object นั้น
- แม้ข้อมูลที่สนใจจะอยู่ใน chunk เดียว ก็ยังดึงข้อมูลจาก OSD ทั้งหมดที่เข้าร่วมใน stripe
- Clyso ได้นำ PR ที่ implement partial stripe reads ของ erasure coding ในฤดูร้อนปี 2023 กลับมาปัดฝุ่น และให้ผลชัดเจน
- ยังไม่ชัดเจนว่าจะ merge เข้า Squid ได้หรือไม่
ผลของการเข้ารหัส msgr
- เพื่อประเมินผลกระทบกรณีลูกค้าใช้การเข้ารหัสระดับ msgr จึงทดสอบ msgr v2 encryption ด้วย
- เปรียบเทียบผลเมื่อเปิดการเข้ารหัสในทั้ง 3X replication และ 6+2 erasure coding กับผลก่อนหน้า
- ผลกระทบมากที่สุดเกิดกับ large read
- ลดจากราว 1 TiB/s เหลือราว 750GiB/s
- รายการอื่นลดลงอย่างนุ่มนวลกว่าแต่สม่ำเสมอ
- ยังต้องการทดสอบ PG scaling และ kernel RBD ด้วย แต่ต้องส่งระบบคืนให้ลูกค้าเพื่อทำ re-imaging และผสานเข้าระบบ
สรุปสมรรถนะสูงสุดสุดท้าย
- ค่าสูงสุดที่ทำได้ในการทดสอบมีดังนี้
| รายการ | 30 OSDs (3x) | 100 OSDs (3x) | 320 OSDs (3x) | 630 OSDs (3x) | 630 OSDs (EC62) |
|---|---|---|---|---|---|
| Co-located FIO | No | No | No | Yes | Yes |
| 4MB Read | 63 GiB/s | 214 GiB/s | 635 GiB/s | 1025 GiB/s | 547 GiB/s |
| 4MB Write | 15 GiB/s | 46 GiB/s | 133 GiB/s | 270 GiB/s | 387 GiB/s |
| 4KB Rand Read | 1.9M IOPS | 5.8M IOPS | 16.6M IOPS | 25.5M IOPS | 3.4M IOPS |
| 4KB Rand Write | 248K IOPS | 745K IOPS | 2.4M IOPS | 4.9M IOPS | 936K IOPS |
- หลังจบการทดสอบ ฮาร์ดแวร์ทั้งหมดถูก re-imaging และ OSD ใหม่ถูก deploy เข้าไปในคลัสเตอร์ HDD เดิมของลูกค้า
- ใช้ upmap-remapped script ของ Dan เพื่อควบคุมการ migration และข้อมูลเดิมราว 80% ถูกย้ายไปยัง OSD ที่ใช้ NVMe
- ช่วงแรกตัดสินใจยังไม่ใช้ tuning ทั้งหมดที่ใช้ในการทดสอบทันที แต่จะตรวจสอบการทำงานของคลัสเตอร์ด้วยคอนฟิกส่วนใหญ่เป็นค่าเริ่มต้นก่อน
- ข้อมูลการทดสอบสามารถใช้ปรับแต่งระบบเพิ่มเติมในอนาคต หากลูกค้าพบปัญหาสมรรถนะ
งานที่เหลือและข้อจำกัดการขยาย
- ปัญหา laggy PG ที่เกิดภายใต้โหลดเขียนขนาดใหญ่ยังต้องได้รับการแก้ไข
- สถานการณ์ที่ Ceph ล้มลงเมื่อ workload เขียนใหญ่ขึ้นเป็นสิ่งที่ยอมรับไม่ได้
- การทดสอบครั้งนี้ยืนยันว่า Ceph สามารถใช้ NIC 2×100GbE ได้เต็ม
- หากใช้ NVMe drive มากกว่า 10 ตัวต่อโหนดและต้องการ throughput สูงขึ้น จำเป็นต้องใช้ 200GbE ขึ้นไป
- IOPS ซับซ้อนกว่า
- จำนวน PG อาจส่งผลมาก
- OSD threading model ก็มีบทบาทสำคัญ
- ในหลายการติดตั้งเจอกำแพง random read IOPS ราว 400K~600K ต่อโหนด
- จุดที่ถูกระบุว่าสามารถปรับปรุงได้คือ interface ระหว่าง async msgr กับเคอร์เนล และวิธีที่ OSD thread ถูกปลุกเมื่อมีงานใหม่เข้ามาใน shard queue
- เคยแก้โค้ด OSD เพื่อให้ผลดีขึ้นภายใต้โหลดสูง แต่มีต้นทุนคือ latency ที่โหลดต่ำแย่ลง
- การเพิ่ม IOPS ต้องใช้แนวทางหลายด้านและอาจต้องเขียนโค้ด OSD threading บางส่วนใหม่
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
Ceph มีประวัติที่น่าสนใจ
ผู้ก่อตั้ง DreamHost สร้างขึ้นเพราะความต้องการภายใน และก่อนที่คำว่า IaaS กับ PaaS จะเป็นที่ยอมรับในวงการ DreamHost ก็ให้บริการในลักษณะนั้นอยู่แล้ว เช่น VPS, OS/ฐานข้อมูล/แอปเซิร์ฟเวอร์แบบมีการจัดการ
ต่อมาได้แยก Ceph ออกมาเป็นบริษัท และ Red Hat ก็เข้าซื้อกิจการ
https://en.wikipedia.org/wiki/DreamHost
เป็นยุคที่ไม่มี ถ้อยคำการตลาด ที่ขัดเกลาทุกประโยคเพื่อขายของ แค่แชร์สิ่งที่กำลังลองเล่นกันอยู่
เท่าที่จำได้ มันเป็นโปรเจกต์ในมหาวิทยาลัยของหนึ่งในผู้ก่อตั้ง แล้วผู้ก่อตั้งคนอื่น ๆ ก็เข้ามาร่วมสนับสนุน และผมเข้าใจว่า Docker ก็มีจุดเริ่มต้นคล้ายกัน
UCSC เป็นที่ที่มีงานวิจัยด้าน สตอเรจ ดี ๆ ออกมามากมาย
เป็นบทความที่ดี CERN ก็เพิ่งแตะ 1TB/s ได้เมื่อไม่นานมานี้ แต่ทำได้ด้วย EOS(https://cern.ch/eos) ไม่ใช่ Ceph
https://www.home.cern/news/news/computing/exabyte-disk-stora...
อย่างไรก็ตาม คลัสเตอร์ EOS ของเรามีโหนดมากกว่ามาก และส่วนใหญ่ใช้ HDD ส่วน CERN ก็ใช้ Ceph อย่างกว้างขวางเช่นกัน
ผมชอบการทดลองแบบนี้มาก ตอนทำงานเป็นเทคนิคลีดที่ Cisco ผมได้มีโอกาสหรูหราในการตั้งค่า Kubernetes บน bare metal แล้วลองเซ็ตอัป GlusterFS กับ Ceph ด้วยตัวเอง เพื่อเรียนรู้และเปรียบเทียบว่าอันไหนดีกว่า
เท่าที่จำได้น่าจะราวปี 2017/2018 เป็นช่วงเวลาดี ๆ บทความนี้ก็ดีมากเช่นกัน
NVMe SSD บางตัวถูกใช้งานมามากกว่าตัวอื่น ๆ เลยเกิดความต่างกัน เป็นงานที่ไร้สาระสุด ๆ จริง ๆ
อยากให้มีใครลองลดขนาดของโหนดให้เล็กลงกว่านี้ ระบบที่อธิบายไว้ตรงนี้มีดิสก์ 10 ลูกต่อโหนด และใช้ไฟประมาณ 300W/โหนด ก็ตกดิสก์ละราว 30W
โอเวอร์เฮดค่อนข้างสูง และถ้าต้องการ redundancy แม้เพียงเล็กน้อยก็ต้องใช้พื้นที่จัดเก็บไม่น้อย
ถ้าลงแรงด้านวิศวกรรมสักหน่อย น่าจะย่อทั้งระบบลงเหลือหนึ่งในสิบได้ เช่น ทำคอมพิวเตอร์บอร์ดเดี่ยวขนาดเล็กที่มี PCIe lanes 4 เลนสำหรับ NVMe, 2x10GbE (ซ็อกเก็ต SFP+ 2 ช่อง), CPU ARM หรือ RISC-V ที่เร็วพอ และใส่ eMMC หรือสล็อต SD สำหรับบูต
แบบนี้จะลดลงมาได้ถึงระดับไม่กี่โหนด และลดการเปิดรับความเสี่ยงที่ความเสียหายครั้งเดียวจะทำให้ดิสก์ 10 ลูกหายไปพร้อมกัน
น่าจะใส่ระบบแบบนี้จำนวนมากไว้ใน enclosure 4U ได้ และอาจใส่สวิตช์อิสระเต็มรูปแบบ 2 ตัวไว้ใน enclosure เดียวกันเพื่อ aggregate โหนดภายในได้ด้วย
เพราะเป็นโปรเซสเซอร์ armhf การติดตั้งเลยเจ็บปวดมาก แต่พอเริ่มรันได้แล้วก็ทำงานได้ดี แค่ช้าเพราะมี NIC 1Gb ตัวเดียว
ตอนนั้นทำเพื่อเรียนรู้เฉย ๆ
[0] https://www.hardkernel.com/shop/odroid-hc2-home-cloud-two/
เร็ว ๆ นี้จะได้รับ ARM Turing RK1 สองตัวที่กินไฟ 7W ซึ่งแต่ละตัวทำได้ 4GB/s ผ่าน PCIe 3x4 และบอร์ดคลัสเตอร์ Turing Pi 2 ใส่ได้ 4 ตัวในฟอร์มแฟกเตอร์ ITX
ด้วยต้นทุนรวม 820 ดอลลาร์ คาดว่าจะได้มากกว่า 3Gbps ต่อวัตต์
จนถึงตอนนี้ PCIe lanes คือคอขวด แม้แต่ SSD 2TB ราคา 90 ดอลลาร์ก็ระบุว่าได้ 7GB/s บน PCIe 4x4 ดังนั้นยังไม่คิดว่าคอมพิวเตอร์บอร์ดเดี่ยวคือคำตอบที่เหมาะที่สุด
ไลน์ Ampere Altra ดูเหมือนจะรองรับ PCIe 4x128 ที่ 40W ดังนั้น blade 1U ที่ติดเน็ตเวิร์ก 100G ก็น่าสนใจได้
แต่แม้ในโฮมแล็บก็เห็นบั๊กเกี่ยวกับ ARM และ optimization ที่ขาดหายไปมากมาย จึงอาจบอกได้ยากว่าโซลูชันแบบนี้พร้อมสำหรับดาต้าเซ็นเตอร์แล้ว
ถ้าจะทำให้การตั้งค่า Ceph ด้วยอินเทอร์เฟซ 10Gbps ในตอนนี้สมเหตุสมผล มันต้องเล็กจริง ๆ และถูกมาก ๆ
ถ้าเล็กระดับนั้น การมีที่เก็บข้อมูล NVMe แบบ local ในแต่ละเซิร์ฟเวอร์น่าจะดีกว่า
เป็นการคำนวณคร่าว ๆ แบบ 1TB/s × 8 บิต/ไบต์ × 1024GB/TB ÷ 34 โหนด ÷ 300W
ระบบ ARM ที่มีประสิทธิภาพสูงอย่าง Mac mini รุ่นใหม่ใช้ไฟราว 10W ในการใช้งานแบบ interactive และรองรับเครือข่าย 10Gbps ได้ จึงอยู่ที่ประมาณ 1Gbps ต่อวัตต์ตามข้อมูล
กล่าวคือคลัสเตอร์ในบทความต้นทางมีระดับบิต/วินาที/วัตต์ใกล้เคียงกับระบบ ARM ที่มีประสิทธิภาพสูงโดยคร่าว ๆ
การใช้โหนดเล็ก ๆ ดูไม่น่าจะทำให้ประสิทธิภาพจริงดีขึ้น และอาจจะแพงกว่าด้วยซ้ำ ทุกวันนี้ประสิทธิภาพต่อวัตต์ของเซิร์ฟเวอร์แรง ๆ ค่อนข้างดี
อย่างไรก็ตาม นี่คือซอฟต์แวร์โอเพนซอร์สที่รันบนฮาร์ดแวร์ทั่วไป จึงลองทำเองได้ด้วยเงินไม่กี่ร้อยดอลลาร์
เมื่อระบบปฏิบัติการกับอุปกรณ์ NVMe อยู่ห่างกัน คอนโทรลเลอร์ต้องอนุมานเจตนาของคำขอแล้วจัดการ batching และ wear leveling ให้ดีที่สุด จึงเกิดความไม่มีประสิทธิภาพตามธรรมชาติ
ฟีเจอร์ FDP (flexible data placement) ใหม่เป็นความพยายามแก้ปัญหานี้โดยให้ระบบปฏิบัติการมีสิทธิ์ควบคุมมากขึ้น
ทางที่ดีที่สุดคือดึงสิ่งนี้ขึ้นมาฝั่งระบบปฏิบัติการของโฮสต์ และเปิดเผยแฟลชให้เหมือน “อาร์เรย์ทรานซิสเตอร์โง่ ๆ ขนาดยักษ์ที่ต่ออยู่เป็นอุปกรณ์ PCIe” ให้มากที่สุด
ถ้าตัดชั้น abstraction ออกไป ก็น่าจะประกอบเป็นหน่วยฮาร์ดแวร์แบบ Atom ที่มี NIC 100Gbps แบบรวมในตัวและแฟลชในสัดส่วนที่สอดคล้องกัน เพื่อให้ได้ระดับ parallelism ของระบบตามต้องการ
คงเคยมีช่วงเวลาหนึ่งในประวัติศาสตร์ที่ ปริมาณข้อมูลดิจิทัลทั้งหมด ที่ถูกจัดเก็บทั่วโลกแตะ 1TiB เป็นครั้งแรก
วันนั้นแทบจะแน่นอนว่าน่าจะอยู่ภายใน 60 ปีที่ผ่านมา
แต่ตอนนี้ เซิร์ฟเวอร์ขององค์กรที่ค่อนข้างสุ่มสักแห่งกำลังย้ายข้อมูลปริมาณนั้นทุกวินาที ทั้งที่ไม่ใช่ระดับประเทศหรือโครงการวิจัยข้ามชาติด้วยซ้ำ
เป็นบทความที่น่าสนใจ เราใช้คลัสเตอร์สตอเรจ Ceph เพื่อรักษา Docker layer cache
หลังจากย้ายจาก EBS มาเป็น Ceph ความต่างของ throughput มหาศาลมาก ปริมาณงานเขียนเพิ่มจาก 146MB/s และ 3,000 IOPS เป็น 900MB/s และ 30,000 IOPS
จุดที่ดีที่สุดคือแทบจะใช้งานได้เองเลย นอกจากบางครั้งต้องทำอย่าง filesystem trim ก็แทบไม่ต้องดูแล
สำหรับระบบแคชแล้วถือว่าเป็นการปรับปรุงครั้งใหญ่มาก
[0] https://depot.dev/blog/cache-v2-faster-builds
สุดท้ายเมื่อย้ายไปแร็กของตัวเอง ก็ลดต้นทุนลงได้อีกเกือบหนึ่งในสิบ และพอมีความสามารถในการปฏิบัติการภายในเองก็เป็นอิสระขึ้น
ดูจากบล็อกแล้วยังไม่ชัดเจนทันที
ปัญหาแย่ที่สุดที่เจอใน dynamic storage ภายในคลัสเตอร์ไม่ได้เป็นปัญหา I/O ล้วน ๆ
แต่เป็นฝั่งซอฟต์แวร์ storage controller ของ Kubernetes ที่จัดการปัญหาในสภาพแวดล้อมจริงได้ไม่ดี เช่น pod ตายแล้ว PVC ไม่ถูก attach จนกว่า timeout ที่ยาวมากจะจบ และ pod ค้างอยู่ในสถานะ ContainerCreating จนกว่า lock ของ PVC จะถูกปล่อย
เรื่องแบบนี้เกิดขึ้นในหลายคลัสเตอร์ที่ใช้ rook/ceph และ Longhorn
สงสัยว่ามีใครเคยรัน Ceph ในโฮมแล็บบ้างไหม ครั้งสุดท้ายที่เคยดู ความต้องการฮาร์ดแวร์ค่อนข้างสูง
ตอนที่มันทำงานได้ดีมันก็ยอดเยี่ยม แต่ถ้าเกิดปัญหาขึ้นมาจะกลายเป็นเรื่องปวดหัวมาก
ถ้าสนใจ distributed storage เอง สำหรับโฮมแล็บมีตัวเลือกที่ดีกว่า
seaweedfs เสถียรมากมาหลายปีแล้วทั้งในสเกลเล็กและสเกลใหญ่มาก และจริง ๆ แล้วยังย้ายชุด Ceph โปรดักชันไปใช้ตัวนี้ด้วย
ตอนอยู่ในโลก Kubernetes นั้น Longhorn ก็เสถียรเช่นกัน
GlusterFS ก็ยังโอเคอยู่ ถ้าเข้าไปโดยรู้ว่าต้องแลกกับอะไรบ้าง
แต่การทำให้ได้ประสิทธิภาพที่ดีนั้นยากมาก และในคลัสเตอร์ขนาดเล็ก metadata daemon สามารถหยุดทำงานได้ค่อนข้างง่าย
สุดท้ายพอหมดความสนุกก็กลับไปใช้ ZFS บนเครื่องเดี่ยว
ก่อนอื่นต้องจำไว้ว่า Ceph เป็น distributed storage system ดังนั้นการมีหลายโหนดจึงเป็นสมมติฐานพื้นฐาน
เพื่อการเรียนรู้ จะทำให้ทุกอย่างเป็น virtualized บนเครื่องเดียวก็ได้ แต่ถ้ามีเครื่องจริงแยกกันจะดีกว่ามาก
Ceph คล้ายกับ ZFS ตรงที่ชอบการเข้าถึงดิสก์แบบกายภาพ
นอกจากนี้ยังต้องมีการเชื่อมต่อเครือข่ายที่ดีด้วย คิดว่านี่คือส่วนที่คนมักนึกถึงเมื่อพูดถึงความต้องการฮาร์ดแวร์สูงของ Ceph
ตามอุดมคติอย่างน้อยควรเป็น 10GbE และถ้าต้องการประสิทธิภาพสูงกว่านั้นก็ต้องมากกว่านี้ โดยเฉพาะงานอย่าง backfill อาจมีทราฟฟิกเครือข่ายเยอะ
ถ้าหาอุปกรณ์โฮมแล็บได้ถูก 25Gbps ก็ดี, 50Gbps แทบจะเป็นทางตันทางเทคนิค ส่วน 100Gbps ทำงานได้ดี
ถึงอย่างนั้นสำหรับโฮมแล็บ มินิพีซีหรือ NUC ราคาถูกที่มี 10GbE ก็รันได้พอ และให้ประสิทธิภาพกับผลการเรียนรู้ที่ยอมรับได้
จะติดตั้ง Ceph โดยตรงบน bare metal ก็ได้ หรือถ้าอยากไปทาง Kubernetes ในโฮมแล็บ ก็ใช้ Rook(https://rook.io/) ได้
หวังว่าจะช่วยได้ ถ้ามีคำถามเพิ่มเติมก็บอกได้
ระดับนั้นคงเรียกว่าเป็นฮาร์ดแวร์ขนาดใหญ่ไม่ได้เลย
[1] https://ceph.io/en/news/blog/2022/install-ceph-in-a-raspberr...
อย่างน้อยควรเป็น 10Gb และถ้าเป็นไปได้ 40Gb ขึ้นไปจะดี ถ้าใช้ดิสก์จานหมุน ก็ควรมีดิสก์อย่างน้อย 6 ลูกในแต่ละโหนดหลาย ๆ โหนด
ถ้าเป็น SSD ทั้งหมด มีโอกาสสูงที่จะลดจำนวนดิสก์ต่อโหนดลงได้มาก
ลองคำนวณดูเพราะอยากเห็นว่า 1TiB/s เทียบกับขีดจำกัดเชิงทฤษฎีของฮาร์ดแวร์จริงอย่างไร
คลัสเตอร์นี้ประกอบด้วย 68 โหนด และแต่ละโหนดเป็น Dell PowerEdge R6615(https://www.delltechnologies.com/asset/en-us/products/server...)
คอนฟิกที่ใช้คือ R6615 ที่มีช่องไดรฟ์ U.2 10 ช่อง และลิงก์ U.2 ส่งข้อมูลผ่าน PCIe Gen 4 จำนวน 4 เลน เลน PCIe หนึ่งเลนคือ 16Gbit/s และด้วยการเข้ารหัส 128b-132b โอเวอร์เฮดจึงราว 3% ซึ่งแทบมองข้ามได้
ดังนั้นแบนด์วิดท์ลิงก์สูงสุดของลิงก์ U.2 หนึ่งลิงก์คือ 16×4=64Gbit/s หรือ 8Gbyte/s อย่างไรก็ตาม ไดรฟ์ U.2 NVMe ที่ใช้คือ Dell 15.36TB Enterprise NVMe Read Intensive AG ดูเหมือนจะมี throughput การอ่านที่ 7Gbyte/s(https://www.serversupply.com/SSD%20W-TRAY/NVMe/15.36TB/DELL/...) ดังนั้นลิงก์ U.2 8Gbyte/s จึงไม่ใช่คอขวด
เนื่องจากมีไดรฟ์ U.2 10 ตัวต่อโหนด แต่ละโหนดจึงทำ local read I/O ได้สูงสุด 10×7=70Gbyte/s
แต่แบนด์วิดท์เครือข่ายของแต่ละโหนดมีเพียง 200Gbit/s (2×100GbE Mellanox ConnectX-6) หรือ 25Gbyte/s เท่านั้น นี่หมายความว่าในการอ่านจากระยะไกล ไม่สามารถใช้ความสามารถ 70Gbyte/s ของไดรฟ์ได้เต็มที่ และ เครือข่ายเป็นคอขวด
หากสมมติว่าไม่มีคอขวดเครือข่ายเพิ่มเติม 68 โหนดจะให้การอ่านผ่านเครือข่ายได้ 68×25=1700Gbyte/s ผู้เขียนเบนช์มาร์กได้จริงที่ 1TiB/s หรือให้แม่นคือ 1025GiB/s=1101Gbyte/s ดังนั้นจึงอยู่ราว 65% ของค่าสูงสุดเชิงทฤษฎี 1700Gbyte/s
ถือว่าดีทีเดียว แต่ถ้าทุกโหนดสามารถทำให้ลิงก์เครือข่าย 200Gbit/s อิ่มตัวพร้อมกันได้เต็มที่ ในทางทฤษฎีก็น่าจะไปได้ไกลกว่านี้อีกเล็กน้อย
เมื่ออ่านบทความทั้งหมดแล้ว ได้ความรู้สึกว่าความซับซ้อนของ Ceph สร้างภาระต่อ CPU ค่อนข้างมาก แค่การไม่คอมไพล์โมดูลด้วย -O2 (“Fix Three” ที่ผู้เขียนลิงก์ไว้: https://bugs.launchpad.net/ubuntu/+source/ceph/+bug/1894453) ก็ทำให้ในเวิร์กโหลด I/O ล้วน ๆ “บางเวิร์กโหลดอาจช้าลงได้สูงสุด 5 เท่า”(https://bugs.gentoo.org/733316) ซึ่งค่อนข้างน่าประหลาดใจ
การที่เธรด OSD เสีย CPU มากเกินไปกับการจับ IOMMU spinlock ก็ดูแปลกเช่นกัน เห็นด้วยกับข้อสรุปที่ว่า โมเดลเธรดของ OSD ยังไม่เหมาะสมที่สุด
เบนช์มาร์กสังเคราะห์ที่ค่อนข้างเรียบง่ายอย่างอ่าน 100% ไม่ควรทำให้เห็น contention ของเธรด ถ้าส่วนนั้นของสถาปัตยกรรมซอฟต์แวร์ Ceph ออกแบบมาดี นี่เป็นปัญหาที่แก้ไขได้ จึงหวังว่านักพัฒนา Ceph จะให้ลำดับความสำคัญสูงขึ้น
ในแล็บ Ceph upstream มีเครื่องที่ใช้แชสซี 1U รุ่นก่อนหน้าของ Dell แบบเดียวกันและโปรเซสเซอร์ AMD Rome ซึ่งให้ประสิทธิภาพใกล้เคียงกันที่ขนาดพอ ๆ กันคือประมาณ 30 OSD โดยไม่เจอปัญหานี้
ลูกค้าบอกว่าเคยเห็นปัญหานี้ในดาต้าเซ็นเตอร์ของตนมาก่อน และหวังว่าจะสามารถหาสาเหตุร่วมกับ AMD ได้
เมื่อฤดูร้อนที่แล้วได้ทำงานเสริมโมเดลเธรดเดิมของ OSD แบบชั่วคราวอยู่เล็กน้อย เช่น double buffering ของ handoff ระหว่าง async msgr กับ worker thread และการปลุกเธรดแบบ adaptive
ภายใต้โหลด สามารถเพิ่มประสิทธิภาพและประสิทธิภาพการใช้ทรัพยากรได้มาก แต่ต้องแลกกับ latency ที่เพิ่มขึ้นในโหลดต่ำ โดยพื้นฐานแล้ว Ceph จะค่อนข้าง aggressive มากในการปลุกเธรดเมื่อมี I/O ใหม่เข้ามายัง shard ใด shard หนึ่ง
ได้คุยกับนักพัฒนาหลักอีกคนหนึ่ง และทั้งคู่สรุปว่า การยกเครื่องโค้ดเธรดทั้งหมด น่าจะสมเหตุสมผลกว่า
ถ้ามี OSD 320 ตัว ก็จะอยู่ราว 1.6TiB/s
อย่างน้อยตัวเลขที่ผมหาได้ก็เป็นแบบนั้น รีวิวดิสก์ NVMe ระดับ enterprise แบบนี้ก็ไม่ได้มีมากนัก
ถึงอย่างนั้นก็ดูเป็นตัวเลขที่เข้ากันดีกับ NIC ในสเกลนี้ เวิร์กโหลดส่วนใหญ่น่าจะดูเหมือน I/O แบบสุ่มในชั้น storage
สิ่งที่น่าประหลาดใจคือทำไมถึงเลือก โหนด 1U ที่ระบายความร้อนได้ยากกว่า พร้อม SSD 10 ตัว/คอนฟิก NIC 2×100Gb
ถ้าใช้โหนด 2U ที่มี SSD 24 ตัวและ NIC 2×200Gb หรือ 400Gb ก็น่าจะตัดคอขวดเครือข่ายออกได้ และลดพลังงานได้ด้วยเพราะใช้พัดลมที่ใหญ่กว่าและหมุนช้ากว่า รวมถึงมีแพ็กเกจ CPU น้อยกว่า จำนวนคอร์ต่อซ็อกเก็ตอาจมากขึ้นด้วย
จำนวนโหนดที่น้อยลงจะทำให้ขอบเขตผลกระทบเมื่อเกิดความขัดข้องใหญ่ขึ้น แต่ถ้าอยู่ราว 34 โหนดก็ไม่น่าจะเป็นปัญหาใหญ่นัก
ถ้าโหนดน้อยลง ก็น่าจะสร้างเครือข่ายที่แบนกว่าได้ด้วยสวิตช์ประมาณ 4 ตัว
แร็กกับสวิตช์มีอยู่แล้วและใช้งานเพื่อวัตถุประสงค์อื่นอยู่มาก ดังนั้นพื้นที่กายภาพที่เพิ่มขึ้นเพราะ Ceph จึงน้อยมาก :)