what-is-raft-example
what-is-raft-example

ช่วงนี้ส่วนใหญ่จะเป็นบทความเกี่ยวกับโลกของ Distributed ซะเป็นส่วนใหญ่ ซึ่งความรู้มันก็จะแตกต่างกับโลกฝั่ง Frontend มากๆ ทั้งเรื่องของ Reactive Manifesto ที่เป็นหัวใจหลักของทุกอย่าง และ tools set ดีๆอย่าง Akka Toolkit กับ basic อย่าง clustering ก็ช่วยทำให้เราเข้าใจภาพกว้างทั้งหมดล่ะ

แต่….เราลืมไรอย่างนึงมั้ย??? ถ้าเครื่องเป็นร้อยเป็นพันเครื่อง แล้วเวลา request เข้ามาเยอะๆ มันจะเข้าเครื่องไหนก่อนอะ????? 1,2,3,4,….,X หรือ อย่าง cassandra หลายร้อยเครื่องมันจะมีวิธีการคุยกันยังไง?

นั้นเลยเป็นที่มาของ Raft Protocol ที่มีไว้เพื่อจัดการ state ให้มัน sync กันตลอดเวลา ซึ่งเจ้า Protocol นี้ใช้กันแบบเยอะมาก ใน distributed system เช่น Cassandra with Raft , etcd , Mongodb หรือพูดง่ายๆอีกอย่างคือ อะไรก็ตามที่เป็น Clustering น่ะ ใช้ Raft กันแทบทั้งหมดเลย

ถ้างั้นอะไรคือ Raft กันล่ะ?

Raft คือ Protocol นึงที่นิยมใช้มากใน Clustering ทั้งหลาย เพราะมันช่วยให้ Cluster นั้นๆเกิดความ consistent กัน และสามารถที่จะ replicate data ได้อย่างถูกต้อง

โดยการที่จะเข้าใจ Raft ต้องมาเข้าใจตัวละครของเรื่องนี้ก่อน

