Wall of Text #10: Cloud

จากข่าว SCB Easy ล่มเพราะไปใช้ AWS ผมเดาไว้ใน Facebook ว่าเค้าน่าจะเอา ELB มาแล้ว load balance on premise แล้ว Link พัง น้องเค้าถามว่าเข้าใจว่าหมายถึงอะไร

ย้ำอีกทีว่าเรื่องที่เกี่ยวกับธนาคาร ผมก็เดามั่วไปเท่านั้นแหละ

On Premises

เพิ่งมารู้ว่าการเขียนว่า On Premise นี่ไม่ถูกต้อง ต้องเขียนว่า On Premises เสมอ เพราะ Premises แปลว่าที่ตั้งและมันไม่ใช่รูปพหูพจน์

สำหรับธนาคารแล้ว Server ต่างที่ให้บริการจะอยู่ในศูนย์ข้อมูลของธนาคารเอง เค้าก็เลยเรียกว่า On Premises ก็คือมันอยู่ในที่ตั้งของเรา

มาร์เก็ตติ้งของ Cloud มักจะใช้คำว่า On Premises หมายรวมไปถึงระบบที่ไม่ใช่ Cloud ทั้งหมดถึงมันจะไม่อยู่ที่ออฟฟิศของเราก็ตาม ซึ่งไม่ว่ามันจะถูกหรือผิดมันก็เห็นภาพชัดเจนดีเวลาเราบอกว่าย้ายระบบจาก On Premises ขึ้น Cloud ก็คือย้ายจาก server เดิมไปยังผู้ให้บริการ cloud

Cloud

ทีนี้ถามว่าทำไมธนาคารถึงจะอยากใช้ Cloud? Cloud คืออะไร…

มีตำนานเล่าว่านานมาแล้วมีอุกกาบาตตกลงทุ่งข้าวสาลี ในช่วง Black Friday มีคนเข้ามาซื้อของที่เว็บ Amazon.com เป็นจำนวนมาก Amazon ก็เลยจะต้องจัดซื้อ server มารองรับผู้ใช้งานมหาศาลไม่ให้ล่ม

ทีนี้พอนอกเทศกาล เครื่องมันก็ปล่อยว่างไว้ ทำยังไงดี? Amazon ก็เลยพัฒนา Amazon EC2 ขึ้นมาปล่อยเช่าเครื่อง

ในความเป็นจริงแล้วเรื่องข้างบนขี้โม้ทั้งเพ เพราะ Werner Vogels CTO ของ AWS ก็บอกว่าถ้าเอาเครื่องเหลือมาขายน่ะ 2 เดือนก็ได้ลูกค้ามาจนเครื่องไม่เหลือแล้ว และบริการตัวแรกของ AWS คือ S3 ไม่ใช่ EC2

ไม่ว่าจะจริงหรือไม่จริงแต่เรื่องมีคนเข้าเว็บเยอะบางเวลาเป็นเรื่องจริงที่ทุกคนมีปัญหา ไม่ใช่แค่ Amazon

ระบบลงทะเบียนมหาวิทยาลัยจะมีคนเข้าเยอะมากในช่วงเปิดลงทะเบียน กับเกรดออก

ธนาคารจะมีคนเข้าเยอะในช่วงปลายเดือนไปจนถึงต้นเดือนที่เงินเดือนออก

Startup จะมีคนเข้าเยอะในช่วงเปิดตัวผลิตภัณฑ์ใหม่

กรมสรรพากรจะมีคนเข้าเยอะในช่วงฤดูยื่นภาษี

การที่ระบบล่มส่งผลต่อการดำเนินธุรกิจของหน่วยงานเหล่านี้โดยตรง แล้วจะให้เค้าทำอย่างไร?

ถ้าสุดท้ายแล้วทุกคนซื้อ server มาเพื่อรองรับ spike load เหล่านี้คงจะสิ้นเปลืองมาก และไม่คุ้มทุนที่จะทำ

Cloud อนุญาตให้เราเช่าเครื่องได้เพียงยิง API เข้าไปสั่งเปิดเครื่อง แล้วรอ 2 นาทีให้เครื่องเปิดเสร็จ

