Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

I log sono una parte importante del sistema, permettendo di capire se funziona (o non funziona) come previsto. Nelle architetture a microservizi, lavorare con i log diventa una disciplina a sé stante per le olimpiadi speciali. È necessario risolvere subito una serie di questioni:

  • come scrivere i log dall'applicazione;
  • dove scrivere i log;
  • come consegnare i log per l'archiviazione e l'elaborazione;
  • come elaborare e archiviare i log.

L'uso di tecnologie di containerizzazione attualmente popolari aggiunge ulteriori insidie nel campo delle possibili soluzioni.

È proprio di questo che parla la trascrizione della conferenza di Yuri Bushmelev «Mappa delle insidie nel campo di raccolta e consegna dei log»

Guarda il video

Chi è interessato, prego di proseguire.

Mi chiamo Yuri Bushmelev. Lavoro in Lazada. Oggi parlerò di come abbiamo gestito i nostri log, come li abbiamo raccolti e cosa scriviamo in essi.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Da dove veniamo? Chi siamo? Lazada è il negozio online numero 1 in sei paesi del Sud-Est asiatico. Questi paesi sono distribuiti nei nostri data center. Attualmente abbiamo un totale di 4 data center. Perché è importante? Perché alcune soluzioni sono state determinate dal fatto che tra i centri c'è un collegamento molto debole. Abbiamo un'architettura a microservizi. Sono rimasto sorpreso scoprendo che abbiamo già 80 microservizi. Quando ho iniziato a lavorare sui log, ce ne erano solo 20. Inoltre, c'è un bel pezzo di legacy PHP con cui dobbiamo convivere. Questo genera attualmente più di 6 milioni di messaggi al minuto nel sistema in generale. In seguito mostrerò come cerchiamo di gestire questa situazione e perché è così.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Con questi 6 milioni di messaggi dobbiamo trovare un modo per convivere. Cosa dobbiamo fare con essi? 6 milioni di messaggi che devono essere:

  • inviati dall'applicazione
  • ricevuti per la consegna
  • consegnati per l'analisi e l'archiviazione.
  • analizzare
  • in qualche modo archiviati.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Quando sono stati inviati tre milioni di messaggi, avevo un aspetto simile. Perché siamo partiti da pochi centesimi. È chiaro che lì vengono scritti i log delle applicazioni. Ad esempio, non sono riuscito a connettermi al database, sono riuscito a connettermi al database, ma non sono riuscito a leggere qualcosa. Ma oltre a questo, ogni nostro microservizio scrive anche un access-log. Ogni richiesta che arriva al microservizio viene registrata nel log. Perché facciamo questo? Gli sviluppatori vogliono avere la possibilità di fare tracing. In ogni access-log c'è un campo traceid, che poi un'interfaccia speciale utilizza per ricostruire tutto il tracciato e mostrare il tracing in modo chiaro. Il tracing mostra come è passata la richiesta e questo aiuta i nostri sviluppatori a gestire più rapidamente ogni problema sconosciuto.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Come vivere con tutto ciò? Ora vi racconterò brevemente alcune opzioni — come viene affrontato questo problema. Come risolvere il compito di raccolta, trasmissione e archiviazione dei log.

Yuri Bushmelev «Mappa delle insidie 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, come ci raccontano i trendy. C'è il vecchio stile in due forme, come raccontavano i nostri nonni. Ci sono altri metodi.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

