OOAAOWOOAAOW
LinuxNetworkingGitPythonDockerKubernetesHelmAWS
YouTube
কোর্সসমূহ
আমার লাইব্রেরি
LinuxNetworkingGitPythonDockerKubernetesHelmAWS
YouTube
OOAAOW YouTube Channel
Sponsor OOAAOW

DevOps Lab — Bangladeshi learner-দের জন্য তৈরি

সাবস্ক্রিপশনসাবস্ক্রিপশন নীতি

হোম/aws/মডিউল ১৬
১৬

Lambda — সার্ভার ছাড়া কোড, আর একটা শিক্ষামূলক ব্যর্থতা

কোন স্তরটা কে সামলায়, FaaS-এর বিলিং কেন আলাদা আকৃতির, handler আর event, deployment package ও dependency, cold start, আর এই কোর্সের সবচেয়ে শিক্ষামূলক ব্যর্থতা — একটা কমান্ড `StatusCode: 200` বলছে আর কিছুই হচ্ছে না।

lambdaserverlessfaashandlerlogsiamdebuggingcold start⏱ ~৪০ মিনিট
💡 ধারণা

কোন স্তরটা কে সামলায়

পর্ব ২-এ আমরা IaaS, PaaS আর SaaS নিয়ে কথা বলেছি। এখন চতুর্থ একটা জিনিস: FaaS — Functions as a Service, যার AWS-এর নাম Lambda।

ছবিটা দেখো। ছ-টা স্তর, আর তিনটে কলাম — আর FaaS-এর কলামে তোমার কাছে মাত্র দুটো স্তর থাকে: তোমার কোড আর তোমার ডেটা।

অপারেটিং সিস্টেম প্যাচ করা, runtime বসানো, scaling সাজানো — সব অদৃশ্য। পর্ব ৫-৮-এ আমরা যে চারটে পর্ব খরচ করেছি (সার্ভার, firewall, স্ক্রিপ্ট, টেমপ্লেট) — Lambda-তে ওই চারটে পর্বের কোনোটাই লাগে না।

প্রথমে এটা জাদু মনে হয়। তাহলে EC2-র দরকার কী? উত্তরটা নিচের বাক্সে, আর সেটাই এই সেকশনের আসল কথা: বিলিংয়ের আকৃতি বদলে গেছে।

EC2Lambda
কীসের দামমেশিন চালু থাকার ঘণ্টাকোড চলার মিলিসেকেন্ড
বসে থাকলেপুরো দামশূন্য
সর্বোচ্চ সময়অসীম১৫ মিনিট
অবস্থা ধরে রাখাডিস্কে, স্মৃতিতেনা — প্রতিবার নতুন

এই চারটে সারি থেকে সিদ্ধান্তটা বেরিয়ে আসে, আর এটা প্রযুক্তির প্রশ্ন নয় — কাজের আকৃতির প্রশ্ন:

Lambda জেতে যখন কাজটা থেমে থেমে আসে। একটা স্ক্রিপ্ট যেটা ঘণ্টায় একবার দু-সেকেন্ড চলে: Lambda-তে মাসে ১,৪৪০ বার × ২ সেকেন্ড = ৪৮ মিনিট গণনা। দাম প্রায় শূন্য। EC2-তে ওই একই কাজের জন্য একটা সার্ভার ৭৩০ ঘণ্টা চালু রাখতে হয়, যার ৯৯% সময় সে বসে থাকে।

EC2 জেতে যখন কাজটা সারাক্ষণ চলে। একটা ব্যস্ত API যেটা সেকেন্ডে একশো অনুরোধ নেয়: Lambda-তে প্রতিটা অনুরোধের দাম যোগ হতে হতে একটা সঠিক মাপের instance-এর চেয়ে বেশি হয়ে যায়।

আর তিনটে জিনিস Lambda-তে সরাসরি অসম্ভব:

১. ১৫ মিনিটের বেশি সময় লাগে এমন কাজ। একটা বড় ডেটা প্রক্রিয়াকরণ, একটা ভিডিও এনকোড — সীমাটা কঠিন।

২. একটা সার্ভার যেটা শুনতে থাকে। Lambda ঘটনায় সাড়া দেয়, সে নিজে থেকে একটা port-এ বসে থাকে না।

৩. স্মৃতিতে অবস্থা ধরে রাখা। প্রতিটা কল একটা নতুন পরিবেশ পেতে পারে, তাই "আগের কলের ভ্যারিয়েবল" বলে কিছু নেই।

তাহলে সঠিক প্রশ্নটা কী? "Lambda না EC2" নয়, বরং: "এই কাজটা কি একটা ঘটনায় সাড়া দেওয়া, নাকি একটা চলতে থাকা সেবা?"

ঘটনায় সাড়া দেওয়া — একটা ফাইল আপলোড হলো, একটা সময় হলো, একটা অনুরোধ এলো — Lambda। চলতে থাকা সেবা — EC2 বা একটা container।

