Tracciamento distribuito: abbiamo sbagliato

Nota. trad.: L'autrice di questo materiale è Cindy Sridharan, un'ingegnere di imgix specializzata nello sviluppo di API e, in particolare, nel test dei microservizi. In questo materiale condivide la sua visione dettagliata dei problemi attuali nel campo del tracciamento distribuito, dove, a suo avviso, mancano strumenti veramente efficaci per risolvere problemi urgenti.

Tracciamento distribuito: abbiamo sbagliato
[Illustrazione tratta da altro materiale sulla traccia distribuita.]

Si ritiene che tracciamento distribuito difficile da implementare e il ritorno che ne deriva dubbioso nella migliore delle ipotesi. Esistono molte ragioni per cui la tracciabilità è problematica, spesso citando il lavoro coinvolto nella configurazione di ciascun componente del sistema per trasmettere le intestazioni appropriate con ciascuna richiesta. Sebbene questo problema esista, non è affatto insormontabile. A proposito, non spiega perché agli sviluppatori non piace molto il tracciamento (anche quando è già funzionante).

La sfida principale con la tracciabilità distribuita non è la raccolta di dati, la standardizzazione dei formati per la distribuzione e la presentazione dei risultati o la determinazione di quando, dove e come campionare. Non sto cercando di immaginare banale questi "problemi di comprensibilità" sono, infatti, piuttosto significativi a livello tecnico e (se consideriamo veramente Open Source) standard e protocolli) sfide politiche che devono essere superate affinché questi problemi possano essere considerati risolti.

Tuttavia, se immaginiamo che tutti questi problemi siano risolti, è molto probabile che nulla cambierà in modo significativo in termini di esperienza dell'utente finale. La traccia potrebbe non essere ancora di utilità pratica negli scenari di debug più comuni, anche dopo la distribuzione.

Una traccia così diversa

La traccia distribuita include diversi componenti disparati:

  • dotare applicazioni e middleware di strumenti di controllo;
  • trasferimento di contesto distribuito;
  • raccolta di tracce;
  • archiviazione delle tracce;
  • la loro estrazione e visualizzazione.

Molti discorsi sul tracciamento distribuito tendono a trattarlo come una sorta di operazione unaria il cui unico scopo è aiutare a diagnosticare completamente il sistema. Ciò è in gran parte dovuto al modo in cui si sono storicamente formate le idee sulla tracciabilità distribuita. IN voci di blog, realizzato quando sono state aperte le fonti Zipkin, è stato menzionato questo it [Zipkin] rende Twitter più veloce. Sono state inoltre promosse le prime offerte commerciali per la tracciabilità Strumenti dell'APM.

Nota. trad.: Per rendere il testo più facile da comprendere, definiamo due termini fondamentali secondo Documentazione del progetto OpenTracing:

  • Durata — l'elemento base della tracciabilità distribuita. È una descrizione di un determinato flusso di lavoro (ad esempio, una query sul database) con un nome, orari di inizio e fine, tag, registri e contesto.
  • Gli span in genere contengono collegamenti ad altri span, consentendo la combinazione di più span Traccia — visualizzazione della vita di una richiesta mentre si muove attraverso un sistema distribuito.

Le tracce contengono dati incredibilmente preziosi che possono aiutare con attività quali test di produzione, test di ripristino di emergenza, test di inserimento di errori, ecc. In effetti, alcune aziende utilizzano già la tracciabilità per scopi simili. Cominciamo con trasferimento universale del contesto ha altri usi oltre al semplice spostamento delle campate nel sistema di accumulo:

  • Ad esempio, Uber usi risultati del tracciamento per distinguere tra traffico di test e traffico di produzione.
  • Facebook usi tracciare i dati per l'analisi del percorso critico e per la commutazione del traffico durante i normali test di ripristino di emergenza.
  • Anche i social network si applica Notebook Jupyter che consentono agli sviluppatori di eseguire query arbitrarie sui risultati della traccia.
  • Aderenti LDFIA (Iniezione di guasti guidati dal lignaggio) usato tracce distribuite per test con inserimento di errori.

Nessuna delle opzioni sopra elencate si applica interamente allo scenario eseguire il debug, durante il quale l'ingegnere cerca di risolvere il problema osservando la traccia.

