Serverless Big Data Architecture on Google Cloud Platform @ Credit OK | EP 1

สวัสดีครับทุกท่าน สืบเนื่องจากที่ผมได้ทำงานอยู่ที่ Credit OK ซึ่งเป็น Fintech Startup ที่ต้องใช้เทคโนโลยีสำหรับจัดการกับ Big Data แบบเป็นเรื่องเป็นราว มาตั้งแต่ตอนต้นปี 2018 โดยเริ่มต้นจากไม่มีอะไรเลย จึงได้มีโอกาสได้ศึกษาและเลือกเทคโนโลยีที่จะใช้อย่างอิสระ ได้ทดลองแล้วมาถูกใจกับ Google Cloud Platform (GCP) เพราะบริการที่มีให้ค่อนข้างตรงกับโจทย์ธุรกิจที่ต้องการ นอกจากนั้นยังเป็นบริการที่เข้าไปใช้งานได้เลยผ่านทาง GUI หรือ Library โดยไม่ต้องมากดตั้งเครื่องสักตัว (Serverless) ก็เลยรู้สึกว่าอยากจะมาแบ่งปันประสบการณ์​ที่ได้พบเจอมา และได้มีโอกาสไปพูดเป็นวิทยากรในหัวข้อนี้กับ MSIT ของ ม.เกษตร และในงาน Barcamp Bangkhen 2018 ก็พบว่าหลายคนให้ความสนใจในหัวข้อนี้ จึงเป็นอันควรแล้วจะมาเขียน Blog แบ่งปันความรู้กัน 🙂

สำหรับ Slide ในงาน Barcamp สามารถดูได้จากที่นี่ครับ
Serverless Big Data Architecture on Google Cloud Platform at Credit OK

บทความชุดนี้รู้จะประกอบด้วย 3 episodes ดังนี้ (จะพยายามเขียนให้ได้สัปดาห์ละตอน)

  1. Server & Application Deployment History
  2. Introduction to Google Cloud Platform Big Data Tools
  3. How Credit OK Utilize Google Cloud Platform as a Serverless Big Data Service

EP 1 : Server & Application Deployment History

ใน Episode แรกนี้ จะขอเริ่มกันที่เรื่องประวัติศาตร์ของการ Deploy Server กันก่อน ตั้งแต่ต้น ไปจนถึง Serverless ที่กำลังฮ็อต​ฮิตติดกระแส ผมจะขอแบ่งเป็นยุคๆ ดังนี้

Bare Metal

การเอาคอมพิวเตอร์เครื่องนึงมาตั้งเป็น server วิธีการ Deploy ก็ลง OS อยากใช้โปรแกรมอะไรก็ลงไปเสร็จแล้วก็เสียบเข้ากับ Public IP Internet ทีนี้คนบนอินเทอร์เน็ตก็เข้ามาใช้ได้ละ

แต่เครื่องคอมพิวเตอร์เครื่องนี้ก็จะต้องเปิดอยู่ตลอดเวลาเพื่อรอให้บริการ แถมโปรแกรมส่วนใหญ่ก็มักจะ Utilize ทรัพยากรไม่คุ้มเอาเสียเลย จินตนาเกิดว่าสร้าง Blog ตัวเองขึ้นมาแล้วต้องเปิดคอมพิวเตอร์ทิ้งเอาไว้กับ Network ISP ระดับเทพ ราคาต่อเดือนมหาศาล แต่คนเข้าแทบจะไม่มี แถมเครื่องก็แทบไม่กระดิกอะไรเลยเวลามีคน Request เข้ามา ด้วยเหตุผลต่างๆ เหล่านี้ จึงเกิดเทคโนโลยีในยุคต่อไปขึ้นมา

Virtualization

