Skip to main content

Guida allo Scaling della Piattaforma

Principi di Scaling

La piattaforma Impronto Enterprise e composta da 13 tipi di nodo Moleculer, ciascuno con caratteristiche di scaling diverse. La regola fondamentale e: non tutti i nodi si scalano allo stesso modo.

Matrice di Scaling per Tipo di Nodo

Tipo NodoHPARepliche MinRepliche MaxNote
gatewaySi (CPU)210Entry point, scala con il traffico HTTP
coreSi (CPU)28Ordini, prodotti, clienti
authSi (CPU)26Validazione JWT, sessioni
commerceSi (CPU)28Pagamenti, fiscale
warehouseSi (CPU)14Magazzino, movimentazione
mediaSi (CPU)14Upload immagini, S3 proxy
reportsSi (CPU)14Generazione report pesanti
platformSi (CPU)13Gestione tenant e reseller
financeSi (CPU)13Fatturazione, abbonamenti
knowledgeSi (CPU)13Documentazione, AI chat
cashSi (CPU)14Prima nota, sessioni cassa
schedulerNo11Singleton - cron job, mai scalare
simulatorNo01Solo in ambiente di test
Scheduler = Singleton

Il nodo scheduler esegue cron job (archiviazione, ETL, alert). Scalare a piu di 1 replica causerebbe esecuzione duplicata di tutti i job schedulati. Utilizzare sempre replicas: 1 con strategy: Recreate.


Horizontal Pod Autoscaler (HPA)

Configurazione Attuale (CPU-based)

# k8s/hpa/gateway-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: pos-gateway-hpa
namespace: pos-enterprise
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: pos-gateway
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 65 # Scala quando CPU media > 65%
behavior:
scaleUp:
stabilizationWindowSeconds: 60 # Attendi 1 min prima di scale-up
policies:
- type: Pods
value: 2
periodSeconds: 60 # Max 2 pod ogni 60s
scaleDown:
stabilizationWindowSeconds: 300 # Attendi 5 min prima di scale-down
policies:
- type: Pods
value: 1
periodSeconds: 120 # Max 1 pod ogni 2 min
# k8s/hpa/core-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: pos-core-hpa
namespace: pos-enterprise
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: pos-core
minReplicas: 2
maxReplicas: 8
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleDown:
stabilizationWindowSeconds: 300

Applicazione e Verifica

# Applicare gli HPA
kubectl apply -f k8s/hpa/

# Verificare stato degli HPA
kubectl get hpa -n pos-enterprise

# Output tipico:
# NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
# pos-gateway-hpa Deployment/pos-gateway 42%/65% 2 10 3 5d
# pos-core-hpa Deployment/pos-core 55%/70% 2 8 2 5d

# Dettaglio di un HPA specifico
kubectl describe hpa pos-gateway-hpa -n pos-enterprise

Evoluzione: HPA basato su Metriche Prometheus (Futuro)

L'obiettivo futuro e scalare basandosi su metriche applicative (request queue depth, action latency):

# Esempio futuro con Prometheus Adapter
spec:
metrics:
- type: Pods
pods:
metric:
name: moleculer_action_queue_depth
target:
type: AverageValue
averageValue: 50 # Scala quando la coda media > 50
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70

Requisiti per l'implementazione:

  1. Installare Prometheus Adapter
  2. Configurare le metriche custom da esporre all'HPA
  3. Testare il comportamento di scaling in staging

Scaling Verticale: Risorse per Nodo

Limiti di Risorse Raccomandati

# Profilo risorse per tipo di nodo
resources:
# gateway - leggero, I/O bound
gateway:
requests: { cpu: "200m", memory: "256Mi" }
limits: { cpu: "1000m", memory: "512Mi" }

# core - medio, CPU e memory per CRUD
core:
requests: { cpu: "300m", memory: "512Mi" }
limits: { cpu: "1500m", memory: "1Gi" }

# commerce - medio-alto, calcoli fiscali
commerce:
requests: { cpu: "300m", memory: "512Mi" }
limits: { cpu: "1500m", memory: "1Gi" }

