Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

I log e un'importante parte del sistema, che permette di capire se funziona (o non funziona) come previsto. In un'architettura a microservizi, la gestione dei log diventa una disciplina a sé stante. È necessario affrontare una serie di quesiti:

  • come scrivere i log dall'applicazione;
  • dove scrivere i log;
  • come inviare i log per la conservazione e l'elaborazione;
  • come elaborare e conservare i log.

L'uso di tecnologie di containerizzazione popolari aggiunge ulteriori complessità alla già complessa questione della gestione dei log.

Questo è esattamente il tema della relazione di Yuri Bushmelev "La mappa dei problemi nella raccolta e consegna dei log"

Riproduci video

Chi è interessato, prosegua oltre.

Mi chiamo Yuri Bushmelev. Lavoro in Lazada. Oggi parlerò di come gestiamo i nostri log, come li raccogliamo e cosa ci scriviamo.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Da dove veniamo? Chi siamo? Lazada è il numero 1 degli e-commerce in sei paesi del Sud-Est asiatico. Tutti questi paesi sono distribuiti tra diversi data center. Al momento abbiamo 4 data center. Perché è importante? Perché alcune soluzioni sono state dettate dalla debole connessione tra i centri. Abbiamo un'architettura a microservizi. Sono rimasto sorpreso di scoprire che abbiamo già 80 microservizi. Quando ho iniziato a lavorare sulla gestione dei log, erano solo 20. Inoltre, c'è un considerevole pezzo di legacy PHP con cui dobbiamo convivere. Tutto ciò genera attualmente oltre 6 milioni di messaggi al minuto nel sistema complessivo. Ora mostrerò come gestiamo tutto questo e perché è così.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Dobbiamo in qualche modo convivere con questi 6 milioni di messaggi. Cosa dobbiamo fare con loro? 6 milioni di messaggi che dobbiamo:

  • inviare dall'applicazione
  • ricevere per la consegna
  • consegnare per analisi e conservazione.
  • analizzare
  • deve essere conservato in qualche modo.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Quando sono apparsi tre milioni di messaggi, il mio aspetto era più o meno lo stesso. Anche perché eravamo partiti da piccole cifre. È chiaro che nei log dell'applicazione ci sono scritti messaggi come "impossibile connettersi al database" o "connessione riuscita, ma impossibile leggere qualcosa". Oltre a questo, ciascun nostro microservizio registra anche un access log. Ogni richiesta che arriva a un microservizio viene registrata nel log. Perché lo facciamo? I programmatori vogliono avere la possibilità di tracciare. In ogni access log c'è un campo traceid, che permette a un'interfaccia speciale di seguire l'intera catena e mostrare il tracciamento in modo chiaro. Il tracciamento mostra come è passata la richiesta, e questo aiuta i nostri sviluppatori a risolvere più rapidamente eventuali problemi non identificati.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Come vivere con tutto ciò? Ora vi parlerò brevemente delle soluzioni disponibili per risolvere il problema della raccolta, trasmissione e conservazione dei log.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Come scrivere dall'applicazione? È chiaro che ci sono diversi modi. In particolare, ci sono le best practice raccomandate dai guru del settore. Esiste l'approccio vecchia scuola in due varianti, come raccontano i nonni. Ci sono anche altri modi.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

La situazione è simile anche per la raccolta dei log. Non ci sono molte soluzioni specifiche per questa parte, già ci sono più opzioni, ma non tantissime.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Per quanto riguarda la consegna e l'analisi successiva, il numero di varianti inizia ad esplodere. Non descriverò ogni opzione ora. Penso che le principali siano note a tutti coloro che sono interessati all'argomento.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Mostrerò come abbiamo fatto in Lazada e come è iniziato tutto questo.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Un anno fa sono arrivato in Lazada e mi hanno assegnato a un progetto sui log. Era circa così. Il log dall'applicazione veniva scritto in stdout e stderr. Tutti hanno fatto tutto secondo le ultime mode. Ma poi gli sviluppatori lo hanno rimosso dai flussi standard e hanno lasciato che i professionisti dell'infrastruttura si occupassero del resto. Tra i professionisti dell'infrastruttura e gli sviluppatori ci sono anche i responsabili delle release, che hanno detto: "eh... ok, semplicemente avvolgiamoli in un file usando lo shell, e basta". Poiché il tutto era in un container, l'hanno avvolto direttamente all'interno del container, mappando la directory all'interno e ponendovi questi log. Credo che sia chiaro a tutti cosa ne sia uscito.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Guardiamo ora più da vicino come consegnavamo questi log. Qualcuno ha scelto td-agent, che in realtà è fluentd, ma non propriamente fluentd. Non ho mai capito bene il rapporto tra questi due progetti, ma sembrano riguardare la stessa cosa. Questo fluentd, scritto in Ruby, leggevano i file di log, li analizzava in JSON utilizzando alcune espressioni regolari. Poi li inviava a Kafka. Inoltre, in Kafka avevamo 4 topic separati per ciascuna API. Perché 4? Perché ci sono l'ambiente di produzione, quello di staging, e perché ci sono stdout e stderr. Gli sviluppatori li generano, mentre i professionisti dell'infrastruttura devono crearli in Kafka. Inoltre, Kafka era controllata da un altro dipartimento. Quindi, era necessario creare un ticket affinché creassero 4 topic per ciascuna API. Tutti dimenticavano questa cosa. Insomma, era un disastro totale.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Cosa abbiamo fatto dopo? Lo abbiamo inviato a Kafka. Poi metà dei log andava a Logstash. L'altra metà veniva distribuita. Parte andava in un Graylog, parte in un altro Graylog. Alla fine, tutto questo finiva in un unico cluster Elasticsearch. Quindi, tutto questo disordine finiva lì. Non si dovrebbe fare così!

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Ecco come appare, se lo guardiamo dall'alto. Non si dovrebbe fare così! Qui sono già contrassegnati con dei numeri i punti critici. Ce ne sono in realtà di più, ma 6 sono proprio i più problematici, con cui bisogna fare qualcosa. Di questi parlerò separatamente.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Qui (1,2,3 scriviamo i file e, di conseguenza, qui abbiamo subito tre difficoltà.

Primo (1) — dobbiamo scriverli da qualche parte. Non sempre vorremmo dare all'API la possibilità di scrivere direttamente nei file. È preferibile che l'API sia isolata in un container, e ancor meglio se sia in sola lettura. Io sono un sysadmin, quindi ho una visione un po' alternativa su queste cose.

Secondo punto (2,3) — riceviamo molte richieste nell'API. L'API scrive molti dati nei file. I file crescono. Dobbiamo ruotarli. Perché altrimenti non avrai mai spazio su disco. La rotazione è problematica perché sono gestiti tramite un redirect della shell in una directory. Non riusciamo a ruotare. Non possiamo dire all'applicazione di riaprire i descrittori. Perché gli sviluppatori ti guarderanno come un idiota: "Quali descrittori? Noi scriviamo solo in stdout". Gli infrastruttori hanno fatto un copytruncate in logrotate, che semplicemente copia il file e tronca l'originale. Di conseguenza, tra questi processi di copia, di solito, finisce lo spazio sul disco.

(4) Avevamo diversi formati in diverse API. Si differenziavano leggermente, ma dovevamo scrivere regex diverse. Poiché tutto era gestito da Puppet, c'era una grande rete di classi con le loro complicazioni. Inoltre, td-agent per la maggior parte del tempo poteva consumare memoria, rallentare e semplicemente fare finta di lavorare senza fare nulla. Capire dall'esterno che non stava facendo nulla era impossibile. Nel migliore dei casi, si bloccava e qualcuno doveva farlo ripartire. O meglio, arrivava un alert, e qualcuno andava a riavviarlo manualmente.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

(6) E il peggior problema era Elasticsearch. Perché era una versione vecchia. Perché non avevamo maestri dedicati a quel momento. Avevamo log eterogenei, nei quali i campi potevano sovrapporsi. Log diversi di diverse applicazioni potevano avere nomi di campo identici, ma con dati diversi all'interno. Quindi, un log arriva con un Integer nel campo, ad esempio, level. Un altro log arriva con una String nel campo level. In assenza di una mappatura statica, otteniamo questa situazione notevole. Se dopo la rotazione dell'indice in Elasticsearch primo arriva un messaggio con una stringa, allora va tutto bene. Ma se primo arriva un Integer, tutti i messaggi successivi che sono arrivati come String vengono semplicemente scartati. Perché non corrisponde al tipo di campo.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Abbiamo iniziato a porci queste domande. Abbiamo deciso di non cercare colpevoli.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Ma qualcosa deve essere fatto! È ovvio che dobbiamo stabilire degli standard. Alcuni standard erano già in atto. Alcuni li abbiamo stabiliti più tardi. Fortunatamente, un formato unico per i log di tutte le API era già stato approvato a quel momento. È scritto direttamente negli standard di interazione dei servizi. Di conseguenza, coloro che vogliono ricevere i log devono scriverli in questo formato. Se qualcuno non scrive i log in questo formato, significa che non possiamo garantire nulla.

Inoltre, vorremmo stabilire uno standard unico per i metodi di registrazione, consegna e raccolta dei log. Dove scriverli e come consegnarli. La situazione ideale è quando i progetti utilizzano tutti la stessa libreria. C'è una libreria di registrazione separata per Go, una separata per PHP. Tutti noi — tutti devono utilizzarle. Al momento direi che ci siamo riusciti per il 80%. Ma alcuni continuano a mangiare i cactus.

E lì (nello slide) inizia a intravedersi «SLA per la consegna dei log». Non c'è ancora, ma ci stiamo lavorando. Perché è molto comodo quando l'infrastruttura dice che se scrivi in un certo formato in un certo posto e non più di N messaggi al secondo, con una certa probabilità li consegneremo a quel posto. Questo elimina un sacco di mal di testa. Se l'SLA è presente, è semplicemente fantastico!

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Come abbiamo cominciato a risolvere il problema? Il principale problema riguardava td-agent. Non era chiaro dove andassero i nostri log. Vengono consegnati? Vengono raccolti? Dove sono? Quindi, il primo punto è stato decidere di sostituire td-agent. Qui ho abbozzato brevemente alcune opzioni su cosa sostituirlo.

Fluentd. Prima di tutto, l'ho affrontato nel mio lavoro precedente, e anche lì crashava di tanto in tanto. In secondo luogo, è fondamentalmente lo stesso, solo con un profilo diverso.

Filebeat. Cosa lo rendeva comodo per noi? Il fatto che fosse scritto in Go, e noi abbiamo una grande esperienza in Go. Di conseguenza, se necessario, potevamo adattarlo alle nostre esigenze. Ecco perché non lo abbiamo scelto. Non volevamo nemmeno essere tentati di riscriverlo.

Una soluzione ovvia per gli amministratori di sistema rimangono vari sistemi di logging in questa forma (syslog-ng/rsyslog/nxlog).

Oppure scrivere qualcosa da zero, ma abbiamo scartato anche l'idea di filebeat. Se dobbiamo scrivere qualcosa, è meglio che sia utile per il business. Per la trasmissione dei log, è meglio utilizzare qualcosa di già pronto.

Pertanto, la scelta si è sostanzialmente ridotta tra syslog-ng e rsyslog. Ho optato per rsyslog semplicemente perché nel nostro Puppet c'erano già classi per rsyslog, e non ho trovato differenze evidenti tra i due. Che sia syslog qui o là, la sostanza non cambia. Certamente, qualcuno ha documentazione migliore, qualcun altro peggiore. Uno sa fare una cosa, l'altro in un altro modo.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

E un po' su rsyslog. Prima di tutto, è fantastico perché ha molti moduli. Possiede un RainerScript comprensibile dall'uomo (un linguaggio di configurazione moderno). Un grande vantaggio è che abbiamo potuto emulare il comportamento di td-agent con strumenti standard, e per le applicazioni non è cambiato nulla. Cioè, sostituiamo td-agent con rsyslog, mentre tutto il resto rimane invariato. E otteniamo subito una trasmissione funzionante. Inoltre, mmnormalize è una cosa fantastica in rsyslog. Permette di analizzare i log, non tramite Grok e regexp. Crea un albero di sintassi astratta. Analizza i log in modo simile a come fa un compilatore con il codice sorgente. Questo consente di lavorare molto rapidamente, consumando poca CPU, ed è davvero una cosa straordinaria. Ci sono molti altri vantaggi, ma non mi soffermerò su di essi.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

rsyslog ha anche molti svantaggi. Sono, in un certo senso, simili ai vantaggi. I principali problemi sono che bisogna sapere come configurarlo e scegliere la versione giusta.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Abbiamo deciso che scriveremo i log in un socket Unix. Non in /dev/log, perché lì ci sono confusione di log di sistema, con journald in quel pipeline. Quindi, scriviamo in un socket personalizzato. Lo collegheremo a un ruleset separato. Non mescoleremo nulla. Tutto sarà trasparente e chiaro. E così abbiamo proceduto. La cartella con questi socket è standardizzata e viene passata a tutti i container. I container possono vedere e scrivere nel socket di cui hanno bisogno.

Perché non un file? Perché tutti hanno letto l'articolo su Badushka, che cercava di passare un file a Docker, e si scopriva che dopo il riavvio rsyslog cambiava il file descriptor, e Docker perdesse quel file. Teneva aperto qualcos'altro, ma non era più quel socket dove si scrive. Abbiamo deciso di aggirare questo problema, e, nel frattempo, di evitare anche i problemi di blocco.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Rsyslog esegue le azioni indicate nella slide e invia i log o a un relay, o a Kafka. Kafka corrisponde al vecchio metodo. Relay è il tentativo di utilizzare rsyslog per la consegna dei log. Senza Message Queue, con gli strumenti standard di rsyslog. In linea di principio, funziona.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Ma ci sono sfide su come immetterli poi in quella parte (Logstash/Graylog/ES). Questa parte (rsyslog-rsyslog) è utilizzata tra i data center. Qui c'è un link TCP compresso, che consente di risparmiare larghezza di banda e, di conseguenza, aumentare la probabilità di ricevere alcuni log da un altro data center quando la connessione è congestionata. Perché abbiamo l'Indonesia dove le cose non vanno bene. Lì c'è questo problema costante.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Ci siamo chiesti come monitorare, a quale probabilità i log che abbiamo registrato dall'applicazione, arrivano dall'altra parte? Abbiamo deciso di avviare delle metriche. rsyslog ha il proprio modulo di raccolta statistiche, con alcuni contatori. Ad esempio, può mostrarti la dimensione della coda, o quanti messaggi sono stati ricevuti in una certa azione. Da lì possiamo ottenere qualcosa. Inoltre, ha contatori personalizzati che possono essere configurati, e mostrerà, ad esempio, il numero di messaggi registrati da un certo API. In seguito, ho scritto rsyslog_exporter in Python, e tutto è stato inviato a Prometheus per costruire grafici. Volevamo moltissimo le metriche di Graylog, ma non abbiamo ancora avuto tempo per configurarle.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Quali problemi sono sorti? I problemi sono emersi quando abbiamo scoperto (IMPROVVISAMENTE!) che le nostre API Live scrivono 50.000 messaggi al secondo. Questo solo per le Live API senza il staging. E Graylog ci mostra solo 12.000 messaggi al secondo. E sorge la legittima domanda, dove sono i rimanenti? Da cui abbiamo dedotto che Graylog semplicemente non riesce a gestire questo flusso. Abbiamo verificato, e in effetti, Graylog con Elasticsearch non riesce a sostenere questo carico.

In seguito, ci sono state altre scoperte fatte nel processo.

La scrittura nel socket viene bloccata. Come è successo? Quando ho utilizzato rsyslog per la consegna, ad un certo punto abbiamo avuto un'interruzione del canale tra i data center. La consegna si è bloccata in un punto, bloccandosi in un altro punto. Tutto questo è arrivato a una macchina con API, che scrive nel socket rsyslog. Lì si è riempita la coda. Poi si è riempita la coda per la scrittura nel socket unix, che per impostazione predefinita contiene 128 pacchetti. E la prossima write() nell'applicazione si blocca. Quando abbiamo esaminato la libreria che utilizziamo nelle applicazioni Go, era scritto che la scrittura nel socket avviene in modalità non bloccante. Eravamo certi che nulla si bloccasse. Perché avevamo letto l'articolo su Badushka, che ne parlava. Ma c'è un problema. Intorno a questa chiamata c'era un ciclo infinito, in cui si tentava continuamente di inviare un messaggio nel socket. Questo non lo abbiamo notato. Abbiamo dovuto riscrivere la libreria. Da allora è cambiata diverse volte, ma adesso ci siamo liberati dai blocchi in tutti i sottosistemi. Quindi, possiamo fermare rsyslog senza che nulla si interrompa.

È necessario monitorare la dimensione delle code, il che aiuta a evitare di inciampare in questi problemi. Innanzitutto, possiamo monitorare quando iniziamo a perdere messaggi. In secondo luogo, possiamo monitorare se abbiamo a che fare con problemi di consegna.

E c'è anche un aspetto sgradevole: l'amplificazione dieci volte nell'architettura a microservizi è molto facile. Non abbiamo molti richieste in entrata, ma a causa del grafo dove questi messaggi si muovono, a causa dei log di accesso, aumentiamo davvero il carico sui log circa dieci volte. Purtroppo non ho avuto il tempo di calcolare le cifre esatte, ma i microservizi sono così. Bisogna tenerne conto. Risulta che attualmente il sottosistema di raccolta dei log è il più sovraccarico in Lazada.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Come risolvere il problema di elasticsearch? Se è necessario ottenere rapidamente i log in un unico luogo, per non dover girovagare tra tutte le macchine e raccoglierli, utilizzare uno storage di file. Questo funziona garantito. Può essere creato da qualsiasi server. È sufficiente attaccare dischi e installare syslog. Dopo di ciò, avrete garantito tutti i log in un unico luogo. Poi potete impostare elasticsearch, graylog o qualcos'altro. Ma avrete già tutti i log, e, per di più, potrete conservarli a seconda della capacità dei dischi.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Al momento della mia presentazione, lo schema era così. Abbiamo praticamente smesso di scrivere su file. Ora, probabilmente, disattiveremo il resto. Sulle macchine locali, su cui sono eseguite le API, smetteremo di scrivere su file. In primo luogo, c'è uno storage di file che funziona molto bene. In secondo luogo, su queste macchine il posto finisce sempre, bisogna monitorarlo costantemente.

Questa parte con Logstash e Graylog è davvero problematica. Quindi dobbiamo liberarci di essa. È necessario scegliere una sola cosa.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Abbiamo deciso di eliminare Logstash e Kibana. Perché abbiamo un dipartimento di sicurezza. Qual è il legame? La connessione è che Kibana senza X-Pack e Shield non consente di limitare i diritti di accesso ai log. Pertanto, abbiamo scelto Graylog. Ha tutto ciò che serve. Non mi piace, ma funziona. Abbiamo acquistato nuovo hardware, installato Graylog recente e trasferito tutti i log con formati rigorosi in un Graylog separato. Abbiamo risolto il problema con i diversi tipi di campi identici a livello organizzativo.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Ciò che entra nel nuovo Graylog. Abbiamo semplicemente registrato tutto in docker. Abbiamo preso una serie di server, distribuito tre istanze di Kafka, 7 server Graylog versione 2.3 (perché volevamo Elasticsearch versione 5). Tutto questo su RAID di HDD. Abbiamo visto una velocità di indicizzazione fino a 100.000 messaggi al secondo. Abbiamo visto che 140 terabyte di dati vengono elaborati a settimana.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