Single-node-system
Single-node-system (http://thesecretlivesofdata.com/raft/)

เจ้าสีฟ้านี้คือ Node System ให้สมมุติว่ามันเป็น database server ก็ได้ มีหน้าที่ไว้เก็บข้อมูล

client-multiple-node
client-multiple-node (http://thesecretlivesofdata.com/raft/)

ส่วนเจ้าสีเขียวคือ Client ที่จะส่ง request เข้ามาหา node system ของเรา ถ้าแบบ 1 ต่อ 1 ก็โอเคอะ มันก็จะส่งข้อมูลกันง่ายๆตรงๆ ไม่มีปัญหาอะไร

distributed-consensus
distributed-consensus (http://thesecretlivesofdata.com/raft/)

แต่ถ้าจาก 1 node system กลายเป็น 3 node ล่ะ?? ข้อมูลจะถูกจัดการถูกต้องได้อย่างไร? เพราะว่าข้อมูลมันจะถูกส่งมาที่ node 1 เท่านั้น เพราะฉะนั้นมันต้องมีการทํา replication แต่ยังไงกันล่ะ?

ทีนี้การจะทํา replication แบบนั้นได้แต่ละ node system ต้องมี 3 states คือ

  1. Follower
  2. Candidate
  3. Leader

โดยทุก node จะเริ่มต้นด้วย Follower โดยถ้า followers ไม่ได้รับข้อมูลอะไรจาก Leader เลยมันจะผลักดันตัวเองออกมาเป็น Candidate (วงกลมเส้นประตามข้างล่าง)

candidate-raft
candidate-raft (http://thesecretlivesofdata.com/raft/)

และจาก node a ที่เป็น candidate มันก็จะเริ่มส่ง request votes ไปที่ node อื่นๆเช่น b และ c (อารมณ์เหมือนเลือกตั้งนายกอ่ะ) หลังจากนั้นเมื่อมัน reply vote กลับมา เจ้า node นั้นก็จะกลายเป็น Leader ซึ่งเราเรียกขบวนการนี้ว่า Leader Election

leader-raft
leader-raft (http://thesecretlivesofdata.com/raft/)

ซึ่งหลังจากเราได้ Leader แล้ว แปลว่า changes ทั้งหมดในระบบจะมาจาก Leader นั้นเอง! 🙂

ทีนี้ย้อนกลับไปที่คําถามตอนแรก ถ้ามี request เข้ามา คร่าวนี้มันจะพุ่งไปที่ Node a ก่อนเลย เพราะมันเป็น leader เช่น สมมุติมี request เข้ามาให้ set ค่าเลข 5 ในระบบ มันก็จะวิ่งไป A ก่อน (โดยทุกการ change จะถูก add ลง Node log ก่อนเลย)

raft-leader-change
raft-leader-change (http://thesecretlivesofdata.com/raft/)

มาถึงจังหวะนี้จะต้องรู้จักคําว่า commit และ uncommit ซึ่งมีความหมายว่ามันจะไป update node อื่นๆหรือยัง อย่างเช่นตอนจังหวะนี้ ค่ามันยังไม่อัพเดต มันแค่เก็บใน Log

เพราะการที่จะ update follower node อื่นๆ ได้ (replicate)

  1. มันต้อทําการส่งข้อมูลไปให้ follower ทั้งหมดก่อน และรอให้ follower ตอบกลับมา
  2. มันถึงจะ commit และ change state เป็น 5 (เอาง่ายๆคือต้องให้ ต้องให้ลูกน้องตัวเอง set ทั้งหมดก่อน ถึงจะ set ตัวเองได้นั้นแหละ 🙂 )
  3. หลังจาก commit เสร็จแล้วมันก็ต้องแจ้งไปที่ node อื่นๆอีกว่า commited แล้วน่ะ
raft-commit-uncommit
raft-commit-uncommit (http://thesecretlivesofdata.com/raft/)

เจ้า process พวกนี้เรียก Log Replication!

ทบทวนก่อนไปต่อ

เห็นมั้ย? ไม่ยากเลย

Node แต่ละ cluster มี 3 types

  1. Follower
  2. Candidate
  3. Leader

มีกระบวนการเลือก Leader โดยการ Vote ผ่านกระบวนการ Leader Election

การจะ replicate data ได้ node พวกนี้จะทํา Log Replication โดยการรับข้อมูลเข้าที่ Leader และกระจายออกไปให้ Follower ก่อน เมื่อ Follower ได้รับค่าทุก node แล้ว ถึงจะ commit ของตัวเองเลงไป และ ส่งไปบอก node ว่า commit แล้วน่ะ 🙂 แค่นี้แหละ

Raft Timeout

แล้วถ้าเกิด timeout ระหว่างการทํา election ล่ะ? Node ต่างๆจะทําไง มันจะเคว้งมั้ยที่ไม่มีผู้นําดีๆ 🙂

เลยเป็นที่มาของ timeout 2 แบบใน Raft

  1. election timeout
    • เวลาทั้งหมดที่ Follower รอจนกว่าจะกลายเป็น candidate โดยปกติอยู่ที่ 150ms ถึง 300ms (โลก Backend เค้าคุยกับเป็นหน่วย ms ไม่ใช่ s น่ะครัช)
    • สมมุติถ้า node ใด node นึงต้องการที่จะเป็น candidate มันจะวัดความเร็วจาก election timeout เนี่ยแหละ ว่าถ้ามันรอครบแล้วก็จะขึ้นจาก follower เป็น candidate แล้วก็เริ่มเข้าทําการ vote ด้วย Leader Election
  2. heartbeat timeout
    • หลังจากนั้นเมื่อมี Leader แล้ว มันจะมี timeout อีกตัวที่ไว้เช็คกับ node อื่นๆว่า มันยังเป็น Leader อยู่น่ะ เราเรียกว่า Hearbeat timeout
    • คือหลังจากส่ง Message ออกไปมันจะ Append Entity ไว้ด้วย เพื่อให้รู้ว่า Node ที่ส่งออกไปเป็น leader และมันจะคอยส่ง message หากันเสมอ และ reset timeout ของ election เพราะมันยังมี leader อยู่ไง 🙂

      heartbeat-raft
      heartbeat-raft (http://thesecretlivesofdata.com/raft/)
    • ถ้าไม่มี heartbeat timeout ยิงเข้าไปน่ะ election timeout มันก็จะครบ และ ก็ทําการเลือกตั้งใหม่ Leader Election นั้นเอง

      re-election-raft
      re-election-raft (http://thesecretlivesofdata.com/raft/)

มีแสบกว่านั้นอีกคือ …. ถ้าเกิด Leader 2 ตัวพร้อมกันล่ะ !!!!

spilt-vote-raft
spilt-vote-raft (http://thesecretlivesofdata.com/raft/)

แต่มันก็ไม่ได้ยาก เพราะมันจะมีการนับ vote count ว่าตัวไหนได้มากสุด แล้วก็ให้ตัวนั้นเป็น แต่ถ้า vote count เท่ากัน มันก็จะทําการ election ใหม่ ให้ได้ตัว vote count มากที่สุดนั้นเอง 🙂 เหมือนเลือกตั้งเป๊ะ….

FYI: มันยึด Vote มากสุดเป็นหลัก ถ้าเกิดปัญหาไรขึ้น เจอตัวที่มี vote มากกว่า Leader ตัวนั้นก็จะ step down ให้อีกตัวนึงขึ้นแทนเสมอ และ replicate ลูกน้องด้วยค่าของ Leader ใหม่ เพื่อให้ Cluster เกิด consistent ตลอดเวลาการทํางานของมัน (เพราะ Reactive Manifesto คือเรื่องของ elastic ที่เราจะเพิ่มลดเครื่องได้ตลอดเวลานั้นเอง)

จบ!

อ่านฉบับจริงได้ที่ Raft Github ซึ่งจะมีของเล่นให้เล่นด้วยน่ะ

raft-github
raft-github (https://raft.github.io/)

รู้ไว้ใช่ว่า เพราะเรื่องของโลก Distributed มันกว้างใหญ่ คนละส่วนกับ Front end มากๆจริงๆ 🙂

 

Leave a Reply

avatar

This site uses Akismet to reduce spam. Learn how your comment data is processed.