La situazione con la raccolta dei log è più o meno la stessa. Le opzioni per risolvere questa particolare parte non sono molte. Ce ne sono di più, ma non ancora tante.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Ma per quanto riguarda la consegna e l'analisi successiva, il numero di varianti inizia a esplodere. Non vi descriverò ogni opzione ora. Penso che le opzioni principali siano note a chiunque abbia seguito l'argomento.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

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

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Un anno fa sono arrivato in Lazada e mi hanno mandato a lavorare su un progetto relativo ai log. Era più o meno così. Il log dall'applicazione veniva scritto in stdout e stderr. Tutti hanno fatto secondo le mode. Ma poi gli sviluppatori lo hanno tolto dai flussi standard, mentre lì come buona sorte ci avrebbero pensato gli specialisti dell'infrastruttura. Tra gli specialisti dell'infrastruttura e gli sviluppatori ci sono anche i rilascisti, che hanno detto: «eeeh... va bene, avvolgiamoli semplicemente in un file con shell, e basta». E poiché tutto questo era in un contenitore, è stato avvolto direttamente nel contenitore stesso, con la mappatura della directory interna e l'archiviazione lì. Penso che sia abbastanza chiaro a tutti cosa sia uscito da questo.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Guardiamo un po’ più in là. Come abbiamo consegnato questi log. Qualcuno ha scelto td-agent, che in realtà è fluentd, ma non è proprio fluentd. Non ho mai capito il rapporto tra questi due progetti, ma sembrerebbe che trattino entrambi della stessa cosa. E questo fluentd, scritto in Ruby, leggeva i file di log, li analizzava in JSON secondo alcune espressioni regolari. Poi li inviava a Kafka. Tra l'altro, in Kafka avevamo 4 topic separati per ogni API. Perché 4? Perché ci sono live, staging e ci sono stdout e stderr. Gli sviluppatori li creano, e chi si occupa dell'infrastruttura deve crearli in Kafka. Inoltre, Kafka era controllata da un altro dipartimento. Quindi bisognava aprire un ticket affinché creassero 4 topic per ogni API. Tutti si dimenticavano di ciò. Insomma, c'era un gran caos.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Cosa abbiamo fatto dopo con questo? Lo abbiamo inviato a Kafka. Successivamente, dalla Kafka, metà dei log andava a Logstash. L'altra metà dei log veniva suddivisa. Una parte andava a un Graylog, un'altra parte a un altro Graylog. Alla fine tutto questo finiva in un unico cluster Elasticsearch. Cioè, tutto quel disordine alla fine andava a finire lì. Così non si deve fare!

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Ecco come appare, se si guarda dall'alto. Non bisogna farlo in questo modo! Qui ci sono segnati immediatamente i punti problematici. Ce ne sono in realtà di più, ma 6 sono proprio quelli gravi, con cui bisogna fare qualcosa. Di questi parlerò separatamente ora.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Qui (1,2,3) stiamo scrivendo i file e, di conseguenza, qui ci sono subito tre grane.

Primo (1) — dobbiamo scriverli da qualche parte. Non sempre è desiderabile dare all'API la possibilità di scrivere direttamente nel file. È preferibile che l'API sia isolata in un contenitore, e sarebbe ancora meglio se fosse in sola lettura. Io sono un sysadmin, quindi ho un po’ un punto di vista alternativo su queste cose.

Il secondo punto (2,3) è che riceviamo molte richieste tramite l'API. L'API scrive molti dati in un file. I file crescono. Dobbiamo ruotarli. Altrimenti non riusciremo mai a tenere sotto controllo lo spazio su disco. Ruotarli è problematico perché sono gestiti tramite un redirect in shell in una directory. Non possiamo farlo. Non possiamo chiedere all'applicazione di riaprire i descrittori. Perché gli sviluppatori ti guarderebbero come se fossi un idiota: "Quali descrittori? Scriviamo direttamente in stdout". Gli esperti di infrastruttura hanno creato il copytruncate in logrotate, che fa semplicemente una copia del file e tronca l'originale. Di conseguenza, tra questi processi di copia di solito finisce lo spazio su disco.

(4) Avevamo diversi formati in diverse API. Si differenziavano un po', ma era necessario scrivere regex diversi. Poiché tutto era gestito da Puppet, c'era un gran numero di classi con le proprie idiosincrasie. Inoltre, il td-agent spesso poteva usare molta memoria, impantanarsi o semplicemente fare finta di funzionare senza fare nulla. Era impossibile capire dall'esterno che non stava facendo nulla. Nel migliore dei casi, si bloccava e qualcuno lo riavviava poi. Anzi, arrivava un alert e qualcuno andava a riavviarlo manualmente.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

(6) Il vero caos era elasticsearch. Perché era una versione obsoleta. Non avevamo master dedicati in quel momento. Avevamo log eterogenei i cui campi potevano sovrapporsi. Log di diverse applicazioni potevano avere gli stessi nomi di campo, ma contenere dati diversi. Ad esempio, un log potrebbe arrivare con un Integer nel campo level. Un altro log potrebbe arrivare con un String nello stesso campo level. In assenza di un mapping statico, si otteneva una situazione interessante. Se, dopo la rotazione dell'indice in elasticsearch, il primo messaggio arrivava con una stringa, tutto funzionava normalmente. Ma se il primo messaggio arrivava con un Integer, tutti i seguenti messaggi con String venivano semplicemente scartati. Perché il tipo di campo non corrisponde.