Quando viene ancora raggiunge lo script di debug, l'interfaccia primaria rimane il diagramma traceview (anche se alcuni lo chiamano anche "Diagramma di Gantt" o "diagramma della cascata"). Sotto traceview я Intendo tutti gli span e i relativi metadati che insieme costituiscono la traccia. Ogni sistema di tracciamento open source, così come ogni soluzione di tracciamento commerciale, offre a traceview interfaccia utente per visualizzare, dettagliare e filtrare le tracce.

Il problema con tutti i sistemi di tracciamento che ho visto finora è che il risultato visualizzazione (traceview) riflette quasi completamente le caratteristiche del processo di generazione delle tracce. Anche quando vengono proposte visualizzazioni alternative: mappe di calore, topologie di servizio, istogrammi di latenza, alla fine si riducono comunque a traceview.

In passato io lamentato a cui sembra limitarsi la maggior parte delle "innovazioni" nel tracciamento UI/UX accendere metadati aggiuntivi in ​​traccia, investendo in essi informazioni con elevata cardinalità (alta cardinalità) o fornire la possibilità di approfondire intervalli specifici o eseguire query inter e intra-traccia. In questo caso, traceview rimane lo strumento di visualizzazione principale. Finché questo stato di cose continua, il tracciamento distribuito occuperà (nella migliore delle ipotesi) il 4° posto come strumento di debug, dopo metriche, log e stack trace, e nel peggiore dei casi si rivelerà uno spreco di tempo e denaro.

Problema con traceview

destino traceview — fornire un quadro completo del movimento di una singola richiesta attraverso tutti i componenti del sistema distribuito a cui è correlata. Alcuni sistemi di tracciamento più avanzati consentono di approfondire i singoli intervalli e visualizzare una ripartizione nel tempo interno un processo (quando gli span hanno confini funzionali).

La premessa di base dell’architettura dei microservizi è l’idea che la struttura organizzativa cresca con le esigenze dell’azienda. I sostenitori dei microservizi sostengono che la distribuzione di varie attività aziendali in singoli servizi consente a piccoli team di sviluppo autonomi di controllare l'intero ciclo di vita di tali servizi, dando loro la possibilità di creare, testare e distribuire in modo indipendente tali servizi. Tuttavia, lo svantaggio di questa distribuzione è la perdita di informazioni su come ciascun servizio interagisce con gli altri. In tali condizioni, la tracciabilità distribuita afferma di essere uno strumento indispensabile per eseguire il debug interazioni complesse tra servizi.

Se davvero sistema distribuito incredibilmente complesso, allora nessuna persona è in grado di tenerlo in testa pieno immagine. In effetti, sviluppare uno strumento partendo dal presupposto che sia possibile è una sorta di anti-modello (un approccio inefficace e improduttivo). Idealmente, il debug richiede uno strumento che aiuti restringere l'area di ricerca, in modo che gli ingegneri possano concentrarsi su un sottoinsieme di dimensioni (servizi/utenti/host, ecc.) rilevanti per lo scenario problematico considerato. Nel determinare la causa di un guasto, gli ingegneri non sono tenuti a capire cosa è successo durante il processo tutti i servizi contemporaneamente, poiché tale requisito contraddirebbe l’idea stessa di architettura a microservizi.

Tuttavia, traceview lo è esattamente Questo. Sì, alcuni sistemi di tracciamento offrono visualizzazioni di traccia compresse quando il numero di intervalli nella traccia è così grande da non poter essere visualizzato in un'unica visualizzazione. Tuttavia, a causa della grande quantità di informazioni contenute anche in una visualizzazione così ridotta, gli ingegneri continuano a farlo costretto a “setacciarlo”, restringendo manualmente la selezione a un insieme di servizi che sono fonte di problemi. Purtroppo, in questo campo, le macchine sono molto più veloci degli esseri umani, meno soggette a errori e i loro risultati sono più ripetibili.

Un altro motivo per cui penso che traceview sia sbagliato è perché non è utile per il debug basato su ipotesi. Fondamentalmente, il debug è iterativo un processo che inizia con un'ipotesi, seguito dalla verifica di varie osservazioni e fatti ottenuti dal sistema lungo diversi vettori, conclusioni/generalizzazioni e ulteriore valutazione della verità dell'ipotesi.