Virtualization คือการใช้ โปรแกรมจำลอง (Hypervisor) คอมพิวเตอร์เสมือน (Virtual Machine) ขึ้นมารัน Guest Operating System ใช้งานบนเครื่องจริง (Host) อีกทีหนึ่ง (พักเบรกแปบ Jargon overload)​ จากนั้นเราก็ส่ง Request​ จาก Host ต่อเครื่อง Guest เหล่านั้นให้ใช้งานได้จากภายนอก ทำให้เครื่องคอมพิวเตอร์หนึ่งเครื่องสามารถแบ่งทรัพยากรเป็นชิ้นเล็กๆ ให้บริการกับผู้ขอใช้บริการรายเล็กๆ ได้หลายเจ้า (แต่ละเจ้าก็เอาเครื่องจำลองเล็กๆ นี้ไปใช้คนละเครื่อง)​ ช่วยเพิ่ม Utilization ของเครื่องเป็นอย่างดี ลักษณะนี้มีให้ใช้บริการค่อนข้างมากในยุค Cloud ตอนต้น เครื่องเหล่านี้เรียกว่า VPS (Virtual Private Server) การให้บริการระดับนี่เราเรียกว่า IaaS (Infrastructure as a Service)

แต่ทว่า.. สำหรับผู้ใช้บริการแล้ว เวลาจะ Deploy โปรแกรมก็ยังจะต้อง Remote เข้าไปเพื่อติดตั้งโปรแกรมต่างๆ เองอยู่ หรือใครที่มีความสามารถหน่อยก็เขียน Script ให้มัน Deploy อัตโนมัติได้ (มีให้บริการใน cloud ชั้นนำ)​ ซึ่งจริงแล้วครั้งมันไม่ใช่เรื่องง่าย และเวลามีปัญหาก็ดูแลลำบากเพราะเครื่องมันแยกกันอยู่ บางทีอยาก deploy หลายโปรแกรม ใช้ dependency ไม่เหมือนกัน ก็ต้องตั้ง VPS แยกเครื่องละโปรแกรม นอกจากนั้นการทำ Virtualization ยังมี Overhead สูง เพราะโปรแกรมของเรารันบน OS จำลอง ซึ่งจะส่งทอดมาที่ Hypervisor อีกที ทำให้ถ้าวัดในเชิงประสิทธิภาพแล้วมันไม่ได้ดีเท่าที่ควร และถ้ามีโหลดหนักๆ ขึ้นมา การ Auto deployment ก็ทำได้ลำบาก จึงเกิดเทคโนโลยีต่อขึ้นไปอีกชั้นก็คือ

Containerization

ทำไมเราถึงจะต้องมาตั้งเครื่อง Guest มา 1 เครื่องเพื่อโฮส 1 แอป แล้วเกิด Overhead ล่ะ ปัญหามันติดอยู่ตรงที่ว่าแต่ละแอปมันใช้ Dependency ไม่เหมือนกัน เช่นบางแอปเป็น Java อีกแอปเป็น PHP หรือถ้าจะร้ายไปกว่านั้นคือ แอปนี้เก่า ต้องรันด้วย PHP 5 ส่วนอีกแอปเขียนใหม่ต้องรันด้วย PHP 7 เช่นนี้แล้วจึงเกิดการสร้างโปรแกรมขึ้นมาเพื่อครอบเฉพาะในส่วนของ App กับ Dependency (โปรแกรมที่ใช้รันและ library ต่างๆ)​ ของมันเอาไว้ด้วยกัน โดย 1 ก้อนนี้ เรียกมันว่า Container แต่ละ Container สามารถเอาไปรันได้บนแอปที่จำลอง OS ขึ้นอีกชั้นหนึ่ง ซึ่งตอนนี้ที่เป็นที่นิยมกันจนเป็นมาตรฐานไปแล้วก็คือ Docker นั่นเอง ซึ่งผู้ให้บริการก็มักจะมี Image ให้ใช้อยู่แล้ว เราเพียงเขียนโปรแกรมต่อไปลง ซึ่งการให้บริการระดับนี้จะเรียกว่า PaaS (Platform as a Service)

Docker ไม่ได้ทำการสร้างเครื่องใหม่ขึ้นมาให้แต่ละแอป แต่มันใช้ทรัพยากรก้อนเดียวกับเครื่องของโฮส แล้วทำการจำลองส่วนของ Dependency ที่ขาดไปขึ้นมารันเฉพาะใน Container นั้นๆ ทำให้เกิด Overhead น้อยกว่าการทำ VM มหาศาล แต่การจะใช้ Docker นั้น ก็จำเป็นจะต้องเขียน Code สำหรับการลง Dependency ต่างๆ ให้เป็นไปอย่างอัตโนมัติจึงจะสะดวก ทำให้เกิดสิ่งที่เรียกว่า Infrastructure as Code ซึ่งเป็นการเขียน Code เพื่อ Deploy เครื่องจำลองทั้งชุดขึ้นมาลงพร้อมรันแอป ซึ่งมีข้อดีตรงที่ว่า ถ้าแอปของเรามีโหลดเข้ามามาก มันก็สามารถ Spawn เครื่องขึ้นมาเพิ่มได้โดยอัตโนมัติ แล้วกระจายโหลดไปเครื่องที่สร้างขึ้นมาใหม่ เพื่อให้ยังสามารถรับโหลดให้บริการต่อไปได้ และเมื่อไหร่การใช้งานลดลงแล้วก็ลดจำนวนเครื่องลงซะ เพื่อให้จ่ายเงินค่าเครื่องน้อยลง แนะนำให้ไปอ่านใน Blognone: รู้จัก Container มันคืออะไร เพิ่มเติมสำหรับผู้ที่ยังไม่รู้จักครับ

Image result for kubernetes

แต่ Container นั้นความจริงก็ยังรันอยู่บน Server (node) เนี่ยแหละ คำถามคือ ถ้าเรา Deploy Containers จนเครื่องโหลดไม่ไหวแล้วจะทำอย่างไร เราก็จะต้องเพิ่มจำนวนเครื่อง Server นั่นเอง แต่จะทำอย่างไรให้ดูแลง่ายล่ะ เราก็ควรจะมอง Server เหล่านั้นเป็นผืนเดียวกัน แทนที่จะแยกกันหลายๆ ตัว แล้วทำสร้างโปรแกรมขึ้นมาควบคุมว่า Container ไหน ควรจะรันบน Server ไหน และคอยดูแลว่า Container ต่างๆ ยังทำงานได้สุขภาพ​ดี มีการทำ Auto Scaling ให้ ซึ่งโปรแกรมที่พูดถึงนี้มีชื่อเรียกว่า Container Orchestration ซึ่งช่วงหลังมานี่คนส่วนใหญ่จะเลือกใช้ Kubernetes (k8s) กัน ซึ่ง Kubernetes ทำหน้าที่ช่วยจัดการ Container ให้เราทุกอย่าง (ยกเว้นการสร้างใหม่) ตั้งแต่ จับกลุ่มใหม่ขึ้นมาอีก Level เรียกว่า Pod ซึ่งในนั้นอาจจะประกอบด้วย Containers ได้หลายตัวรันด้วยกัน แล้วก็ deploy, replica, destroy ให้เราโดยอัตโนมัติ เพียงแค่เขียนสั่งมันเอาไว้ล่วงหน้าเท่านั้นเอง เมื่อไหร่เครื่องไม่พอก็สามารถต่อ Node เข้ามาเพิ่มเข้าไป ที่เหลือมันจัดการให้หมดเลย (ฟังดูง่ายแต่ความจริงไม่ได้ง่ายอย่างนั้นหรอก 555 กว่าจะเซทให้มัน automate ได้ ไม่ธรรมดา) สามารถอ่านทำความเข้าใจได้เรื่อง Kubernetes แบบง่ายๆ ได้เพิ่มเติมจากเว็บ Blognone: Kubernetes คืออะไร