Yuri Bushmelev «Mappa delle insidie 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 delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Ecco, c'è qualcosa che dobbiamo fare! È ovvio che dobbiamo stabilire degli standard. Alcuni standard li avevamo già, altri sono stati introdotti successivamente. Fortunatamente, a quel momento era già stato approvato un formato unico per i log di tutte le API. È scritto direttamente negli standard di interazione dei servizi. Pertanto, coloro che desiderano ricevere i log devono scriverli in questo formato. Se qualcuno non scrive i log in questo formato, significa che non possiamo garantire nulla.

In seguito, sarebbe utile stabilire uno standard unico per i metodi di registrazione, consegna e raccolta dei log. In sostanza, dove scriverli e come consegnarli. La situazione ideale è quando nei progetti viene utilizzata la stessa libreria. Esiste una libreria di log separata per Go e una separata per PHP. Tutti quelli che abbiamo devono usarle. Al momento direi che ci siamo riusciti per l'80%. Ma alcuni continuano a mangiare cactus.

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

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Come abbiamo iniziato a risolvere il problema? Il principale ostacolo era con il td-agent. Non era chiaro dove finissero i nostri log. Vengono consegnati? Vengono raccolti? Dove sono? Pertanto, il primo punto è stato deciso: sostituire il td-agent. Qui ho rapidamente elencato le opzioni per una sostituzione.

Fluentd. Prima di tutto, ho avuto a che fare con esso nel lavoro precedente e anche lì è caduto periodicamente. In secondo luogo, è la stessa cosa, ma con una specializzazione.

Filebeat. Perché era comodo per noi? Perché è scritto in Go e abbiamo una grande esperienza in questo linguaggio. Pertanto, se necessario, avremmo potuto modificarlo in base alle nostre esigenze. Ecco perché non l'abbiamo scelto. Per evitare anche il tentativo di modificarlo.

Una soluzione ovvia per un amministratore di sistema rimane l'uso di vari syslog in una tale quantità (syslog-ng/rsyslog/nxlog).

Oppure scrivere qualcosa di nostro, ma abbiamo scartato anche questa opzione, così come filebeat. Se dobbiamo scrivere qualcosa, è meglio scrivere qualcosa di utile per il business. Per la consegna dei log, è meglio utilizzare qualcosa di già pronto.

Quindi, la scelta si è ridotta a una scelta tra syslog-ng e rsyslog. Ho optato per rsyslog semplicemente perché avevamo già delle classi per rsyslog in Puppet, e non ho trovato differenze evidenti tra i due. Che sia syslog da una parte, o syslog dall'altra. Sì, ci sono documentazioni migliori e peggiori. Alcuni gestiscono in un modo, altri in un altro.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

E un po' su rsyslog. Prima di tutto, è fantastico, perché ha molti moduli. Ha un RainerScript facilmente comprensibile (un linguaggio di configurazione moderno). Un fantastico bonus è che abbiamo potuto emulare il comportamento di td-agent con strumenti standard e per le applicazioni non è cambiato niente. Quindi, cambiamo td-agent con rsyslog e lasciamo tutto il resto per ora. E otteniamo immediatamente una consegna funzionante. Inoltre, mmnormalize è una funzione eccezionale in rsyslog. Consente di analizzare i log non utilizzando Grok o regexp. Crea un albero di sintassi astratta. Analizza i log in modo simile a come un compilatore analizza il codice sorgente. Questo permette di lavorare molto velocemente, consumando poco CPU, ed è veramente una cosa molto utile. Ci sono molti altri bonus. Non mi soffermerò su di essi.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

rsyslog ha anche molte carenze. Sono praticamente simili ai bonus. I principali problemi sono che bisogna saperlo configurare e bisogna scegliere la versione giusta.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Abbiamo deciso di scrivere i log in un socket unix. Non in /dev/log, perché lì abbiamo un miscuglio di log di sistema, c'è journald in questo pipeline. Quindi, scriviamo in un socket custom. Lo collegheremo a un ruleset separato. Non ci sarà confusione. Sarà tutto trasparente e chiaro. Così abbiamo fatto. La directory con questi socket è standardizzata e viene inoltrata a tutti i contenitori. I contenitori possono vedere il socket di cui hanno bisogno, aprirlo e scriverci.

