what-is-cluster
what-is-cluster

หลังจากหลงเข้ามาโลก Backend ซักพักใหญ่ๆ ทําให้ได้เรียนรู้ภาพทั้ง flow ของ Frontend ไปยัน Backend จนจบ flow จริงๆ 🙂

ซึ่งหัวใจหลักๆ ของ Backend เลยน่าจะเป็นเรื่อง Reactive Manifesto ตามที่ได้เขียนไปในบทความนี้แล้ว Akka สุดยอด Reactive tool เพราะฉะนั้นจะเห็นได้ว่าหลักๆของ Backend Architecture นั้นอะมีแค่เรื่อง

  • Clustering
  • Reactive Manifesto

เป็นหลัก เพราะฉะนั้นแปลว่า ถ้าเราสนใจที่จะเข้ามาเหยียบโลกนี้ เราควรที่จะเข้าในภาพรวมของ 2 อย่างนี้ให้ดีที่สุดก่อนจะได้ไม่งง….เพราะที่เหลือมันก็คือแค่ Tools (puppet,consul,etc..) และ Feature ทั่วไปของ Business Logic มากกว่า ซึ่งเรียนรู้ได้ไม่ยาก เพราะก็คือแค่จําว่า Flags ไหนเป็น Flags ไหน? มี Rules อะไรบ้าง? ทํา Non-functional test รึยังเป็นต้น

ดังนั้นวันนี้มาเรียนหัวข้อหลักของ Backend ซึ่งนั้นก็คือ Cluster นั้นเอง ซึ่งยังยึด Akka toolkit เป็นหลักเหมือนเดิม เพื่อใช้อธิบายๆส่วนต่างๆน่ะ เพราะส่วนตัวคิดว่าเจ้า Concept นี้ดีสุดล่ะ 🙂 หัวข้อสําคัญๆที่วันนี้จะพูดถึงคือ

  1. อะไรคือ Cluster?
  2. อะไรคือ Akka Cluster?
  3. อะไรคือ Etcd & ConstructR?

อะไรคือ Cluster?

