Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Immagine dal film “Il nostro universo segreto: la vita nascosta della cellula”

L'attività di investimento è una delle aree più complesse del mondo bancario, perché non ci sono solo prestiti, prestiti e depositi, ma anche titoli, valute, materie prime, derivati ​​e ogni sorta di complessità sotto forma di prodotti strutturati.

Recentemente, abbiamo assistito ad un aumento dell’alfabetizzazione finanziaria della popolazione. Sempre più persone si impegnano nel commercio sui mercati mobiliari. I conti di investimento individuali sono apparsi non molto tempo fa. Ti consentono di fare trading sui mercati mobiliari e di ricevere detrazioni fiscali o di evitare di pagare le tasse. E tutti i clienti che si rivolgono a noi vogliono gestire il proprio portafoglio e vedere i report in tempo reale. Inoltre, molto spesso questo portafoglio è multiprodotto, ovvero le persone sono clienti di varie linee di business.

Inoltre, crescono le esigenze delle autorità di regolamentazione, sia russe che straniere.

Per soddisfare le esigenze attuali e gettare le basi per futuri aggiornamenti, abbiamo sviluppato un core business di investimento basato su Tarantool.

Alcune statistiche. L'attività di investimento di Alfa-Bank fornisce servizi di intermediazione per persone fisiche e giuridiche per offrire l'opportunità di negoziare su vari mercati mobiliari, servizi di deposito per la custodia di titoli, servizi di gestione fiduciaria per persone con capitali privati ​​e di grandi dimensioni, servizi di emissione di titoli per altre società . L'attività di investimento di Alfa-Bank comprende più di 3mila quotazioni al secondo, che vengono scaricate da varie piattaforme di trading. Durante la giornata lavorativa vengono concluse sui mercati più di 300mila transazioni per conto della banca o dei suoi clienti. Su piattaforme esterne e interne si verificano fino a 5mila esecuzioni di ordini al secondo. Allo stesso tempo, tutti i clienti, sia interni che esterni, vogliono vedere la propria posizione in tempo reale.

Sfondo

A partire dall'inizio degli anni 2000, le nostre aree di attività di investimento si sono sviluppate in modo indipendente: negoziazione di cambi, servizi di intermediazione, negoziazione di valute, negoziazione fuori borsa di titoli e vari derivati. Di conseguenza, siamo caduti nella trappola dei pozzi funzionali. Cos'è? Ogni linea di business ha i propri sistemi che duplicano le reciproche funzioni. Ogni sistema ha il proprio modello di dati, sebbene operino con gli stessi concetti: transazioni, strumenti, controparti, quotazioni e così via. E man mano che ciascun sistema si è evoluto in modo indipendente, è emerso uno zoo diversificato di tecnologie.

Inoltre, il codice base dei sistemi è già piuttosto obsoleto, poiché alcuni prodotti sono nati a metà degli anni '1990. E in alcune aree ciò ha rallentato il processo di sviluppo e si sono verificati problemi di prestazioni.

Requisiti per una nuova soluzione

Le imprese hanno capito che la trasformazione tecnologica è vitale per un ulteriore sviluppo. Ci sono stati assegnati compiti:

  1. Raccogli tutti i dati aziendali in un unico archivio veloce e in un unico modello dati.
  2. Non dobbiamo perdere o modificare queste informazioni.
  3. È necessario versionizzare i dati, perché in qualsiasi momento il regolatore può richiedere le statistiche degli anni precedenti.
  4. Non dobbiamo semplicemente portare dei DBMS nuovi e alla moda, ma creare una piattaforma per risolvere i problemi aziendali.

Inoltre, i nostri architetti stabiliscono le proprie condizioni:

  1. La nuova soluzione dovrà essere di classe enterprise, ovvero dovrà essere già sperimentata in alcune grandi aziende.
  2. La modalità operativa della soluzione dovrebbe essere fondamentale. Ciò significa che dobbiamo essere presenti in più data center contemporaneamente e sopravvivere con calma all'interruzione di un data center.
  3. Il sistema deve essere scalabile orizzontalmente. Il fatto è che tutti i nostri sistemi attuali sono scalabili solo verticalmente e stiamo già raggiungendo il limite a causa della bassa crescita della potenza hardware. Pertanto, è giunto il momento in cui abbiamo bisogno di un sistema scalabile orizzontalmente per sopravvivere.
  4. Tra l'altro ci è stato detto che la soluzione doveva essere economica.

