EP 3: Serverless Big Data Architecture on Google Cloud Platform @ Credit OK

สวัสดีทุกท่าน มาถึงตอนสุดท้ายแล้วนะครับ ซึ่งในตอนนี้ผมจะเล่าถึงวิธีการจัดการกับ Big Data แบบที่ Credit OK ทำอยู่นั้นเป็นประมาณไหน แล้วเราใช้ Serveeless Service จาก GCP อย่างไร เราเจออุปสรรคอะไรบ้าง และแก้ปัญหามาได้อย่างไร

บทความนี้เขียนขึ้นเพราะได้ขึ้นไปพูดที่งาน Barcamp นะครับ ใครสนใจดู Slide เปิดได้จากที่นี่เลย Serverless Big Data Architecture on Google Cloud Platform at Credit OK

บทความชุดนี้ประกอบด้วย 3 episodes ดังนี้

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

สำหรับมือใหม่แนะนำให้ไปอ่านตอนก่อนๆ เพิ่มเติมด้วยครับ


EP 3 : How Credit OK Utilize Google Cloud Platform as a Serverless Big Data Service

ขอเริ่มจากเล่าคร่าวๆ ว่า Credit OK ทำอะไร จะได้มีความเข้าใจในสิ่งที่เรากำลังทำกันก่อน

Credit OK เป็น FinTech Startup ที่มี Mission คือการแก้ปัญหาเรื่องการเข้าไม่ถึงแหล่งเงินทุน ผ่านการพัฒนาระบบประเมินความเสี่ยง (Credit Scoring) ของผู้ที่มาขอสินเชื่อ โดยใช้ Big Data มาประกอบและหาความน่าจะเป็นว่าเขาที่กำลังจะขอสินเชื่อนี้ มีความเสี่ยงที่จะเบี้ยวหนี้ขนาดไหน เพื่อให้สถาบันการเงิน หรือผู้ที่ต้องการให้สินเชื่อการค้ามีมองเห็นข้อมูล และมีระบบประเมินความเสี่ยงที่ชัดเจน โดยการทำ Credit Scoring ของเรานั้นอาศัยข้อมูลทางเลือกอื่นๆ ไม่ว่าจะเป็นข้อมูลแบบสอบถามทางจิตวิทยา ข้อมูลจากอุปกรณ์ ข้อมูลการทำธุรกรรมต่างๆ บลาๆๆ เท่าที่เราจะหาได้ เนื่องจากทุกวันนี้มีข้อมูล Digital มากมาย และนั่นคือความน่าสนใจว่าเราจะสามารถนำข้อมูลเหล่านี้มาใช้ให้เป็นประโยชน์ได้อย่างไร ทั้งการเพิ่มสภาพคล่องทางการเงินในการทำธุรกิจ ไปจนถึงการเพิ่มโอกาสให้คนที่ทุกวันนี้ต้องพึ่งพาหนี้นอกระบบอยู่เพราะสถาบันการเงินมองไม่เห็นข้อมูลของเขา ให้เขาได้รับสินเชื่อในดอกเบี้ยที่เหมาะสม

ต่อมาจะเล่าถึงสถาปัตยกรรมการดึงข้อมูลจากร้านลูกค้าของเราที่กระจายอยู่ทั่วประเทศหลักร้อยร้านที่เป็นระบบแบบ On-premise ให้ขึ้นมาประมวลผลใช้งานได้บน Cloud ไปจนถึงการจัดเก็บและนำข้อมูลมาประมวลผลข้อมูลอย่างไร

ซึ่งองค์ประกอบหลักๆ ก็จะต้องมีโปรแกรมที่ไปลงไว้บนเครื่อง On-premise สำหรับส่งข้อมูลกลับขึ้นมา จะต้องมีระบบสำหรับรับข้อมูลดังกล่าวมาเก็บในถังข้อมูลขนาดใหญ่ และเอาไปประมวลผลจนพร้อมสำหรับการใช้งาน เอาล่ะ เรามาเข้าเรื่อง Technical กันเลย!


