Architettura e possibilità di Tarantool Data Grid

Architettura e possibilità di Tarantool Data Grid

Nel 2017 abbiamo vinto il concorso per lo sviluppo del nucleo transazionale del business degli investimenti di Alfa-Bank e abbiamo iniziato a lavorare (al HighLoad++ 2018 con una relazione sul nucleo del business degli investimenti. ha parlato Vladimir Drynkin, responsabile della direzione del nucleo transazionale del business degli investimenti di Alfa-Bank). Questo sistema doveva aggregare dati su transazioni da diverse fonti in vari formati, standardizzare i dati in un formato unificato, conservarli e fornire accesso ad essi.

Durante lo sviluppo, il sistema è evoluto e ha acquisito funzionalità, e a un certo punto ci siamo resi conto che stava emergendo qualcosa di molto più grande di un semplice software applicativo, creato per risolvere un ambito ristretto di compiti: abbiamo creato un sistema per costruire applicazioni distribuite con archiviazione persistente. L'esperienza acquisita è diventata la base per un nuovo prodotto — Tarantool Data Grid (TDG).

Voglio parlarvi dell'architettura TDG e delle soluzioni che abbiamo trovato durante lo sviluppo, presentarvi le funzionalità principali e mostrarvi come il nostro prodotto possa diventare la base per costruire soluzioni complete.

Architettonicamente abbiamo suddiviso il sistema in singoli ruoli, ognuno dei quali è responsabile per la risoluzione di un determinato insieme di compiti. Un'istanza dell'applicazione eseguita realizza uno o più tipi di ruoli. In un cluster possono esserci più ruoli dello stesso tipo:

Architettura e possibilità di Tarantool Data Grid

Connector

Il connettore è responsabile della connessione con il mondo esterno; il suo compito è ricevere la richiesta, analizzarla e, se questo va a buon fine, inviare i dati per l'elaborazione al processore di input. Supportiamo i formati HTTP, SOAP, Kafka e FIX. L'architettura permette di aggiungere facilmente il supporto per nuovi formati, e presto sarà disponibile anche il supporto per IBM MQ. Se l'analisi della richiesta termina con un errore, il connettore restituirà un errore; altrimenti, risponderà che la richiesta è stata elaborata con successo, anche se si è verificato un errore durante la successiva elaborazione. Questo è stato fatto appositamente per lavorare con sistemi che non sono in grado di ripetere le richieste – o viceversa, lo fanno in modo troppo insistente. Per evitare di perdere dati, si utilizza una coda di riparazione: l'oggetto viene prima inserito in essa e solo dopo l'elaborazione riuscita viene rimosso. L'amministratore può ricevere notifiche sugli oggetti rimasti nella coda di riparazione e, dopo aver risolto l'errore software o guasto hardware, può eseguire un nuovo tentativo.

Processore di input

Il processore di input classifica i dati ricevuti in base a caratteristiche specifiche e chiama i gestori appropriati. I gestori sono codice scritto in Lua, eseguito in un ambiente isolato, così non possono influenzare il funzionamento del sistema. In questa fase, i dati possono essere formattati come richiesto e, se necessario, è possibile avviare un numero arbitrario di attività che possono implementare la logica necessaria. Ad esempio, nel prodotto MDM (Master Data Management), costruito su Tarantool Data Grid, quando aggiungiamo un nuovo utente, per non rallentare l'elaborazione della richiesta, creiamo un record d'oro avviando un'attività separata. L'ambiente isolato supporta richieste di lettura, modifica e aggiunta di dati, permette di eseguire alcune funzioni su tutti i ruoli di tipo storage e l'aggregazione del risultato (map/reduce).

I gestori possono essere descritti in file:

sum.lua

local x, y = unpack(...)
return x + y

E poi, dichiarati nella configurazione:

functions:
  sum: { __file: sum.lua }

Perché Lua? Lua è un linguaggio molto semplice. Dalla nostra esperienza, dopo poche ore di familiarizzazione, le persone iniziano a scrivere codice che risolve i loro problemi. E non parliamo solo di sviluppatori professionisti, ma anche, ad esempio, di analisti. Inoltre, grazie al compilatore JIT, Lua è molto veloce.

