Serverless rješenja za EdTech na AWS Lambda u Bosni
Čitanje: 5 minMohammad Shaker

Serverless rješenja za EdTech na AWS Lambda u Bosni

Alphazed koristi AWS Lambda za backend s 95.000+ učenika i 7+ aplikacija, optimizirajući učenje arapskog jezika efikasnom serverless arhitekturom.

Engineering

Brzi odgovor

Alphazed koristi AWS Lambda za backend s 95.000+ učenika i 7+ aplikacija, optimizirajući učenje arapskog jezika efikasnom serverless arhitekturom.

Serverless rješenja za EdTech na AWS Lambda

Alphazed pokreće cijeli svoj backend — koji opslužuje više od 95.000 učenika u preko 50 zemalja — na AWS Lambda uz Serverless Framework. Arhitektura koristi Flask na Lambda funkcijama iza API Gateway-a, MySQL 8 na RDS-u, S3 za distribuciju sadržaja i prilagođeni analytics lake (SQS → Kinesis Firehose → S3 → Glue → Athena). Tanke Lambda funkcije optimiziraju latenciju hladnog starta, a sistem servisira više od 7 aplikacija iz jedinstvene baze koda sa runtime konfiguracijom.

Zašto Serverless za EdTech?

Upotreba edukativnih aplikacija je nepredvidiva:

  • Jutra radnih dana: roditelji preuzimaju aplikaciju prije škole (nagli skok prometa)
  • Popodne radnih dana: vježbe poslije škole (stalni promet)
  • Vikendi: intenzivni maratonski termini (2-3 puta veće opterećenje)
  • Tijekom Ramazana: večernja upotreba raste (porodične kur'anske sesije)
  • Školski praznici: potpuno drugačiji obrasci korištenja

Prednosti serverless pristupa:

  • Naplata po zahtjevu: plaćate samo za stvarnu upotrebu, bilo da je 10 ili 100.000 korisnika u jednoj sekundi
  • Nulti hladni startovi za frekventne dijelove: „Uvijek tople“ Lambda slojeve koristimo za često pozivane endpoint-e
  • Automatsko skaliranje: od 10 do 10.000 korisnika bez promjena infrastrukture
  • Nema održavanja servera: tim se fokusira na nastavni sadržaj i AI, a ne na klastere ili load balancere

Detaljna arhitektura

API Gateway → Lambda → RDS

[Klijentska aplikacija] (iOS, Android, Web)
    ↓
[API Gateway] (HTTP usmjeravanje, kontrola saobraćaja)
    ↓
[Lambda handleri] (Flask aplikacija, 512MB memorije, 28s timeout)
    ├── /app/* (mobilni endpointi)
    ├── /user/* (autentifikovani korisnici)
    └── /boss/* (admin dashboard)
    ↓
[MySQL 8 na RDS] (postojani podaci)
    ↓
[Odgovor] (JSON nazad klijentu)

Tanki Lambda handleri za brzinu

Većina Lambda funkcija je minimalna i brza:

# Tanak handler (~100KB)
import json
import pymysql

def get_user_progress(event, context):
    user_id = event['pathParameters']['user_id']
    
    conn = pymysql.connect(host='rds.aws.com', user='app', password='...', database='amal')
    cursor = conn.cursor()
    cursor.execute(
        'SELECT concept_id, accuracy FROM user_memory WHERE user_id = %s',
        (user_id,)
    )
    rows = cursor.fetchall()
    conn.close()
    
    return {
        'statusCode': 200,
        'body': json.dumps([{'concept': r[0], 'accuracy': r[1]} for r in rows])
    }

Bez Flask uvoza, ORM-a ili middleware-a. Rezultat: oko 500ms hladni start u odnosu na 5-10 sekundi za potpun Flask app.

Teški endpointi (generisanje sadržaja, analitika) koriste pun Flask:

# Težak handler (~30MB sa Flask, SQLAlchemy, numpy)
from flask import Flask, jsonify
from models import UserMemory
import numpy as np

app = Flask(__name__)

@app.route('/content_duo/generate', methods=['POST'])
def generate_content_duo():
    user = UserMemory.query.filter_by(user_id=request.json['user_id']).first()
    # ... generiše personalizovanu sesiju ...
    return jsonify(session_data)

Rizik: sporiji hladni startovi, ali se pozivaju rjeđe.

Prefiksi tabela po aplikaciji

Jedan RDS instanca opslužuje 7+ aplikacija s izolacijom na nivou baza podataka:

-- Amal app
CREATE TABLE amal_users (...)
CREATE TABLE amal_content_bytes (...)
CREATE TABLE amal_user_memory (...)

-- Thurayya app
CREATE TABLE thurayya_users (...)
CREATE TABLE thurayya_content_bytes (...)
CREATE TABLE thurayya_user_memory (...)

-- Druge aplikacije: qais_*, kidelite_*, itd.

Tijekom deploy-a, varijabla okruženja APP_NAME bira prefiks:

app_name = os.getenv('APP_NAME', 'amal')  # 'amal', 'thurayya', 'qais', itd.

# Dinamički upiti
table_name = f'{app_name}_users'
cursor.execute(f'SELECT * FROM {table_name} WHERE id = %s', (user_id,))

Analitički lake

Problem: direktni upiti za analitiku usporavaju produkciju i zaključavaju tabele.

Rješenje: asinkroni pipeline za analitiku

[Mobilna aplikacija]
    ↓ (šalje događaj)
[API Endpoint] → [SQS Queue] (asinkrono)
    ↓ (odmah vraća odgovor)
    ↓ (ne čeka analitiku)
[Kinesis Firehose] (grupisanje svakih 5 minuta ili 100MB)
    ↓
[S3] (particionirano: s3://analytics-lake/amal/2026/03/28/events.parquet)
    ↓
[AWS Glue] (indeksira i prepoznaje šemu)
    ↓
[Athena] (SQL upiti preko Presto engine-a)
    ↓
[Dashboard] (prikazuje real-time uvide)

Dead Letter Queue (DLQ) mehanizam

U slučaju grešaka u analitici:
SQS → [Firehose greška]
  ↓
  [DLQ prima greške]
  ↓
  [Obavještava operativni tim]
  ↓
  [API u produkciji nije pogođen]

Analitika nikada ne blokira korisničke zahtjeve. Djeca mogu učiti čak i ako pipeline nije dostupan.

Strategije optimizacije troškova

1. Tanki Lambda handleri: prosječni korisnik zove API 15 puta po sesiji, 95.000 korisnika × 3 sesije × 15 poziva = 4.275.000 poziva dnevno. Lambda košta oko $0.0000002 po pozivu — ukupno $0.86 dnevno. Smanjenjem hladnog starta za 10 sekundi ušteda do $500 mjesečno.

2. Rezervisani RDS instance: trogodišnje rezervacije smanjuju troškove za ~60% u odnosu na na-demand.

3. Cache: često korišteni podaci (nastavni sadržaj, bajtovi sadržaja) keširani u ElastiCache (Redis), smanjujući broj upita prema RDS za 70%.

Jedna baza koda za 7+ aplikacija

AplikacijaPrefiksBaze podatakaLambda stackStatus
Amalamal_40+ tabelaZajedničkiProdukcija
Thurayyathurayya_40+ tabelaZajedničkiProdukcija
Qaisqais_35+ tabelaZajedničkiBeta
KidElitekidelite_40+ tabelaZajedničkiProdukcija
Alphazed Schoolschool_50+ tabelaZajedničkiBeta
Alphazed Montessorimontessori_45+ tabelaZajedničkiInterno

Jedan backend i pipeline, šest simultanih aplikacija — novi projekti se lansiraju za sedmice, ne mjesece.

Česta pitanja (FAQ)

P: Lambda ima limit od 15 minuta timeouta, kako se nosite s tim?
O: Rijetko treba duže trajanje. Za težak workload (generisanje sadržaja, veliki eksporti) koristimo asinkrone zadatke s SQS i Step Functions.

P: Šta ako baza padne?
O: RDS koristi Multi-AZ failover (primarni + standby replika). Failover traje oko 60 sekundi, sa kratkim prekidima koje klijenti osjete.

P: Kako radite connection pooling u bezdržavnim Lambda funkcijama?
O: Svaka Lambda instanca održava pool konekcija za višestruke pozive dok je „topla“, hladni start koristi nove konekcije. RDS Proxy je posrednik između Lambda i RDS-a za upravljanje limitima konekcija.

Povezani članci