Abbiamo seguito il percorso standard: abbiamo formulato i requisiti e contattato l'ufficio acquisti. Da lì abbiamo ricevuto un elenco di aziende che, in generale, sono pronte a farlo per noi. Abbiamo parlato del problema a tutti e sei di loro hanno valutato le soluzioni.

In banca non crediamo alla parola di nessuno: ci piace testare tutto da soli. Pertanto, una condizione obbligatoria della nostra gara d'appalto era il superamento delle prove di carico. Abbiamo formulato attività di test di carico e tre aziende su sei hanno già accettato di implementare una soluzione prototipo basata su tecnologie in-memory a proprie spese per testarla.

Non ti dirò come abbiamo testato tutto e quanto tempo ci è voluto, mi limiterò a riassumere: le migliori prestazioni nei test di carico sono state mostrate da una soluzione prototipo basata su Tarantool del team di sviluppo del Gruppo Mail.ru. Abbiamo firmato un accordo e abbiamo iniziato lo sviluppo. C'erano quattro persone del gruppo Mail.ru e tre sviluppatori, tre analisti di sistema, un solution architect, un product Owner e uno Scrum Master di Alfa-Bank.

Successivamente ti parlerò di come è cresciuto il nostro sistema, come si è evoluto, cosa abbiamo fatto e perché esattamente questo.

Разработка

La prima domanda che ci siamo posti è stata come ottenere dati dai nostri attuali sistemi. Abbiamo deciso che HTTP fosse adatto a noi, perché tutti i sistemi attuali comunicano tra loro inviando XML o JSON tramite HTTP.

Utilizziamo il server HTTP integrato in Tarantool perché non abbiamo bisogno di terminare le sessioni SSL e le sue prestazioni sono sufficienti per noi.

