Heim >Backend-Entwicklung >Golang >Pflege eines Open-Source-Backup-Tools: Einblicke und mehr

Pflege eines Open-Source-Backup-Tools: Einblicke und mehr

WBOY
WBOYOriginal
2024-07-18 09:37:101097Durchsuche

Backup-Strategien scheinen ein gelöstes Problem zu sein, doch Systemadministratoren kämpfen oft mit Fragen dazu, wie Daten ordnungsgemäß gesichert werden, wo sie gespeichert werden und wie der Backup-Prozess in verschiedenen Softwareumgebungen standardisiert werden kann. Im Jahr 2011 haben wir benutzerdefinierte Backup-Skripte entwickelt, die Backups für die Webprojekte unserer Kunden effizient durchführen. Diese Skripte haben uns viele Jahre lang gute Dienste geleistet und bei Bedarf Backups sowohl in unserem Speicher als auch in externen Repositorys gespeichert. Als unser Software-Ökosystem jedoch wuchs und sich diversifizierte, reichten unsere Skripte nicht mehr aus, da sie keine Unterstützung für neue Technologien wie Redis und MySQL/PostgreSQL boten. Außerdem wurden die Skripte umständlich, da es außer E-Mail-Benachrichtigungen kein Überwachungssystem gab.

Unsere einst kompakten Skripte haben sich zu einem komplexen und unüberschaubaren System entwickelt. Die Aktualisierung dieser Skripte für verschiedene Kunden wurde zu einer Herausforderung, insbesondere wenn sie angepasste Versionen verwendeten. Anfang letzten Jahres wurde uns klar, dass wir eine modernere Lösung brauchten.

In diesem Artikel erklären wir alle Schwierigkeiten, mit denen wir bei der Entwicklung von nxs-backup konfrontiert waren, und teilen unsere Erfahrungen und Herausforderungen. Sie können das Tool auch an Ihrem Projekt testen und Ihre Erfahrungen teilen, wir würden uns sehr über eine Rückmeldung von Ihnen freuen. Jetzt fangen wir an!

Wir haben unsere Anforderungen an ein neues System aufgelistet:

  • Sicherungsdaten der am häufigsten verwendeten Software: (Dateien: diskret und inkrementell; MySQL; PostgreSQL; MongoDB; Redis);
  • Speichern Sie Backups in gängigen Repositorys: (FTP; SSH; SMB; NFS; WebDAV; S3);
  • Erhalten Sie Benachrichtigungen bei Problemen während des Backup-Vorgangs;
  • Verfügen Sie über eine einheitliche Konfigurationsdatei, um Backups zentral zu verwalten;
  • Fügen Sie Unterstützung für neue Software hinzu, indem Sie externe Module anschließen;
  • Geben Sie zusätzliche Optionen zum Sammeln von Dumps an;
  • Backups mit Standardtools wiederherstellen können;
  • Einfache Erstkonfiguration. Alle diese Anforderungen wurden vor etwa 5 Jahren basierend auf unseren Bedürfnissen aufgelistet. Leider wurden nicht alle veröffentlicht.

Wir haben uns bereits vor der Erstellung unserer ersten Version von nxs-backup mit Open-Source-Lösungen befasst, die bereits existierten. Aber sie alle hatten ihre Fehler. Beispielsweise ist Bacula für uns mit unnötigen Funktionen überlastet, die Erstkonfiguration ist aufgrund der hohen manuellen Arbeit (z. B. zum Schreiben/Suchen von Skripten für Datenbanksicherungen) eine ziemlich mühsame Aufgabe, und zum Wiederherstellen von Kopien müssen spezielle Dienstprogramme verwendet werden usw.

Kein Wunder, dass wir vor dem gleichen Problem standen, als wir überlegten, unser Tool neu zu schreiben. Die Wahrscheinlichkeit, dass sich in vier Jahren etwas verändert hat und neue Tools online aufgetaucht sind, war nicht so hoch, aber immerhin.

Wir haben ein paar neue Tools untersucht, die vorher nicht in Betracht gezogen wurden. Aber wie bereits erwähnt, passten auch diese nicht zu uns. Weil sie unsere Anforderungen nicht vollständig erfüllten.