System Requirements

มาเริ่มกันที่ระบบเราจำเป็นจะต้องทำอะไรให้ได้บ้าง

  • Data Ingestion (ระบบโหลดและย่อยข้อมูล)
    • ระบบของลูกค้าเราเป็น On-premise (ติดตั้งแยกในแต่ละสาขา) ไม่สามารถเข้าไปสั่งดึงข้อมูลได้ตรงได้จากอินเทอร์เน็ต
    • ต้องอัพโหลดข้อมูลขึ้นมาบน Cloud ผ่านช่องทางที่ปลอดภัย
    • ลูกค้าของเรามีอยู่มากกว่า 400 สาขาทั่วประเทศ
    • โปรแกรมสำหรับอัพโหลดข้อมูลจะต้องถูกติดตั้งบนทุกๆ สาขา
    • โปรแกรมสำหรับอัพโหลดข้อมูลต้องรันบน Windows XP ได้ด้วย 🙄
    • เราไม่มีกำลังลงไปติดตั้งโปรแกรมเองในทุกร้าน ดังนั้นโปรแกรมต้องติดตั้งได้ง่ายมาก มีเสถียรภาพสูง และทำงานได้โดยอัตโนมัติ
  • Data Warehousing
    • สร้าง Data warehouse ที่เก็บข้อมูลได้มาก และไม่ต้องห่วงเรื่อง Maintinance เพราะเราไม่มีคนดูแล Server
    • ต้องง่ายแต่การ Integrate ส่งข้อมูลไปประมวลผลที่บริการอื่นๆ
  • Data Pipeline
    • ต้องสามารถประมวลผลข้อมูลจาก Data warehouse ได้อย่างมีประสิทธิภาพ
    • ต้องตั้งให้ทำงานได้โดยอัตโนมัติได้ และมี Logging ที่ชัดเจน

Data Ingestion

ก่อนอื่นก็ต้องพัฒนาโปรแกรมสำหรับโหลดข้อมูลออกจาก On-premise Database ให้ได้ก่อน ซึ่งโปรแกรมดังกล่าวจะต้องทำงานบน Windows XP ด้วย (เรื่องนี้ทำเอาผมคิดไม่ตกไป 3 วัน 3 คืน) ซึ่งสุดท้ายผมก็นึกขึ้นมาถึง Golang ที่ส่วนตัวเขียนถนัดอยู่แล้ว ก็เลยลองดูแล้วก็สำเร็จจริงๆ ทีนี้ก็เลยหมดห่วงเรื่องฝั่ง Client ไปเลย

ประเด็นต่อมาเป็นเรื่องโปรแกรมที่พัฒนาขึ้นมาต้องติดตั้งง่าย และทำงานโดยอัตโนมัติ ต้องมีข้อมูลขึ้นมาอัพเดททุกวัน เนื่องจากเราเป็น Startup เล็กๆ ไปวิ่งลงทุกร้านทั่วประเทศคงต้องแย่แน่ เราขอให้ทีมที่ดูแลโปรแกรมเหล่านี้อยู่แล้วช่วยลงให้ (โดยพี่ๆ ก็ใจดีค่อยๆ ลงให้จนครบ) เราจึงก็ต้องพัฒนาตัวติดตั้งให้ง่ายที่สุด และโปรแกรมนี้จะต้องตั้ง Task Scheduler โดยอัตโนมัติ ให้โปรแกรมรันเองทุกวันโดยอัตโนมัติ ร้านค้าจะปิดเวลาใกล้เคียงกัน เราก็ดึงข้อมูลก่อนร้านจะปิดนั่นล่ะดีที่สุด