Come ho già detto, tutti i nostri sistemi vivono in modelli di dati diversi e all'input dobbiamo portare l'oggetto al modello che descriviamo noi stessi. Era necessario un linguaggio che permettesse la trasformazione dei dati. Abbiamo scelto l'imperativo Lua. Eseguiamo tutto il codice di conversione dei dati in una sandbox: questo è un luogo sicuro oltre il quale il codice in esecuzione non va. Per fare ciò, carichiamo semplicemente il codice richiesto, creando un ambiente con funzioni che non possono bloccare o eliminare nulla.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Dopo la conversione, è necessario verificare la conformità dei dati con il modello che stiamo creando. Abbiamo discusso a lungo su quale dovrebbe essere il modello e quale linguaggio utilizzare per descriverlo. Abbiamo scelto Apache Avro perché il linguaggio è semplice e ha il supporto di Tarantool. Le nuove versioni del modello e del codice personalizzato possono essere messe in funzione più volte al giorno, anche sotto carico o senza, in qualsiasi momento della giornata, e adattarsi ai cambiamenti molto rapidamente.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Dopo la verifica, i dati devono essere salvati. Lo facciamo utilizzando vshard (disponiamo di repliche geodisperse di frammenti).

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Inoltre, la specificità è tale che alla maggior parte dei sistemi che ci inviano dati non importa se li abbiamo ricevuti o meno. Ecco perché abbiamo implementato una coda di riparazione fin dall'inizio. Cos'è? Se per qualche motivo un oggetto non viene sottoposto a trasformazione o verifica dei dati, confermiamo comunque la ricezione, ma allo stesso tempo salviamo l'oggetto nella coda di riparazione. È coerente e si trova nel data warehouse aziendale principale. Abbiamo immediatamente scritto un'interfaccia amministrativa, varie metriche e avvisi. Di conseguenza, non perdiamo dati. Anche se qualcosa è cambiato nell'origine, se il modello di dati è cambiato, lo rileveremo immediatamente e potremo adattarci.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Ora devi imparare come recuperare i dati salvati. Abbiamo analizzato attentamente i nostri sistemi e abbiamo visto che il classico stack di Java e Oracle contiene necessariamente una sorta di ORM che converte i dati da relazionali a oggetti. Allora perché non dare subito oggetti ai sistemi sotto forma di grafico? Quindi abbiamo adottato con gioia GraphQL, che ha soddisfatto tutte le nostre esigenze. Ti consente di ricevere dati sotto forma di grafici ed estrarre solo ciò di cui hai bisogno in questo momento. Puoi anche creare versioni dell'API con molta flessibilità.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Quasi subito ci siamo resi conto che i dati che stavamo estraendo non erano sufficienti. Abbiamo creato funzioni che possono essere collegate agli oggetti nel modello, essenzialmente campi calcolati. Cioè, alleghiamo una determinata funzione al campo, che, ad esempio, calcola il prezzo medio del preventivo. E il consumatore esterno che richiede i dati non sa nemmeno che si tratta di un campo calcolato.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Implementato un sistema di autenticazione.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Poi abbiamo notato che diversi ruoli si cristallizzavano nella nostra decisione. Un ruolo è una sorta di aggregatore di funzioni. In genere, i ruoli hanno diversi profili di utilizzo delle apparecchiature:

  • T-Connect: gestisce le connessioni in entrata, CPU limitata, basso consumo di memoria, stateless.
  • IB-Core: trasforma i dati che riceve tramite il protocollo Tarantool, ovvero opera con tabelle. Inoltre non memorizza lo stato ed è scalabile.
  • Archiviazione: memorizza solo i dati, non utilizza alcuna logica. Questo ruolo implementa le interfacce più semplici. Scalabile grazie a vshard.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Cioè, utilizzando i ruoli, abbiamo disaccoppiato le diverse parti del cluster l'una dall'altra, che possono essere scalate indipendentemente l'una dall'altra.

Pertanto, abbiamo creato una registrazione asincrona del flusso di dati transazionali e una coda di riparazione con un'interfaccia di amministrazione. La registrazione è asincrona dal punto di vista aziendale: se abbiamo la garanzia di scriverci i dati, non importa dove, allora lo confermeremo. Se non viene confermato, qualcosa è andato storto ed è necessario inviare i dati. Questa è la registrazione asincrona.

Test

Fin dall'inizio del progetto, abbiamo deciso che avremmo provato a implementare lo sviluppo basato sui test. Scriviamo unit test in Lua utilizzando il framework tarantool/tap e test di integrazione in Python utilizzando il framework pytest. Allo stesso tempo, coinvolgiamo sia gli sviluppatori che gli analisti nella scrittura dei test di integrazione.

Come utilizziamo lo sviluppo basato sui test?

Se vogliamo qualche nuova funzionalità, proviamo prima a scriverne un test. Quando scopriamo un bug, ci assicuriamo di scrivere prima un test e solo dopo correggerlo. All’inizio è difficile lavorare in questo modo, ci sono incomprensioni da parte dei dipendenti, persino sabotaggi: “Risolviamolo subito, facciamo qualcosa di nuovo e poi copriamolo con i test”. Solo che questo “dopo” non arriva quasi mai.

Pertanto, devi sforzarti di scrivere prima i test e chiedere ad altri di farlo. Credimi, lo sviluppo test-driven porta benefici anche nel breve periodo. Sentirai che la tua vita è diventata più facile. Riteniamo che il 99% del codice sia ora coperto da test. Sembra molto, ma non abbiamo problemi: i test vengono eseguiti su ogni commit.

Tuttavia, ciò che amiamo di più è il test di carico; lo consideriamo il più importante e lo eseguiamo regolarmente.

Ti racconterò una piccola storia su come abbiamo eseguito la prima fase di test di carico di una delle prime versioni. Abbiamo installato il sistema sul laptop dello sviluppatore, abbiamo acceso il carico e abbiamo ottenuto 4mila transazioni al secondo. Buon risultato per un laptop. L'abbiamo installato su un banco di carico virtuale di quattro server, più debole rispetto alla produzione. Distribuito al minimo. Lo eseguiamo e otteniamo un risultato peggiore che su un laptop in un thread. Contenuti scioccanti.