Wir kamen schließlich zu zwei wichtigen Schlussfolgerungen:

  1. Keine der vorhandenen Lösungen war vollständig für uns geeignet;
  2. Es scheint, dass wir genug Erfahrung und Verrücktheit hatten, um unsere Lösung zum ersten Mal zu schreiben. Und das könnten wir im Grunde noch einmal machen. Das haben wir also getan.

Bevor wir uns mit der neuen Version befassen, schauen wir uns an, was wir bisher hatten und warum es uns nicht gereicht hat.

Die alte Version unterstützte Datenbanken wie MySQL, PostgreSQL, Redis, MongoDB, diskretes und inkrementelles Kopieren von Dateien, mehrere Remote-Speicher (S3; SMB; NFS; FTP; SSH; WebDAV) und verfügte über Funktionen wie Backup-Rotation und Protokollierung , E-Mail-Benachrichtigungen und externe Module.

Jetzt mehr darüber, worüber wir uns Sorgen gemacht haben.

Führen Sie eine Binärdatei aus, ohne die Quelldatei unter jedem Linux neu zu starten

Im Laufe der Zeit ist die Liste der Systeme, mit denen wir arbeiten, erheblich gewachsen. Jetzt bedienen wir Projekte, die andere als standardmäßige Deb- und RPM-kompatible Distributionen wie Arch, Suse, Alt usw. verwenden.

Neuere Systeme hatten Schwierigkeiten beim Ausführen von nxs-backup, da wir nur Deb- und RPM-Pakete gesammelt und eine begrenzte Liste von Systemversionen unterstützt haben. Irgendwo haben wir das gesamte Paket neu zusammengestellt, irgendwo nur binär, irgendwo mussten wir nur den Quellcode ausführen.

Das Arbeiten mit der alten Version war für Ingenieure sehr umständlich, da sie mit der Quelle arbeiten mussten. Ganz zu schweigen davon, dass die Installation und Aktualisierung in diesem Modus mehr Zeit in Anspruch nimmt. Anstatt 10 Server pro Stunde einzurichten, mussten Sie nur eine Stunde auf einem Server verbringen.

Wir wissen seit langem, dass es viel besser ist, wenn Sie eine Binärdatei ohne Systemabhängigkeiten haben, die Sie auf jeder Distribution ausführen können und keine Probleme mit unterschiedlichen Versionen von Bibliotheken und Architekturunterschieden in Systemen haben. Wir wollten, dass dieses Tool dasselbe ist.

Docker-Image mit nxs-backup minimieren und ENV in Konfigurationsdateien unterstützen

In letzter Zeit arbeiten so viele Projekte in einer Containerumgebung. Auch diese Projekte erfordern Backups und wir führen nxs-backup in Containern aus. Für Containerumgebungen ist es sehr wichtig, die Bildgröße zu minimieren und mit Umgebungsvariablen arbeiten zu können.

Die alte Version bot keine Möglichkeit, mit Umgebungsvariablen zu arbeiten. Das Hauptproblem bestand darin, dass Passwörter direkt in der Konfiguration gespeichert werden mussten. Aus diesem Grund müssen Sie anstelle eines Satzes von Variablen, die nur Passwörter enthalten, die gesamte Konfiguration in eine Variable einfügen. Das Bearbeiten großer Umgebungsvariablen erfordert mehr Konzentration von Ingenieuren und erschwert die Fehlerbehebung etwas.

Außerdem mussten wir bei der Arbeit mit der alten Version ein bereits großes Debian-Image verwenden, in dem wir mehrere Bibliotheken und Anwendungen für korrekte Backups hinzufügen mussten.

Selbst mit einer schlanken Version des Bildes haben wir eine Mindestgröße von ~250 MB erreicht, was für ein kleines Dienstprogramm ziemlich viel ist. In einigen Fällen wirkte sich dies auf den Startvorgang der Sammlung aus, weil das Bild so lange auf den Knoten gezogen wurde. Wir wollten ein Bild erhalten, das nicht größer als 50 MB ist.

Arbeiten mit Remote-Speicher ohne Sicherung

Ein weiteres Problem für Containerumgebungen ist die Verwendung von Sicherungen zum Mounten von Remotespeicher.

Während Sie Backups auf dem Host ausführen, ist dies immer noch akzeptabel: Sie haben die richtigen Pakete installiert und Fuse im Kernel aktiviert, und jetzt funktioniert es.