আর শেখার সময় একটা ব্যবহারিক পরামর্শ: Lambda-র free tier অসাধারণ উদার — মাসে ১০ লাখ অনুরোধ আর ৪ লাখ GB-সেকেন্ড, আর সেটা চিরকালের জন্য, শুধু প্রথম বছরের জন্য নয়। অর্থাৎ শেখার সময় Lambda-র দাম বাস্তবিকভাবে শূন্য, যেটা EC2-র ক্ষেত্রে সত্যি নয়।
তিনটে কলামে IaaS, PaaS আর function-এর অধীনে তুমি কোন স্তর সামলাও তার তুলনা। প্রতিটা কলাম ছ-টা স্তরের একটা স্তূপ — হার্ডওয়্যার, অপারেটিং সিস্টেম, runtime, scaling, তোমার কোড আর তোমার ডেটা। IaaS-এ হার্ডওয়্যারের উপরে সব কিছু তুমি সামলাও। PaaS-এ scaling-এর কনফিগ, তোমার কোড আর ডেটা। Function-এ শুধু তোমার কোড আর ডেটা, আর বিলিং ঘণ্টা থেকে বদলে চলার মিলিসেকেন্ড হয়ে যায়
নিচের বাক্সটাই সিদ্ধান্তের ভিত্তি — ঘণ্টার দাম বনাম মিলিসেকেন্ডের দাম। কাজের আকৃতিই ঠিক করে দেয় কোনটা, প্রযুক্তি নয়।
💡 ধারণা

Handler আর event — একটা ফাংশনের দুটো অংশ

একটা Lambda ফাংশন আসলে একটা ফাংশন — আক্ষরিক অর্থে, তোমার ভাষার একটা function। AWS ওটাকে ডাকে, আর দুটো argument দেয়।

def lambda_handler(event, context):
    return {"statusCode": 200, "body": "done"}

event — কী ঘটেছে। একটা dictionary, আর তার আকৃতি নির্ভর করে কে ফাংশনটাকে ডেকেছে তার উপর:

কে ডেকেছেevent-এ কী থাকে
S3-তে একটা ফাইল আপলোডbucket-এর নাম, key, আকার
একটা সময়সূচি (cron)শুধু সময় আর একটা id
API Gateway (একটা HTTP অনুরোধ)path, method, header, body
তুমি, হাতেতুমি যা দিয়েছ
DynamoDB-র একটা পরিবর্তনপুরোনো আর নতুন আইটেম

এই বৈচিত্র্যটাই নতুনদের সবচেয়ে বেশি আটকায়, কারণ কোডটা লিখতে হয় একটা নির্দিষ্ট আকৃতি ধরে নিয়ে। আর যেহেতু তুমি জানো না ঠিক কী আসবে, প্রথম কাজটা সবসময় একই:

import json

def lambda_handler(event, context):
    print(json.dumps(event))     # ← প্রথম সংস্করণে এই এক লাইন
    return {"ok": True}

একবার চালাও, লগে event-টা দেখো, তারপর আসল কোড লেখো। অনুমান করার দরকান নেই।

context — চলার পরিবেশ সম্পর্কে তথ্য। এটা কম ব্যবহার হয়, কিন্তু দুটো ঘর সত্যিই কাজের:

context.get_remaining_time_in_millis()   # আর কত সময় আছে
context.aws_request_id                   # এই কলের অনন্য id

প্রথমটা লম্বা কাজের জন্য গুরুত্বপূর্ণ: timeout-এ পৌঁছানোর আগে নিজে থেকে থেমে একটা অবস্থা সংরক্ষণ করা — কারণ timeout-এ AWS ফাংশনটাকে মাঝপথে কেটে দেয়, আর কোনো finally ব্লক চলে না।

দ্বিতীয়টা লগে খোঁজার জন্য — ওই id দিয়ে একটা নির্দিষ্ট কলের সব লাইন খুঁজে পাওয়া যায়।

আর handler-এর নামটা একটা সেটিং, আর এটা একটা সাধারণ বিভ্রান্তির উৎস:

Handler: lambda_function.lambda_handler
          └─ ফাইলের নাম   └─ ফাংশনের নাম

অর্থাৎ lambda_function.py ফাইলের lambda_handler ফাংশন। নাম যা খুশি রাখা যায়, কিন্তু দুটোকে মিলতে হবে — আর না মিললে ভুলটা হয়:

Unable to import module 'lambda_function': No module named 'lambda_function'

বার্তাটা স্পষ্ট, কিন্তু কারণটা সাধারণত অপ্রত্যাশিত: ZIP ফাইলের ভেতরে ফাইলটা একটা ফোল্ডারের ভেতরে চলে গেছে। পরের সেকশনে সেটা নিয়ে।

আর শেষে একটা জিনিস যা জানা দরকার, কারণ এটা একটা আসল ফাঁদ: ফাংশনটা দু-বার ডাকা হতে পারে।

AWS "অন্তত একবার" নিশ্চিত করে, "ঠিক একবার" নয় — নেটওয়ার্কের সমস্যায় একটা ঘটনা দু-বার পৌঁছাতে পারে। তাই একটা ফাংশন যেটা "এই সংখ্যাটা এক বাড়াও" করে, সেটা মাঝে মাঝে দুই বাড়াবে।

সমাধান: ফাংশনটা idempotent লেখো — একই event দু-বার চললেও ফল একই হোক। সাধারণত এটা করা যায় event-এর id-টা key হিসেবে ব্যবহার করে, যাতে দ্বিতীয় লেখাটা একই আইটেমটাই আবার লেখে।
💡 ধারণা

Deployment package — dependency কোথায় যায়

তোমার কোড Lambda-তে পৌঁছায় একটা deployment package হিসেবে — মূলত একটা ZIP ফাইল। আর এখানে একটা প্রশ্ন আসে যেটার উত্তর প্রথমবার অবাক করে: pip install দিয়ে বসানো লাইব্রেরিগুলো কোথায় যায়?

🔒

বাকি অংশটা সাবস্ক্রাইবারদের জন্য

১৬৩টি অংশের ৩৩টি দেখানো হয়েছে, ১৩০টি বাকি

←

আগের module

Boto3 — Python থেকে AWS চালানো

পরের module

DynamoDB — আর পুরো pipeline-টা একসাথে

→