พอ Task Scheduler รันเวลาเดียวกัน Server ก็จะต้องรับโหลดจากร้าน 400 ร้านพร้อมๆ กัน บางร้านก็ข้อมูลเยอะ อาจถึง 50 MB หลังจาก Zip แล้ว ถ้าจะตั้ง Server มารับโหลดก็พร้อมกันขนาดนี้ก็ไม่ธรรมดาละ ทางออกของเราก็คือ ใช้ Cloud Function รับไฟล์มาใส่ Google Cloud Stoage พักไว้ก่อน เวลามี Request เข้ามาพร้อมๆ กัน Cloud Function ก็จะ Scale Up ตัวเองขึ้นมารับ Request ได้โดยอัตโนมัติ พอทำเสร็จแล้วก็จะ Scale Down ไม่ต้องจ่ายเงินค่าเครื่องแต่อย่างใด

แต่ Cloud Function ไม่ได้ตอบโจทย์ไปซะหมด เพราะรับ Request ได้ไม่เกิน 10 MB จึงต้องแบ่งไฟล์ใหญ่จริงๆ ไปรับทาง App กับ Compute Engine แทน โชคดีที่ไฟล์ส่วนใหญ่ส่วนจะแบ่งให้ขนาดไม่เกิน 10 MB ได้


Data Warehousing

ในส่วนของที่เก็บข้อมูล เราก็จะมีข้อมูลอยู่ 2 ประเภท ก็คือ

Files
เก็บบน Google Cloud Storage เตรียมพร้อมสำหรับโหลดเข้าไปใส่ใน Google BigQuery แล้วยังถูกใช้ในการ Export และ Backup ด้วย

Structured Data
ข้อมูลที่ Process ทำความสะอาดแล้ว เก็บลง Google BigQuery งาน Data Pipeline ที่ใช้ SQL ทำได้ก็ทำบนนี้เลย


Data Pipeline

  1. Zip file ที่ข้างในเป็น CSV จะถูกโหลดขึ้นมาจากทาง Client ส่งขึ้นมาทาง Cloud Function หรือไม่ก็ Compute Engine ขึ้นอยู่กับขนาดไฟล์ แล้วบันทึกไว้บน GCS ที่ถัง Upload
  2. ไฟล์ที่ถูกบันทึกลง GCS แล้ว ก็จะมี Cloud Function อีกตัวที่รอถูก Trigger อยู่ ทำการโหลดไฟล์ขึ้นมา แตก Zip เอา CSV มาแปลง Encoding รวมถึงจัด format ต่างๆ ให้เรียบร้อย แล้วเก็บไว้บน GCS อีกถัง เตรียมพร้อมสำหรับการโหลดไปเป็น Structured Data
  3. ตอนกลางคืน CSV ทั้งหมดจะถูกโหลดผ่าน Dataprep เพื่อทำความสะอาดเพิ่มเติม แล้วจึงโหลดต่อเข้าไปที่ BigQuery
  4. ตัว BigQuery ก็จะมี Data Pipeline ของตัวเองเช่นกัน เขียนด้วยภาษา SQL ที่จะ Process ข้อมูลข้ามจาก Table หนึ่ง ไปอีก Table หนึ่ง จนกระทั้งได้ข้อมูลสำหรับแสดงผลบนฝั่ง Application
  5. ต่อมาเราใช้ Lumen ที่เราใช้เป็น Micro-service (แบบไม่ค่อย micro สักเท่าไหร่) โหลดข้อมูลจาก Big Query แล้วทำการ Caching เอาไว้บนตัวเองทุกวัน หลังจาก Table ในข้อ 4 ทำเสร็จแล้ว เพื่อที่ว่าเวลา Application มาเรียกใช้งานจะได้ไม่ต้องต่อเข้าไปที่ Big Query อีก ไม่เช่นนั้นจะทำให้ช้าและที่สำคัญคือเปลืองเงิน นอกจากนั้นยังช่วยให้ตัว Application หลักที่เขียนด้วย Laravel ไม่ใหญ่โตจนเกินไป
  6. สุดท้ายคือ Web Application ที่เขียนด้วย Laravel และ VueJS ทางฝั่งนี้ก็จะดึงข้อมูลจาก Lumen เอาไปใช้แสดงผลได้เลย ข้อมูลเล็กๆ ที่ใช้บ่อยๆ ก็ Cache ไว้กับ Laravel เลย ส่วนข้อมูลที่เรียก On-demand เฉพาะเวลาผู้ใช้เรียกก็ Cache ไว้บน Micro-service จะได้ไม่ต้องเปลือง DB ของ Application และสุดท้ายข้อมูลที่ต้องทำผ่าน Big Query เท่านั้น เพราะด้วยเรื่องเหตุผลของขนาด ก็จะยิงผ่าน Lumen เอา ฝั่ง Laravel จะได้ไม่ต้องวุ่นวาย

จบแล้วสำหรับคำอธิบายวิธีการจัดการกับข้อมูลที่ Credit OK ใช้งานอยู่แบบรวบรัด

ความจริงมีเรื่องสำคัญอีกเรื่องหนึ่งคือการทำ Logging ไม่ได้วาดไว้ใน Diagram แต่จะขอเล่าคร่าวๆ สำหรับ Logging เราทำผ่านทาง Stackdriver โดยตัวของ Google Cloud Functions มันจะเขียน Log ของมันเองอยู่ละ แต่ถ้าอยากได้ละเอียดขึ้นเช่น กำลัง Process ไฟล์อะไร ของร้านไหน ก็สามารถเขียนเพิ่มเข้าไปเองได้ แล้วก็สร้าง Dashboard ขึ้นมาดูว่า Data เข้ามาเป็นยังไง แต่ที่เด็ดกว่านั้นก็คือเราสามารถตั้งให้ Stackdriver Export ข้อมูลลงไปใส่ใน BigQuery ได้ด้วย จากนั้นก็เขียน GCF อีกตัวไป Query ข้อมูลที่ต้องการออกมา จับใส่ JSON แล้ว Render ผ่าน VueJS ก็จะได้ Dashboard ที่สวยงามเอาไว้ดูความเรียบร้อยของฝั่ง Data Ingestion 🙂


สรุปข้อดีจากการใช้ Serverless บน GCP

No server maintenance
เหตุผลเรื่องแรกเลยคือ ไม่ต้องมาดูแล Server เอง คือเราเป็น Startup ทีมเล็ก ถ้าจะต้องมาดูแลฟาร์มก็คงลำบาก จึงเลือกปรับการทำงานให้ใช้งานได้กับบริการที่มีอยู่แล้วก็จะเหมาะกว่า จะได้มีเวลาไปทำงานอื่นเพิ่มขึ้น

Scaleable & high performance
ไม่ว่า Data จะใหญ่ขนาดไหน ก็ไม่ต้องห่วงว่าเครื่องที่มีจะโหลดไม่ไหว เพราะว่า GCP จัดการเรื่องทรัพยากรให้ทั้งหมด ความจริงแต่ละเครื่องมือมันก็มีข้อจำกัดของมันแหละ แต่ใน doc ของ GCP ก็เขียนไว้ค่อนข้างครบถ้วน

Pay as you go
เนื่องจากโจทย์ของเราเป็นงาน Batch Processing ซะมาก จึงได้ประโยชน์จากเรื่องนี้เต็มๆ รันวันละครั้ง ก็จ่ายแค่วันละครั้ง ส่วนค่าเก็บข้อมูลก็ไม่ได้แพงมากมายอะไรอยู่แล้ว ราคาตกอยู่ที่ $0.02/GB เท่านั้น ที่น่ากลัวคือค่า Process ข้อมูลของ BigQuery ซึ่งเดี๋ยวจะเล่าให้ฟังข้างล่าง

อุปสรรคและสิ่งที่ต้องระวัง

Cloud Functions จำกัด Max Request Size ไว้ที่ 10 MB
Cloud functions ไม่ได้เป็นยาวิเศษแก้ปัญหาได้ทุกเรื่อง หนึ่งในข้อจำกัดที่ทำผมเจ็บมากคือ มันจำกัด Max Request Size ไว้ที่ 10 MB ดังนั้นถ้าจะอัพโหลดไฟล์ใหญ่ ฝั่ง Client ต้องแบ่งให้ไฟล์เล็กเสียก่อน หรือไม่ก็ไปใช้ Compute หรือ App Engine แทน
อย่างไรก็ตาม ผมมองว่า HTTP ไม่ใช่ Protocol ที่ดีสำหรับงานอัพโหลดไฟล์อยู่ดี ถ้าจะใช้อัพโหลดไฟล์ใหญ่จากเน็ตช้า ควรไปใช้ท่าอื่นจะเหมาะสมกว่า เช่น rsync ถ้าเป็นไปได้

เลือก Zone สำหรับใช้งานให้ดีตั้งแต่ต้น
แต่ละ Zone ค่าบริการที่แตกต่างกัน ดังนั้นถ้าเลือก Zone สำหรับเก็บ Data เรียบร้อยแล้ว ก็ควรจะ Process กันอยู่ใน Zone เดียวกัน เพื่อความเร็วในการใช้งาน ไม่งั้นถ้าส่งข้อมูลข้าม Zone กันก็จะโดนเก็บเงินค่าส่งข้อมูลอีก การจะต้องย้ายข้อมูลหลัง Production ไปแล้วแม้จะทำได้แต่ก็ไม่สนุกแน่นอน ถ้าไม่ได้ติดขัดอะไรก็ไปใช้ US ผมว่าน่าจะดีที่สุดเพราะราคาต่ำกว่าเพื่อน ส่วนฝั่ง Application ยังไงก็ควรอยู่ Zone ที่ใกล้ผู้ใช้ (ตั้งที่สิงคโปร์) ถ้าข้อมูลอะไรจะใช้รัวๆ ก็ควรจะทำการ Caching ด้วย ยิงข้าม Zone กันไปมาไม่มีอะไรดี

ตรวจสอบค่า Process ของ BigQuery ด้วย
ราคาเก็บข้อมูลของ BigQuery นั้นเท่ากับ GCS เลย ซึ่งไม่แพง แต่มันมีคิดเงินเป็นจำนวนปริมาณข้อมูลที่เอาขึ้นมา Process โดยราคาอยู่ที่ $5/TB ดังนั้นถ้า Table ไหนใหญ่ๆ การ Query แต่ละทีก็จะมี Cost ที่แพงขึ้นไปตามขนาด แล้วถ้าเข้ามาเรียกใช้งานบ่อยๆ ราคามันจะพุ่งทะยานแบบ O(n) ลองจินตนาการถ้าเรา Query ทีละ 100GB ก็จะตกทีละ $0.5 ถ้าทำ 100 ครั้ง ก็ $50 เข้าไปละ (ความจริงอาจไม่ถึงเพราะมันจะ Process ตาม Columns ที่ต้องใช้จริงๆ แล้วก็มี Auto Caching ให้เราด้วยในบางส่วน) ต่อมาถ้า User กดทีแอปเราที มาต่อ Big Query ที มันจะหนักหน่วงขนาดไหน ดังนั้นข้อมูลที่จะต้องถูกเรียกใช้งานบ่อยๆ จึงไม่ควรเอามาไว้ที่นี่ ให้หาทาง Cache บน DB ประเภทอื่น เวลาเรียกใช้งานจะได้เรียกผ่าน Cache เอา ไม่เช่นนั้นจะพบว่ามันแพงมาก!

อยากทราบค่าบริการของ BigQuery เข้าไปดูกันได้ที่นี่เลย https://cloud.google.com/bigquery/pricing เอาจริงๆ ผมว่ามันไม่ได้แพงหรอกถ้าเทียบกับต้องมาเปิด Farm Hadoop ใช้งานเอง แต่ก็ต้องคอยระมัดระวังหน่อยเหมือนกัน