Perché non un file? Perché tutti hanno letto l'articolo su Badushka, che cercava di inoltrare un file in docker, e si scopriva che dopo il riavvio di rsyslog il descrittore di file cambiava, e docker perdeva quel file. Tiene aperto qualcos'altro, ma non più quel socket in cui scrivono. Abbiamo deciso di aggirare questo problema e, in aggiunta, evitare il problema del blocco.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Rsyslog esegue le azioni indicate nella diapositiva e invia i log o a un relay, o a Kafka. Kafka corrisponde al metodo tradizionale. Relay è stato un tentativo di utilizzare solo rsyslog per la consegna dei log. Senza Message Queue, con le sole funzionalità standard di rsyslog. In linea di principio, funziona.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Ma ci sono delle sfide su come inserirli poi in questa 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 il canale è congestionato. Perché abbiamo l'Indonesia, dove le cose vanno male. Lì c'è questa costante problematica.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Ci siamo chiesti come monitorare effettivamente con quale probabilità i log che abbiamo registrato dall'applicazione arrivino all'altra estremità? Abbiamo deciso di introdurre delle metriche. rsyslog ha il suo modulo di raccolta statistica, che ha alcuni contatori. Ad esempio, può mostrarti la dimensione della coda o quanti messaggi sono arrivati in un certo action. Da questi puoi estrarre delle informazioni. Inoltre, ha contatori personalizzati che possono essere configurati, e ti mostrerà, ad esempio, il numero di messaggi registrati da un certo API. Inoltre, ho scritto rsyslog_exporter in Python, e abbiamo inviato tutto a Prometheus e costruito dei grafici. Ci sarebbe piaciuto molto avere le metriche di Graylog, ma per ora non abbiamo avuto tempo di configurarle.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Quali problemi sono emersi? I problemi sono emersi quando abbiamo scoperto (PLUTONICAMENTE!) che le nostre Live API scrivono 50k messaggi al secondo. Questo solo per le Live API senza staging. E Graylog ci mostra solo 12 mila messaggi al secondo. E sorge la domanda legittima: dove sono andati a finire gli altri? Da ciò abbiamo dedotto che Graylog semplicemente non ce la fa. Abbiamo controllato e, in effetti, Graylog con Elasticsearch non stava gestendo questo flusso.

In seguito, ulteriori scoperte che abbiamo fatto durante il processo.

La scrittura nel socket è stata bloccata. Come è successo? Quando ho usato rsyslog per la consegna, a un certo punto si è rotto il canale tra i data center. La consegna si è bloccata in un posto, la consegna si è bloccata in un altro posto. Tutto questo è arrivato alla macchina con le API, che scrivevano nel socket rsyslog. Là la coda si è riempita. Poi si è riempita la coda per la scrittura nel unix socket, che per impostazione predefinita è di 128 pacchetti. E la successiva 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 ha scritto a riguardo. Ma c'è un momento. Attorno a questa chiamata c'era un ciclo infinito, in cui si tentava costantemente di inserire un messaggio nel socket. Questo non lo abbiamo notato. Abbiamo dovuto riscrivere la libreria. Da allora è cambiata diverse volte, ma ora ci siamo liberati dei blocchi in tutti i sottosistemi. Pertanto, possiamo fermare rsyslog, e nulla cadrà.

È necessario monitorare la dimensione delle code, il che aiuta a non inciampare in queste trappole. In primo luogo, possiamo monitorare quando iniziamo a perdere messaggi. In secondo luogo, possiamo monitorare se abbiamo problemi di consegna.

E c'è anche una sgradevole questione: l'amplificazione di 10 volte in un'architettura a microservizi è molto semplice. Non abbiamo così tante richieste in ingresso, ma a causa del grafo attraverso il quale questi messaggi vengono inviati, a causa dei log di accesso, aumentiamo realmente il carico dei log di circa dieci volte. Purtroppo non ho avuto tempo di calcolare i numeri esatti, ma i microservizi sono così. Questo è da tenere a mente. Risulta che al momento il sottosistema di raccolta dei log è il più sovraccarico in Lazada.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Come risolvere il problema di elasticsearch? Se è necessario ricevere rapidamente i log in un unico posto, per non dover andare in giro per tutte le macchine e raccoglierli, utilizzare uno storage di file. Questo funziona garantito. Può essere fatto da qualsiasi server. Basta semplicemente inserire dei dischi e impostare syslog. Dopo di che avrete garantito tutti i log in un solo posto. Dopo sarà possibile configurare con calma elasticsearch, graylog o qualcos'altro. Ma avrete già tutti i log e, tra l'altro, potete conservarli quanto basta le risorse di disco.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Al momento della mia presentazione, lo schema è diventato così. Abbiamo praticamente smesso di scrivere nei file. Adesso, probabilmente, disconneteremo i resti. Sulle macchine locali, su cui sono avviati gli API, non scriveremo più nei file. In primo luogo, c'è uno storage di file che funziona molto bene. In secondo luogo, su queste macchine lo spazio finisce costantemente, è necessario monitorarlo continuamente.

Questa parte con Logstash e Graylog è veramente fastidiosa. Pertanto, dobbiamo liberarci di essa. È necessario scegliere una sola opzione.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Abbiamo deciso di abbandonare Logstash e Kibana. Perché abbiamo un reparto sicurezza. Qual è il nesso? Il nesso è che Kibana senza X-Pack e senza Shield non consente di differenziare i diritti di accesso ai log. Perciò abbiamo scelto Graylog. Ha tutto ciò di cui abbiamo bisogno. A me non piace, ma funziona. Abbiamo acquistato nuovo hardware, installato un Graylog fresco e trasferito tutti i log con formati rigidi in un Graylog separato. Abbiamo risolto il problema con i diversi tipi di campi identici a livello organizzativo.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Cosa comprende effettivamente il nuovo Graylog. Abbiamo semplicemente registrato tutto in Docker. Abbiamo preso un bel po' di server, distribuito tre istanze di Kafka, 7 server Graylog versione 2.3 (perché volevamo Elasticsearch versione 5). Tutto questo è stato caricato su RAID di HDD. Abbiamo visto un tasso di indicizzazione fino a 100 mila messaggi al secondo. Abbiamo visto che i dati ammontano a 140 terabyte a settimana.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

E di nuovo ostacoli! Abbiamo davanti a noi due vendite straordinarie. Siamo passati a 6 milioni di messaggi. Graylog non riesce a elaborare in tempo. Dobbiamo trovare un modo per sopravvivere di nuovo.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

Siamo sopravvissuti in questo modo. Abbiamo aggiunto qualche server e SSD in più. Attualmente viviamo in questo modo. Ora stiamo elaborando già 160.000 messaggi al secondo. Non abbiamo ancora raggiunto il limite, quindi non è chiaro fin dove possiamo realmente spingerci.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

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

Raccogliere metriche da Graylog.

Implementare un rate limit affinché un'API impazzita non ci distrugga la larghezza di banda e tutto il resto.

E infine, firmare qualche SLA con gli sviluppatori, in modo da evidenziare che possiamo gestire solo un certo volume. Se ne scrivete di più, ci dispiace.

E redigere la documentazione.

Yuri Bushmelev «Mappa delle insidie sul campo di raccolta e consegna dei log» — trascrizione della relazione

In sintesi, ecco i risultati di tutto ciò che abbiamo vissuto. Prima di tutto, gli standard. In secondo luogo, syslog — un capolavoro. In terzo luogo, rsyslog funziona proprio come scritto nella diapositiva. E ora passiamo alle domande.

Domande.

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

Risposta: È necessario scrivere su file. Molto controvoglia. Quando hai un'API che scrive migliaia di messaggi al secondo, anche se ruoti ogni ora, non è comunque una soluzione praticabile. Si può scrivere su pipe. A questo punto, gli sviluppatori mi hanno chiesto: "E se il processo in cui scriviamo si interrompe?" Non ho trovato cosa rispondere e ho detto: "Va bene, non facciamolo".

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

Risposta: Questo è il prossimo passo. Ci abbiamo pensato all'inizio, ma poiché al momento non ci sono risorse per occuparci di questo, resta una soluzione a lungo termine.

Domanda: Il formato colonnare sarebbe più appropriato.

Risposta: Capisco tutto. Siamo «sì» con entrambe le mani.

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

Risposta: Ci sono due aspetti. Prima di tutto, dico subito a tutti che non garantiamo la consegna dei log. Perché quando i programmatori vengono e dicono: «Iniziamo a scrivere i dati finanziari lì, e voi li archivierete da qualche parte nel caso succeda qualcosa», noi rispondiamo: «Ottimo! Iniziate a bloccarvi nella scrittura nel socket e fatelo in transazioni, per assicurarvi di metterlo nel socket e di essere certi che noi dall'altra parte lo abbiamo ricevuto.» E in quel momento a tutti non interessa più. E se non interessa, quali domande possono avere nei nostri confronti? Se non volete garantire la scrittura nel socket, perché dovremmo garantire la consegna? Noi facciamo il massimo sforzo. Ci impegniamo davvero a consegnare il più possibile e nel miglior modo possibile, ma non diamo il 100% di garanzia. Pertanto, non scrivete lì i dati finanziari. Per questo ci sono database con transazioni.

Domanda: Quando l'API genera un messaggio nei log e passa il controllo ai microservizi, non vi siete mai imbattuti nel problema che i messaggi dai diversi microservizi arrivano nell'ordine sbagliato? Questo crea confusione.

Risposta: È normale che arrivino in ordine diverso. Bisogna essere pronti a questo. Perché qualsiasi consegna di rete non garantisce l'ordine, o si deve spendere risorse specifiche per questo. Se consideriamo i file di archiviazione, ogni API salva i log nel proprio file. In realtà, rsyslog li organizza in cartelle. Ogni API ha i propri log, dove si può andare a vedere e poi confrontarli per timestamp. Se vanno a vedere in Graylog, lì saranno ordinati per timestamp. Tutto andrà bene.

Domanda: Il timestamp può differire di millisecondi.

Risposta: Il timestamp viene generato dall'API stessa. Questa è tutta la questione. Abbiamo NTP. L'API genera il timestamp già nel messaggio. Non è rsyslog a aggiungerlo.

Domanda: Non è molto chiara l'interazione tra i data center. All'interno del data center è chiaro come vengono raccolti e elaborati i log. Come avviene l'interazione tra i data center? O ogni data center vive di vita propria?

Risposta: Quasi. Ogni paese si trova in un unico data center. Al momento non abbiamo una distribuzione tale che un paese sia ospitato in più data center. Quindi non c'è bisogno di unirli. All'interno di ogni centro c'è un Log Relay. È un server Rsyslog. In realtà ci sono due macchine di gestione. Sono configurate allo stesso modo. Ma al momento tutto il traffico passa attraverso una di esse. Essa aggrega tutti i log. Ha una coda su disco per ogni evenienza. Comprime i log e li invia al data center centrale (quello di Singapore), dove vengono poi inviati a Graylog. E in ogni data center c'è il proprio storage di file. In caso di perdita di connessione, abbiamo tutti i log lì. Resteranno lì. Saranno salvati.

Domanda: In situazioni di emergenza ricevete log da lì?

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

Domanda: Come monitorate di non perdere i log?

Risposta: In realtà li perdiamo, e lo monitoriamo. Il monitoraggio è stato avviato un mese fa. Nella libreria utilizzata da Go API, ci sono delle metriche. È in grado di contare quante volte non è riuscita a scrivere nel socket. Attualmente c'è un'euristica ingegnosa. C'è un buffer. Prova a scrivere un messaggio dal buffer nel socket. Se il buffer si riempie, inizia a scartare i messaggi. E conta quanti ne ha scartati. Se i contatori iniziano a riempirsi, lo veniamo a sapere. Ora tutto questo arriva anche in Prometheus, e in Grafana è possibile vedere i grafici. È possibile impostare avvisi. Ma per ora non è chiaro a chi inviarli.

Domanda: In Elasticsearch conservate i log con ridondanza. Quante repliche avete?

Risposta: Una replica.

Domanda: Solo una replica?

Risposta: Questo è il master e la replica. I dati sono conservati in due esemplari.

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

Risposta: Scriviamo datagrammi in un socket unix personalizzato. Questo ci impone subito un limite di 128 kilobyte. Non possiamo scrivere più di questo. Abbiamo registrato questo nello standard. Chi vuole accedere agli storage deve scrivere 128 kilobyte. Le librerie, tra l'altro, accorciano e impostano un flag che indica che il messaggio è stato accorciato. Nel nostro standard del messaggio stesso c'è un campo speciale che mostra se è stato accorciato durante la scrittura o meno. Quindi abbiamo la possibilità di monitorare anche questo aspetto.

Domanda: Scrivete JSON danneggiati?

Risposta: Un JSON danneggiato verrà scartato o durante il relay, a causa di un pacchetto troppo grande. Oppure verrà scartato da Graylog, perché non sarà in grado di analizzare il JSON. Ma ci sono delle sfumature che devono essere sistemate, e in gran parte sono legate a rsyslog. Ho già segnalato alcuni problemi lì, su cui dobbiamo ancora lavorare.

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

