RedisRaft (อยู่ระหว่างการพัฒนา) เป็นโมดูลใหม่สำหรับโอเพ่นซอร์ส Redis ที่ทำให้สามารถใช้งานเซิร์ฟเวอร์ Redis จำนวนหนึ่งได้เป็นคลัสเตอร์เดียวที่ทนทานต่อข้อผิดพลาดและมีความสอดคล้องอย่างยิ่ง ตามชื่อของมัน มันขึ้นอยู่กับอัลกอริธึมฉันทามติ Raft และไลบรารี C โอเพ่นซอร์สที่ปรับใช้มัน
RedisRaft นำเสนอความสอดคล้องที่แข็งแกร่งใหม่พร้อมตัวเลือกการทำให้เป็นอนุกรมที่เข้มงวดสำหรับ Redis และระบบนิเวศ Redis โมดูลใหม่นี้ทำให้สามารถใช้ Redis ร่วมกับไคลเอ็นต์ ไลบรารี และประเภทข้อมูลที่มีอยู่ของ Redis ได้ในสถานการณ์นอกแคชที่ต้องการความน่าเชื่อถือและความสม่ำเสมอในระดับสูง
จุดเริ่มต้นของ RedisRaft
RedisRaft เริ่มต้นจาก "โครงการเสริม" ทดลองไม่นานก่อน Redis 5 จะออกวางจำหน่าย API โมดูล Redis ถูกนำมาใช้ใน Redis 4 ซึ่งได้รับการออกแบบมาเพื่อรองรับโมดูลที่ใช้ประเภทข้อมูลและคำสั่งใหม่เป็นหลัก เราต้องการสำรวจว่าเราจะขยาย API ได้ไกลแค่ไหน และใช้โมดูลเพื่อขยาย Redis ด้วยวิธีที่รุนแรงยิ่งขึ้นไปอีก แต่เราก็ต้องการผลลัพธ์ที่เป็นประโยชน์เช่นกัน ซึ่งก็คือตัวเลือกการปรับใช้ที่สม่ำเสมอสำหรับ Redis
คลัสเตอร์ RedisRaft มีความสอดคล้องและความน่าเชื่อถือในระดับเดียวกับที่คาดหวังจากที่เก็บข้อมูลที่เชื่อถือได้และเป็นที่รู้จัก เช่น ZooKeeper หรือ Etcd โดยสรุปใน RedisRaft:
- การเขียนที่รับทราบจะรับประกันว่าจะมีความมุ่งมั่นและไม่สูญหาย
- การอ่านจะส่งคืนการเขียนที่คอมมิตล่าสุดเสมอ
ตามที่คาดไว้จากที่เก็บข้อมูลที่เชื่อถือได้ซึ่งมีระดับความสอดคล้องนี้ การรับประกันดังกล่าวนำมาซึ่งการแลกเปลี่ยนในด้านประสิทธิภาพและความพร้อมใช้งาน ใน RedisRaft:
- การทำงานของไคลเอ็นต์ขึ้นอยู่กับโหนดคลัสเตอร์ที่แลกเปลี่ยนข้อความ ดังนั้นจึงเชื่อมโยงกับเวลาแฝงของเครือข่าย
- ต้องล้างการเขียนไปยังดิสก์ก่อนจะเสร็จสิ้น ดังนั้นจึงเชื่อมโยงกับเวลาแฝงของ I/O ของดิสก์
- คลัสเตอร์จะใช้งานได้ก็ต่อเมื่อโหนดส่วนใหญ่อยู่ในสภาพปกติ แข็งแรง และสามารถสื่อสารกันได้
วิธีการทำงานของ RedisRaft
เมื่อโหลดโมดูล RedisRaft ลงใน Redis แล้ว โมดูลจะเข้าควบคุมการสื่อสารระหว่างโหนดคลัสเตอร์ การจำลองบันทึก Raft หรือสแน็ปช็อต ความคงอยู่ และอื่นๆ แกนหลักของ Redis ยังคงไม่ทราบเรื่องนี้ และเท่าที่เกี่ยวข้อง แกนประมวลผลนั้นทำงานเป็นเซิร์ฟเวอร์แบบสแตนด์อโลนโดยไม่มีการทำคลัสเตอร์ การคงอยู่ หรือการจำลองแบบ
การตั้งค่าคลัสเตอร์ RedisRaft แบบสามโหนดนั้นง่ายพอๆ กับการเริ่มเซิร์ฟเวอร์ Redis สามเซิร์ฟเวอร์ดังที่แสดงไว้ที่นี่:
redis-server --loadmodule /path/to/redisraft.so
นี่คือวิธีการเชื่อมต่อกับเซิร์ฟเวอร์แรกและสร้างคลัสเตอร์ Raft:
10.0.0.1:6379> RAFT.CLUSTER INIT
OK 989645460313dd2ddb051f033c791222
จากนั้นคุณเชื่อมต่อกับเซิร์ฟเวอร์อีกสองเครื่องและเข้าร่วมกับคลัสเตอร์:
10.0.0.2:6379> RAFT.CLUSTER JOIN 10.0.0.1:6379
OK
10.0.0.3:6379> RAFT.CLUSTER JOIN 10.0.0.1:6379
OK
การเข้าถึงคลัสเตอร์
เมื่อตั้งค่า RedisRaft แล้ว เราสามารถเขียนข้อมูลไปยังคลัสเตอร์ของเรา:
10.0.0.1:6379> INCR counter:1
(integer) 1
ได้รับการตอบกลับแสดงว่าการเขียนของเราได้รับการทำซ้ำเพื่อ อย่างน้อย โหนดคลัสเตอร์ส่วนใหญ่ (ในกรณีของเรา 2 โหนด) และผูกมัดกับที่เก็บข้อมูลถาวร
Raft อิงตามแนวคิดผู้นำที่แข็งแกร่ง ซึ่งหมายความว่าการดำเนินการของลูกค้าทั้งหมดควรไปที่โหนดผู้นำและเริ่มต้นจากมัน ในกรณีนี้ ลูกค้าของเราเชื่อมโยงกับผู้นำอย่างแท้จริง แต่ความเป็นผู้นำของคลัสเตอร์นั้นเป็นแบบไดนามิก และลูกค้าอาจไม่จำเป็นต้องรู้ว่าใครเป็นผู้นำ
การลองใช้การดำเนินการเดียวกันกับโหนดผู้ติดตาม (ไม่ใช่ผู้นำ) จะสร้างการตอบสนองนี้:
10.0.0.3:6379> INCR counter:1
(error) MOVED 10.0.0.1:6379
ในฐานะไคลเอนต์ ตอนนี้เราสามารถตรวจจับข้อผิดพลาดนี้ สร้างการเชื่อมต่อกับโหนดผู้นำอีกครั้งตามที่ระบุ และลองใช้คำสั่งของเราอีกครั้ง
แต่ถ้าเราไม่ต้องการที่จะแก้ไขแอปพลิเคชันที่มีอยู่ของเราล่ะ โชคดีที่ RedisRaft สามารถกำหนดค่าให้จัดการสิ่งนี้ให้เราโดยอัตโนมัติ โดยเปิดใช้งาน โหมดพร็อกซีผู้ติดตาม เราสามารถให้โหนดคลัสเตอร์ส่งต่อคำขอของเราไปยังผู้นำโดยอัตโนมัติและตอบกลับเมื่อพร้อมใช้งาน:
10.0.0.3:6379> RAFT.CONFIG SET follower-proxy yes
OK
10.0.0.3:6379> INCR counter:1
(integer) 2
แน่นอนว่าวิธีนี้ง่ายกว่ามาก แต่ส่งผลกระทบต่อเวลาแฝงและโหลดของเครือข่าย เนื่องจากการกดปุ่มที่ไม่ใช่โหนดผู้นำจะสร้างการกระโดดของเครือข่ายเพิ่มเติม
การเปลี่ยนแปลงคลัสเตอร์
เมื่อตั้งค่าคลัสเตอร์ เราได้ดำเนินการสามอย่างที่แตกต่างกัน:
- สร้างคลัสเตอร์บนโหนดเดียว
- เพิ่มโหนดที่สองแล้ว
- เพิ่มโหนดที่สามแล้ว
การกำหนดค่าคลัสเตอร์ RedisRaft ไม่ใช่แบบคงที่ และคุณสามารถเพิ่มหรือลบโหนดเพิ่มเติมได้หลังจากที่สร้างคลัสเตอร์แล้วและในขณะที่ทำงานอยู่
ตัวอย่างเช่น เราอาจจำเป็นต้องเปลี่ยนโหนดที่สามของเรา ขั้นแรก เราเข้าร่วมโหนดใหม่ที่จะมาแทนที่ โปรดทราบว่าเรา "add-then-remove" แทน "remove-then-add" เพื่อหลีกเลี่ยงไม่ให้คลัสเตอร์และข้อมูลอันมีค่าของเราอยู่ในสถานะซ้ำซ้อนที่เสื่อมโทรมระหว่างการเปลี่ยน:
10.0.0.4:6379> RAFT.CLUSTER JOIN 10.0.0.1:6379
OK
ต่อไป เราจะค้นหา ID ที่สุ่มกำหนดให้กับโหนดที่สามของเรา:
redis-cli -h 10.0.0.1 --raw RAFT.INFO | grep 10.0.0.3
node2:id=1739451728,state=connected,voting=yes,addr=10.0.0.3,port=6379,
last_conn_secs=3537,conn_errors=0,conn_oks=1
แล้วเราก็ลบมันออก:
10.0.0.1:6379> RAFT.NODE REMOVE 1739451728
OK
สถานะการเปิดตัว RedisRaft
ในฐานะที่เป็นส่วนหนึ่งของงานพัฒนา RedisRaft เราได้ร่วมมือกับ Kyle Kingsbury (a.k.a Aphyr) เพื่อวิเคราะห์และทดสอบ RedisRaft โดยใช้ Jepsen ซึ่งเป็นกรอบงานที่รู้จักกันดีสำหรับการทดสอบความปลอดภัยและความถูกต้องของระบบแบบกระจาย การทำงานร่วมกันครั้งนี้ส่งผลให้เกิดการวิเคราะห์ที่เผยแพร่นี้
แม้ว่าจะยังอยู่ระหว่างการพัฒนา แต่ฟังก์ชันพื้นฐานของ RedisRaft ส่วนใหญ่ก็ยังคงอยู่ ขณะนี้ เรากำลังดำเนินการเวอร์ชันพรีวิวแรก ซึ่งคาดว่าจะพร้อมใช้งานในอีกไม่กี่เดือนข้างหน้า เมื่อพร้อมใช้งานโดยทั่วไป RedisRaft จะเผยแพร่ภายใต้สิทธิ์ใช้งานแบบคู่ ไม่ว่าจะเป็น GNU AGPLv3 หรือ Redis Source Available License (RSAL)