Eravamo molto tristi. Osserviamo il carico del server, ma risulta che sono inattivi.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Chiamiamo gli sviluppatori e loro spiegano a noi, persone che vengono dal mondo Java, che Tarantool è a thread singolo. Può essere utilizzato efficacemente solo da un core del processore sotto carico. Quindi abbiamo distribuito il numero massimo possibile di istanze di Tarantool su ciascun server, abbiamo acceso il carico e abbiamo già ricevuto 14,5mila transazioni al secondo.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Lasciami spiegare di nuovo. A causa della divisione in ruoli che utilizzano le risorse in modo diverso, i nostri ruoli responsabili dell'elaborazione delle connessioni e della trasformazione dei dati caricavano solo il processore e in modo strettamente proporzionale al carico.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
In questo caso la memoria è stata utilizzata solo per l'elaborazione delle connessioni in entrata e degli oggetti temporanei.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Al contrario, sui server di archiviazione, il carico del processore è aumentato, ma molto più lentamente rispetto ai server che elaborano le connessioni.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
E il consumo di memoria è cresciuto in modo direttamente proporzionale alla quantità di dati caricati.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool

Servizi

Per sviluppare il nostro nuovo prodotto specificamente come piattaforma applicativa, abbiamo creato un componente per la distribuzione di servizi e librerie su di esso.

I servizi non sono solo piccoli pezzi di codice che operano su alcuni campi. Possono essere strutture piuttosto grandi e complesse che fanno parte di un cluster, controllano i dati di riferimento, eseguono la logica aziendale e restituiscono risposte. Esportiamo anche lo schema del servizio in GraphQL e il consumatore riceve un punto di accesso universale ai dati, con introspezione sull'intero modello. È molto comodo

Poiché i servizi contengono molte più funzioni, abbiamo deciso che dovrebbero esserci librerie in cui sposteremo il codice utilizzato di frequente. Li abbiamo aggiunti all'ambiente sicuro, dopo aver verificato in precedenza che non si rompesse nulla per noi. E ora possiamo assegnare ambienti aggiuntivi alle funzioni sotto forma di librerie.

Volevamo avere una piattaforma non solo per l'archiviazione, ma anche per l'elaborazione. E poiché avevamo già un sacco di repliche e frammenti, abbiamo implementato una sorta di calcolo distribuito e l'abbiamo chiamato map reduce, perché si è rivelato simile alla map reduce originale.

Vecchi sistemi

Non tutti i nostri sistemi legacy possono chiamarci tramite HTTP e utilizzare GraphQL, sebbene supportino il protocollo. Pertanto, abbiamo creato un meccanismo che consente la replica dei dati in questi sistemi.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Se qualcosa cambia per noi, vengono attivati ​​trigger univoci nel ruolo Archiviazione e il messaggio con le modifiche finisce nella coda di elaborazione. Viene inviato a un sistema esterno utilizzando un ruolo replicatore separato. Questo ruolo non memorizza lo stato.

Nuovi miglioramenti

