Uber ha dovuto affrontare alcune sfide dopo aver introdotto gli annunci su UberEats. Gli eventi da loro generati dovevano essere elaborati in modo rapido, affidabile e accurato. Questi requisiti sono stati soddisfatti da un sistema basato su Apache Flink, Kafka e Pinot in grado di elaborare flussi di eventi in tempo reale con semantica exactly-once. Un articolo che descrive la sua architettura è stato pubblicato di recente nel blog di Uber Engineering.
Gli autori spiegano che l'elaborazione degli eventi doveva pubblicare i risultati con il minor ritardo possibile, senza perdere dati e senza sovraccaricarli. Questi requisiti sono stati soddisfatti da una soluzione realizzata con l'aiuto di Apache Flink, Kafka e Pinot. Il sistema è composto da Flink jobs che comunicano tramite topics Kafka e memorizzano i dati dell'utente finale in Hive e Pinot.
Secondo gli autori, l'affidabilità del sistema è garantita dalla duplicazione cross-region, dai checkpoint di Flink e dalla politica di conservazione dei record di Kafka. La precisione si ottiene sfruttando la semantica exactly-once in Kafka e Flink, operazioni di upsert in Pinot e identificatori di record univoci per scopi di idempotency e deduplica.
La combinazione delle transazioni Kafka con i checkpoint Flink e il suo protocollo di commit in due fasi garantisce che i consumatori Kafka vedano solo gli eventi completamente elaborati. Inoltre, prevede che gli offset di Kafka memorizzati nei checkpoint siano in linea con i record committati. Con le transazioni Kafka, tutti gli eventi non vincolati causati da errori vengono ignorati. I checkpoint di Flink si verificano periodicamente e forniscono ai jobs con stato la stessa semantica dell'esecuzione senza errori, consentendogli di recuperare lo stato e le posizioni di flusso da un punto temporale noto in caso di errore. La combinazione dei checkpoint di Flink con il suo protocollo di commit a due fasi permette la semantica exactly-once.
Eventi e raw in arrivo vengono convalidati, deduplicati con l'aiuto dello stato con chiave di Flink, archiviati temporaneamente in un database Docstore e aggregati in finestre a cascata di un minuto. Gli autori spiegano di aver scelto questa finestra di un minuto perché è contemporaneamente abbastanza piccola da fornire una buona granularità per l'analisi e abbastanza grande da evitare di sovraccaricare i loro database con operazioni di scrittura. I risultati dell'aggregazione ricevono un identificatore univoco.
Un altro job mette in relazione l'ordine e gli eventi. I suoi risultati ricevono anche un identificatore univoco. Gli autori aggiungono che l'impostazione time-to-live degli eventi archiviati nel database Docstore garantisce che si svolgano solo eventi rilevanti: esistono solo durante la durata della loro finestra di correlazione.
Secondo gli autori, gli identificatori di record univoci generati vengono utilizzati con la funzione upsert di Pinot per garantire che i record con lo stesso identificatore non vengano mai duplicati e mantengano la semantica exactly-once. Vengono utilizzati con uno scopo simile in Hive per la deduplicazione dei record.
Gli autori sottolineano che la loro distribuzione Pinot è active-active nelle due regioni e non replica i dati. Pertanto, un job Flink unisce gli eventi di entrambe le regioni, assicurando che gli stessi dati siano archiviati in entrambe.
Apache Kafka è una piattaforma di streaming di eventi distribuita ampiamente utilizzata nel settore. Apache Flink viene utilizzato per eseguire calcoli stateful sui dati in streaming a causa della sua bassa latenza, affidabilità e caratteristiche esattamente una volta. Apache Pinot consente di creare applicazioni analitiche sensibili alla latenza rivolte all'utente.
Fonte: Vasco Veloso di Infoq.com