Storage

Storage gestisce dati persistenti. Prima del salvataggio, i dati vengono convalidati rispetto allo schema di dati. Per descrivere lo schema utilizziamo un formato esteso. Apache Avro. Esempio:

{
    "name": "User",
    "type": "record",
    "logicalType": "Aggregate",
    "fields": [ 
        { "name": "id", "type": "string"}, 
        {"name": "first_name", "type": "string"}, 
        {"name": "last_name", "type": "string"} 
    ], 
    "indexes": ["id"] 
}

Da questa descrizione viene generato automaticamente il DDL (Data Definition Language) per il DBMS Tarantool e GraphQL lo schema per l'accesso ai dati.

Supporta la replicazione asincrona dei dati (prevede di aggiungere quella sincrona).

Output processor

A volte è necessario informare i consumatori esterni sull'arrivo di nuovi dati; a tal fine esiste il ruolo di Output processor. Dopo il salvataggio dei dati, questi possono essere inviati al rispettivo gestore (ad esempio, per formattarli secondo le richieste del consumatore) — e successivamente inoltrati al connector per l'invio. Anche qui si utilizza la coda di riparazione: se l'oggetto non viene ricevuto da nessuno, l'amministratore può riprovare più tardi.

Scalabilità

I ruoli di connector, input processor e output processor non hanno uno stato, il che ci consente di scalare orizzontalmente il sistema semplicemente aggiungendo nuove istanze dell'applicazione con il ruolo del tipo necessario. Per la scalabilità orizzontale, si utilizza lo storage approccio per l'organizzazione del cluster utilizzando bucket virtuali. Dopo aver aggiunto un nuovo server, parte dei bucket dai vecchi server viene trasferita in background sul nuovo server; questo avviene in modo trasparente per gli utenti e non influisce sul funzionamento dell'intero sistema.

Proprietà dei dati

Gli oggetti possono essere molto grandi e contenere altri oggetti. Garantiamo l'atomicità nell'aggiunta e nell'aggiornamento dei dati, conservando l'oggetto con tutte le dipendenze in un unico bucket virtuale. In questo modo si evita la "scomposizione" dell'oggetto su più server fisici.

È supportata la versioning: ogni aggiornamento dell'oggetto crea una nuova versione, e possiamo sempre fare un'istantanea temporale e vedere com'era il mondo all'epoca. Per i dati che non necessitano di una lunga storia, possiamo limitare il numero di versioni o persino conservare solo una — l'ultima — disabilitando di fatto il versioning per un determinato tipo. È anche possibile limitare la cronologia nel tempo: ad esempio, eliminando tutti gli oggetti di un certo tipo più vecchi di 1 anno. Supportiamo anche l'archiviazione: possiamo esportare oggetti più vecchi del tempo specificato, liberando spazio nel cluster.

Attività

Tra le funzionalità interessanti, vale la pena menzionare la possibilità di avviare attività programmate, su richiesta dell'utente o programmaticamente dalla sandbox:

Architettura e possibilità di Tarantool Data Grid

Qui vediamo un'altra funzione: il runner. Questo ruolo non ha uno stato e, se necessario, è possibile aggiungere ulteriori istanze dell'applicazione con questo ruolo nel cluster. La responsabilità del runner è quella di eseguire i compiti. Come già detto, dalla sandbox è possibile generare nuovi compiti; questi vengono memorizzati in coda sullo storage e poi eseguiti dal runner. Questa tipologia di compiti è chiamata Job. Abbiamo anche un tipo di compiti, chiamato Task — sono compiti definiti dall'utente e avviati secondo una pianificazione (utilizzando la sintassi cron) oppure su richiesta. Per avviare e monitorare tali compiti, abbiamo un comodo gestore di compiti. Per rendere questa funzionalità disponibile, è necessario attivare il ruolo scheduler; questo ruolo ha uno stato, quindi non è scalabile, il che, in effetti, non è necessario; tuttavia, come tutti gli altri ruoli, può avere una replica che inizia a funzionare se il master fallisce improvvisamente.