# reports - pesante, generazione PDF
reports:
requests: { cpu: "500m", memory: "1Gi" }
limits: { cpu: "2000m", memory: "2Gi" }

# scheduler - singleton, esecuzione cron job
scheduler:
requests: { cpu: "200m", memory: "512Mi" }
limits: { cpu: "1000m", memory: "1Gi" }

# knowledge - AI embeddings e search
knowledge:
requests: { cpu: "300m", memory: "512Mi" }
limits: { cpu: "1500m", memory: "1.5Gi" }
# Verificare l'utilizzo effettivo vs limiti
kubectl top pods -n pos-enterprise --sort-by=cpu
kubectl top pods -n pos-enterprise --sort-by=memory

# Dettaglio per un pod specifico
kubectl describe pod -n pos-enterprise pos-core-xxxxx | grep -A5 "Limits\|Requests"
Regola del 75%

Impostare il NODE_OPTIONS --max-old-space-size al 75% del memory limit del container. Esempio: limit 1Gi -> --max-old-space-size=768.


Scaling MongoDB

Strategia per Cluster Pool

MongoDB Atlas utilizza un cluster condiviso. La strategia di scaling prevede la separazione in pool quando il numero di tenant cresce:

Tenant CountStrategiaCluster
1-500Singolo cluster M30pos-prod-1
500-2000Singolo cluster M40pos-prod-1 (upgrade)
2000-40002 cluster M30, routing per hashpos-prod-1, pos-prod-2
4000+N cluster, routing centralizzatopos-prod-N

Il routing tra cluster e gestito dal servizio platform che mantiene una mappa tenantId -> clusterId:

// Logica di routing (semplificata)
getClusterForTenant(tenantId) {
const tenantConfig = await this.broker.call("tenant-management.get", { id: tenantId });
return tenantConfig.clusterId || "pos-prod-1"; // Default al cluster primario
}

Scaling Verticale Atlas

# Upgrade tier via Atlas CLI (richiede downtime minimo, rolling restart)
atlas clusters update pos-production \
--tier M40 \
--diskSizeGB 100

# Aggiungere storage (zero downtime)
atlas clusters update pos-production \
--diskSizeGB 200

Scaling Redis Cloud

Redis Cloud scala automaticamente con il piano scelto. Monitorare:

# Utilizzo memoria Redis (alert a 80%)
pos_redis_memory_used_bytes / pos_redis_memory_max_bytes

# Connessioni attive
redis_connected_clients

# Operazioni al secondo
rate(redis_commands_processed_total[5m])

Se necessario, scalare il piano Redis Cloud dal portale o via API.


Aggiungere Nuovi Nodi al Cluster K8s

Quando il cluster non ha abbastanza risorse per ospitare nuovi pod:

# Verificare le risorse disponibili nel cluster
kubectl describe nodes | grep -A5 "Allocated resources"

# Verificare pod in stato Pending (risorse insufficienti)
kubectl get pods -n pos-enterprise --field-selector=status.phase=Pending

# Se su IBM Cloud Kubernetes Service:
ibmcloud ks worker-pool resize \
--cluster pos-production \
--worker-pool default \
--size-per-zone 5 # Numero di nodi per zona

# Verificare i nuovi nodi
kubectl get nodes -o wide

Node Affinity per Workload Pesanti

# I nodi reports e knowledge preferiscono worker con piu RAM
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: node-type
operator: In
values: ["high-memory"]

Monitoraggio Scaling

# Cronologia eventi HPA
kubectl describe hpa -n pos-enterprise pos-gateway-hpa | grep -A20 "Events"

# Verificare che il PDB (Pod Disruption Budget) sia rispettato
kubectl get pdb -n pos-enterprise
# Numero repliche attuali vs desiderate
kube_horizontalpodautoscaler_status_current_replicas{namespace="pos-enterprise"}
kube_horizontalpodautoscaler_status_desired_replicas{namespace="pos-enterprise"}

# Pod in stato Pending (cluster pieno)
kube_pod_status_phase{namespace="pos-enterprise", phase="Pending"}

Riferimenti Incrociati

Questa pagina ti è stata utile?