Keyword สำคัญคือเช่า เราไม่ต้องมีเงินก้อนที่จะจัดซื้อเครื่องเซิร์ฟเวอร์ราคาแพงอีกต่อไปเพียงแค่จ่ายเงินค่าเช่าเท่านั้นก็สามารถมีเซิร์ฟเวอร์นับร้อยเครื่องได้

ยิ่งไปกว่านั้น สัญญาการเช่าปัจจุบันอยู่ที่ 1 วินาที (ขั้นต่ำ 10) นาที นั่นแปลว่าเซิร์ฟเวอร์นับร้อยเครื่องที่เปิดมารองรับผู้ใช้งานนั้น พอไม่ได้ใช้แล้วจะปิดเมื่อไรก็ได้ แล้วจะไม่เสียค่าอะไรอีกเลย

ไม่ว่าคิดบัญชียังไง Cloud ก็ดูจะคุ้มค่ากว่าเห็นๆ ใช้เท่าไหน จ่ายเท่านั้น เหมือนค่าไฟฟ้าที่ไม่เปิดไฟก็ไม่เสีย

แต่ราคาของ Cloud ไม่ถูก ราคาค่าเช่ามันแพงกว่าค่าเช่าซื้อเครื่องเซิร์ฟเวอร์ไว้เองด้วยซ้ำ แล้วทำไมมันถึงยังน่าสนใจ?

Scale

สิ่งที่ Cloud computing ต้องการเสนอขายไม่ใช่การให้เช่าระบบคอมพิวเตอร์ แต่เค้ากำลังจะขาย “ความสามารถที่จะ scale”

นอกเหนือไปจากการที่เราจะสามารถขยับจาก 0-100 server ได้ในเวลาไม่กี่นาทีแล้วนั้น ผู้ให้บริการ Cloud ยังมีบริการอื่นๆ อีกที่พร้อมจะโตไปกับโปรแกรมของเรา

ถ้าต้องการฐานข้อมูล AWS มีฐานข้อมูลระดับเดียวกับที่ Amazon ใช้ภายในให้บริการ หรือจะเป็น MySQL มาตรฐานก็ใช้ได้

ถ้าต้องการ Message queue AWS ก็มี API เปิดให้ใช้โดยไม่ต้องซื้อซอฟต์แวร์ Message queue ราคาแพง

ถ้าต้องการเก็บข้อมูล AWS มีระบบเก็บข้อมูลไว้ใช้ที่ขนาดแทบไม่จำกัด สามารถเปิดอ่านพร้อมกันได้ 5,500 ครั้งต่อวินาทีต่อโฟล์เดอร์

บริการเหล่านี้ Cloud มีให้เนื่องจากเป็นระบบที่ Application ส่วนมากจำเป็นต้องใช้ แล้วเราจะพัฒนาขึ้นเองทำไมในเมื่อ Cloud ทำให้แล้ว ในราคาที่ถูกกว่า รองรับผู้ใช้งานได้มหาศาล และไม่ต้องนั่งเฝ้าเซิร์ฟเวอร์เอง

Migrating to Cloud

นั่นคือเหตุผลที่ทุกคนกำลังย้ายไป Cloud ในขณะนี้ ถ้าบริษัทไม่ได้ใหญ่มากจนสามารถทำระบบแบบ Cloud ได้ในราคาที่คุ้มทุน และไม่ติดข้อกำหนดอะไรที่ต้องเอาข้อมูลไว้ On Premises การใช้ Cloud ทำให้ระบบมีเสถียรภาพได้ในราคาที่คุ้มค่า

ทีนี้จาก Diagram ของ SCB ซึ่งไม่มีบอกว่าระบบไหนอยู่ที่ไหน ผมเดาว่าสิ่งที่เกิดขึ้นคือ ด้านหน้าของ Experience API โดยปกติแล้วจะมีระบบ Load balancer ที่กระจาย load ให้กับ server ด้านหลังอีกที (Load balancer ทำแค่กระจายโหลดจึงใช้เครื่องน้อยกว่าเครื่องที่ประมวลผล)