พอการจัดการ Container ทำได้ง่ายแล้ว จึงเกิดสถาปัตยกรรมแบบใหม่ขึ้นมาอีก เรียกว่า Micro Services เรื่องนี้เกิดขึ้นมาเพราะว่าแอปใหญ่ๆ นั้นดูแลยาก เพราะบางครั้งแอปที่ล่มไปอาจเกิดจาก Module เดียวเป็นต้นเหตุ จึงมีการพยายามแยก module ออกมาเป็นชิ้นเล็กๆ เอาไปรันบน Container ของตัวเอง แล้วให้มันคุยกันระหว่าง Container ทีนี้แต่ละ Module ก็จะได้รับการจัดสรรค์ทรัพยากรอย่างเหมาะสม และเกิดตัวไหนเน่าไป เช่น Commit Code ที่เสียขึ้นไป (โดยไม่ได้ตั้งใจ)​ ก็จะเสียแค่ service นั้นอันเดียว การดูแลก็ดูแลง่ายกว่า เพราะแต่ละทีมดูแลแค่ส่วนของตัวเอง ไม่ต้องกลัวว่าจะไปทำส่วนของทีมอื่นพัง (แต่สิ่งที่ยากคือการแบ่งว่าแต่ละ service จะมีขอบเขตเท่าไหร่ เพราะแบ่งผิดก็จะทำให้ทำงานยากขึ้นซะงั้นเพราะต้องคอยประสานงานข้ามทีม) ทีนี้ก็มีเครื่องมือต่างๆ คอยดูแลเรื่องพวกนี้ให้ ที่มีชื่อเสียงสุดตอนนี้ก็คือ Istio แต่ล่าสุด Kubernetes จะมีตัวจัดการ micro services ให้แล้ว ซึ่งนั่นก็แปลว่าใช้ Kubernetes ตัวเดียวจบ

Serverless

lambda

อย่างที่บอกไปว่า การทำ Kubernetes นั้นเหมือน Concept จะดี แต่การใช้งานจริงนั้นมิใช่ง่ายเหมือนปลอกกล้วยเข้าปาก จำเป็นต้องมีความรู้ในการสร้าง Container และการทำ Orchestration เรียนกันเป็นเดือนถึงจะมั่นใจกล้าใช้บน production คำถามคือ แล้วทำไมเราไม่เขียน Code แล้วก็เอาไปรันได้เลยล่ะ จึงเกิดกลุ่มบริการที่เรียกว่า Serverless ขึ้นมา จิตนาการว่าเราสามารถรัน Code ของเราได้โดยที่ไม่ต้องแตะเรื่อง Infrasturuture เลย การให้บริการในระดับนี้จะเรียกว่า Software as a Service ซึ่งในจุดนี้เรามองว่าโปรแกรมของเราถูกแยกส่วนออกมาใช้งาน 1 ชิ้น ต่อ 1 ฟังก์ชั่น คือมันทำงานเล็กๆ ของมันอันเดียวเหมือน Micro service เลย เราเพียงแค่เขียน Code ใส่ลงไป ในเบื้องต้นจะขอแนะนำสิ่งที่เรียกว่า Google Cloud Functions มันคือบริการที่เราสามารถ Code ของเราขึ้นไปรันได้เลย โดยที่ไม่ต้องตั้ง Server ทาง GCP จัดการ Deploy แอปของเรา ไปถึง Auto Scaling ให้โดยอัตโนมัติ แถมยังคิดเงินตามการใช้งานจริง ขอโชว์รูปนิดนึงว่ามันใช้ง่ายเพียงใด

Step 1 ใส่ Code กด Create

Step 2 เปิดเว็บ

แค่นี้แหละ ทีนี้ก็แก้เอาซิอยากให้มันทำอะไร นอกจากจะใช้เขียนโปรแกรมเล็กๆ แบบนี้ได้แล้ว ก็สามารถเอา Lib ต่างๆ เข้ามาใช้ได้ด้วย (แต่ถ้าใส่ lib เข้ามาเยอะๆ จะทำให้ cold start ช้าลง เอาไว้จะเขียน Blog เรื่อง Cloud Funtions แบบเป็นเรื่องเป็นราวแล้วจะเล่าให้อ่านกันอีกที)

สำหรับภาษาที่มีให้เลือกใช้ตอนนี้ก็มี Node.js 6, Node.js 8 และ Python ซึ่งสำหรับทำเว็บก็ใช้ Node.js ไป ส่วนการใช้งานเพื่อเอามา Process Data นั้น การได้ Python มาเป็นเรื่องที่ดีมาก เพราะสามารถโหลด lib สำหรับจัดการข้อมูลต่างๆ มาใช้งานได้ด้วยแหละ 🙂

ทีนี้เราก็ออกแบบเลยว่าจะมีงานอะไรที่แยกออกมารันด้วยสิ่งเปล่านี้ได้บ้าง ก็แยกออกมา

Generate PDF ด้วย Google Cloud Functions

สำหรับ Credit OK นอกจากเอามาใช้กับ Data แล้ว เรายังเอามาใช้สร้าง PDF ด้วย สำหรับคนที่เคยต้องทำ PDF ก็จะรู้ว่ามันยากลำบากขนาดไหน ตอนหลังมานี้ Project Puppeteer ทำให้เราสามารถรันบน Headless Google Chrome บน Node.js ได้ ยิ่งไปกว่านั้นยิงมีฟีเจอร์ปริ้นหน้านั้นออกมาเป็น PDF ด้วย

นั่นหมายความว่า เราสามารถเขียน PDF โดยใช้ภาษา HTML/CSS แล้วมันจะ render ออกมาเหมือนกับที่เรากด print จาก Google Chrome ซึ่งช่วยให้ชีวิตง่ายมหาศาล!!!

Code ตรงนี้ เราสามารถเอาไปรันบน Google Cloud Functions ได้ โดยส่ง HTML และ Config ต่างๆ เข้าไปใส่ใน Post Request จากนั้น Cloud Function ก็จะรัน Render PDF แล้วส่งไฟล์กลับมาให้แบบสวยๆ จะ Render นานหรือไม่อยู่กับปริมาณ Content ซึ่งจากที่เคยใช้งานนั้นไม่เกิน 10 วินาทีจาก cold start ถ้าปรกติไม่เกิน 5 วินาทีก็เสร็จละ

การสร้าง PDF นั้นเป็นงานที่ใช้ Computational Power สูง จินตนาการว่าถ้าเราจะต้องสร้าง PDF พร้อมกันหลายๆ ไฟล์ เราก็จะต้องตั้งเครื่องมาเผื่อสถาการณ์นี้ไว้ แต่หากเปลี่ยนเป็นการ Generate แค่ HTML แล้วโยนขึ้นไปบนนั้น ทางฝั่ง Server ของเราก็จะแค่รอ Response กลับมาจาก GCF ซึ่งกิน Computational Power น้อยกว่ามาก แล้วอยากจะรันพร้อมกันเยอะขนาดไหนก็รันไปเลย ตรวจใดที่ยัง Query Database มาสร้าง HTML ได้ทัน เพราะว่า GCF auto scale ให้อัตโนมัติ แถมยังจ่ายเฉพาะเท่าที่รันด้วย และราคาถูกมากถ้าใช้งานไม่ได้เยอะ

ส่วน Code สำหรับรันฟังก์ชั่นนี้ เราได้ Open Source เอาไว้บน GitLab สามารถเอาไปใช้งานกันได้ตามสบายครับ https://gitlab.com/creditok/puppeteer-pdf-report-server 🙂


น่าจะพอหอมปากหอมคอสำหรับ Episode แรกนะครับ คงจะได้เห็นการเปลี่ยนแปลงของเทคโนโลยีในฝั่ง Deployment และข้อดีข้อเสียไปบ้างไม่มากก็น้อย สำหรับผู้อ่านท่านใดเห็นว่ามีเนื้อหาส่วนไหนที่คลาดเคลื่อนไปจากความเป็นจริง หรือมีคำถามอะไร ก็สามารถ Comment พูดคุยกันไว้ได้นะครับ แล้วใครมีไอเดียน่าสนใจเรื่องการนำ Google Cloud Functions ไปใช้แบบเจ๋งๆ เล่าให้ฟังกันได้เช่นกัน

ก่อนจะจากกัน ผมขอประชาสัมพันธ์นิดนึง ตอนนี้ Credit OK กำลังขยายทีมนะครับ เรากำลังตามหา Laravel Developer และ Risk Analyst ที่จะมาวิเคราะห์ข้อมูลเพื่อประเมินความเสี่ยงของผู้คนจาก Big Data สำหรับรายละเอียดสามารถเข้าไปดูกันได้ที่นี่เลยครับ https://jobs.blognone.com/company/creditok
แล้วเจอกันใหม่สัปดาห์หน้า 🙂