Serverless ใช่ว่าจะมี Resource ไม่จำกัด
มีช่วงหนึ่งที่ GCP มีปัญหาเรื่อง ZONE_RESOURCE_POOL_EXHAUSTED คือ Resource Pool ของ Zone ที่เราใช้เต็มนั่นเอง แล้วพอเกิดเหตุการณ์นี้ขึ้น Job วันนันก็ Fail กันไป ต้องมาตามรันเองในตอนหลัง และที่สำคัญคือเราก็ทำอะไรไม่ได้ด้วย เพราะมันเป็นฝั่ง GCP ต้องสวดมนต์ภาวนาให้ Google แก้ปัญหาโดยเร็ว ซึ่งตอนเหมือนจะกลับมาดีแล้ว
ดังนั้นถ้าจะรันงานที่สำคัญ พลาดไม่ได้ อาจต้องมีแผนสำรองเอาไว้กันด้วยนะครับ


อัพเดท 2018-12-27
Q: คุณ Chamnarn ถามว่าทำไมไม่อัพขึ้น GCS ตรงไปเลย
A: นั่นก็เป็น Option ที่ผมดันมองข้ามไป เพราะว่าก่อนหน้านี้เรามี Pipeline ที่จำเป็นต้องอัพผ่าน HTTPS เท่านั้น เพราะว่าทางฝั่ง Client จำกัดว่าห้ามลงโปรแกรมเพิ่ม การเขียน Script ยิงผ่าน Powershell จึงเป็นทางออกที่ดีที่สุด ผมก็เลยพัฒนา Pipeline แบบเดิมขึ้นมาใช้งาน แต่ปรับตรงเรื่อง Scaling ให้ไปใช้ GCF แทน จนลืมไปว่าความจริงแล้วเราก็ฝัง Credential ไปในแอปของ Go แล้วก็อัพตรงขึ้น GCS ได้เลย แบบนี้ก็จะไม่จำเป็นต้องเป็นห่วงเรื่อง GCF เรื่องขนาดของไฟล์ด้วยครับ


สำหรับตอนที่ 3 นี้ก็ขอจบไว้ที่เท่านี้ครับ น่าจะพอช่วยให้เห็นภาพในงานของ Credit OK ว่าเอา Serverless Big Data Architecture ของ GCP มาใช้งานได้อย่างไร ตั้งแต่โหลดข้อมูลด้วย Cloud Functions ผ่านการ Data Prep ไปจนถึงประมวลผลให้ได้ข้อมูลแบบที่ต้องการด้วย BigQuery สุดท้ายแล้วก็ต้องยกความดีความชอบให้กับ GCP เนี่ยแหละที่สร้างเครื่องมือต่างๆ มีค่อนข้างพร้อม จับอันนี้ต่ออันนั้นใช้งานได้แทบจะทันที แถมในราคาที่ไม่แพงด้วย เมื่อเทียบกับการไปตั้งเครื่องเอง ส่วนตัวผมมองว่า Cloud Functions และ BigQuery จะขึ้นมาเป็นบริการที่จะเป็นตัวชูโรงในอนาคตอันใกล้นี้ อยากให้ทุกคนได้เข้าไปลองเล่นกันดูครับ Google มาโควต้าฟรีให้ใช้ด้วยนะ

เช่นเคยครับ สำหรับท่านใดมีคำถาม คำแนะนำ สามารถพูดคุยกันได้ที่ช่อง Comment ข้างล่างเลย และก่อนจะจากไป Credit OK กำลังขยายทีมอยู่นะครับ ท่านใดกำลังมองหาโอกาสใหม่ที่ท้าทาย อยากร่วมงานกับทีมที่ไฟแรง อยากเรียนรู้ทักษะและเครื่องมือใหม่ๆ สมัครเข้ามาร่วมงานกันได้นะครับ สามารถไปดูประกาศสมัครงานกันได้ที่นี่เลย https://jobs.blognone.com/company/creditok แล้วเจอกันใหม่ครับ 🙂