Logger

Un altro ruolo si chiama logger. Questo raccoglie i log da tutti i membri del cluster e fornisce un'interfaccia per il loro caricamento e visualizzazione tramite interfaccia web.

Servizi

È importante notare che il sistema consente di creare facilmente servizi. Nel file di configurazione, è possibile specificare quali richieste indirizzare al gestore personalizzato, eseguito in un ambiente sandbox. In questo gestore, ad esempio, è possibile eseguire una richiesta analitica e restituire il risultato.

Il servizio è descritto nel file di configurazione:

services:
   sum:
      doc: "aggiunge due numeri"
      function: sum
      return_type: int
      args:
         x: int
         y: int

L'API GraphQL è generata automaticamente e il servizio diventa disponibile per la chiamata:

query {
   sum(x: 1, y: 2) 
}

Questo porterà alla chiamata del gestore sum, che restituirà il risultato:

3

Profilazione delle richieste e metriche

Per comprendere il funzionamento del sistema e profilare le richieste, abbiamo implementato il supporto per il protocollo OpenTracing. Il sistema può inviare informazioni su richiesta agli strumenti che supportano questo protocollo, come Zipkin, consentendo di capire come è stata eseguita la richiesta:

Architettura e possibilità di Tarantool Data Grid

Naturalmente, il sistema fornisce metriche interne che possono essere raccolte tramite Prometheus e visualizzate utilizzando Grafana.

Deploy

Tarantool Data Grid può essere distribuito tramite pacchetti RPM o archivi, utilizzando gli strumenti forniti o Ansible, con supporto per Kubernetes.Tarantool Kubernetes Operator).

Le applicazioni che implementano la logica di business (configurazione, gestori) vengono caricate nel cluster distribuito di Tarantool Data Grid sotto forma di archivio tramite interfaccia utente o tramite script, utilizzando l'API fornita da noi.

Esempi di applicazioni

Quali applicazioni possono essere create con Tarantool Data Grid? In effetti, la maggior parte delle sfide aziendali è legata in un modo o nell'altro all'elaborazione di flussi di dati, alla loro memorizzazione e accesso. Quindi, se hai grandi flussi di dati che devono essere archiviati in modo affidabile e a cui deve essere fornito accesso, il nostro prodotto può farti risparmiare molto tempo nello sviluppo, consentendoti di concentrarti sulla tua logica di business.

Ad esempio, vogliamo raccogliere informazioni sul mercato immobiliare, per avere, in seguito, notizie sulle offerte più vantaggiose. In questo caso, evidenziamo i seguenti compiti:

  1. I robot che raccolgono informazioni da fonti aperte saranno le nostre fonti di dati. Questo compito può essere affrontato utilizzando soluzioni già pronte o scrivendo codice in qualsiasi linguaggio.
  2. Successivamente, Tarantool Data Grid riceverà e salverà i dati. Se il formato dei dati provenienti da diverse fonti è diverso, puoi scrivere codice in Lua che eseguirà la conversione in un formato comune. Durante la fase di pre-elaborazione, potrai anche filtrare frasi duplicate o aggiornare ulteriormente nel database le informazioni sugli agenti attivi sul mercato.
  3. Ora hai già una soluzione scalabile nel cluster, che può essere riempita con dati e da cui è possibile estrarre informazioni. Puoi implementare nuove funzionalità, ad esempio creare un servizio che faccia una richiesta ai dati e fornisca l'offerta più vantaggiosa della giornata — questo richiederà alcune righe nel file di configurazione e un po' di codice in Lua.

E ora?

La nostra priorità è migliorare la facilità di sviluppo tramite Tarantool Data Grid. Ad esempio, questa è un'IDE con supporto per il profiling e il debugging di gestori che operano in sandbox.

Ci concentriamo molto anche sulla sicurezza. Attualmente stiamo completando la certificazione FSTEC della Russia per confermare l'alto livello di sicurezza e per soddisfare i requisiti di certificazione dei prodotti software utilizzati nei sistemi informatici per la gestione dei dati personali e nei sistemi informatici pubblici.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster