Wechsel von Redshift zu ClickHouse



IBunny nutzte Redshift lange Zeit als Datenbank für Ereignisse, die in Backend-Diensten und mobilen Anwendungen auftreten. Es wurde gewählt, weil es zum Zeitpunkt der Implementierung im Großen und Ganzen keine Alternativen gab, die hinsichtlich Kosten und Zweckmäßigkeit vergleichbar waren.

Nach der Veröffentlichung von ClickHouse änderte sich jedoch alles. Wir haben es lange studiert, die Kosten verglichen, die ungefähre Architektur geschätzt und schließlich diesen Sommer beschlossen, herauszufinden, wie nützlich es für uns ist. In diesem Artikel erfahren Sie mehr über das Problem, das Redshift uns bei der Lösung geholfen hat, und wie wir diese Lösung auf ClickHouse verschoben haben.

Das Problem


iFunny benötigte einen ähnlichen Service wie Yandex.Metrica, jedoch ausschließlich für den Inlandsverbrauch. Ich werde erklären warum.

Externe Clients schreiben Ereignisse. Dies können mobile Anwendungen, Websites oder interne Backend-Dienste sein. Für diese Kunden ist es sehr schwierig zu erklären, dass der Empfangsdienst für Veranstaltungen derzeit nicht verfügbar ist. Versuchen Sie, ihn in 15 Minuten oder in einer Stunde zu senden. Es gibt viele Kunden, die ständig Ereignisse senden möchten und überhaupt nicht warten können.

Im Gegensatz dazu gibt es interne Dienste und Benutzer, die diesbezüglich recht tolerant sind: Sie können auch mit einem unzugänglichen Analysedienst ordnungsgemäß arbeiten. Und die meisten Produktmetriken und die Ergebnisse von A / B-Tests sind im Allgemeinen sinnvoll, um sie nur einmal am Tag oder sogar noch seltener anzusehen. Daher sind die Leseanforderungen recht gering. Im Falle eines Unfalls oder einer Aktualisierung können wir es uns leisten, mehrere Stunden oder sogar Tage lang unzugänglich oder inkonsistent zu lesen (in einem besonders vernachlässigten Fall).

Wenn wir über Zahlen sprechen, müssen wir ungefähr fünf Milliarden Ereignisse (300 GB komprimierte Daten) pro Tag erfassen und Daten drei Monate lang in einer für SQL-Abfragen verfügbaren „heißen“ Form und zwei Jahre lang in einer „kalten“ Form speichern oder mehr, aber damit wir sie innerhalb weniger Tage in "heiß" verwandeln können.

Grundsätzlich handelt es sich bei Daten um eine Sammlung von Ereignissen, die nach Zeit geordnet sind. Es gibt ungefähr dreihundert Arten von Ereignissen, von denen jedes seine eigenen Eigenschaften hat. Es gibt noch einige Daten aus Quellen von Drittanbietern, die mit der Analysedatenbank synchronisiert werden sollten: z. B. eine Sammlung von Anwendungsinstallationen von MongoDB oder einen externen AppsFlyer-Dienst.

Es stellt sich heraus, dass wir ungefähr 40 TB Festplatte für die Datenbank und ungefähr 250 TB für den „kalten“ Speicher benötigen.

Rotverschiebungslösung




Es gibt also mobile Clients und Backend-Services, von denen Sie Ereignisse empfangen müssen. Der HTTP-Dienst akzeptiert die Daten, führt die Mindestüberprüfung durch, sammelt Ereignisse auf der lokalen Festplatte in Dateien, die nach einer Minute gruppiert sind, komprimiert sie sofort und sendet sie an den S3-Bucket. Die Verfügbarkeit dieses Dienstes hängt von der Verfügbarkeit der Server mit der Anwendung und AWS S3 ab. Anwendungen speichern den Status nicht, sodass sie leicht ausgeglichen, skaliert und ausgetauscht werden können. S3 ist ein relativ einfacher Dateispeicherdienst mit einem guten Ruf und einer guten Verfügbarkeit, sodass Sie sich darauf verlassen können.

Als nächstes müssen Sie die Daten irgendwie an Redshift liefern. Hier ist alles ganz einfach: Redshift verfügt über einen integrierten S3-Importer, der die empfohlene Methode zum Laden von Daten darstellt. Daher wird alle 10 Minuten ein Skript gestartet, das eine Verbindung zu Redshift herstellt und es auffordert, Daten mit dem Präfix s3://events-bucket/main/year=2018/month=10/day=14/10_3* herunterzuladen s3://events-bucket/main/year=2018/month=10/day=14/10_3*

Um den Status der Download-Aufgabe zu überwachen, verwenden wir Apache Airflow : Sie können den Vorgang im Fehlerfall wiederholen und haben einen klaren Ausführungsverlauf, der für eine große Anzahl solcher Aufgaben wichtig ist. Und bei Problemen können Sie den Download für einige Zeitintervalle wiederholen oder die „kalten“ Daten von S3 vor einem Jahr herunterladen.

Im gleichen Airflow funktionieren auf die gleiche Weise gemäß dem Zeitplan Skripte, die eine Verbindung zur Datenbank herstellen und regelmäßige Downloads von externen Repositorys durchführen oder Aggregationen über Ereignisse in Form von INSERT INTO ... SELECT ... erstellen.

Redshift hat schwache Verfügbarkeitsgarantien. Einmal pro Woche, bis zu einer halben Stunde (das Zeitfenster ist in den Einstellungen angegeben), kann AWS die Aktualisierung des Clusters oder andere geplante Arbeiten stoppen. Im Falle eines Fehlers auf einem Knoten ist der Cluster auch nicht verfügbar, bis der Host wiederhergestellt ist. Dies dauert normalerweise etwa 15 Minuten und geschieht etwa alle sechs Monate. Im aktuellen System ist dies kein Problem, es wurde ursprünglich so konzipiert, dass die Basis regelmäßig nicht verfügbar ist.

Unter Redshift wurden 4 ds2.8xlarge-Instanzen verwendet (36 CPU, 16 TB HDD), was insgesamt 64 TB Festplattenspeicher ergibt.

Der letzte Punkt ist die Sicherung. Der Sicherungszeitplan kann in den Clustereinstellungen angegeben werden und funktioniert einwandfrei.

ClickHouse Transition Motivation


Wenn es keine Probleme gegeben hätte, hätte natürlich niemand daran gedacht, auf ClickHouse zu migrieren. Sie waren es jedoch.

Wenn Sie sich das ClickHouse-Speicherschema mit der MergeTree- und Redshift-Engine ansehen, können Sie feststellen, dass ihre Ideologie sehr ähnlich ist. Beide Datenbanken sind spaltenweise, funktionieren gut mit einer großen Anzahl von Spalten und komprimieren Daten auf der Festplatte sehr gut (und in Redshift können Sie Komprimierungstypen für jede einzelne Spalte konfigurieren). Sogar die Daten werden auf die gleiche Weise gespeichert: Sie sind nach Primärschlüsseln sortiert, sodass Sie nur bestimmte Blöcke lesen und keine einzelnen Indizes im Speicher behalten können. Dies ist wichtig, wenn Sie mit großen Datenmengen arbeiten.

Der wesentliche Unterschied liegt wie immer im Detail.

Täglicher Tisch


Das Sortieren von Daten auf der Festplatte und das tatsächliche Löschen in Redshift erfolgt, wenn Sie Folgendes tun:
 VACUUM <tablename> 
In diesem Fall arbeitet der Vakuumprozess mit allen Daten in dieser Tabelle. Wenn Sie Daten für alle drei Monate in einer Tabelle speichern, dauert dieser Vorgang sehr lange und Sie müssen ihn mindestens täglich ausführen, da alte Daten gelöscht und neue hinzugefügt werden. Ich musste für jeden Tag separate Tabellen erstellen und diese über die Ansicht kombinieren. Dies ist nicht nur die Schwierigkeit, diese Ansicht zu drehen und zu unterstützen, sondern auch die Verlangsamung von Abfragen. Auf Anfrage wurden nach Tabellen alle Tabellen gescannt. Und obwohl das Scannen einer Tabelle weniger als eine Sekunde dauert, stellt sich bei einer Menge von 90 Teilen heraus, dass jede Abfrage mindestens eine Minute dauert. Dies ist nicht sehr praktisch.

Duplikate


Das nächste Problem sind Duplikate. Auf die eine oder andere Weise gibt es beim Übertragen von Daten über ein Netzwerk zwei Möglichkeiten: entweder Daten verlieren oder Duplikate empfangen. Wir konnten keine Nachrichten verlieren, deshalb haben wir uns einfach damit abgefunden, dass ein kleiner Prozentsatz der Ereignisse dupliziert würde. Sie können Duplikate pro Tag löschen, indem Sie eine neue Tabelle erstellen und Daten aus der alten Tabelle einfügen. Dabei werden mithilfe der Fensterfunktion Zeilen mit doppelter ID gelöscht, die alte Tabelle gelöscht und die neue umbenannt. Da über den täglichen Tabellen eine Ansicht vorhanden war, musste diese nicht vergessen und für die Zeit des Umbenennens der Tabellen gelöscht werden. In diesem Fall war es auch erforderlich, die Sperren zu überwachen. Andernfalls konnte dieser Vorgang bei einer Abfrage, die die Ansicht oder eine der Tabellen blockierte, über einen längeren Zeitraum verschoben werden.

Überwachung und Wartung


Keine einzige Anforderung in Redshift dauert weniger als ein paar Sekunden. Selbst wenn Sie nur einen Benutzer hinzufügen oder eine Liste der aktiven Anforderungen anzeigen möchten, müssen Sie einige zehn Sekunden warten. Natürlich können Sie das tolerieren, und für diese Klasse von Datenbanken ist dies akzeptabel, aber am Ende bedeutet dies eine Menge verlorener Zeit.

Kosten


Nach unseren Berechnungen ist die Bereitstellung von ClickHouse auf AWS-Instanzen mit genau denselben Ressourcen genau halb so teuer. Natürlich sollte es so sein, denn mit Redshift erhalten Sie eine vorgefertigte Datenbank, mit der Sie sofort nach dem Klicken auf einige Schaltflächen in der AWS-Konsole eine Verbindung zu jedem PostgreSQL-Client herstellen können, und AWS erledigt den Rest für Sie. Aber ist es das wert? Wir haben bereits die Infrastruktur, wir scheinen in der Lage zu sein, Backups, Überwachung und Konfiguration durchzuführen, und wir tun dies für eine Reihe interner Dienste. Warum nicht die ClickHouse-Unterstützung in Angriff nehmen?

Übergangsprozess


Zuerst haben wir eine kleine ClickHouse-Installation von einem Computer aus gestartet, wo wir regelmäßig mit den integrierten Tools Daten von S3 heruntergeladen haben. So konnten wir unsere Annahmen über die Geschwindigkeit und die Fähigkeiten von ClickHouse testen.

Nach einigen Wochen des Testens einer kleinen Kopie der Daten wurde klar, dass einige Probleme gelöst werden müssen, um Redshift durch Clickhouse zu ersetzen:

  • auf welchen Arten von Instanzen und Festplatten bereitgestellt werden soll;
  • Replikation verwenden?
  • wie man installiert, konfiguriert und ausführt;
  • wie man überwacht;
  • welche Art von Schema wird sein;
  • wie man Daten von S3 liefert;
  • Wie schreibe ich alle Abfragen von Standard-SQL auf Nicht-Standard um?

Arten von Instanzen und Datenträgern . Bei der Anzahl der Prozessoren, der Festplatte und des Speichers haben sie beschlossen, auf der aktuellen Installation von Redshift aufzubauen. Es gab verschiedene Optionen, einschließlich i3-Instanzen mit lokalen NVMe-Festplatten, aber es wurde beschlossen, bei r5.4xlarge anzuhalten und für jede Instanz in Form von 8T ST1 EBS zu speichern. Schätzungen zufolge hätte dies eine vergleichbare Leistung mit Redshift für die Hälfte der Kosten ergeben müssen. Gleichzeitig erhalten wir aufgrund der Verwendung von EBS-Festplatten einfache Sicherungen und Wiederherstellungen durch Snapshots von Festplatten, fast wie bei Redshift.

Replikation . Da wir von Redshift ausgegangen sind, haben wir uns entschieden, keine Replikation zu verwenden. Darüber hinaus zwingt uns dies nicht dazu, ZooKeeper, das sich noch nicht in der Infrastruktur befindet, sofort zu untersuchen. Es ist jedoch großartig, dass es jetzt möglich ist, Replikationen bei Bedarf durchzuführen.

Installation Dies ist der einfachste Teil. Eine ausreichend kleine Rolle für Ansible, die vorgefertigte RPM-Pakete installiert und auf jedem Host dieselbe Konfiguration vornimmt.

Überwachung Um alle Dienste zu überwachen, wird Prometheus zusammen mit Telegraf und Grafana verwendet. Daher setzen sie Telegraf-Agenten einfach mit ClickHouse auf Hosts. In Grafana wurde ein Dashboard erstellt, in dem die aktuelle Serverlast nach Prozessor, Speicher und Festplatten angezeigt wird. Über das Plugin für Grafana haben wir die aktuell aktiven Anforderungen für den Cluster, den Status der Importe aus S3 und andere nützliche Dinge in dieses Dashboard gebracht. Es stellte sich als noch besser und informativer (und deutlich schneller) heraus als das Dashboard, mit dem die AWS-Konsole ausgestattet war.

Schema . Einer unserer Hauptfehler bei Redshift bestand darin, nur die Hauptereignisfelder in separaten Spalten auszugeben und die Felder hinzuzufügen, die selten zum Hinzufügen verwendet werden
in einer großen Spalte Eigenschaften. Dies gab uns einerseits Flexibilität bei der Änderung der Felder in der Anfangsphase, als nicht genau bekannt war, welche Ereignisse wir sammeln würden, mit welchen Eigenschaften sie sich außerdem fünfmal am Tag änderten. Andererseits dauerte die Anfrage nach einer großen Spalte von Immobilien immer länger. In ClickHouse haben wir uns entschlossen, sofort das Richtige zu tun. Deshalb haben wir alle möglichen Spalten gesammelt und den optimalen Typ für sie eingegeben. Das Ergebnis ist eine Tabelle mit ungefähr zweihundert Spalten.

Die nächste Aufgabe bestand darin, die richtige Engine für die Speicherung und Partitionierung auszuwählen.
Sie haben nicht über eine erneute Partitionierung nachgedacht, sondern das Gleiche wie in Redshift - eine Partition für jeden Tag, aber jetzt sind alle Partitionen eine Tabelle, die
beschleunigt Anfragen erheblich und vereinfacht die Wartung. Die Speicher-Engine wurde von ReplacingMergeTree übernommen, da Sie damit Duplikate von einer bestimmten Partition entfernen können, indem Sie einfach OPTIMIZE ... FINAL ausführen . Darüber hinaus ermöglicht das tägliche Partitionierungsschema bei Fehlern oder Unfällen, nur mit Daten für einen Tag und nicht für einen Monat zu arbeiten, was viel schneller ist.

Lieferung von Daten von s3 an ClickHouse . Dies war einer der längsten Prozesse. Das Laden mit den integrierten ClickHouse-Tools hat einfach nicht funktioniert, da sich die Daten in S3 in JSON befinden, jedes Feld wie in Redshift in einem eigenen JSON-Pfad extrahiert werden muss und manchmal auch eine Transformation verwendet werden muss: Zum Beispiel die UUID einer Nachricht aus einem Standarddatensatz in der Form DD96C92F-3F4D-44C6-BCD3-E25EB26389E9 in Bytes konvertieren und in den Typ FixedString (16) eingeben.

Ich wollte einen speziellen Service haben, der dem ähnelt, den wir in Redshift als COPY-Befehl hatten . Sie fanden nichts fertig, also musste ich es tun. Sie können einen separaten Artikel über die Funktionsweise schreiben. Kurz gesagt, dies ist ein HTTP-Dienst, der auf jedem Host mit ClickHouse bereitgestellt wird. Sie können sich auf jeden von ihnen beziehen. Die Anforderungsparameter geben das S3-Präfix an, aus dem die Dateien entnommen werden, die jsonpath-Liste für die Konvertierung von JSON in eine Reihe von Spalten sowie eine Reihe von Konvertierungen für jede Spalte. Der Server, an den die Anforderung gesendet wurde, beginnt mit dem Scannen von Dateien in S3 und dem Verteilen der Parsing-Arbeit an andere Hosts. Gleichzeitig ist es für uns wichtig, dass die Zeilen, die nicht importiert werden konnten, zusammen mit dem Fehler einer separaten ClickHouse-Tabelle hinzugefügt werden. Dies hilft sehr bei der Untersuchung von Problemen und Fehlern im Ereignisempfangsdienst und den Clients, die diese Ereignisse generieren. Mit der Platzierung des Importers direkt auf den Datenbankhosts haben wir die Ressourcen verwendet, die in der Regel inaktiv sind, da komplexe Anforderungen nicht rund um die Uhr gestellt werden. Wenn mehr Anfragen vorliegen, können Sie den Service des Importeurs natürlich jederzeit auf separate Hosts übertragen.

Es gab keine großen Probleme beim Importieren von Daten aus externen Quellen. In diesen Skripten wurde lediglich das Ziel von Redshift in ClickHouse geändert.

Es gab die Möglichkeit, MongoDB in Form eines Wörterbuchs zu verbinden und keine täglichen Kopien zu erstellen. Leider passte es nicht, da das Wörterbuch im Speicher abgelegt werden muss und die Größe der meisten Sammlungen in MongoDB dies nicht zulässt. Aber auch Wörterbücher waren für uns nützlich: Ihre Verwendung ist sehr praktisch, um GeoIP-Datenbanken von MaxMind aus zu verbinden und in Abfragen zu verwenden. Hierzu verwenden wir Layout-ip_trie- und CSV-Dateien, die vom Service bereitgestellt werden. Die Konfiguration des Wörterbuchs geoip_asn_blocks_ipv4 sieht beispielsweise folgendermaßen aus:

 <dictionaries> <dictionary> <name>geoip_asn_blocks_ipv4</name> <source> <file> <path>GeoLite2-ASN-Blocks-IPv4.csv</path> <format>CSVWithNames</format> </file> <\/source> <lifetime>300</lifetime> <layout> <ip_trie /> </layout> <structure> <key> <attribute> <name>prefix</name> <type>String</type> </attribute> </key> <attribute> <name>autonomous_system_number</name> <type>UInt32</type> <null_value>0</null_value> </attribute> <attribute> <name>autonomous_system_organization</name> <type>String</type> <null_value>?</null_value> </attribute> </structure> </dictionary> </dictionaries> 

Es reicht aus, diese Konfiguration in /etc/clickhouse-server/geoip_asn_blocks_ipv4_dictionary.xml können Sie das Wörterbuch /etc/clickhouse-server/geoip_asn_blocks_ipv4_dictionary.xml , um den Namen des Anbieters anhand der IP-Adresse /etc/clickhouse-server/geoip_asn_blocks_ipv4_dictionary.xml :

 SELECT dictGetString('geoip_asn_blocks_ipv4', 'autonomous_system_organization', tuple(IPv4StringToNum('192.168.1.1'))); 

Datenschema ändern . Wie oben erwähnt, haben wir uns entschieden, die Replikation noch nicht zu verwenden, da wir es uns jetzt leisten können, bei Unfällen oder geplanten Arbeiten unzugänglich zu werden. Eine Kopie der Daten befindet sich bereits auf s3 und wir können sie in angemessener Zeit an ClickHouse übertragen. Wenn keine Replikation vorhanden ist, wurde ZooKeeper nicht erweitert, und das Fehlen von ZooKeeper führt auch dazu, dass der Ausdruck ON CLUSTER in DDL-Abfragen nicht verwendet werden kann. Dieses Problem wurde durch ein kleines Python-Skript gelöst, das eine Verbindung zu jedem ClickHouse-Host herstellt (es gibt bisher nur acht) und die angegebene SQL-Abfrage ausführt.

Unvollständige SQL-Unterstützung in ClickHouse . Der Prozess der Übertragung von Anforderungen von der Redshift-Syntax zur ClickHouse-Syntax verlief parallel zur Entwicklung des Importers und wurde hauptsächlich von einem Analystenteam bearbeitet. Seltsamerweise war die Sache aber nicht einmal in der JOIN, sondern in den Fensterfunktionen. Es dauerte mehrere Tage, um zu verstehen, wie sie über Arrays und Lambda-Funktionen ausgeführt werden können. Es ist gut, dass dieses Problem häufig in Berichten über ClickHouse behandelt wird, von denen es eine große Anzahl gibt, z. B. events.yandex.ru/lib/talks/5420 . Zu diesem Zeitpunkt wurden die Daten bereits an zwei Stellen gleichzeitig geschrieben: sowohl in Redshift als auch im neuen ClickHouse. Bei der Übertragung der Anforderungen haben wir die Ergebnisse verglichen. Es war problematisch, die Geschwindigkeit zu vergleichen, da wir eine große Spalte mit Eigenschaften entfernt haben und die meisten Abfragen nur mit den erforderlichen Spalten zu arbeiten begannen, was natürlich zu einem signifikanten Anstieg führte. Die Abfragen, an denen die Eigenschaftsspalte nicht teilnahm, funktionierten jedoch auf die gleiche Weise oder etwas schneller.

Als Ergebnis haben wir das folgende Schema erhalten:



Ergebnisse


Unter dem Strich haben wir folgende Vorteile:

  • Ein Tisch statt 90
  • Serviceanfragen werden in Millisekunden ausgeführt
  • Die Kosten haben sich halbiert
  • Einfaches Entfernen doppelter Ereignisse

Es gibt auch Nachteile, für die wir bereit sind:

  • Im Falle eines Unfalls müssen Sie den Cluster selbst reparieren
  • Schemaänderungen müssen jetzt auf jedem Host separat vorgenommen werden
  • Das Aktualisieren auf neue Versionen muss selbst durchgeführt werden

Wir können die Geschwindigkeit von Anfragen nicht direkt vergleichen, da sich das Datenschema erheblich geändert hat. Viele Abfragen sind schneller geworden, einfach weil sie weniger Daten von der Festplatte lesen. In guter Weise musste eine solche Änderung in Redshift vorgenommen werden, aber es wurde beschlossen, sie mit der Migration zu ClickHouse zu kombinieren.

Die gesamte Migration und Vorbereitung dauerte etwa drei Monate. Sie ging von Anfang Juli bis Ende September und forderte die Teilnahme von zwei Personen. Am 27. September haben wir Redshift ausgeschaltet und arbeiten seitdem nur noch an ClickHouse. Es stellt sich heraus, bereits etwas mehr als zwei Monate. Der Begriff ist kurz, aber bisher ist noch nie ein Datenverlust oder ein kritischer Fehler aufgetreten, aufgrund dessen der gesamte Cluster aufstehen würde. Vor uns warten Updates auf neue Versionen!

Source: https://habr.com/ru/post/de433346/


All Articles