Interessant wird es, wenn Sie eine Sicherung in einem Behälter benötigen. Ohne eine Aktualisierung der Berechtigungen mit direktem Zugriff auf den Kern des Hostsystems ist das Problem nicht gelöst und dies führt zu einer erheblichen Verringerung des Sicherheitsniveaus.

Dies muss koordiniert werden, da nicht alle Kunden einer Abschwächung der Sicherheitsrichtlinien zustimmen. Aus diesem Grund mussten wir eine Menge Problemumgehungen vornehmen, an die wir uns nicht einmal erinnern möchten. Darüber hinaus erhöht die zusätzliche Schicht die Ausfallwahrscheinlichkeit und erfordert eine zusätzliche Überwachung des Zustands der bereitgestellten Ressourcen. Es ist sicherer und stabiler, mit Remote-Speicher direkt über deren API zu arbeiten.

Status überwachen und Benachrichtigungen nicht nur per E-Mail senden

Heutzutage nutzen Teams immer weniger E-Mails in ihrer täglichen Arbeit. Das ist verständlich, denn es geht viel schneller, das Problem in einem Gruppenchat oder einem Gruppenanruf zu besprechen. Telegram, Slack, Mattermost, MS Teams und andere ähnliche Produkte werden dadurch weit verbreitet.

Wir haben auch einen Bot, der verschiedene Warnungen sendet und uns darüber benachrichtigt. Und natürlich würden wir gerne Berichte über abstürzende Backups im Arbeitsbereich wie Telegram und nicht in E-Mails neben Hunderten anderer E-Mails sehen. Manche Kunden möchten übrigens auch Informationen über Ausfälle in ihrem Slack oder einem anderen Messenger sehen.

Außerdem möchten Sie den Status verfolgen und die Details der Arbeit in Echtzeit sehen können. Dazu müssen Sie das Format der Anwendung ändern und sie in einen Dämon verwandeln.

Unzureichende Leistung

Ein weiterer akuter Schmerz war unzureichende Leistung in bestimmten Szenarien.

Einer der Clients hat einen riesigen Datei-Dump von fast einem Terabyte und alles besteht aus kleinen Dateien – Text, Bilder usw. Wir sammeln inkrementelle Kopien dieser Dinge und haben das folgende Problem – eine jährliche Kopie dauert DREI Tage. Ja, nun ja, die alte Version kann dieses Volumen einfach nicht in weniger als einem Tag verdauen.

Unter den gegebenen Umständen sind wir tatsächlich nicht in der Lage, Daten zu einem bestimmten Datum wiederherzustellen, was uns überhaupt nicht gefällt.

Anfangs haben wir unsere Backup-Lösung aufgrund ihrer Einfachheit und Flexibilität in Python implementiert. Als jedoch die Anforderungen wuchsen, wurde die Python-basierte Lösung unzureichend. Nach einer gründlichen Diskussion haben wir uns aus mehreren Gründen entschieden, das System in Go neu zu schreiben:

  1. Kompilierung und Abhängigkeiten: Der AOT-Compiler von Go erzeugt eine universelle, abhängigkeitsfreie Binärdatei, die die Bereitstellung auf verschiedenen Systemen vereinfacht;
  2. Leistung: Die inhärenten Multithreading-Funktionen von Go versprachen eine bessere Leistung;
  3. Teamkompetenz: Wir hatten mehr Entwickler mit Go-Erfahrung als mit Python.

Eine Lösung finden

Alle oben genannten Probleme bereiteten der IT-Abteilung mehr oder weniger spürbare Schmerzen und führten dazu, dass sie wertvolle Zeit mit sicherlich wichtigen Dingen verschwendete, aber diese Kosten hätten vermieden werden können. Darüber hinaus entstanden in bestimmten Situationen bestimmte Risiken für Geschäftsinhaber – die Wahrscheinlichkeit, an einem bestimmten Tag ohne Daten zu sein, ist zwar äußerst gering, aber nicht Null. Wir weigerten uns, den Stand der Dinge zu akzeptieren.

Nxs-backup 3.0