Opportunità veloce ed economico testare ipotesi e migliorare di conseguenza il modello mentale lo è pietra angolare debug Qualsiasi strumento di debug dovrebbe esserlo interattivo e restringere lo spazio di ricerca o, in caso di falsa pista, consentire all'utente di tornare indietro e concentrarsi su un'area diversa del sistema. Lo strumento perfetto farà questo in modo proattivo, attirando immediatamente l'attenzione dell'utente su potenziali aree problematiche.

ahimè, traceview non può essere definito uno strumento con un'interfaccia interattiva. Il meglio che puoi sperare quando lo usi è trovare qualche fonte di maggiore latenza e guardare tutti i possibili tag e log ad esso associati. Ciò non aiuta l'ingegnere a identificare modelli nel traffico, ad esempio le specifiche della distribuzione del ritardo, o rilevare correlazioni tra diverse misurazioni. Analisi generalizzata delle tracce può aiutare a risolvere alcuni di questi problemi. Veramente, ci sono esempi analisi di successo utilizzando l'apprendimento automatico per identificare intervalli anomali e identificare un sottoinsieme di tag che potrebbero essere associati a comportamenti anomali. Tuttavia, devo ancora vedere visualizzazioni convincenti dei risultati dell'apprendimento automatico o del data mining applicati a intervalli significativamente diversi da un traceview o da un DAG (grafico aciclico diretto).

Le campate sono di livello troppo basso

Il problema fondamentale con traceview è questo campate sono primitive di livello troppo basso sia per l'analisi della latenza che per l'analisi della causa principale. È come analizzare i comandi dei singoli processori per cercare di risolvere un'eccezione, sapendo che esistono strumenti di livello molto più elevato come il backtrace con cui è molto più comodo lavorare.

Inoltre, mi permetto di affermare quanto segue: idealmente, non ne abbiamo bisogno quadro completo si è verificato durante il ciclo di vita della richiesta, rappresentato dai moderni strumenti di tracciamento. È invece necessaria una qualche forma di astrazione di livello superiore che contenga informazioni su cosa finito male (simile al backtrace), insieme ad un po' di contesto. Invece di guardare l'intera traccia, preferisco vederla parte, dove accade qualcosa di interessante o insolito. Attualmente la ricerca viene effettuata manualmente: l'ingegnere riceve la traccia e analizza autonomamente le campate alla ricerca di qualcosa di interessante. L'approccio delle persone che osservano gli span nelle singole tracce nella speranza di rilevare attività sospette non è affatto scalabile (specialmente quando devono dare un senso a tutti i metadati codificati in diversi span, come ID span, nome del metodo RPC, durata dello span 'a, log, tag, ecc.).

Alternative a traceview

I risultati della traccia sono particolarmente utili quando possono essere visualizzati in modo da fornire informazioni non banali su ciò che sta accadendo nelle parti interconnesse del sistema. Fino a quando ciò non accade, il processo di debug rimane in gran parte invariato inerte e dipende dalla capacità dell'utente di notare le giuste correlazioni, controllare le parti giuste del sistema o mettere insieme i pezzi del puzzle, invece di strumento, aiutando l'utente a formulare queste ipotesi.

Non sono un visual designer o uno specialista di UX, ma nella prossima sezione voglio condividere alcune idee su come potrebbero apparire queste visualizzazioni.

Concentrarsi su servizi specifici

In un momento in cui l’industria si consolida attorno alle idee SLO (obiettivi del livello di servizio) e SLI (indicatori del livello di servizio), sembra ragionevole che i singoli team diano la priorità a garantire che i loro servizi siano allineati con questi obiettivi. Ne consegue che orientato al servizio la visualizzazione è più adatta per tali team.

Le tracce, soprattutto senza campionamento, sono un tesoro di informazioni su ciascun componente di un sistema distribuito. Queste informazioni possono essere fornite a un astuto processore che le fornirà agli utenti orientato al servizio reperti che possono essere identificati in anticipo, anche prima che l'utente guardi le tracce:

  1. Diagrammi di distribuzione della latenza solo per richieste molto importanti (richieste anomale);
  2. Diagrammi della distribuzione dei ritardi per i casi in cui gli obiettivi SLO del servizio non vengono raggiunti;
  3. I tag più "comuni", "interessanti" e "strani" nelle query più frequenti si ripetono;
  4. Ripartizione della latenza per i casi in cui a seconda i servizi non raggiungono gli obiettivi SLO;
  5. Ripartizione della latenza per vari servizi downstream.

Ad alcune di queste domande semplicemente non viene data risposta dalle metriche integrate, costringendo gli utenti a esaminare attentamente gli intervalli. Di conseguenza, abbiamo un meccanismo estremamente ostile all’utente.

Ciò solleva la domanda: che dire delle interazioni complesse tra diversi servizi controllati da team diversi? Non è vero? traceview non è ritenuto lo strumento più idoneo per evidenziare una situazione del genere?

Gli sviluppatori mobili, i proprietari di servizi stateless, i proprietari di servizi gestiti con stato (come i database) e i proprietari di piattaforme potrebbero essere interessati a qualcos'altro presentazione sistema distribuito; traceview è una soluzione troppo generica per queste esigenze fondamentalmente diverse. Anche in un’architettura di microservizi molto complessa, i proprietari dei servizi non necessitano di una conoscenza approfondita di più di due o tre servizi upstream e downstream. In sostanza, nella maggior parte degli scenari, gli utenti devono solo rispondere a domande riguardanti insieme limitato di servizi.

È come guardare un piccolo sottoinsieme di servizi attraverso una lente d'ingrandimento per il gusto di scrutarlo. Ciò consentirà all'utente di porre domande più urgenti riguardanti le complesse interazioni tra questi servizi e le loro immediate dipendenze. Questo è simile al backtrace nel mondo dei servizi, dove l'ingegnere lo sa che sbagliato, e deve anche capire cosa sta succedendo nei servizi circostanti perché.

L'approccio che sto promuovendo è l'esatto opposto dell'approccio top-down, basato su traceview, in cui l'analisi inizia con l'intera traccia e poi procede gradualmente fino ai singoli intervalli. Al contrario, un approccio dal basso verso l’alto inizia analizzando una piccola area vicina alla potenziale causa dell’incidente, per poi espandere lo spazio di ricerca secondo necessità (con la possibilità di coinvolgere altri team per analizzare una gamma più ampia di servizi). Il secondo approccio è più adatto per testare rapidamente le ipotesi iniziali. Una volta ottenuti risultati concreti si potrà passare ad un’analisi più mirata e dettagliata.

Costruire una topologia

Le visualizzazioni specifiche del servizio possono essere incredibilmente utili se l'utente lo sa cosa un servizio o un gruppo di servizi è responsabile dell'aumento della latenza o della causa di errori. Tuttavia, in un sistema complesso, identificare il servizio incriminato può essere un compito non banale durante un guasto, soprattutto se dai servizi non sono stati segnalati messaggi di errore.

Costruire una topologia di servizio può essere di grande aiuto per capire quale servizio sta riscontrando un picco nei tassi di errore o un aumento della latenza che sta causando un notevole degrado del servizio. Quando parlo di costruire una topologia, non intendo mappa dei servizi, visualizzando tutti i servizi disponibili nel sistema e conosciuti per la sua mappe di architettura a forma di stella della morte. Questa visualizzazione non è migliore della traceview basata su un grafico aciclico diretto. Invece vorrei vedere topologia di servizio generata dinamicamente, in base a determinati attributi come tasso di errore, tempo di risposta o qualsiasi parametro definito dall'utente che aiuta a chiarire la situazione con specifici servizi sospetti.

Facciamo un esempio. Immaginiamo un ipotetico sito di notizie. Servizio di home page (prima pagina) scambia dati con Redis, con un servizio di consigli, con un servizio pubblicitario e con un servizio video. Il servizio video acquisisce video da S3 e metadati da DynamoDB. Il servizio di consigli riceve metadati da DynamoDB, carica dati da Redis e MySQL e scrive messaggi su Kafka. Il servizio pubblicitario riceve dati da MySQL e scrive messaggi a Kafka.

Di seguito è riportata una rappresentazione schematica di questa topologia (molti programmi di routing commerciali creano la topologia). Può essere utile se è necessario comprendere le dipendenze del servizio. Tuttavia, durante eseguire il debug, quando un determinato servizio (ad esempio un servizio video) presenta un tempo di risposta maggiore, tale topologia non è molto utile.

Tracciamento distribuito: abbiamo sbagliato
Diagramma di servizio di un ipotetico sito di notizie

Lo schema seguente sarebbe più adatto. C'è un problema con il servizio (Video) raffigurato proprio al centro. L'utente se ne accorge immediatamente. Da questa visualizzazione risulta chiaro che il servizio video funziona in modo anomalo a causa di un aumento del tempo di risposta di S3, che influisce sulla velocità di caricamento di parte della pagina principale.

Tracciamento distribuito: abbiamo sbagliato
Topologia dinamica che mostra solo i servizi “interessanti”.

Le topologie generate dinamicamente possono essere più efficienti delle mappe di servizi statiche, soprattutto nelle infrastrutture elastiche e scalabili automaticamente. La capacità di confrontare e contrastare le topologie di servizio consente all'utente di porre domande più pertinenti. Domande più precise sul sistema hanno maggiori probabilità di portare a una migliore comprensione di come funziona il sistema.

Visualizzazione comparativa

Un'altra visualizzazione utile sarebbe una visualizzazione comparativa. Attualmente le tracce non sono molto adatte per i confronti affiancati, quindi di solito i confronti lo sono campate. E l'idea principale di questo articolo è proprio che gli span sono di livello troppo basso per estrarre le informazioni più preziose dai risultati della traccia.

Il confronto di due tracce non richiede visualizzazioni fondamentalmente nuove. In effetti, è sufficiente qualcosa come un istogramma che rappresenti le stesse informazioni di una traceview. Sorprendentemente, anche questo semplice metodo può portare molti più frutti rispetto al semplice studio di due tracce separatamente. Ancora più potente sarebbe la possibilità visualizzare confronto di tracce nell'aggregato. Sarebbe estremamente utile vedere come una modifica alla configurazione del database implementata di recente per abilitare GC (garbage collection) influisce sul tempo di risposta di un servizio downstream su una scala di diverse ore. Se quello che sto descrivendo qui suona come un'analisi A/B dell'impatto dei cambiamenti infrastrutturali in molti servizi utilizzando i risultati della traccia, non sei troppo lontano dalla verità.

conclusione

Non metto in dubbio l'utilità del tracciamento in sé. Credo sinceramente che non esista altro metodo per raccogliere dati così ricchi, causali e contestuali come quello contenuto in una traccia. Tuttavia, ritengo anche che tutte le soluzioni di tracciamento utilizzino questi dati in modo estremamente inefficiente. Finché gli strumenti di tracciamento rimangono bloccati sulla rappresentazione del traceview, saranno limitati nella loro capacità di sfruttare al massimo le preziose informazioni che possono essere estratte dai dati contenuti nelle tracce. Inoltre, esiste il rischio di sviluppare ulteriormente un'interfaccia visiva completamente ostile e poco intuitiva che limiterà gravemente la capacità dell'utente di risolvere gli errori nell'applicazione.

Il debug di sistemi complessi, anche con gli strumenti più recenti, è incredibilmente difficile. Gli strumenti dovrebbero aiutare lo sviluppatore a formulare e testare un'ipotesi, fornendo attivamente informazioni rilevanti, identificando i valori anomali e notando le caratteristiche nella distribuzione dei ritardi. Affinché la tracciabilità diventi lo strumento preferito dagli sviluppatori durante la risoluzione dei problemi di produzione o dei problemi che si estendono su più servizi, sono necessarie interfacce utente e visualizzazioni originali che siano più coerenti con il modello mentale degli sviluppatori che creano e gestiscono tali servizi.

Sarà necessario uno sforzo mentale significativo per progettare un sistema che rappresenterà i vari segnali disponibili nei risultati della traccia in un modo ottimizzato per facilitare l'analisi e l'inferenza. È necessario pensare a come astrarre la topologia del sistema durante il debug in modo da aiutare l'utente a superare i punti ciechi senza guardare le singole tracce o intervalli.

Abbiamo bisogno di buone capacità di astrazione e stratificazione (specialmente nell'interfaccia utente). Quelli che si adatterebbero bene a un processo di debug basato su ipotesi in cui è possibile porre domande in modo iterativo e testare ipotesi. Non risolveranno automaticamente tutti i problemi di osservabilità, ma aiuteranno gli utenti ad affinare la propria intuizione e a formulare domande più intelligenti. Chiedo un approccio più ponderato e innovativo alla visualizzazione. C’è una reale prospettiva qui per espandere gli orizzonti.

PS da traduttore

Leggi anche sul nostro blog:

Fonte: habr.com

Aggiungi un commento