ทีนี้ระบบบางส่วนน่าจะถูกย้ายขึ้นไปบน Cloud (ซึ่งเราไม่อาจจะเดาได้ว่ามีอะไรบ้าง) แต่ที่เห็นจากภายนอกคือ Load balancer ถูกย้ายไปด้วย

แต่ไม่ใช่ทั้งแอพที่ถูกย้ายไป ระบบที่อยู่บน Cloud ยังต้องเรียกข้อมูลจากระบบเดิมอยู่ ซึ่งการเชื่อมต่อระหว่าง Cloud กลับมาระบบ On Premises ก็มีอยู่สามวิธีคือ

  1. เรียกผ่านอินเทอร์เน็ตปกติ ข้อเสียคือไม่สามารถเรียกเครื่องที่ไม่มี IP จริงได้
  2. ติดตั้ง VPN แล้วเชื่อมทั้งสองระบบเข้าด้วยกัน
  3. ลากสายจาก Cloud มายังสถานที่เรา ซึ่งแน่นอนว่าแพงมาก

นอกเหนือจาก 1 แล้ว ปัญหาที่เกิดขึ้นได้คือการเชื่อมต่อจะเกิดคอขวดขึ้น เนื่องจากถ้าใช้ VPN การเชื่อมต่อทั้งหมดจะต้องวิ่งผ่าน VPN server ที่ต้องเข้ารหัสข้อมูลก่อนส่งไปปลายทาง หรือสายที่เชื่อมต่อไปยัง Cloud ก็อาจจะมีความเร็วจำกัด

ที่ยังเดาอะไรไม่ได้คือถ้าหากปัญหาอยู่ที่ตรงนี้จริงก็ควรจะสามารถตัดสินใจ Rollback ได้ไม่ยากเพียงแค่สลับไปใช้ Load balancer ชุดเดิม ก็เป็นไปได้ว่า Application อาจจะถูกย้ายไปแล้วทำให้สลับกลับไม่ได้ (เพราะต้องย้ายข้อมูลกลับมาด้วย)

#HugOps

ในคอนเสิร์ท ถ้า Sound Engineer ทำงานออกมาดีจะไม่มีใครรู้เลยว่ามีเค้าอยู่ แต่ถ้าไมค์หอนเมื่อไรทุกคนจะด่าทันที

ในช่วงเวลาที่แอพล่มแบบนี้ก็เช่นกัน เราอาจจะอารมณ์เสียที่เข้าแอพแล้วใช้งานไม่ได้

แต่ Operation ที่กำลังกู้ระบบ โปรแกรมเมอร์ที่นั่งจ้องหาบั๊ก Support ที่รับสายจนคอแห้ง ก็เป็นมนุษย์เหมือนกับเรา

โปรดใจดีกับ Operation

Wall of Text #9: Tree

น้องที่โรงเรียนให้ช่วยติวไปแข่งขันรายการหนึ่ง ซึ่งเราก็เคยไป จำได้ว่าคำถามที่เคยถามมีเกี่ยวกับ Data Structure เลยเล่าเรื่อง Tree ให้ เพราะในมัธยมไม่มีสอน

Tree Data Structure

โครงสร้างข้อมูลแบบ Tree แปลตรงตัวก็คือต้นไม้

แต่ละวงกลมในภาพ มีชื่อเรียกว่า Node แต่ละ Node จะมีตัวพ่อของมันเสมอ ยกเว้นด้านบนสุดของต้นไม้ ซึ่งดันเรียกว่าราก (Root)

Tree ที่อยากจะเล่าถึงเป็นพิเศษวันนี้คือ Binary Tree ซึ่งก็คือ Tree ที่มีลูก 0-2 กิ่ง

Math statement as a tree

การใช้งาน Binary Tree รูปแบบหนึ่งที่น่าสนใจคือเราสามารถแทนสมการคณิตศาสตร์เป็น Tree ได้ เช่น (1 +3) x 5 เขียนได้ดังนี้

ข้อสังเกตอย่างหนึ่งคือการเขียนเป็น Tree ช่วยลดการสับสนได้โดยไม่ต้องใส่วงเล็บ เช่น ถ้าเราเขียนสูตรด้านบนเป็น 1+3 x 5 แล้ว ตามลำดับความสำคัญของ operator เราจะต้องทำคูณหารก่อน คือ 1 + (3×5) ความหมายไม่เหมือนกัน

เมื่อเราแทนสูตรเป็น Tree แล้วก็ทำให้ประโยคไม่กำกวมเช่นเดียวกับการใส่วงเล็บ

Tree traversal

ยังอยู่กันที่ 1+(3×5)
(บทความนี้เผยแพร่ครั้งแรกเขียนว่าใช้ (1×3)+5 แต่รูปผิด เลยขอแก้สูตรให้ถูกต้อง)

เวลาเราไล่ Tree เราสามารถไล่ได้ 2 แบบดังนี้ (สมมุติว่ามองจากซ้ายไปขวา)

Depth first

แปลว่าไล่เอาด้านลึกลงก่อน เราจะได้

  • + จากด้านบนสุดก่อน
  • 1 เกาะด้านซ้าย ไม่มีลูกต่อกลับไปด้านบน
  • x จากด้านขวา
  • 3 จากด้านซ้าย
  • 5 จากด้านขวา

ส่วนมากที่จะพูดถึงต่อไปจะใช้ Depth first เป็นหลัก

Breath first

แปลว่าไล่เอาด้านกว้างก่อน เราจะได้

  • + จากแถวบนสุด
  • 1, x จากแถวที่สอง
  • 3, 5 จากแถวที่สาม

Project อันนึงที่เราเคยทำคือสำรวจความสัมพันธ์ของสองคนบน Steam ใช้ Breath first search เพื่อหาเส้นทางที่สั้นที่สุดระหว่างคนสองคนบน Steam (แต่นี่ไม่ใช่ Tree มันคือ Graph) เช่น

  • เราเป็นเพื่อนกับ A, B, C, …
  • A เป็นเพื่อนกับ A1, A2, A3, A4, …
  • B เป็นเพื่อนกับ B1, B2, B3, B4, …
  • C เป็นเพื่อนกับ C1, C2, C3, C4, …
  • ในชั้นแรกยังไม่เจอเป้าหมาย เราจะดูว่า A1, A2, A3, A4, B1, B2, B3, B4, C1, C2, C3, C4 เป็นเพื่อนกับใครบ้าง
  • A1 เป็นเพื่อนกับ A11, A12, A13, …
  • A2 เป็นเพื่อนกับ A21, A22, A23, …
  • ก็ยังไม่เจอ เราจะดูเพื่อนของ A11, A12, A13, A21, A22, A23, …
  • เราพบว่า A12 เป็นเพื่อนกับเป้าหมาย
  • สรุปว่า เส้นทางที่ใกล้ที่สุดคือ เรา -> A -> A1 -> A12 -> เป้าหมาย

ตอนที่ทำ ใช้สูตรโกงเล็กน้อยคือเราใช้ algorithm นี้สองข้างพร้อมกันเพื่อให้เร็วขึ้น

  • เราเป็นเพื่อนกับ A, B, C, …
  • เป้าหมายเป็นเพื่อนกับ ก, ข, ค, …
  • เอา set {A, B, C}, {ก, ข, ค} มา Intersect เพื่อดูว่าทับซ้อนหรือเปล่า
  • ถ้าไม่มีให้เปิดเพิ่มอีก 1 ชั้นของทั้งสองฝั่ง แล้วเอา set เพื่อนของเพื่อน ทั้งสองคนมา intersect กัน

Notation

นอกจากว่าเราจะไล่ลงด้านลึกก่อนหรือด้านกว้างก่อนแล้ว เรายังสามารถเลือกได้ด้วยว่าหัวของ tree จะอยู่ตรงไหน

กลับมาที่ (1+3)x5

Prefix

สมมุติว่าเราจะไล่ Depth first, Prefix เราจะเขียนหัวก่อนเสมอ ได้ว่า x + 1 3 5

ถ้าย้อนกลับไปอ่านหัวข้อ Depth first จะสังเกตว่าวิธีที่เราไล่ตอนนั้นคือแบบ Prefix

Infix

Infix จะเขียนหัวไว้ตรงกลาง เขียนได้ว่า 1 + 3 x 5