Das Ergebnis unserer Arbeit war eine neue Version von nxs-backup v 3.0, die kürzlich auf v3.8.0 aktualisiert wurde
Hauptmerkmale der neuen Version:

  • Implementieren Sie die entsprechenden Schnittstellen aller Speichereinrichtungen und aller Arten von Backups. Jobs und Speicher werden beim Start initialisiert und nicht während der Arbeit;
  • Arbeiten Sie mit Remote-Speicher über API. Hierzu nutzen wir verschiedene Bibliotheken;
  • Verwenden Sie Umgebungsvariablen in Konfigurationen dank des Mini-Anwendungsframeworks go-nxs-appctx, das wir in unseren Projekten verwenden;
  • Protokollereignisse über Hooks senden. Sie können verschiedene Ebenen konfigurieren und nur Fehler oder Ereignisse der gewünschten Ebene erhalten;
  • Geben Sie nicht nur den Zeitraum für die Sicherung an, sondern auch eine bestimmte Anzahl von Sicherungen;
  • Backups laufen jetzt einfach auf Ihrem Linux ab dem 2.6-Kernel. Dies machte es viel einfacher, mit nicht standardmäßigen Systemen zu arbeiten und Docker-Images schneller zu erstellen. Das Image selbst wurde auf 23 MB reduziert (mit zusätzlichen MySQL- und SQL-Clients);
  • Möglichkeit zum Sammeln, Exportieren und Speichern verschiedener Metriken im Prometheus-kompatiblen Format.
  • Begrenzung des Ressourcenverbrauchs für die lokale Festplattenrate und den Remote-Speicher.

Wir haben versucht, die meisten Konfigurationen und Anwendungslogiken beizubehalten, es sind jedoch einige Änderungen vorhanden. Sie alle beziehen sich auf die Optimierung und Korrektur von Fehlern in der Vorgängerversion.

Zum Beispiel legen wir die Verbindungsparameter zu den Remote-Repositorys in der Grundkonfiguration fest, damit wir sie nicht jedes Mal für verschiedene Arten von Backups vorschreiben.

Im Folgenden finden Sie ein Beispiel für die Grundkonfiguration für Backups. Es enthält allgemeine Einstellungen wie Benachrichtigungskanäle, Remote-Speicher, Protokollierung und Jobliste. Dies ist die grundlegende Hauptkonfiguration mit E-Mail-Benachrichtigung. Wir empfehlen dringend, E-Mail-Benachrichtigungen als Standardmethode zu verwenden. Wenn Sie weitere Funktionen benötigen, können Sie die Referenz in der Dokumentation sehen.

server_name: wp-server
project_name: My Best Project

loglevel: info

notifications:
  mail:
    enabled: true
    smtp_server: smtp.gmail.com
    smtp_port: 465
    smtp_user: j.doe@gmail.com
    smtp_password: some5Tr0n9P@s5worD
    recipients:
      - j.doe@gmail.com
      - a.smith@mail.io
  webhooks: []
storage_connects: []
jobs: []
include_jobs_configs: [ "conf.d/*.conf" ]

Ein paar Worte zu Fallstricken

Wir haben erwartet, dass wir uns bestimmten Herausforderungen stellen müssen. Es wäre dumm, anders zu denken. Aber zwei Probleme sorgten für den stärksten Hintern.

Image description

Speicherverlust oder nicht optimaler Algorithmus

Schon in der Vorgängerversion von nxs-backup haben wir unsere eigene Implementierung der Dateiarchivierung verwendet. Die Logik dieser Lösung bestand darin, die Verwendung externer Tools zum Erstellen von Backups zu vermeiden, und die Arbeit mit Dateien war der einfachste Schritt, der möglich ist.

In der Praxis erwies sich die Lösung als praktikabel, wenn auch bei einer großen Anzahl von Dateien nicht besonders effektiv, wie die Tests zeigten. Damals haben wir es auf die Besonderheiten von Python zurückgeführt und gehofft, einen signifikanten Unterschied zu sehen, als wir zu Go wechselten.

Als wir endlich zum Lasttest der neuen Version kamen, bekamen wir enttäuschende Ergebnisse. Es gab keine Leistungssteigerungen und der Speicherverbrauch war sogar noch höher als zuvor. Wir suchten nach einer Lösung. Lesen Sie viele Artikel und Recherchen zu diesem Thema, aber alle sagten, dass die Verwendung von „filepath.Walk“ und „filepath.WalkDir“ die beste Option ist. Die Leistung dieser Methoden steigt nur mit der Veröffentlichung neuer Versionen der Sprache.

Um den Speicherverbrauch zu optimieren, haben wir sogar Fehler bei der Erstellung inkrementeller Kopien gemacht. Übrigens waren kaputte Optionen tatsächlich effektiver. Aus offensichtlichen Gründen haben wir sie nicht verwendet.

