in Technology

จัดสรรทรัพยากร AWS Lambda อย่างไร ให้ราคาถูกและเร็วที่สุด

มาจัดเรื่อง AWS Lambda อีกสักโพสต์ (ก่อนที่ผมจะสลับไปเขียนเรื่องท่องเที่ยวบ้าง ฮ่าๆ) ซึ่งครั้งนี้ขอเขียนถึงวิธีการเลือกใช้ทรัพยากร อย่างเช่น Memory ให้เหมาะสมที่สุด ทำงานได้เร็วด้วย และต้องคุ้มค่ากับการจ่ายเงินด้วย

ใน Slide ของ Become a Serverless Black Belt ได้พูดถึงเรื่องการจัดสรรทรัพยากรไว้หลายหน้า และในหน้าปิดท้ายของตอน ได้บอกไว้ว่า

Dont’s Guestimate

หมายถึง เรื่องพวกนี้ “อย่าไปเดา” นะหนู เพราะเราไม่สามารถรู้ได้เลยว่า โค้ดที่เราเขียน ใช้ Memory เท่าไร ดังนั้นจะต้องจัดสรรให้มันเท่าไรถึงจะเพียงพอ ซึ่งถ้าจัดให้มากไป ก็เสียเงินจับจองเมมโมรี่ (Allocated Memory) โดยเปล่าประโยชน์, และถ้าจัดให้น้อยไป ก็ใช้เวลาคำนวณนานขึ้น (Computed Time) ไม่ว่าจะทางใด ก็มีผลกับค่าใช้จ่ายที่เกิดขึ้นทั้งคู่.. ความสนุก Serverless มันอยู่ตรงนี้แหละ!!

เลิกเดา แล้วมาคุยกันด้วยข้อมูลดีกว่า

ใน Slide เรื่องเดียวกัน ได้อ้างถึงเครื่องมือตัวหนึ่ง ชื่อ AWS Lambda Power Tuning ที่พัฒนาโดย Alex Casalboni และเขาได้เล่าที่มาในบล็อก AWS Lambda Power Tuning with AWS Step Functions ว่า Serverless Developer ทุกคนมักหลับหูหลับตาเพื่อจัดสรรทรัพยากร หรือไม่ก็ใช้วิธีการ Manual Test เพื่อทดสอบดูทีละแบบ ซึ่งมันก็เสียเวลาและไม่ได้ผลลัพธ์ที่ดีแน่นอน

พี่แกเลยบอกว่า ถ้าเช่นนั้นเรามาใช้วิธี Data-Driven ดีกว่า! แกเลยเริ่มจากทำโพลสำรวจใน Twitter ว่าสิ่งที่สังเกตเห็นมันเป็นจริงไหม

ซึ่งกว่า 50% ในโพล เคยใช้ Memory เท่าไรก็ตั้งไว้แบบเดิมเท่านั้น ไม่ได้สนใจที่จะ Tuning อะไร และครึ่งหนึ่งนิยมตั้งค่าไว้ที่ 128MB ทุก Function ด้วยเหตุผลที่ว่า เพราะมันราคาถูกที่สุดน่ะสิ! ไม่ได้สนใจเลยว่าจะทำงานได้ไวไหม

แต่ไม่ว่าจะเลือกตอบข้อไหน ก็ยังไม่ใช่สิ่งที่ควรทำในการตั้งค่า Memory ให้กับ Serverless อย่าง AWS Lambda

จากนั้นเขาก็เขียนเล่าถึงเหตุผลว่าทำไม Function ทำงานได้ช้า และคอนเซปของการแก้ปัญหาของ (ซึ่งถ้าใครอยากอ่านฉบับเต็ม ไปอ่านได้ที่ AWS Lambda Power Tuning with AWS Step Functions) จนสรุปได้ว่า การ Tuning Memory ทีละลำดับ พร้อมกับทดสอบเรียกใช้ (Invocating) ด้วยจำนวนที่ต้องการ ​กับ Lambda Function ทีละตัว คือหนทางที่เหมาะสม และต้องเป็นการทดสอบแบบ Automate ทั้งหมดด้วย เพื่อความรวดเร็ว จึงเป็นที่มาของเครื่องมือ AWS Lambda Power Tuning ที่ผมกำลังจะเขียนถึง

รู้จักกับ AWS Lambda Power Tuning

เจ้าเครื่องมือ AWS Lambda Power Tuning นี้ ถูกพัฒนาด้วย Node.js โดยจะมี Lambda Function จำนวน 4 ตัว และเราต้องสร้าง Role กับ StepFunction เพื่อใช้มัน

แต่ไม่ต้องตกใจ ว่าจะยุ่งยาก เพราะโค้ดบน Github นาย Alex ได้มีไฟล์ Serverless.yml หรือเป็น AWS CloudFormation Script ไว้ให้เราใช้ Provision Infrastructure เรียบร้อย แต่เราจะต้องรันคำสั่งด้วยเครื่องมือชื่อ Serverless

การทำงานของมันคือ มันจะไปสร้าง Version ใน Lambda Function และกำหนด Memory ทีละช่วงที่เราต้องการ และทดสอบทีละ Version โดยจะหาค่าที่เหมาะสมที่สุดว่า ต้องใช้ Memory เท่าไร ที่สามารถ Compute ได้เร็วสุด และจ่ายเงินถูกที่สุด

ถ้าทำเอง น่าจะใช้เวลามากๆ เลยทีเดียว กว่าจะทดสอบ Lambda ได้ทีละตัว

ตัวอย่างผลลัพธ์ของ AWS Lambda Power Tuning

เช่น ผมมี Lambda Function เพื่อแสดงรายการสินค้า 1 ตัว ผมต้องการรู้ว่า Memory ในช่วง 128 MB – 1024 MB จำนวนเท่าไรจะเหมาะสมที่สุด..

ตัว AWS Lambda Power Tuning ก็จะเรียก Function ของมันมาเรียงเป็น Step ทำงานให้เราดูเป็นกราฟ

เมื่อทำการทดสอบเสร็จ จะสรุปที่ Output ด้านขวามือ เพื่อบอกว่า ควรใช้ Power (Memory) เท่าไร ถึงจะคุ้มค่าที่สุด ด้วย Cost และ Duration Time เท่าไร

ถ้าใครอยากเห็นรายละเอียดการทดสอบแต่ละ Memory ให้เลื่อนลงมาดูด้านล่าง จะมี Output บอกอีกส่วนหนึ่งแบบละเอียด

คราวนี้ ทดสอบครั้งแรก ผมไม่ค่อยเชื่อผลเท่าไร จึงลองทดสอบทั้งหมด 4 รอบ, แต่ละรอบและแต่ละ Memory ผมจำลองให้มีการร้องขอ (Invocation) จำนวน 10 ครั้ง จำนวน 3 รอบ และ 100 ครั้ง จำนวน 1 รอบ ผลที่ได้ออกมา คือ

Execution #1 – Invocation 10

Execution #2 – Invocation 10

Execution #3 – Invocation 10

Execution #4 – Invocation 100

จากผลการทดสอบ แปลว่า Function แสดงรายการสินค้า ถ้าใช้ Memory ที่ 320 MB จะเร็วและถูกที่สุด โดยเราไม่จำเป็นต้องใช้ Memory ถึง 1024 MB ก็ได้ เพราะผลที่ได้อาจจะไม่ต่างกันมาก ไม่ว่าจะมีการเรียกใช้ 10 ครั้งหรือ 100 ครั้ง ต่อเนื่องก็ตาม

(อย่าลืมว่า ค่าใช้จ่ายการ Compute จะปัดเศษขึ้น เป็นหน่วย 100ms นะครับ ไม่ว่าจะ 40.2ms , 80.8ms ก็ถูกปัดไปคิดเงินเป็น 100ms เท่ากัน)

