Architettura della piattaforma Lokad
La piattaforma di Lokad è una soluzione SaaS multi-tenant ospitata sul cloud. Questa pagina presenta l’architettura ad alto livello della piattaforma. Sebbene la pagina sia destinata a un pubblico IT, un operatore esperto di supply chain potrebbe trovare queste informazioni interessanti, poiché questa architettura riflette la nostra visione tecnologica per l’ottimizzazione predittiva di supply chain.

Panoramica dell’architettura
Lokad si presenta come un ambiente per sviluppare e gestire app di ottimizzazione predittiva destinate a problematiche di supply chain. Al suo nucleo si trova un linguaggio specifico del dominio (DSL) chiamato Envision, progettato da Lokad. Envision è accessibile agli utenti finali e molte delle funzionalità sono erogate tramite esso. Sebbene Envision implichi programmazione, Lokad è destinato a specialisti di supply chain e non a specialisti IT o ingegneri del software.
La piattaforma di Lokad è multi-tenant: la stessa app serve tutti i nostri clienti e comprende una breve serie di servizi. La granularità della suddivisione è principalmente motivata da requisiti divergenti in termini di affidabilità, sicurezza e prestazioni di ciascun servizio – piuttosto che da una pura separazione funzionale. Infatti, il grado di accoppiamento esistente tra questi servizi è relativamente elevato. Questi servizi condividono lo stesso repository Git e vengono aggiornati frequentemente insieme.
Il nostro codice è implementato in F#, C# e TypeScript con poche dipendenze di terze parti al di fuori di .NET, un framework open-source sviluppato da Microsoft. Inoltre, a parte .NET stesso, abbiamo pochissime altre dipendenze (circa un ordine di grandezza in meno rispetto alla norma).
Questa architettura si discosta notevolmente dalle architetture “usuali” riscontrate nelle app aziendali – e per buone ragioni. L’app aziendale comune dipende da dipendenze pesanti ed estese; ogni dipendenza solitamente pesa più di 1 milione di righe di codice. Lokad, invece, non ha dipendenze di terze parti nelle seguenti aree:
- Database relazionale: Invece, utilizziamo un event store insieme a un content addressable store.
- Sistema di caching: Invece, colocalizziamo il calcolo e l’archiviazione transitoria.
- Gestore della pipeline: Invece, disponiamo di un nostro scheduler (detagliato di seguito)
- Motore analitico: Invece, il nostro DSL chiamato Envision fornisce capacità analitiche.
- Toolkit per il machine learning: Invece, il DSL offre anche capacità di ML.
- Toolkit per la visualizzazione dei dati: Invece, abbiamo sviluppato il nostro, con una stretta integrazione con il DSL.
Va notato che, sebbene sviluppiamo internamente gran parte della nostra piattaforma, ci affidiamo intenzionalmente ed esclusivamente a componenti di terze parti per tutte le nostre componenti di sicurezza, come gli algoritmi crittografici.
Il front-end
Il front-end si riferisce agli elementi accessibili agli utenti finali, inclusi gli agenti automatizzati utilizzati per trasferire dati da e verso Lokad. La maggior parte di queste interazioni avviene tramite un browser web via HTTPS, sebbene Lokad supporti anche i protocolli FTPS e SFTP per il trasferimento dei file.
go.lokad.com
Questo servizio ospita React, il framework front-end della webapp di Lokad, implementato come una single-page application (SPA). Questo front-end dipende dalle API (application programming interfaces) fornite dagli altri servizi.
Questo servizio serve esclusivamente contenuti statici - per lo più JavaScript. Non ci sono parti dinamiche lato server e, in particolare, nessuna persistenza dei dati. Questo design è intenzionale poiché l’uptime è la priorità principale per questo servizio; qualunque sia il servizio accessibile tramite il web, il servizio go.lokad.com deve essere sempre disponibile.
Cruscotti
Il servizio di cruscotti, come suggerisce il nome, si occupa di rendere i cruscotti analitici web forniti da Lokad.
Ogni cruscotto è il risultato di uno script Envision eseguito. I cruscotti sono ampiamente pre-computati, sebbene vengano offerte anche alcune capacità interattive. Il design stesso di Envision garantisce che le interazioni lato client rimangano problemi di small data, indipendentemente dalla dimensione del dataset originale.
Lato client, tutti i dati necessari per il primo rendering del cruscotto vengono ottenuti tramite una singola richiesta HTTPS. Questo design a richiesta unica serve a minimizzare la latenza. L’impacchettamento binario e la compressione riducono il consumo di banda.
Lato server, i dati associati a un determinato cruscotto vengono impacchettati dal content store. Ancora, l’impacchettamento è essenziale per mantenere un numero totale di richieste di rete molto basso, normalmente inferiore a una mezza dozzina – indipendentemente dalla complessità del cruscotto.
I cruscotti interattivi danno all’utente finale la possibilità di accedere a grandi dataset, ben oltre quanto sarebbe possibile trasferire e visualizzare tramite un browser. Passare da una vista all’altra richiede al massimo una singola richiesta lato client (e pochissime lato server).
Lokad vs mainstream
Il design a tempo di rendering costante di Lokad differisce dagli strumenti di business intelligence (BI) e altri strumenti analitici mainstream. I cruscotti che si trovano in tali strumenti sono invariabilmente composti da una lista di riquadri, a volte chiamati blocchi o widget. Il modo standard di gestire questi riquadri prevede 1 richiesta lato client per ogni riquadro, seguita da un numero non specificato/non garantito di richieste lato server. Purtroppo, questo design porta a cruscotti lenti con un ritardo evidente per ogni riquadro. Inoltre, la visualizzazione completa di tutti i riquadri del cruscotto richiede spesso diversi secondi.
Lokad elimina questo problema facendo in modo che il compiler di Envision produca una strategia di impacchettamento dei dati utilizzati per il rendering del cruscotto, garantendo così un numero di richieste a singola cifra lato client, e ancora meno lato server. Dal nostro punto di vista, le prestazioni del cruscotto iniziano al momento della compilazione, con gli script che supportano i cruscotti.
Inoltre, la maggior parte degli strumenti analitici posticipa una grande parte del calcolo fino a quando un cruscotto (a volte chiamato report) non viene richiesto. Purtroppo, questo design porta invariabilmente a problemi di prestazioni quando aumenta il numero di utenti finali concorrenti, poiché c’è un conflitto inevitabile per le risorse di calcolo lato server, che sono mutualizzate per servire tutti gli utenti finali.
Lokad mitiga ampiamente questo problema pre-computando i cruscotti. Il nostro design minimizza le risorse lato server necessarie – su richiesta degli utenti finali – per servire un cruscotto, lasciando il content store come principale (ma voluto) collo di bottiglia per fornire i dati del cruscotto. Questo design assicura che un gran numero di utenti finali possa essere servito contemporaneamente con cruscotti con una degradazione minima delle prestazioni.
Progetti
Il servizio progetti gestisce script e job batch (chiamati sequenze). Questo servizio presenta una gerarchia di progetti. Gli utenti finali, che dispongono dei diritti di accesso appropriati, possono visualizzare, modificare ed eseguire i progetti. Un’app di ottimizzazione predittiva personalizzata implementata da Lokad include tipicamente una lista di progetti.
L’event sourcing viene usato per persistere le voci degli utenti, sfruttando l’event store descritto qui. Ogni singolo comando o interazione inviato al servizio viene registrato e trasformato in un evento risultante. L’interfaccia utente presenta lo stato ottenuto aggregando tutti gli eventi. Questo approccio è noto come pattern CQRS+ES. CQRS sta per Command and Query Responsibility Segregation, mentre ES sta per Event Source.
Il pattern CQRS+ES fornisce by design una completa storicizzazione di tutte le modifiche introdotte nell’applicazione. Nel caso specifico di Lokad, esso fornisce un versionamento in stile Git di tutte le modifiche mai applicate agli script Envision presenti all’interno dell’account.
Lokad vs mainstream
In termini di UI e UX, il servizio progetti segue l’approccio mainstream. Tuttavia, sotto il cofano viene utilizzato il pattern CQRS+ES come alternativa a quello CRUD (create, read, update, delete) usato per la maggior parte dei software aziendali. Questo pattern sostituisce il database relazionale con un event store (discusso di seguito).
L’approccio CQRS+ES offre molti vantaggi rispetto al pattern CRUD. Ad esempio, offre una semantica superiore, una maggiore tracciabilità e, nel caso di Lokad, prestazioni superiori in quanto ci permette di personalizzare ampiamente la strategia di persistenza usata per memorizzare e recuperare il codice sorgente di Envision. In effetti, la maggior parte dei dati da persistere nel servizio progetti consiste nel codice sorgente di Envision.
Codice
Il servizio codice presenta un IDE (integrated development environment) dedicato al linguaggio Envision. Questo IDE basato sul web ha tutte le funzionalità e caratteristiche attese da un ambiente di sviluppo moderno, come la colorazione del codice, l’autocompletamento e una serie di azioni sul codice (es: rinominare le variabili), rese possibili grazie all’analisi statica del codice.
La maggior parte della complessità del servizio codice risiede nel suo backend language server che fornisce feedback in tempo reale: suggerimenti per l’autocompletamento, errori o azioni sul codice ad ogni pressione dei tasti. In particolare, una delle sfide tecniche principali consiste nel mantenere una bassa latenza per questa funzione, poiché i ritardi sarebbero piuttosto evidenti considerando il ritmo delle normali interazioni con la tastiera.
File
Ogni account su Lokad ha il proprio spazio per memorizzare file. Il servizio file presenta un file system distribuito versionato che viene utilizzato per gestire i suoi file. Questo file system può essere accessibile tramite un’interfaccia web e i protocolli SFTP e FTPS. Concettualmente, questo file system è in gran parte simile a un repository Git, tranne per il fatto che è pensato per file flat di dimensioni gigabyte.
Il versionamento dei file è garantito attraverso il pattern CQRS+ES, che integra la presentazione di una sequenza di “commit”, riflettendo l’evoluzione del file system stesso. La persistenza del contenuto dei file è assicurata tramite un content addressable store (discusso di seguito).
Versionando sia il codice (script Envision) che i dati, Lokad offre una completa riproducibilità dei comportamenti passati per le app di supply chain distribuite sulla sua piattaforma. Dal punto di vista della supply chain, questa capacità è importante per assicurarsi che ogni risultato anomalo generato dall’app di supply chain possa essere analizzato.
Lokad vs mainstream
Il servizio file è strettamente integrato con il linguaggio Envision (offrendo benefici in termini di correttezza), con l’IDE Envision (offrendo benefici in termini di produttività) e con il runtime Envision (offrendo benefici in termini di prestazioni). Questi vantaggi sarebbero difficili da ottenere con un file system generico, un software che è prima di tutto un compagno del kernel.
Inoltre, molti dei benefici del servizio file si ottengono facendo meno rispetto a un file system generico. Ad esempio, il servizio file non permette che un file venga aggiornato in modo concorrente da più processi. Tali funzionalità, nel contesto specifico delle app di supply chain, espongono gli operatori di supply chain a problematiche e complessità tipiche dell’IT senza offrire un valore in cambio.
Account
L’Identity and Access Management (IAM) del servizio account è una delle parti più mainstream di Lokad. Gestisce gli account Lokad, gli utenti di Lokad, l’autenticazione (idealmente, delegated authentication) e l’ACL (Access Control List) che controlla cosa gli utenti possono o non possono fare con un account Lokad.
Questo servizio sfrutta anche il pattern CQRS+ES, che offre log di audit completi per tutte le operazioni IAM - operazioni che sono sempre sensibili in termini di sicurezza a causa della natura stessa dell’IAM. Utilizzare l’event source come log di audit elimina intere classi di problemi di sicurezza, come il log di audit che viene compromesso per la mancanza di registrazione di determinati eventi.
Lo strato di persistenza
Lo strato di persistenza, come suggerisce il nome, garantisce la persistenza di tutti i dati gestiti da Lokad. Questi dati si presentano in due varianti distinte: in primo luogo, i file - sia caricati dai clienti su Lokad che generati tramite script Envision; in secondo luogo, gli eventi derivanti dalle operazioni degli utenti (inclusi agenti automatizzati, come uno script di caricamento file). Lokad persiste entrambe le tipologie di dati tramite Azure Blob Storage che funge da key-value store.
Event Store
L’event store persiste gli eventi generati da tutti i servizi della piattaforma Lokad. Questo store rappresenta il database delle transizioni di stato di Lokad. Abbiamo rilasciato il codice sorgente del nostro event store come open source.
Questo componente è semplice: persiste e fornisce solo eventi, in modo affidabile, sfruttando un key-value store distribuito sottostante (Azure Blob Storage). Gli eventi sono previsti essere piccoli - limitati a 512kB, ma tipicamente inferiori a 1kB.
Non ci sono funzionalità “intelligenti”, come l’analisi in streaming o la gestione delle proiezioni. Ancora una volta, facendo meno, Lokad elimina intere classi di problemi, come gli attacchi di SQL injection, che sorgono a causa delle capacità dello strato di persistenza.
Content Addressable Store
Il content addressable store (CAS) persiste i file, sia caricati sulla piattaforma Lokad che generati tramite gli script Envision. Abbiamo rilasciato il codice sorgente del nostro content addressable storage come open source.
Il CAS è pensato per supportare file di grandi dimensioni, tipicamente di diversi MB, con un limite superiore di 100GB. Il CAS viene utilizzato per memorizzare file, o frammenti di file, sharded seguendo una strategia di storage colonnare. Lo storage colonnare è allineato al pattern di accesso dello strato di esecuzione.
Lo strato di esecuzione
Come suggerisce il nome, lo strato di esecuzione garantisce l’esecuzione degli script Envision all’interno della piattaforma Lokad, e include una serie di componenti. Per motivi di brevità, elencheremo qui solo i più importanti. Il compiler trasforma gli script Envision in istruzioni destinate a una macchina virtuale distribuita. Lo scheduler è un servizio di utilità per l’attivazione, la pianificazione e la sequenza degli script Envision. Thunks è il nome in codice per la macchina virtuale Envision. Infine, Ionic è il nome della strategia di storage colonnare, prodotta e consumata dalla macchina virtuale Envision.
Compiler
Il compiler trasforma gli script Envision in bytecode destinato alla macchina virtuale distribuita della piattaforma Lokad – denominata “Thunks” (vedi sotto). L’architettura di questo compiler segue le prassi di design mainstream: una pipeline di compilazione che inizia con il parsing, seguito da una serie di trasformazioni da una rappresentazione interna all’altra, concludendosi con la produzione di bytecode.
Il backend del language server, che guida le interazioni con il codice sorgente di Envision (vedi il servizio Code, sopra), fa anche parte del compilatore. Il language server è dotato di stato per fornire feedback significativi e messaggi di errore al programmatore di Envision, mentre la scrittura del codice è in corso. Dopo la maggior parte dei tasti premuti, lo script non è ancora un valido script Envision, ma grazie allo stato del language server, viene comunque fornito un feedback significativo.
Schedulatore
Il schedulatore è un servizio ausiliario per l’esecuzione degli script Envision senza interventi manuali. Il schedulatore attiva, pianifica e sequenzia l’esecuzione degli script Envision. Fornisce inoltre capacità di allerta se le esecuzioni si discostano dalle tempistiche previste. L’integrazione stretta del schedulatore con il resto della piattaforma offre una serie di funzionalità desiderabili, come i trigger basati sulle modifiche dei file (per avviare gli script Envision al ricevimento dei file, ad esempio) o la rilevazione anticipata di possibili errori (se uno degli script Envision all’interno di una sequenza non viene compilato).
Thunks
Thunks è il nome in codice della macchina virtuale distribuita di Lokad. Infatti, gli script Envision beneficiano nativamente di un’esecuzione distribuita. In questo senso, il compilatore Envision non si rivolge a una singola macchina ma a un cluster di esse. Questa funzionalità è fondamentale per elaborare grandi set di dati in maniera tempestiva. Il linguaggio Envision è stato appositamente progettato per la parallelizzazione automatica (una funzionalità che altrimenti sarebbe molto difficile da ottenere con un linguaggio di programmazione generale). Incidentemente, il cluster offre anche una maggiore affidabilità nell’esecuzione degli script se una macchina diventa non responsiva.
Il cluster di macchine dedicato a Thunks è condiviso, in modalità multi-tenant, tra tutti gli account. Questa funzionalità è essenziale per mantenere sotto controllo i costi computazionali. Il tipico caso d’uso di supply chain prevede un batch di esecuzione al giorno, solitamente della durata inferiore a 60 minuti. La condivisione delle risorse tramite multi-tenancy attenua in larga misura i costi aggiuntivi associati alle risorse di calcolo - un costo che altrimenti verrebbe addebitato su base 24 ore, mentre verrebbe utilizzata solo un’ora (o meno).
Per una spiegazione approfondita, suggeriamo la serie in 4 parti di Victor Nicollet sul design della Envision Virtual Machine, e per risposte alle domande più comuni relative alle prestazioni di Lokad, consigliamo la sezione 8 della nostra Security FAQ.