E di nuovo problemi! Abbiamo due saldi in arrivo. Siamo passati a 6 milioni di messaggi. Graylog non riesce a elaborare. Dobbiamo trovare un modo per sopravvivere.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Siamo sopravvissuti in questo modo. Abbiamo aggiunto un po' di server e SSD. Attualmente viviamo in questo modo. Ora, stiamo elaborando già 160.000 messaggi al secondo. Non abbiamo ancora raggiunto i limiti, quindi per il momento non è chiaro quanto realmente riusciremo a ottenere da questo.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

Questi sono i nostri piani per il futuro. Tra di essi, probabilmente, la cosa più importante è l'alta disponibilità. Al momento non ce l'abbiamo. Alcune macchine sono configurate allo stesso modo, ma tutto passa ancora attraverso una macchina. Dobbiamo prendere tempo per impostare il failover tra di loro.

Raccogliere le metriche da Graylog.

Impostare un rate limit in modo che una API impazzita non ci uccida la larghezza di banda e tutto il resto.

E infine, firmare un SLA con gli sviluppatori, con cui possiamo garantire questo grado di servizio. Se scrivete di più, ci dispiace.

E scrivere la documentazione.

Yuri Bushmelev 'Mappa dei problemi sul campo di raccolta e consegna dei log' — trascrizione della relazione

In breve, un riepilogo di tutto ciò che abbiamo vissuto. Prima di tutto, gli standard. In secondo luogo, syslog è come una torta. In terzo luogo, rsyslog funziona proprio così come indicato nella slide. Passiamo ora alle domande.

Domande.

Domanda: Perché alla fine avete deciso di non prendere… (filebeat?)

Risposta: È necessario scrivere su file. Non volevo proprio. Quando l'API scrive migliaia di messaggi al secondo, anche se ruoti ogni ora, non è comunque un'opzione. Si può scrivere in pipe. Gli sviluppatori mi hanno chiesto: «E se il processo su cui scriviamo si blocca?» Non sapevo cosa rispondere e ho detto: «Va bene, evitiamo di farlo».

Domanda: Perché non scrivete semplicemente i log in HDFS?

Risposta: Questo è il prossimo passo. Ci abbiamo pensato fin dall'inizio, ma attualmente non abbiamo risorse per gestirlo, quindi rimane una soluzione a lungo termine.

Domanda: Un formato colonnare sarebbe più appropriato.

Risposta: Capisco tutto. Siamo favorevoli con entrambe le mani.

Domanda: Scrivete in rsyslog. Ci si può connettere sia via TCP che UDP. Ma se usate UDP, come garantite la consegna?

Risposta: Ci sono due aspetti. Primo, dico subito a tutti che non garantiamo la consegna dei log. Perché quando gli sviluppatori arrivano e dicono: «Iniziamo a scrivere dati finanziari lì e voi li terrete da qualche parte nel caso succeda qualcosa», noi rispondiamo: «Ottimo! Cominciate a bloccarvi mentre scrivete nel socket e a farlo in transazioni, in modo da garantirci che li mettiate nel socket e che noi li riceviamo dall'altro lato.» E in quel momento tutti si tirano indietro. Se non volete garantire la scrittura nel socket, perché dovremmo garantire la consegna? Facciamo del nostro meglio. Ci impegniamo realmente a consegnare il più possibile e nel modo migliore, ma non offriamo garanzie al 100%. Quindi non scrivete dati finanziari lì. Ci sono database con transazioni per questo.

Domanda: Quando l'API genera un messaggio nel log e passa il controllo ai microservizi, avete riscontrato problemi con l'arrivo dei messaggi in ordine errato? Questo crea confusione.

Risposta: È normale che arrivino in ordine diverso. Bisogna essere pronti a questo. Perché qualsiasi consegna su rete non garantisce l'ordine, o bisogna spendere risorse specifiche per farlo. Se consideriamo gli archivi file, ogni API salva i log nel proprio file. In effetti, rsyslog li organizza in cartelle. Ogni API ha i propri log, dove si può andare a controllare, e poi si possono confrontare per timestamp. Se guardano in Graylog, lì saranno ordinati per timestamp. Tutto sarà in ordine.

Domanda: Il timestamp può differire di millisecondi.

Risposta: Il timestamp è generato dall'API stessa. Questo è, in realtà, il punto. Noi abbiamo NTP. L'API genera il timestamp già nel messaggio. Non lo aggiunge rsyslog.

Domanda: Non è chiaro come avviene l'interazione tra i data center. All'interno del data center è chiaro come sono stati raccolti e elaborati i log. Come avviene l'interazione tra i data center? Oppure ogni data center vive la propria vita?

Risposta: Quasi. Ogni paese è situato in un singolo data center. Attualmente non abbiamo distribuzioni che mettano un paese in diversi data center. Quindi non è necessario unirli. All'interno di ogni centro c'è un Log Relay. È un server Rsyslog. In realtà ci sono due macchine di gestione. Sono configurate in modo identico. Ma per ora il traffico passa attraverso una di esse. Questa aggrega i log. Ha una coda su disco per ogni evenienza. Comprime i log e li invia al data center centrale (a Singapore), dove poi vengono inviati a Graylog. E in ogni data center c'è il proprio storage file. In caso di perdita di connessione, abbiamo tutti i log lì. Rimarranno là. Saranno salvati.

Domanda: In situazioni straordinarie, ricevete i log da lì?

Risposta: Si può andare lì (nello storage file) e controllare.

Domanda: Come monitorate di non perdere log?

Risposta: In realtà, li perdiamo e ne monitoriamo la perdita. Abbiamo avviato il monitoraggio un mese fa. Nella libreria utilizzata dall'API Go, ci sono metriche. È in grado di contare quante volte non è riuscita a scrivere nel socket. Attualmente c'è un'astuzia. C'è un buffer. Cerca di scrivere messaggi in esso nel socket. Se il buffer si riempie, inizia a eliminarli. E conta quanti ne ha eliminati. Se i contatori iniziano a riempirsi, ne veniamo a conoscenza. Questi dati arrivano anche a Prometheus e si possono visualizzare grafici in Grafana. È possibile impostare avvisi. Ma per ora non è chiaro a chi inviarli.

Domanda: In Elasticsearch, conservate i log con il backup. Quante repliche hai?

Risposta: Una replica.

Domanda: È solo una replica?

Risposta: Questo è un master e una replica. I dati sono memorizzati in due copie.

Domanda: Hai modificato in qualche modo la dimensione del buffer di rsyslog?

Risposta: Scriviamo datagrammi in un socket Unix personalizzato. Questo ci impone immediatamente un limite di 128 kilobyte. Non possiamo scrivere più di questo. L'abbiamo specificato nello standard. Chi vuole entrare negli storage deve scrivere 128 kilobyte. Le librerie, tra l'altro, troncano e impostano un flag che indica che il messaggio è stato troncato. Nel nostro standard del messaggio c'è un campo speciale che mostra se è stato troncato durante la scrittura. Quindi abbiamo la possibilità di tracciare anche questo aspetto.

Domanda: Scrivete JSON danneggiati?

Risposta: Un JSON danneggiato verrà scartato o durante il relay, perché il pacchetto è troppo grande. Oppure verrà scartato da Graylog, perché non riesce a fare il parsing del JSON. Ma ci sono delle sfumature che devono essere sistemate, e sono per lo più legate a rsyslog. Ho già inserito alcune issue lì su cui dobbiamo ancora lavorare.

Domanda: Perché Kafka? Hai provato RabbitMQ? Graylog non funziona con questi carichi?

Risposta: Con Graylog non funziona. Ma Graylog funziona con noi. È davvero complicato. È una cosa particolare. E, in realtà, non è necessario. Preferirei scrivere da rsyslog direttamente in Elasticsearch e poi vedere Kibana. Ma dobbiamo risolvere la questione con i responsabili della sicurezza. Questa è una possibile direzione per il nostro sviluppo, quando elimineremo Graylog e utilizzeremo Kibana. Non avrebbe senso usare Logstash. Perché, posso fare tutto ciò con rsyslog. E ha un modulo per scrivere in Elasticsearch. Stiamo cercando di convivere con Graylog. L'abbiamo anche ottimizzato un po'. Ma c'è ancora margine per miglioramenti.

Per quanto riguarda Kafka. È così storicamente. Quando sono arrivato, c'era già e ci scrivevano già i log. Abbiamo semplicemente alzato il nostro cluster e ci siamo trasferiti con i log. Lo gestiamo, sappiamo come si comporta. Per quanto riguarda RabbitMQ... con RabbitMQ non funziona. E noi abbiamo un RabbitMQ funzionante. È in produzione, e c'erano problemi. Ora lo abbiamo sistemato prima della vendita, e ha iniziato a funzionare correttamente. Ma prima non ero pronto a rilasciarlo in produzione. C'è anche un altro punto. Graylog sa leggere la versione AMQP 0.9, mentre rsyslog sa scrivere la versione AMQP 1.0. E non esiste alcuna soluzione che sia in grado di gestire entrambe le versioni. Ci sono o l'uno o l'altro. Quindi al momento solo Kafka. Ma ci sono anche alcune sfide. Perché omkafka, la versione di rsyslog che stiamo utilizzando, può perdere l'intero buffer dei messaggi che ha estratto da rsyslog. Al momento conviviamo con questo.

Domanda: Utilizzate Kafka perché era già presente? Non viene utilizzato per altri scopi?

Risposta: La Kafka che c'era viene utilizzata dal team di Data Science. È un progetto completamente separato, di cui purtroppo non posso dire nulla. Non sono al corrente. Era sotto la gestione del team di Data Science. Quando hanno avviato i log, hanno deciso di utilizzarla per non doverne installare un'altra. Ora abbiamo aggiornato Graylog, e abbiamo perso la compatibilità, perché c'era una vecchia versione di Kafka. Abbiamo dovuto creare la nostra. Allo stesso tempo, ci siamo liberati di quei quattro topic per ogni API. Abbiamo creato un ampio topic per tutto il live, un ampio topic per tutto lo staging e semplicemente ci buttiamo tutto dentro. Graylog estrae tutto questo in parallelo.

Domanda: Perché è necessario questo rito sciamanico con i socket? Hai provato a utilizzare il driver di log syslog per i contenitori?

Risposta: Al momento in cui ci ponemmo questa domanda, i nostri rapporti con Docker erano tesi. Era Docker 1.0 o 0.9. Docker era strano di per sé. In secondo luogo, se dovessimo anche registrare i log... Ho un sospetto non verificato che faccia passare tutti i log attraverso di sé, tramite il demone di Docker. Se un API impazzisce, le altre API non possono inviare stdout e stderr. Non so a cosa porterà questo. Ho la sensazione che non sia necessario utilizzare il driver syslog di Docker in quel contesto. Il nostro dipartimento di test funzionali ha il proprio piccolo cluster Graylog con log. Utilizzano i driver di log di Docker e sembra che funzioni bene. Ma scrivono direttamente in Graylog in formato GELF. Quando abbiamo iniziato tutto questo, dovevamo solo che funzionasse. Forse poi, quando qualcuno dirà che funziona bene da anni, proveremo.

Domanda: Fai il trasporto tra i datacenter utilizzando rsyslog. Perché non con Kafka?

Risposta: Facciamo così e così in realtà. Per due motivi. Se il canale è completamente danneggiato, i nostri log, anche in forma compressa, non riescono a passarvi attraverso. Kafka consente semplicemente di perderli nel processo. In questo modo ci liberiamo dall'intasamento di questi log. In questo caso, utilizziamo Kafka direttamente. Se il nostro canale è buono e vogliamo liberarlo, utilizziamo rsyslog. Ma in realtà può essere configurato in modo tale da scartare ciò che non passa. Al momento utilizziamo direttamente la consegna di rsyslog in alcune situazioni e Kafka in altre.

Fonte: habr.com

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