Risposta: Con Graylog non ci siamo. Ma Graylog funziona per noi. È davvero problematico. È una cosa particolare. E, in effetti, non è necessario. Preferirei scrivere direttamente da rsyslog in elasticsearch e poi guardare in 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 esattamente la stessa cosa con rsyslog. E ha un modulo per scrivere in elasticsearch. Con Graylog stiamo cercando di convivere. L'abbiamo anche un po' ottimizzato. Ma c'è ancora spazio per i miglioramenti.

Riguardo a Kafka. È così storicamente. Quando sono arrivato, era già presente e ci si scrivevano già i log. Abbiamo semplicemente avviato il nostro cluster e ci siamo trasferiti lì con i log. Lo gestiamo, sappiamo come si comporta. Per quanto riguarda RabbitMQ... non ci stiamo trovando bene con RabbitMQ. Ma con RabbitMQ le cose vanno bene. Un production server ce l'abbiamo, e ci sono stati problemi. Prima dei saldi, l'abbiamo sistemato e ha iniziato a funzionare correttamente. Ma prima di ciò non ero pronto a rilasciarlo in produzione. C'è anche un altro aspetto. Graylog sa leggere la versione AMQP 0.9, mentre rsyslog sa scrivere la versione AMQP 1.0. E non c'è una soluzione che faccia entrambe le cose. O una o l'altra. Pertanto, al momento stiamo usando solo Kafka. Ma ci sono anche delle peculiarità. Perché omkafka, nella versione di rsyslog che stiamo usando, può perdere tutto il buffer dei messaggi che ha estratto da rsyslog. Al momento ci stiamo convivendo.

Domanda: Usate Kafka solo perché ce l'avevate già? Non è utilizzato per altre finalità?

Risposta: Kafka, che già avevate, è utilizzato dal team Data Science. Questo è un progetto completamente separato, di cui purtroppo non posso dire nulla. Non sono aggiornato. Era sotto la gestione del team Data Science. Quando hanno iniziato a raccogliere i log, hanno deciso di usarlo per non dover installare il proprio. Ora abbiamo aggiornato Graylog e abbiamo perso la compatibilità, perché c'era una vecchia versione di Kafka. Abbiamo dovuto crearne uno nostro. Allo stesso tempo, ci siamo liberati di quei quattro topic per ogni API. Ne abbiamo creato uno ampio per tutto il live, uno ampio per tutto il staging e semplicemente ci buttiamo tutto. Graylog lo estrapola tutto in parallelo.

Domanda: Perché c'è bisogno di questa magia con i socket? Avete provato a utilizzare il log-driver syslog per i container?

Risposta: Al momento in cui ci stavamo ponendo questa domanda, il nostro rapporto con Docker era teso. Si trattava di Docker 1.0 o 0.9. Docker in sé era strano. In secondo luogo, se ci si mettevano anche i log... Ho il sospetto non verificato che faccia passare tutti i log attraverso di sé, attraverso il demone di Docker. Se una delle nostre API va in crisi, le altre API si bloccano perché non riescono a inviare stdout e stderr. Non so a cosa porterà. Ho la sensazione che in questo caso non si debba usare il driver syslog di Docker. Il nostro dipartimento di testing funzionale ha il suo cluster di Graylog con i log. Usano i driver di log di Docker e lì sembra che tutto vada bene. Ma scrivono direttamente in Graylog in formato GELF. Al momento in cui stava per iniziare tutto questo, avevamo bisogno che funzionasse e basta. Forse poi, quando qualcuno dirà che funziona bene da un secolo, ci proveremo.

Domanda: Perché fate la consegna tra i data center con rsyslog? Perché non con Kafka?

Risposta: In realtà facciamo entrambe le cose. Per due motivi. Se il canale è completamente danneggiato, tutti i log, anche in formato compresso, non riescono a passare. Kafka ci permette semplicemente di perderli nel processo. In questo modo evitiamo che questi log si bloccano. In questo caso, usiamo Kafka direttamente. Se il nostro canale è buono e vogliamo liberarlo, allora usiamo rsyslog. Ma in realtà è possibile configurarlo in modo che scarti da solo quanto non passa. Al momento usiamo semplicemente rsyslog direttamente in alcune situazioni e Kafka in altre.

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