สังเกตว่าวิธีนี้จะเหมือนที่เราใช้เขียนสูตรตามปกติ เพื่อความชัดเจนทุกครั้งเราอาจจะใส่วงเล็บคร่อมเป็น ((1+3)x5) เพื่อไม่ให้กำกวมว่าต้องอ่านจากซ้ายไปขวา

Postfix

วิธีสุดท้ายคือเอาหัวไว้ด้านหลัง เขียนได้ว่า 1 3 + 5 x

Calculation

ประโยชน์อย่างหนึ่งของ Postfix คือเราสามารถหาคำตอบได้ง่ายๆ โดยไม่ต้องใส่วงเล็บ

วิธีการคือ เอาตัวเลขทีละตัวจากซ้ายไปขวามาทดไว้ ถ้าเจอเครื่องหมายให้ดึงตัวทด 2 ตัวล่าสุดมาทำตามเครื่องหมาย แล้วใส่เฉพาะคำตอบคืน

เช่นจากด้านบน (1+3) x 5 เขียนเป็น Postfix ได้ว่า 1 3 + 5 x

  • 1 ทดไว้
  • 3 ทดไว้ เป็น 1 3
  • เจอเครื่องหมาย + เอามาบวกกันได้ 4 แล้วใส่คืน
  • 5 ทดไว้ เป็น 4 5
  • เจอเครื่องหมายคูณ เอามาคูณกันได้ 20 เป็นคำตอบสุดท้าย

ถ้าเป็นรูปนี้ 1+(3×5) เราจะเขียน Postfix ได้ว่า 1 3 5 x +

  • 1 3 5 x ทดไว้ เจอเครื่องหมาย x เอาสองตัวล่าสุดคูณกัน 3 x 5 = 15 ใส่คืน
  • ตอนนี้ที่ทดอยู่คือ 1 15
  • 1 15 + เจอเครื่องหมายเอามาบวกกันได้ 16

ข้อสังเกตเวลาเราใช้เครื่องคิดเลขที่รองรับการป้อนข้อมูลแบบ Postfix

  • เราไม่ต้องทดเลขไว้ในใจ เช่นถ้าจะกด (1+3) x (2+5) เราต้องกด 1+3, 2+5 แล้วเอาคำตอบมาคูณกัน (อาจจะใช้ระบบ MS ของเครื่องคิดเลข) แต่ถ้าเป็น Postfix เราสามารถกด 1 3 + 2 5 + x ได้เลย
  • เราไม่ต้องกดเครื่องหมาย = เพื่อหาคำตอบสุดท้าย เพราะตัวสุดท้ายเป็นเครื่องหมายคณิตศาสตร์เสมอ

Tree ใช้ตอนไหน

นอกเหนือจาก Binary Tree ที่มีแค่สองขาแล้ว Tree ธรรมดาก็มีประโยชน์หลายอย่าง เช่น

Abstract Syntax Tree

เวลาเขียนโปรแกรมแล้ว Compile ตัว Compiler จะสร้าง Tree จากโปรแกรมของเรา

เช่นโปรแกรมนี้

if (x == 0) {
   x = x + 1;
}
print("%d", x);

เขียนเป็น Tree ได้ว่า

ซึ่งถ้าเราลองคิดตาม Tree แบบ Depth first ดูก็จะพบว่าได้ลำดับการทำงานเหมือนกับโปรแกรมเดิมเลย ซึ่งช่วยให้ compiler สามารถแปลงโค้ดโปรแกรมต่อเป็นภาษาเครื่องได้ง่าย

หาข้อมูล

เราสามารถใช้ Tree เก็บข้อมูลเพื่อให้หาข้อมูลได้ง่ายๆ เช่น

จากภาพนี้ถ้าเราต้องการหาคำว่า bag ว่ามีหรือไม่ เราก็ไล่ไปทีละตัว คือ b, a, แล้วชั้นสุดท้ายพบว่าไม่มี g แสดงว่าไม่มีคำนี้

เมื่อเทียบกับการเขียนทุกคำคือ app, apt, ape, ace, act, bad, ban, bat แล้วไล่จากซ้ายไปขวา การใช้ tree ไวกว่ากันเยอะ