ปล. จุดสังเกต คือ Memory 256 MB จะทำงานได้ช้ากว่า และแพงกว่า ทั้ง 4 รอบเลย ตรงนี้ผมต้องไปตรวจสอบในระดับ Source Code, Logs, หรือใช้ AWS X-Ray ดูต่อว่าทำไม

วิธีการติดตั้ง AWS Lambda Power Tuning ผ่าน Serverless

** หากใครไม่สะดวกติดตั้งผ่าน Serverless สามารถทำด้วยการ Clone git แล้วรันสคริ้ป ซึ่งสามารถดูได้ที่ https://github.com/alexcasalboni/aws-lambda-power-tuning **

ขายของมานาน มาดูวิธีติดตั้งและใช้งานกัน ซึ่งในที่นี้ผมยกตัวอย่างของ MacOS, Linux ส่วนชาว Windows ให้ใช้ PowerShell ดูนะครับ

ความต้องการก่อนติดตั้งใช้งาน

  1. AWS Account จะต้องมีสิทธิ์ใช้งาน ดังนี้
    • cloudformation:*
    • states:*
    • lambda:*
    • iam:CreateRole
  2. เครื่องที่ติดตั้งจะต้องมี npm (วิธีติดตั้ง npm)

ติดตั้ง Serverless Framework และใส่ AWS credentials

$ npm install serverless -g
$ serverless config credentials --provider aws --key XXX --secret YYY

ติดตั้ง AWS Lambda Power Tuning

$ serverless install -u https://github.com/alexcasalboni/aws-lambda-power-tuning

ทำการติดตั้ง Package Dependency

$ cd aws-lambda-power-tuning
$ npm install

สร้าง Config ของ State Machine ในไฟล์ serverless.yml

$ npm run generate -- -A ACCOUNT_ID [-R eu-west-1] [-P 128,256,512,1024]

เช่น

$ npm run generate -- -A 182000046000 -R ap-southeast-1 -P 128,192,256,320,448,512,704,1024

ทำการ Deploy AWS Lambda Power Tuning

$ serverless deploy

วิธีการใช้งาน AWS Lambda Power Tuning

เมื่อติดตั้งเสร็จแล้ว ลองเช็คที่ AWS Lambda Function เรา จะเจอฟังก์ชั่นเพิ่มขึ้นมา ดังนี้

จากนั้นให้ไปดูที่เซอร์วิส Step Function จะพบ State Machine

ให้กดที่ Start Excution

กรอกข้อมูล State Machine Input สำหรับจะใช้ทำงาน โดยมีรูปแบบตามนี้

{
    "lambdaARN": "your-lambda-function-arn",
    "num": 10
}

เช่น

รอสักครู่ จะมี Status บอกเราว่า Successed พร้อมบอกรายละเอียดการทำงาน และผลลัพธ์ ซึ่งถ้ามันขึ้นว่า Failed ให้เราไปดูที่ Exception ได้

การกำหนดค่า State Machine Input

เราสามารถกำหนด parameters ของ input ได้ ดังนี้:

  • lambdaARN (จำเป็น): ARN ของ Lambda Function ที่ต้องการทดสอบ
  • num (จำเป็น): หมายเลขจำนวนที่ต้องการทดสอบเรียกใช้งาน (invocations) ต่อครั้งและต่อ Memory ที่เรากำหนด (อย่างน้อย 5, แนะนำ: 10 – 100)
  • payload (string/object): Input สำหรับใช้ใน Lambda Function ที่ต้องการทดสอบ (ใส่เป็นข้อมูล JSON)
  • parallelInvocation (ค่าตั้งต้น: false): ถ้าเราใส่เป็น true, จะมีการเรียก Execute พร้อมๆ กัน ตามจำนวนที่เราระบุใน num

สรุป

ไม่ยากเลยใช่ไหมครับ สามารถเอาไปใช้ตรวจสอบ AWS Lambda Fucntion ของเราเองได้อย่างรวดเร็วและสะดวก ไม่ต้องทำมือเองท่ีละตัว หรือใช้วิธีการเดา เพื่อความรวดเร็ว และคุ้มค่าที่สุด

อ้างอิง