what-is-cluster
what-is-cluster (https://www.slideshare.net/poojakhatana1/cluster-computing-288866430)

สมัยก่อนคนจะชอบสร้าง computer เครื่องนึงที่แบบว่าสุดยอดคอมพิวเตอร์มากๆประมวลผลแรงๆ เพื่อใช้ในการประมวลผล แต่สมัยเปลี่ยนไปเราใช้วิธี computer หลายสิบหลายร้อยเครื่อง เพื่อมาทํางานเดียวกันแทน เพื่อเพิ่ม reliability ให้กับระบบมากกว่าที่ single computer เครื่องเดียวทํางานให้ เช่น สมมุติน่ะว่า เราปล่อยเครื่องทํางานมา 365 วันเต็มๆ อยากปิดเครื่องเพื่อพักระบบหรืออัพเกรดอะไรซักอย่างเราก็ทําไม่ได้ ไม่งั้นลูกค้าทั้งหมดมีการพังแน่ๆ แต่ถ้าเป็น Cluster model มันจะสามารถปิดเครื่องนึงแล้วก็ปล่อยให้เครื่องที่เหลือทํางานได้แทน 🙂

โดยพื้นฐานแล้ว Clusters จะมีอยู่ 3 แบบคือ

  1. High Performance
  2. High Abailability (Failover)
  3. Load-balancing

High Performance Cluster

มันมีชื่อเรียกอีกอย่างว่า Beowulf Cluster

beowulf-clustering
beowulf-clustering (http://www2.hawaii.edu/~zinner/101/students/MitchelBeowulf/cluster.html)

เป็นอารมณ์ประมาณ เราต้องการคํานวณค่าอะไรมากๆๆๆๆๆๆ เช่น Data mining (ทุกวันนี้มี Bitcoin ด้วย) หรือ จําลอง Simulation อะไรซักอย่าง ทําให้ต้องใช้ workstations หลายๆตัวมาประกอบรวมกันแล้วควบคุมด้วย computer เครื่องนึง เพื่อแสดงผลลัพธ์ออกมา

ลองคิดง่ายๆก็ ตัวอย่างเวลาที่เราต้องใช้ Cluster แบบนั้นก็คือ เวลาเราทําหนัง Monster University เนี่ย ใช้เวลา render ถึง 29 hours เพื่อ single frame เดียว … ถึงแม้เค้าจะมีเครื่อง workstation ถึง 2,000 computers กับอีก 24,000 cores ก็ตามที !!!

pixar-renderfarms
pixar-renderfarms (http://www.slashfilm.com/cool-stuff-a-look-at-pixar-and-lucasfilms-renderfarms/)

High Availability (Failover)

บางทีเวลาเราทํา Application เนี้ย มันอยู่ใน Scale ที่เราจะปล่อยให้อยู่ดีๆเครื่องดับไป เว็ปดับไปดื้อๆไม่ได้น่ะ มันเลยมี concept ของ Failover ขึ้นมา โดยมีเงื่อนไขว่าอย่างน้อยต้องมีสอง Node เพื่อเป็น Primary และ ตัว Backup ให้กันเสมอ

failover-cluster
failover-cluster (http://networksandservers.blogspot.com/2011/04/failover-clustering-i.html)

Load-balancing

สุดท้ายเจ้าตัวยอดนิยม 🙂 นั้นก็คือ Load-balancing cluster ที่ทุกบริษัทใช้กัน concept ของมันก็คือเมื่อ request จํานวนมหาศาลวิ่งเข้ามาที่ cluster ประเภทนี้ cluster จะเช็คว่า server ไหนไม่ได้ทํางานและส่ง request ไปที่ server นั้นๆ

load-balancing-components
load-balancing-components (https://msdn.microsoft.com/en-us/library/ff648960.aspx)

โดยปกติแล้ว Load-balancing จะมีคุณสมบัติของ Fail-over อยู่ในตัวด้วยอยู่แล้ววว (เพราะมันมีหลาย node ต่อๆกันนั้นเอง)

แต่รู้มั้ยสิ่งที่น่าห่วงที่สุดอีกอย่างนึงของการใช้ Load-balancing คือเรื่องอะไร? … นั้นคือเรื่องของ session managment!

ลองจินตนการถึง ภาพเวลาที่ request 1 วิ่งเข้า server 1 เกิดเป็น session A หลังจากนั้น load มันถูก Shift ไปที่ server 2 … อ่าว แล้วทําไงอ่ะ??? มันก็มีหลายอย่างคือถ้า

  • configure ให้ Load balancer ทํา Sticky session นั้นๆ ไปกับ specific instance ได้ เช่น request 1 สร้าง session A ใน server 1 ต่อไปก็จะเข้าที่นั้นตลอดเป็นต้น
  • หรือจะแชร์ asynchronous exchange of session state แบบด้านล่างก็ได้
load-balancing-asynchronous-session
load-balancing-asynchronous-session (https://msdn.microsoft.com/en-us/library/ff648960.aspx)

Tips เล็กๆน้อยๆของ Database กับ Application Scale ใหญ่ๆ

เวลาทํา Application บน Scale ใหญ่มากสําหรับทั่วโลก เช่น เอเชีย, อเมริกา, ยุโรป แปลว่ามันจะต้องมี Cluster กันแยกแต่ล่ะ Data center ด้วยนอกเหนือจากนั้นมันยังต้องมี database แยกกันแต่ละ data center อีกด้วย ไม่งั้นเกิดการ lock ของข้อมูลแน่ๆ ไหนจะเรื่องของ latency ที่แต่ละ DC ต้องส่งข้อมูลเข้ามประเทศเข้ามาเพื่อเก็บข้อมูลลง database อีก เช่นแบบรูปข้างล่างนี้

all-dc-same-database
all-dc-same-database

ดังนั้นเค้าเลยแยก database ออกมาไว้ในแต่ละ data center เพื่อให้การ read/write เร็วขึ้นนั้นเอง

separate-dc-database
separate-dc-database

แต่คําถามสําคัญที่จะพูดถึงก็คือ? ถ้าข้อมูลถูก write ลง database ใน dc1 กับ database ใน dc4 table เดียวกันจะทํายังไง? 🙂 ยังงี้ข้อมูลต้องเกิดการ consistency แน่ๆ และ ลูกค้าด่าโวยวายแน่ๆ เช่น ทั่วโลกเรามี stock ของมือถือเหลือแค่เครื่อเดียว แล้ว DC1 สั่งมือถือเครื่องนี้พร้อมกับตัด stock ไปแล้ว แต่ในเวลาเดียวกัน DC4 เองก็สั่งมือถือเครื่องนี้เหมือนกันและตัด stock ไปเช่นเดียวกัน แปลว่า … ต้องมี ลูกค้าจาก DC1 หรือ DC4 ที่ต้องไม่ได้มือถือแน่ๆ เศร้าใช่มั้ยล่ะ โดนด่าอีก ดังนั้นเวลาใช้ Cluster กับ Scale ทั่วโลกเนี่ย มันจะมีเรื่องของ

Peer-to-Peer Transactional ของ SQL server ขึ้นมานั้นเอง !

sql-server-peer-to-peer
sql-server-peer-to-peer (https://docs.microsoft.com/en-us/sql/relational-databases/replication/transactional/peer-to-peer-transactional-replication)

คือเวลาลูกค้า เข้ามาใช้มันจะกระจายไป read-write ในแต่ละ instance ของ sql server แล้วก็ replicated data กันเอง ถ้าในกรณี instance A เข้าสู่โหมด Maintenance มันก็จะไปอ่านที่ B อย่างเดียวแล้ว Sql server ก็จะมี mechanism ที่ replicate ไป A ได้เอง

replicate-across-dc
replicate-across-dc (https://docs.microsoft.com/en-us/sql/relational-databases/replication/transactional/peer-to-peer-transactional-replication)

เช่นเดียวกับ DC1,DC2,DC3,DC4 ที่ยกตัวอย่างไป มันก็จะ replicate ไปได้ข้าม dc เหมือนกัน 🙂 (performance เป็น ms นาทีที่มัน replicate)

อะไรคือ Akka Cluster?

หลังจากได้เรียนรู้โลกของ Cluster มาแล้ว กลับมาถึง toolkit ของโปรดของเรานั้นก็คือ Akka Toolkit ซึ่งเจ้าตัวนี้ ก็มีความสามารถที่จะทํา clustering ได้ง่ายๆมาให้ด้วยอยู่แล้ว และ อย่างที่เรารู้กันเจ้า cluster เนี่ยจะทําให้เรา decentralized ไม่ยึดติดกับ computer เครื่องเดียวป้องกันเรื่องของ fault-tolerant และทําให้ Scale up/down ตามต้องการได้

เจ้า Akka Cluster มีสิ่งที่น่าสนใจหลายอย่าง แต่หลักๆน่าจะเป็นเรื่องของ Life Cycle และ protocol ที่มันใช้คุยกัน

  • โดยเข้า Akka Cluster หรือ Distributed system หลายๆตัวใช้สื่อสารระหว่างกันคือใช้ Gossip Protocol นั้นเอง โดยหลักการง่ายๆที่เลียนแบบมาจากการขี้เม้าในที่ทํางาน ยกตัวอย่างเช่น Alice เม้าท์มอยให้กับ Bob ฟังเรื่องข่าวลือที่เธอสร้างขึ้น หลังจากนั้น Bob ก็เอาไปเล่าให้ Dave ฟัง ซึ่งขณะเดียวกัน Alice ก็เล่าให้ Eve ฟังด้วย แล้วข่าวลือก็กระจายไปหาบุคคลอื่นๆทั้งบริษัทด้วยจํานวนที่ปริมาณมากขึ้นเรื่อยๆ โดยข่าวลือจะไม่ไปซํ้ากับคนเดิมเพราะรู้แล้ว โดยหลักการณ์นี้เรียกว่า “peer selection” และใช้ใน Distributed system ซะส่วนใหญ่เพื่อกระจายข่าวสารออกไป 🙂
  • เจ้า life cycle สามารถสรุปย่อได้ตามนี้ง่ายๆเลย คือ เมื่อมีการ joining ของ node ใหม่เข้ามา ตัว leader จะเป็นคน set state ให้ node นั้นเป็น up หรือ ถ้า node ไหนออกก็จะถูก set เป็น leaving หลังจากนั้นก็จะเปลี่ยนเป็น exiting จน removed ในที่สุด แต่ในทางกลับกันถ้า node มัน unreachable มันจะถูก mark เป็น down และ removed ในที่สุดแล้ว node พวกนั้นจะต้องเข้าไป joining process ใหม่
    akka-cluster-life-cycle
    akka-cluster-life-cycle (https://blog.codecentric.de/en/2016/01/getting-started-akka-cluster/)

    จริงๆหลักๆก็มีแค่นี้ที่เหลือก็คือการ configure akka cluster ให้ทํางานได้แบบที่เราอยากทํา

akka-cluster-configuration
akka-cluster-configuration (https://doc.akka.io/docs/akka/current/cluster-usage.html)

โดยการเพิ่ม config เข้าไปแบบนี้และใส่ seed-nodes ที่เราจะผูกเข้าไปใน cluster ตามตัวอย่าง Node 1 และ 2 เป็นต้น 🙂

สังเกตุอะไรมั้ย? มันยุ่งยากมั้ยล่ะที่จะต้องมานั่งใส่ node 1 และ 2 โดยใส่ port และอื่นๆ น่าเบื่อมากๆเลยล่ะ แล้วสมมุติอยู่ดีๆมันหายไปล่ะ? ต้องมาเช็คค่าใหม่ แล้ว restart ให้มันอ่านค่าใหม่หรอ? ฟังแล้วน่าเศร้าน่าดูเลยล่ะ มันเลยเกิด technique ใหม่ขึ้นมา เพื่อให้เป็น dynamic มากกว่าเดิมก็คือ

ที่จะช่วยให้ปัญหานี้หมดไป 🙂

อะไรคือ Etcd & ConstructR?

เจ้า etcd มันเป็น distributed reliable key-value store เพื่อเป็นข้อมูลให้กับ distributed system ซึ่งถ้ามองง่ายๆก็เป็นหมือน Mongodb ของ cluster นั้นแหละ เก็บข้อมูลสําคัญๆไว้พื่อให้เอาไปใช้ทําอย่างอื่น เช่น เอาข้อมูล Url หรือ node นั้นเอง (เขียนด้วย Go และใช้ Raft)

ส่วนเจ้า ConstructR นี้เป็น Bootstrapping tool สําหรับ Akka Cluster กับ coordination service (ซึ่งก็คือ etcd นั้นเอง)

ก็คงยังงอยู่ล่ะสิ? อธิบายต่อคือ จําได้ใหม่ในรูปข้างบนตรง seednode เราต้องมานั่งใส่ node ต่างๆเอง และมันมีปัญหาวุ่นวายใจหลายๆอย่างซึ่งก็คือมัน statics มาก จะเปลี่ยนแปลงอะไรทีต้องแก้ไขใหม่ ดังนั้นเราจึงใช้เจ้า etcd กับ constructr ทํางานร่วมกัน โดยจะใช้ etcd เก็บข้อมูลของ node ต่างๆ และใช้ constructR + akka cluster ไปอ่านมันและ joinning กันเอง โดยที่เราไม่ต้องไปยุ่ง ขอให้เพียงแค่เราไป Point configuration ที่ etcd ตัวนั้นๆพอ

/constructr/$clusterName/nodes/$address

โดยเมื่อเราใช้ Plugin 2 ตัวนี้แล้ว server etcd ตัวนั้นมันจะมี path url ที่เก็บข้อมูลของ node นั้นๆตามข้างบนนี้เลย 🙂

สรุปซักที 

โลกของ cluster ช่างกว้างใหญ่นัก 🙂 ยังมีหลายอย่างให้เข้าใจ ให้ศึกษา แต่หลักการณ์ของ cluster concept + reactive toolkit ก็ไม่แตกต่างไปจากนี้หรอก เพราะฉะนั้นนี้น่าจะเป็น concept เริ่มต้นที่ดีสําหรับทุกคนแน่ๆ

Leave a Reply

avatar

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