Come ricorderete, da un punto di vista aziendale, abbiamo effettuato la registrazione asincrona. Ma poi si sono resi conto che non sarebbe bastato, perché esiste una classe di sistemi che hanno bisogno di ricevere immediatamente una risposta sullo stato dell'operazione. Quindi abbiamo esteso il nostro GraphQL e aggiunto mutazioni. Si inseriscono organicamente nel paradigma esistente di lavoro con i dati. Per noi, questo è un unico punto di lettura e scrittura per un'altra classe di sistemi.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Ci siamo anche resi conto che i servizi da soli non ci basterebbero, perché ci sono resoconti abbastanza pesanti che vanno costruiti una volta al giorno, una settimana, un mese. Questa operazione può richiedere molto tempo e i report possono persino bloccare il ciclo di eventi di Tarantool. Pertanto, abbiamo creato ruoli separati: scheduler e runner. I corridori non memorizzano lo stato. Svolgono compiti pesanti che non possiamo calcolare al volo. E il ruolo di pianificazione monitora la pianificazione del lancio di queste attività, come descritto nella configurazione. Le attività stesse vengono archiviate nello stesso posto dei dati aziendali. Quando arriva il momento giusto, il pianificatore prende l'attività, la consegna a un corridore, che la conta e salva il risultato.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Non tutte le attività devono essere eseguite secondo una pianificazione. Alcuni rapporti devono essere letti su richiesta. Non appena arriva questo requisito, un'attività viene creata nella sandbox e inviata al corridore per l'esecuzione. Dopo un po' di tempo, l'utente riceve una risposta asincrona che tutto è stato calcolato e il report è pronto.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Inizialmente, abbiamo aderito al paradigma di archiviazione di tutti i dati, controllo delle versioni e non eliminazione. Ma nella vita, di tanto in tanto devi ancora cancellare qualcosa, soprattutto alcune informazioni grezze o intermedie. Sulla base della scadenza, abbiamo creato un meccanismo per pulire lo spazio di archiviazione dai dati obsoleti.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool
Comprendiamo anche che prima o poi arriverà una situazione in cui non ci sarà abbastanza spazio per archiviare i dati in memoria, ma i dati dovranno comunque essere archiviati. Per questi scopi, presto effettueremo l'archiviazione su disco.

Come abbiamo creato il fulcro dell'attività di investimento di Alfa-Bank basato su Tarantool

conclusione

Abbiamo iniziato con il compito di caricare i dati in un unico modello e abbiamo impiegato tre mesi a svilupparlo. Avevamo sei sistemi di fornitura dati. L'intero codice di trasformazione in un unico modello è di circa 30mila righe in Lua. E la maggior parte del lavoro è ancora da fare. A volte manca la motivazione da parte dei team vicini e ci sono molte circostanze che complicano il lavoro. Se mai ti trovi ad affrontare un compito simile, moltiplica il tempo che ti sembra normale per la sua attuazione per tre o anche quattro.

Ricorda inoltre che i problemi esistenti nei processi aziendali non possono essere risolti utilizzando un nuovo DBMS, anche se molto produttivo. Ciò che intendo? All'inizio del nostro progetto, abbiamo creato l'impressione tra i clienti che ora porteremo un nuovo database veloce e vivremo! I processi andranno più veloci, andrà tutto bene. In effetti, la tecnologia non risolve i problemi dei processi aziendali, perché i processi aziendali sono persone. E devi lavorare con le persone, non con la tecnologia.

Lo sviluppo basato sui test può essere doloroso e richiedere molto tempo nelle fasi iniziali. Ma l’effetto positivo sarà evidente anche a breve termine, quando non sarà necessario fare nulla per condurre test di regressione.

È estremamente importante condurre test di carico in tutte le fasi dello sviluppo. Prima noterai qualche difetto nell'architettura, più facile sarà risolverlo, il che ti farà risparmiare molto tempo in futuro.

Non c'è niente che non va in Lua. Chiunque può imparare a scriverci: sviluppatore Java, sviluppatore JavaScript, sviluppatore Python, front-end o back-end. Anche i nostri analisti lo scrivono.

Quando parliamo del fatto che non abbiamo SQL, la gente terrorizza. “Come si ottengono i dati senza SQL? È possibile? Certamente. In un sistema di classi OLTP, SQL non è necessario. Esiste un'alternativa sotto forma di una sorta di linguaggio che ti riporta immediatamente a una visione orientata ai documenti. Ad esempio, GraphQL. E c’è un’alternativa sotto forma di calcolo distribuito.

Se capisci che dovrai scalare, progetta la tua soluzione su Tarantool in modo tale che possa funzionare in parallelo su dozzine di istanze di Tarantool. Se non lo fai, sarà difficile e doloroso in seguito, poiché Tarantool può utilizzare effettivamente solo un core del processore.

Fonte: habr.com

Aggiungi un commento