Letztendlich hing alles an der Anzahl der zu verarbeitenden Dateien. Wir haben 10 Millionen getestet. Garbage Collector scheint nicht in der Lage zu sein, diese Menge generierter Variablen zu löschen.

Als uns schließlich klar wurde, dass wir hier zu viel Zeit verschwenden könnten, beschlossen wir, unsere Implementierung zugunsten einer bewährten und wirklich effektiven Lösung aufzugeben – GNU tar.

Vielleicht kommen wir später auf die Idee der Selbstimplementierung zurück, wenn wir eine effizientere Lösung für den Umgang mit zig Millionen Dateien finden.

So ein anderes FTP

Bei der Arbeit mit FTP trat ein weiteres Problem auf. Es stellte sich heraus, dass sich verschiedene Server bei denselben Anfragen unterschiedlich verhalten.

Und es ist ein wirklich ernstes Problem, wenn Sie auf dieselbe Anfrage entweder eine normale Antwort oder einen Fehler erhalten, der scheinbar nichts mit Ihrer Anfrage zu tun hat, oder wenn Sie keinen Fehler erhalten, wenn Sie ihn erwarten .

Also mussten wir auf die Verwendung der Bibliothek „prasad83/goftp“ zugunsten einer einfacheren „jlaffaye/ftp“ verzichten, da die erste mit dem Selectel-Server nicht korrekt funktionieren konnte. Der Fehler bestand darin, dass beim ersten Versuch, die Liste der Dateien im Arbeitsverzeichnis abzurufen, beim Herstellen der Verbindung der Fehler bezüglich der Zugriffsrechte auf das höhere Verzeichnis angezeigt wurde. Bei „jlaffaye/ftp“ besteht ein solches Problem nicht, da es einfacher ist und keine Anfragen an den Server sendet.

Das nächste Problem war eine Verbindungsunterbrechung, wenn keine Anfragen eingingen. Nicht alle Server verhalten sich so, einige jedoch schon. Wir mussten also vor jeder Anfrage prüfen, ob der Stecker abgefallen und wieder angeschlossen war.

Das Sahnehäubchen war das Problem, Dateien vom Server abzurufen, oder um es klar auszudrücken, der Versuch, eine Datei abzurufen, die nicht existierte. Einige Server geben einen Fehler aus, wenn sie versuchen, auf eine solche Datei zuzugreifen, andere geben ein gültiges io.Reader-Schnittstellenobjekt zurück, das sogar gelesen werden kann, nur dass Sie einen leeren Byte-Abschnitt erhalten.

Alle diese Situationen wurden empirisch entdeckt und müssen eigenständig behandelt werden.

Schlussfolgerungen

Am wichtigsten ist, dass wir die Probleme der alten Version behoben haben, die die Arbeit der Ingenieure beeinträchtigten und bestimmte Risiken für das Unternehmen mit sich brachten.

Wir haben immer noch unrealisierte „Wünsche“ aus der letzten Version, wie zum Beispiel:

  • Backup-Verschlüsselung;
  • Wiederherstellung aus dem Backup mit NXS-Backup-Tools;
  • Weboberfläche zum Verwalten der Jobliste und ihrer Einstellungen.

Diese Liste wird jetzt um neue erweitert:

  • Eigener Jobplaner. Verwenden Sie benutzerdefinierte Einstellungen anstelle von Systemeinstellungen;
  • Neue Backup-Typen (Clickhouse, Elastic, LVM usw.).

Und natürlich freuen wir uns über die Meinung der Community. Welche weiteren Entwicklungsmöglichkeiten sehen Sie? Welche Optionen würden Sie hinzufügen?

Sie können die Dokumentation lesen und mehr über nxs-backup auf der Website erfahren. Auf unserer Website gibt es auch einen Abschnitt zur Fehlerbehebung, falls Sie Probleme hinterlassen möchten.

Wir haben in unserem Telegram-Kanal bereits eine Umfrage zu kommenden Funktionen durchgeführt. Folgen Sie uns, um an solchen Aktivitäten teilzunehmen und zur Entwicklung des Tools beizutragen!

Bis zum nächsten Mal!

Das obige ist der detaillierte Inhalt vonPflege eines Open-Source-Backup-Tools: Einblicke und mehr. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn