ClickHouse für fortgeschrittene Benutzer in Fragen und Antworten

Im April trafen sich Avito-Ingenieure zu Online-Treffen mit Alexey Milovidov, dem Hauptentwickler von ClickHouse, und Kirill Shvakov, einem Golang-Entwickler von Integros. Wir haben besprochen, wie wir das Datenbankverwaltungssystem nutzen und mit welchen Schwierigkeiten wir konfrontiert sind.

Basierend auf dem Treffen haben wir einen Artikel mit Expertenantworten auf unsere und Publikumsfragen zu Backups, Daten-Resharding, externen Wörterbüchern, dem Golang-Treiber und ClickHouse-Versionsaktualisierungen zusammengestellt. Es kann für Entwickler nützlich sein, die bereits aktiv mit dem Yandex-DBMS arbeiten und sich für dessen Gegenwart und Zukunft interessieren. Standardmäßig die Antworten von Aleksey Milovidov, sofern nicht anders angegeben.

Achtung, unter dem Schnitt befindet sich viel Text. Wir hoffen, dass der Inhalt mit Fragen Ihnen bei der Navigation hilft.

ClickHouse für fortgeschrittene Benutzer in Fragen und Antworten

Inhalt

Wer den Text nicht lesen möchte, kann sich die Aufzeichnung der Versammlungen ansehen auf unserem Youtube-Kanal. Zeitstempel finden Sie im ersten Kommentar unter dem Video.

ClickHouse wird ständig aktualisiert, unsere Daten jedoch nicht. Was tun damit?

ClickHouse wird ständig aktualisiert und unsere von Optimize Final verarbeiteten Daten werden nicht aktualisiert und befinden sich in einem Backup.

Angenommen, wir hätten ein Problem und die Daten wären verloren gegangen. Wir haben uns für eine Wiederherstellung entschieden und es stellte sich heraus, dass die alten Partitionen, die auf den Backup-Servern gespeichert sind, sich stark von der aktuell verwendeten Version von ClickHouse unterscheiden. Was ist in einer solchen Situation zu tun und ist das möglich?

Die Situation, in der Sie Daten aus einem Backup im alten Format wiederhergestellt haben, sie aber mit der neuen Version nicht verbunden sind, ist ausgeschlossen. Wir stellen sicher, dass das Datenformat in ClickHouse stets abwärtskompatibel bleibt. Dies ist viel wichtiger als die Abwärtskompatibilität der Funktionalität, wenn sich das Verhalten einer selten verwendeten Funktion geändert hat. Die Daten, die auf der Festplatte gespeichert sind, sollte die neue Version von ClickHouse immer lesen können. Das ist das Gesetz.

Was sind die aktuellen Best Practices für die Datensicherung von ClickHouse?

Wie erstellt man Backups, wenn man bedenkt, dass wir über optimierte Endabläufe, eine riesige Terabyte-Datenbank und Daten verfügen, die, sagen wir, in den letzten drei Tagen aktualisiert werden und denen dann keine Prozeduren passieren?

Wir können unsere eigene Lösung zusammenstellen und auf den Kopf schreiben: Sammeln Sie diese Backups auf die und die Weise. Vielleicht brauchen Sie keine Krücke und das Fahrrad wurde schon vor langer Zeit erfunden?

Beginnen wir mit den Best Practices. Meine Kollegen raten bei Fragen zu Backups immer, sie an den Yandex.Cloud-Dienst zu erinnern, bei dem diese Aufgabe bereits gelöst wurde. Verwenden Sie es also, wenn möglich.

Für Backups gibt es keine hundertprozentig in ClickHouse integrierte Komplettlösung. Es gibt einige Leerzeichen, die Sie verwenden können. Um eine vollständige Lösung zu erhalten, müssen Sie entweder ein wenig manuell basteln oder Wrapper in Form von Skripten erstellen.

Ich beginne mit den einfachsten Lösungen und schließe mit den anspruchsvollsten ab, abhängig von der Datenmenge und der Clustergröße. Je größer der Cluster, desto schwieriger wird die Lösung.

Wenn die Datentabelle nur wenige Gigabyte belegt, kann die Sicherung wie folgt erfolgen:

  1. Speichern Sie die Definition von Tabellen, d. h. Metadaten − Tabelle erstellen anzeigen.
  2. Erstellen Sie einen Dump mit dem ClickHouse-Client − wählen * aus der Tabelle einordnen. Standardmäßig erhalten Sie eine Datei im TabSeparated-Format. Wenn Sie effizienter arbeiten möchten, können Sie das Native-Format verwenden.

Wenn die Datenmenge größer ist, nimmt die Sicherung mehr Zeit und viel Platz in Anspruch. Dies wird als logische Sicherung bezeichnet und ist nicht an das ClickHouse-Datenformat gebunden. Wenn dies der Fall ist, können Sie zur Not ein Backup erstellen und es zur Wiederherstellung auf MySQL hochladen.

Für fortgeschrittenere Fälle verfügt ClickHouse über eine integrierte Funktion zum Erstellen eines Snapshots von Partitionen im lokalen Dateisystem. Diese Funktion ist auf Anfrage verfügbar. Ändern Sie die Freeze-Partition der Tabelle. Oder einfach Ändern Sie den Tabelleneinfrieren ist eine Momentaufnahme der gesamten Tabelle.

Der Snapshot wird konsistent für eine Tabelle auf einem Shard erstellt, d. h. es ist auf diese Weise unmöglich, einen konsistenten Snapshot des gesamten Clusters zu erstellen. Für die meisten Aufgaben ist dies jedoch nicht erforderlich. Es reicht aus, auf jedem Shard eine Anfrage auszuführen und einen konsistenten Snapshot zu erhalten. Es wird in Form von Hardlinks erstellt und nimmt daher keinen zusätzlichen Platz ein. Anschließend kopieren Sie diesen Snapshot auf den Backup-Server oder auf den Speicher, den Sie für Backups verwenden.

Das Wiederherstellen eines solchen Backups ist recht einfach. Zunächst erstellen Sie Tabellen entsprechend den vorhandenen Tabellendefinitionen. Kopieren Sie als Nächstes die gespeicherten Partitions-Snapshots für diese Tabellen nach „Directory-Detached“ und führen Sie die Abfrage aus Partition anhängen. Diese Lösung eignet sich durchaus für die größten Datenmengen.

Manchmal brauchen Sie etwas noch Cooleres – in Fällen, in denen Sie Dutzende oder sogar Hunderte Terabyte auf jedem Server und Hunderten von Servern haben. Hier gibt es eine Lösung, die ich von Kollegen von Yandex.Metrica ausspioniert habe. Ich würde es nicht jedem empfehlen – lesen Sie es und entscheiden Sie selbst, ob es geeignet ist oder nicht.

Zuerst müssen Sie mehrere Server mit großen Festplatten-Shelfs erstellen. Als nächstes richten Sie mehrere ClickHouse-Server auf diesen Servern ein und konfigurieren sie so, dass sie als weitere Replikate für dieselben Shards funktionieren. Und dann verwenden Sie das Dateisystem auf diesen Servern oder ein Tool, mit dem Sie Snapshots erstellen können. Hier gibt es zwei Möglichkeiten. Die erste Option sind LVM-Snapshots, die zweite Option ist ZFS unter Linux.

Danach müssen Sie jeden Tag einen Schnappschuss erstellen, dieser wird liegen bleiben und etwas Platz beanspruchen. Wenn sich die Daten ändern, erhöht sich natürlich mit der Zeit der Speicherplatz. Sie können diesen Snapshot jederzeit abrufen und die Daten wiederherstellen, was für eine seltsame Entscheidung. Außerdem müssen Sie diese Replikate in der Konfiguration noch einschränken, damit sie nicht versuchen, die Führung zu übernehmen.

Wird es möglich sein, einen kontrollierten Nachbaustau in den Schächten zu organisieren?

Dieses Jahr planen Sie die Herstellung von Schächten im ClickHouse. Wird es möglich sein, einen kontrollierten Rückstand an Replikaten darin zu organisieren? Wir möchten es nutzen, um uns vor negativen Szenarien mit Altars und anderen Veränderungen zu schützen.

Ist es möglich, eine Art Rollback für Änderungen durchzuführen? Nehmen Sie zum Beispiel in einem vorhandenen Schacht Folgendes an und sagen Sie, dass Sie die Änderungen bis zu diesem Moment anwenden und von diesem Moment an die Änderungen nicht mehr anwenden sollen.

Wenn ein Befehl zu unserem Cluster kam und ihn kaputt machte, dann haben wir ein bedingtes Replikat mit einer Stunde Verzögerung, bei dem wir sagen können, dass wir es im Moment verwenden, aber die darin enthaltenen Änderungen in den letzten zehn Minuten nicht anwenden werden?

Zunächst zum kontrollierten Rückstand an Replikaten. Es gab eine solche Anfrage von Benutzern, und wir haben auf Github einen Issue mit der Bitte erstellt: „Wenn jemand das braucht, geben Sie ein „Gefällt mir“ und ein Herz ein.“ Niemand wettete und das Problem wurde geschlossen. Sie können diese Möglichkeit jedoch bereits nutzen, indem Sie ClickHouse einrichten. Richtig, erst ab Version 20.3.

ClickHouse führt ständig Daten im Hintergrund zusammen – Merge. Bei einer Zusammenführung werden einige Datenblöcke durch einen größeren Datenblock ersetzt. Gleichzeitig verbleiben die zuvor gespeicherten Daten noch einige Zeit auf der Festplatte.

Erstens bleiben sie so lange gespeichert, wie es ausgewählte Abfragen gibt, die sie verwenden, um einen nicht blockierenden Betrieb sicherzustellen. Ausgewählte Anfragen werden stillschweigend aus alten Blöcken gelesen.

Zweitens gibt es auch eine Zeitschwelle – alte Daten liegen acht Minuten lang auf der Festplatte. Diese acht Minuten können individuell angepasst und sogar in einen Tag umgewandelt werden. Dies kostet Speicherplatz: Abhängig vom Datenfluss wird sich herausstellen, dass sich die Daten am letzten Tag nicht nur verdoppeln, sondern sogar verfünffachen. Aber im Falle eines ernsthaften Problems können Sie den ClickHouse-Server stoppen und sich um alles kümmern.

Die Frage ist nun, wie dies vor Veränderungen schützt. Es lohnt sich, hier genauer hinzuschauen, denn in älteren Versionen von ClickHouse funktionierte der Alter so, dass er die Teile einfach direkt veränderte. Bei manchen Dateien gibt es ein Datenelement, und wir tun es zum Beispiel: Drop-Spalte ändern. Anschließend wird diese Spalte physisch aus allen Chunks entfernt.

Aber seit Version 20.3 wurde der Änderungsmechanismus komplett geändert, und Datenblöcke sind jetzt immer unveränderlich. Sie ändern sich überhaupt nicht – Änderungen funktionieren jetzt auf die gleiche Weise wie Zusammenführungen. Anstatt ein Teil an Ort und Stelle zu ändern, erstellen wir ein neues. Im neuen Block werden Dateien, die sich nicht geändert haben, zu Hardlinks, und wenn wir eine Spalte löschen, fehlt sie einfach im neuen Block. Das alte Stück wird standardmäßig nach acht Minuten gelöscht, und hier können Sie die oben genannten Einstellungen anpassen.

Das Gleiche gilt für Veränderungen wie Mutationen. Wenn Sie das tun ändern löschen oder Update ändern, es verändert das Stück nicht, sondern erstellt ein neues. Und löscht dann das alte.

Was passiert, wenn sich die Struktur der Tabelle geändert hat?

Wie kann ich ein Backup erstellen, das mit dem alten Schema erstellt wurde? Und die zweite Frage betrifft den Fall mit Snapshots und Dateisystem-Tools. Ist hier Btrfs anstelle von ZFS auf Linux LVM geeignet?

Wenn Sie tun Partition anhängen Wenn Sie Partitionen mit einer anderen Struktur erstellen, wird Ihnen ClickHouse mitteilen, dass dies nicht möglich ist. Die Lösung ist diese. Die erste besteht darin, eine temporäre Tabelle vom Typ MergeTree mit der alten Struktur zu erstellen, dort Daten mit „attach“ anzuhängen und eine Alter-Abfrage durchzuführen. Anschließend können Sie diese Daten entweder kopieren, übertragen und erneut anhängen oder die Abfrage nutzen Tabelle ändern, Partition verschieben.

Die zweite Frage ist nun, ob es möglich ist, Btrfs zu verwenden. Wenn Sie über LVM verfügen, reichen zunächst einmal LVM-Snapshots aus, und das Dateisystem kann ext4 sein, das spielt keine Rolle. Bei Btrts hängt alles von Ihrer Erfahrung damit ab. Es handelt sich hierbei um ein ausgereiftes Dateisystem, es bestehen jedoch noch einige Zweifel, wie sich alles in einem bestimmten Szenario in der Praxis auswirken wird. Ich würde die Verwendung nicht empfehlen, es sei denn, Sie haben Btrfs in der Produktion.

Was sind die aktuellen Best Practices für das Daten-Resharding?

Die Frage des Reshardings ist komplex und vielschichtig. Hier können Sie mehrere Optionen gleichzeitig beantworten. Sie können von einer Seite her hineingehen und Folgendes sagen: In ClickHouse gibt es keine integrierte Resharding-Option. Aber ich fürchte, diese Antwort wird niemandem passen. Daher können Sie von der anderen Seite ausgehen und sagen, dass ClickHouse viele Möglichkeiten zum Resharden von Daten bietet.

Wenn der Cluster nicht mehr über genügend Speicherplatz verfügt oder die Last nicht bewältigen kann, fügen Sie neue Server hinzu. Diese Server sind jedoch standardmäßig leer, es befinden sich keine Daten auf ihnen und es gibt keine Auslastung. Sie müssen die Daten verschieben, damit sie gleichmäßig über den neuen, größeren Cluster verteilt werden.

Die erste Möglichkeit hierfür besteht darin, mithilfe der Abfrage einen Teil der Partitionen auf neue Server zu kopieren Tabellenabrufpartition ändern. Sie hatten beispielsweise Partitionen nach Monaten und kopieren den ersten Monat des Jahres 2017 auf einen neuen Server und kopieren dann den dritten Monat auf einen anderen neuen Server. Und so machen Sie es, bis es mehr oder weniger gleichmäßig wird.

Die Migration kann nur für die Partitionen durchgeführt werden, die sich während der Aufzeichnung nicht ändern. Für neue Partitionen muss das Schreiben deaktiviert werden, da ihre Übertragung nicht atomar erfolgt. Andernfalls kommt es zu Duplikaten oder Lücken in den Daten. Diese Methode ist jedoch praktisch und funktioniert recht effektiv. Über das Netzwerk werden vorgefertigte komprimierte Partitionen übertragen, d. h. die Daten werden nicht komprimiert oder neu kodiert.

Diese Methode hat einen Nachteil und es hängt vom Sharding-Schema ab, ob Sie sich diesem Sharding-Schema angeschlossen haben und welchen Sharding-Schlüssel Sie hatten. In Ihrem Beispiel für den Fall mit Metriken ist der Sharding-Schlüssel ein Hash des Pfads. Wenn Sie eine verteilte Tabelle auswählen, geht diese gleichzeitig zu allen Shards des Clusters und holt sich von dort Daten.

Das bedeutet, dass es für Sie eigentlich egal ist, welche Daten auf welchem ​​Shard landen. Die Hauptsache ist, dass Daten entlang eines Pfads auf einem Shard landen, aber auf welchem ​​Shard ist es nicht wichtig. In diesem Fall ist die Übertragung vorgefertigter Partitionen perfekt, da Sie bei ausgewählten Abfragen auch vollständige Daten erhalten – sowohl vor als auch nach dem Resharding spielt das Schema keine Rolle.

Aber es gibt Fälle, die komplizierter sind. Wenn Sie sich auf der Ebene der Anwendungslogik auf ein spezielles Sharding-Schema verlassen, bedeutet dies, dass sich dieser Client auf diesem oder jenem Shard befindet und die Anfrage sofort dorthin und nicht an die verteilte Tabelle gesendet werden kann. Oder verwenden Sie eine relativ aktuelle Version von ClickHouse und haben die Einstellung aktiviert optimieren, ungenutzte Shards überspringen. In diesem Fall wird während der Auswahlabfrage der Ausdruck im Abschnitt „Where“ analysiert und berechnet, zu welchen Shards gemäß dem Sharding-Schema gewechselt werden soll. Dies funktioniert unter der Voraussetzung, dass die Daten genau nach diesem Sharding-Schema zerlegt werden. Wenn Sie sie manuell verschoben haben, kann sich die Korrespondenz ändern.

Das ist also der beste Weg. Und ich warte auf Ihre Antwort, ist die Methode geeignet, oder machen Sie weiter.

Vladimir Kolobaev, leitender Systemadministrator bei Avito: Alexey, die von Ihnen erwähnte Methode eignet sich nicht sehr gut, wenn Sie die Last, einschließlich des Lesens, verteilen müssen. Wir können eine monatliche Partition verwenden und den vorherigen Monat auf einen anderen Knoten übertragen, aber wenn eine Anfrage für diese Daten eingeht, werden wir sie nur laden. Ich möchte jedoch den gesamten Cluster laden, da sonst für einige Zeit die gesamte Leselast von zwei Shards verarbeitet wird.

Alexey Milovidov: Die Antwort hier ist seltsam – ja, es ist schlecht, aber es kann funktionieren. Ich erkläre dir genau wie. Es lohnt sich, einen Blick auf das Belastungsszenario Ihrer Daten zu werfen. Wenn es sich um Überwachungsdaten handelt, ist es fast sicher, dass die überwiegende Mehrheit der Anfragen neue Daten betrifft.

Sie haben neue Server installiert, alte Partitionen migriert, aber auch die Art und Weise geändert, wie neue Daten geschrieben werden. Und neue Daten werden im gesamten Cluster verteilt. Somit wird der Cluster nach fünf Minuten gleichmäßig durch Anfragen für die letzten fünf Minuten belastet, nach einem Tag wird der Cluster durch Anfragen für einen Tag gleichmäßig belastet. Und Anfragen für den Vormonat gehen leider nur an einen Teil der Clusterserver.

Aber oft werden Sie für Februar 2019 keine Anfragen haben. Wenn die Anfragen bis 2019 gehen, dann höchstwahrscheinlich für das gesamte Jahr 2019 – für einen großen Zeitraum und nicht für einen kleinen Zeitraum. Und solche Anfragen können den Cluster auch gleichmäßig belasten. Aber im Großen und Ganzen ist Ihre Bemerkung völlig richtig, dass es sich um eine Ad-hoc-Lösung handelt, die die Daten nicht völlig gleichmäßig verteilt.

Ich habe noch ein paar Punkte, um die Frage zu beantworten. Bei einer davon geht es darum, wie man das Sharding-Schema zunächst so gestalten kann, dass das erneute Sharding weniger Schmerzen verursacht. Dies ist nicht immer möglich.

Beispielsweise verfügen Sie über Überwachungsdaten. Die Überwachungsdaten nehmen aus drei Gründen zu. Die erste ist die Ansammlung historischer Daten. Der zweite Faktor ist das Verkehrswachstum. Und drittens steigt die Zahl der überwachungspflichtigen Dinge. Es gibt neue Microservices und Metriken, die gespeichert werden müssen.

Es ist möglich, dass der größte Anstieg hiervon auf den dritten Grund zurückzuführen ist – nämlich einen zunehmenden Einsatz von Überwachungsmaßnahmen. Und in diesem Fall lohnt es sich, einen Blick auf die Art der Last zu werfen und herauszufinden, welche Hauptanforderungen an die Auswahl gestellt werden. Die Hauptauswahlabfragen folgen wahrscheinlich einer Teilmenge der Metriken.

Beispielsweise die CPU-Auslastung einiger Server durch einen Dienst. Es stellt sich heraus, dass es eine Teilmenge von Schlüsseln gibt, mit denen Sie diese Daten erhalten. Und die Anfrage selbst nach diesen Daten ist höchstwahrscheinlich recht einfach und dauert mehrere zehn Millisekunden. Wird für Überwachungsdienste und Dashboards verwendet. Ich hoffe, ich verstehe das richtig.

Wladimir Kolobajew: Tatsache ist, dass wir sehr oft auf historische Daten zurückgreifen, da wir die aktuelle Position in Echtzeit mit der historischen vergleichen. Und für uns ist es wichtig, schnell auf große Datenmengen zugreifen zu können, und ClickHouse leistet hier hervorragende Arbeit.

Sie haben völlig Recht, die meisten Leseanfragen erleben wir am letzten Tag, wie bei jedem Überwachungssystem. Gleichzeitig ist aber auch die Belastung historischer Daten recht groß. Es kommt größtenteils von einem Warnsystem, das alle dreißig Sekunden aktiviert wird und ClickHouse mitteilt: „Geben Sie mir die Daten der letzten sechs Wochen.“ Und jetzt erstelle ich daraus einen gleitenden Durchschnitt und vergleiche den aktuellen Wert mit dem historischen Wert.

Ich möchte sagen, dass wir für solche ganz neuen Anfragen eine weitere kleine Tabelle haben, in der wir nur Daten von zwei Tagen speichern und in die die Hauptanfragen einfliegen. Wir senden nur große historische Abfragen an eine große Shard-Tabelle.

Alexey Milovidov: Leider stellt sich heraus, dass es für Ihr Szenario schlecht anwendbar ist, aber ich werde zwei schlechte und komplexe Sharding-Schemata beschreiben, die nicht verwendet werden müssen, aber im Dienst „Meine Freunde“ verwendet werden.

Es gibt einen Hauptcluster mit Yandex.Metrica-Ereignissen. Ereignisse sind Seitenaufrufe, Klicks und Übergänge. Die meisten Anfragen gehen an eine bestimmte Website. Sie öffnen den Yandex.Metrica-Dienst, Sie haben eine Website – avito.ru, gehen zum Bericht und es wird eine Anfrage für Ihre Website gestellt.

Es gibt aber auch andere Anfragen – analytische und globale –, die von internen Analysten gestellt werden. Für alle Fälle stelle ich fest, dass interne Analysten nur Anfragen für Yandex-Dienste stellen. Dennoch nehmen auch Yandex-Dienste einen erheblichen Anteil aller Daten ein. Dabei handelt es sich nicht um Anfragen für bestimmte Zähler, sondern um eine umfassendere Filterung.

Wie organisiert man Daten so, dass für einen Zähler alles effizient funktioniert und auch globale Abfragen? Eine weitere Schwierigkeit liegt darin, dass die Anzahl der Anfragen in ClickHouse für den Metrics-Cluster mehrere Tausend pro Sekunde beträgt. Gleichzeitig verarbeitet ein ClickHouse-Server keine nicht trivialen Anfragen, beispielsweise mehrere Tausend pro Sekunde.

Die Clustergröße beträgt sechshundert und etwas Server. Wenn Sie einfach eine verteilte Tabelle über diesen Cluster ausdehnen und mehrere tausend Anfragen dorthin senden, wird es noch schlimmer, als sie an einen Server zu senden. Andererseits wird die Option, dass die Daten gleichmäßig verteilt werden und wir von allen Servern abfragen, sofort verworfen.

Es gibt eine diametral entgegengesetzte Option. Stellen Sie sich vor, wir teilen Daten nach Site auf und eine Anfrage für eine Site geht an einen Shard. Jetzt kann der Cluster zehntausend Anfragen pro Sekunde abrufen, aber auf einem Shard wird eine Anfrage zu langsam arbeiten. Die Bandbreite wird nicht mehr skaliert. Vor allem, wenn es sich um die Website avito.ru handelt. Ich werde kein Geheimnis preisgeben, wenn ich sage, dass Avito eine der meistbesuchten Seiten in Runet ist. Und es auf einem Shard zu verarbeiten wäre verrückt.

Daher ist das Sharding-Schema komplizierter gestaltet. Der gesamte Cluster ist in mehrere Cluster unterteilt, die wir Schichten nennen. In jedem Cluster befinden sich zehn bis mehrere Dutzend Scherben. Insgesamt gibt es neununddreißig solcher Cluster.

Wie lässt sich das Ganze skalieren? Die Anzahl der Cluster ändert sich nicht – sie bleibt wie vor XNUMX Jahren gleich. Aber innerhalb jedes einzelnen von ihnen erhöhen wir schrittweise die Anzahl der Shards, während sich die Daten ansammeln. Und das Sharding-Schema als Ganzes ist folgendes: Die Aufteilung in diese Cluster erfolgt nach Websites, und um zu verstehen, welche Site sich in welchem ​​Cluster befindet, wird im Allgemeinen eine separate Metabasis in MySQL verwendet. Eine Site – auf einem Cluster. Und darin findet das Sharding entsprechend den Identifikatoren der Besucher statt.

Bei der Erfassung teilen wir sie durch den Rest der Besucher-ID auf. Wenn jedoch ein neuer Shard hinzugefügt wird, ändert sich das Sharding-Schema. Wir teilen weiter, teilen den Rest jedoch durch eine andere Zahl. Dies bedeutet, dass sich ein Besucher bereits auf mehreren Servern befindet und darauf nicht gewettet werden kann. Dies geschieht ausschließlich, um eine bessere Komprimierung der Daten zu gewährleisten. Und bei der Abfrage gehen wir zur Distributed-Tabelle, die sich den Cluster ansieht und auf Dutzende Server zugreift. Das ist so ein dummer Plan.

Aber meine Geschichte wäre unvollständig, wenn ich nicht sagen würde, dass wir diesen Plan aufgegeben haben. Im neuen Schema haben wir alles geändert und alle Daten mit Clickhouse-Kopierer kopiert.

Im neuen Schema sind alle Websites in zwei Kategorien unterteilt – groß und klein. Ich weiß nicht, wie dort der Schwellenwert gewählt wurde, aber als Ergebnis stellte sich heraus, dass große Sites in einem Cluster aufgezeichnet werden, wo es 120 Shards mit jeweils drei Replikaten gibt – also 360 Server. Und das Sharding-Schema ist so, dass jede Anfrage gleichzeitig an alle Shards geht. Wenn Sie jetzt eine Berichtsseite für avito.ru in Yandex.Metrica öffnen, wird die Anfrage an 120 Server weitergeleitet. Es gibt nur wenige große Websites in Runet. Und die Anfragen betragen nicht tausend pro Sekunde, sondern sogar weniger als hundert. All dies wird leise von der verteilten Tabelle gekaut, die jeweils 120 Server verarbeitet.

Und der zweite Cluster ist für kleine Websites gedacht. Hier ist ein Sharding-Schema nach Site-ID, und jede Anfrage geht an genau einen Shard.

ClickHouse verfügt über ein Clickhouse-Kopierer-Dienstprogramm. Kannst du etwas über sie erzählen?

Ich muss gleich sagen, dass diese Lösung umständlicher und etwas weniger produktiv ist. Der Vorteil besteht darin, dass die Daten vollständig gemäß dem von Ihnen angegebenen Schema verwischt werden. Der Nachteil des Dienstprogramms besteht jedoch darin, dass es überhaupt kein Reshard durchführt. Es kopiert Daten von einem Cluster-Schema in ein anderes Cluster-Schema.

Das bedeutet, dass Sie zwei Cluster benötigen, damit es funktioniert. Sie können sich auf denselben Servern befinden, die Daten werden jedoch nicht inkrementell verschoben, sondern kopiert.

Gab es zum Beispiel vier Server, sind es jetzt acht. Sie erstellen eine neue verteilte Tabelle auf allen Servern, neue lokale Tabellen und starten Clickhouse-Copier. Geben Sie darin das Arbeitsschema an, das von dort gelesen werden soll, akzeptieren Sie das neue Sharding-Schema und übertragen Sie Daten dorthin. Und Sie benötigen auf den alten Servern eineinhalb Mal mehr Speicherplatz als jetzt, da die alten Daten auf ihnen verbleiben müssen und die Hälfte der gleichen alten Daten darauf kommt. Wenn Sie im Voraus dachten, dass die Daten erneut aufgeteilt werden müssen und Platz vorhanden ist, dann ist diese Methode geeignet.

Wie funktioniert der Clickhouse-Kopierer im Inneren? Es unterteilt die gesamte Arbeit in eine Reihe von Aufgaben zur Verarbeitung einer Partition einer Tabelle auf einem Shard. Alle diese Aufgaben können parallel ausgeführt werden, und Clickhouse-Copier kann mehrere Instanzen auf verschiedenen Computern ausführen, aber was es für eine einzelne Partition tut, ist nichts anderes als eine Einfügungsauswahl. Die Daten werden gelesen, dekomprimiert, neu partitioniert, dann erneut komprimiert, irgendwohin geschrieben und neu sortiert. Dies ist eine schwierigere Entscheidung.

Sie hatten eine Pilotsache namens Resharding. Was ist mit ihr?

Im Jahr 2017 gab es ein Pilotprojekt namens Resharding. Es gibt sogar eine Option in ClickHouse. Ich verstehe, dass es nicht gestartet ist. Können Sie sagen, warum es passiert ist? Es scheint sehr relevant zu sein.

Das ganze Problem besteht darin, dass, wenn Sie Daten an Ort und Stelle neu aufteilen müssen, eine sehr komplexe Synchronisierung erforderlich ist, um dies atomar durchzuführen. Als wir uns damit beschäftigten, wie diese Synchronisation funktioniert, wurde uns klar, dass es grundsätzliche Probleme gibt. Und diese grundlegenden Probleme sind nicht nur theoretisch, sondern zeigten sich sofort in der Praxis in Form von etwas, das ganz einfach erklärt werden kann: Nichts funktioniert.

Ist es möglich, alle Datenteile zusammenzuführen, bevor sie auf langsame Festplatten verschoben werden?

Eine Frage zu TTL mit der Option „Auf langsame Festplatte verschieben“ im Zusammenhang mit Zusammenführungen. Gibt es eine andere Möglichkeit als cron, alle Teile zu einem zusammenzuführen, bevor auf langsame Festplatten verschoben wird?

Die Antwort auf die Frage, ob es möglich ist, alle Teile vor dem Übertragen irgendwie automatisch zu einem zusammenzukleben, lautet nein. Es scheint mir, dass dies nicht notwendig ist. Sie können nicht alle Teile zu einem zusammenführen, sondern sich einfach darauf verlassen, dass sie automatisch auf langsame Festplatten übertragen werden.

Wir haben zwei Kriterien für Übertragungsregeln. Das erste ist, wie es sich füllt. Wenn die aktuelle Speicherebene weniger als einen bestimmten Prozentsatz an freiem Speicherplatz aufweist, wählen wir einen Block aus und verschieben ihn auf einen langsameren Speicher. Oder besser gesagt, nicht langsamer, sondern das Folgende – wie Sie es einrichten.

Das zweite Kriterium ist die Größe. Er spricht von der Übertragung großer Teile. Sie können den Schwellenwert basierend auf dem freien Speicherplatz auf einer schnellen Festplatte anpassen und die Daten werden automatisch migriert.

Wie migriere ich auf neue Versionen von ClickHouse, wenn es keine Möglichkeit gibt, die Kompatibilität im Voraus zu überprüfen?

Dieses Thema wird regelmäßig diskutiert im Telegram-Chat ClickHouse unter Berücksichtigung verschiedener Versionen, und doch. Wie sicher ist ein Upgrade von Version 19.11 auf 19.16 und beispielsweise von 19.16 auf 20.3? Wie kann man am besten auf neue Versionen umsteigen, ohne vorher die Kompatibilität in der Sandbox prüfen zu können?

Hier gibt es ein paar goldene Regeln. Erste - Änderungsprotokoll lesen. Es ist umfangreich, aber es gibt separate Punkte zu abwärtsinkompatiblen Änderungen. Behandeln Sie diese Punkte nicht als Warnsignal. Hierbei handelt es sich in der Regel um geringfügige Inkompatibilitäten, die mit einigen Edge-Funktionen zusammenhängen, die Sie wahrscheinlich nicht nutzen.

Zweitens: Wenn es keine Möglichkeit gibt, die Kompatibilität in der Sandbox zu überprüfen, und Sie sofort in der Produktion ein Upgrade durchführen möchten, empfehlen wir Ihnen, dies nicht zu tun. Erstellen Sie zunächst eine Sandbox und testen Sie sie. Wenn keine Testumgebung vorhanden ist, haben Sie höchstwahrscheinlich kein sehr großes Unternehmen. Sie können also einen Teil der Daten auf Ihren Laptop kopieren und sicherstellen, dass darauf alles ordnungsgemäß funktioniert. Sie können sogar einige Replikate lokal auf Ihrem Computer erstellen. Oder Sie können irgendwo in der Nähe eine neue Version erstellen und dort einige Daten hochladen – also eine spontane Testumgebung erstellen.

Eine weitere Regel besteht darin, nicht innerhalb einer Woche nach der Veröffentlichung der Version zu aktualisieren, da in der Produktion Fehler auftreten und anschließend schnelle Korrekturen vorgenommen werden. Lassen Sie uns die ClickHouse-Versionsnummerierung verstehen, um nicht verwirrt zu werden.

Es gibt Version 20.3.4. Die Zahl 20 gibt das Herstellungsjahr an – 2020. Aus Sicht des Inhalts spielt dies keine Rolle, daher werden wir nicht darauf achten. Weiter - 20.3. Die zweite Zahl – in diesem Fall 3 – erhöhen wir jedes Mal, wenn wir eine Version mit neuen Funktionen veröffentlichen. Wenn wir ClickHouse eine Funktion hinzufügen möchten, müssen wir diese Zahl erhöhen. Das heißt, in Version 20.4 wird ClickHouse noch besser funktionieren. Die dritte Ziffer ist 20.3.4. Hier ist 4 die Anzahl der Patch-Releases, in denen wir keine neuen Funktionen hinzugefügt, aber einige Fehler behoben haben. Und 4 bedeutet, dass wir es viermal gemacht haben.

Denken Sie nicht, dass es etwas Schreckliches ist. Normalerweise kann der Benutzer die neueste Version installieren und es funktioniert problemlos mit der Betriebszeit pro Jahr. Aber stellen Sie sich vor, dass in einer Funktion zur Verarbeitung von Bitmaps, die von unseren chinesischen Kameraden hinzugefügt wurde, bei der Übergabe falscher Argumente der Server abstürzt. Wir müssen das beheben. Wir werden eine neue Patch-Version veröffentlichen und ClickHouse wird stabiler.

Wenn ClickHouse in der Produktion läuft und eine neue Version von ClickHouse mit zusätzlichen Funktionen veröffentlicht wird (z. B. 20.4.1 ist die allererste), beeilen Sie sich nicht, es gleich am ersten Tag in die Produktion zu bringen. Warum wird sie überhaupt gebraucht? Wenn Sie ClickHouse noch nicht verwenden, können Sie es installieren und höchstwahrscheinlich wird alles gut. Aber wenn ClickHouse bereits stabil funktioniert, dann bleiben Sie dran für Patches und Updates – welche Probleme wir beheben.

Kirill Schwakow: Ich möchte etwas über Testumgebungen hinzufügen. Jeder hat große Angst vor Testumgebungen und glaubt aus irgendeinem Grund, dass die Testumgebung nicht kleiner oder mindestens zehnmal kleiner sein sollte, wenn Sie über einen sehr großen ClickHouse-Cluster verfügen. So ist es überhaupt nicht.

Das kann ich anhand meines Beispiels erkennen. Ich habe ein Projekt und da ist ClickHouse. Unsere Testumgebung für ihn ist eine kleine virtuelle Maschine bei Hetzner für zwanzig Euro, in der wirklich alles zum Einsatz kommt. Dafür verfügen wir über eine vollständige Automatisierung in Ansible, und daher gibt es im Prinzip keinen Unterschied, wo wir rollen – auf Iron-Servern oder einfach in virtuellen Maschinen bereitstellen.

Was kann getan werden? Es wäre schön, in der ClickHouse-Dokumentation ein Beispiel dafür zu machen, wie man einen kleinen Cluster selbst bereitstellt – in Docker, in LXC, vielleicht ein Ansible-Playbook erstellen, weil verschiedene Leute unterschiedliche Bereitstellungen haben. Dadurch wird vieles einfacher. Wenn Sie einen Cluster in fünf Minuten erstellen und bereitstellen, ist es viel einfacher, etwas herauszufinden. Auf diese Weise ist es viel bequemer, denn eine Version, die Sie noch nicht getestet haben, in die Produktion zu bringen, ist ein Weg ins Nichts. Manchmal funktioniert es und manchmal nicht. Und so ist es schlecht, auf Erfolg zu hoffen.

Maxim Kotyakov, leitender Backend-Ingenieur Avito: Ich werde ein wenig über Testumgebungen aus einer Reihe von Problemen für große Unternehmen hinzufügen. Wir verfügen über einen vollwertigen ClickHouse-Akzeptanzcluster, je nach Datenschemata und Einstellungen, eine exakte Kopie dessen, was in Produktion ist. Dieser Cluster wird in ziemlich heruntergekommenen Containern mit einem Minimum an Ressourcen bereitgestellt. Wir schreiben dort einen bestimmten Prozentsatz der Produktionsdaten, da die Möglichkeit besteht, den Stream in Kafka zu replizieren. Dort ist alles synchronisiert und skaliert – sowohl hinsichtlich der Kapazität als auch des Flusses, und theoretisch sollte es sich bei sonst gleichen Bedingungen in Bezug auf die Metriken wie eine Produktion verhalten. Alles, was explosionsgefährlich ist, wird zunächst auf diesen Ständer gerollt und dort mehrere Tage lang infundiert, bis es fertig ist. Aber natürlich ist diese Lösung teuer, schwer und mit Supportkosten ungleich Null verbunden.

Alexey Milovidov: Ich erzähle Ihnen, wie die Testumgebung unserer Freunde von Yandex.Metrica aussieht. Ein Cluster war für etwa 600 Server vorgesehen, der andere für 360, und es gibt einen dritten und mehrere Cluster. Die Testumgebung für einen von ihnen besteht lediglich aus zwei Shards mit jeweils zwei Replikaten. Warum zwei Scherben? Nicht allein sein. Und auch Nachbildungen. Nur ein Mindestbetrag, den Sie sich leisten können.

Mit dieser Testumgebung können Sie den Zustand von Anfragen überprüfen und feststellen, ob ein schwerwiegender Fehler vorliegt. Aber oft treten Probleme ganz anderer Art auf, wenn alles funktioniert, es aber kleine Änderungen bei der Last gibt.

Ich gebe Ihnen ein Beispiel. Wir haben uns entschieden, eine neue Version von ClickHouse zu installieren. Es ist in einer Testumgebung angelegt, in Yandex.Metrica selbst werden automatisierte Tests durchgeführt, die Daten der alten und der neuen Version vergleichen und dabei die gesamte Pipeline ausführen. Und natürlich grüne Tests unserer CI. Sonst hätten wir diese Version gar nicht erst vorgeschlagen.

Alles ist gut. Wir beginnen mit der Produktion. Ich erhalte die Meldung, dass die Belastung der Diagramme um ein Vielfaches gestiegen ist. Wir führen ein Rollback der Version durch. Ich schaue mir die Grafik an und sehe: Die Last ist während des Rollouts tatsächlich um ein Vielfaches gestiegen und beim Rollout wieder zurückgegangen. Dann begannen wir, die Version zurückzusetzen. Und die Belastung nahm in gleicher Weise zu und fiel in gleicher Weise zurück. Die Schlussfolgerung lautet also: Die Belastung ist im Zusammenhang mit der Berechnung gestiegen, was nicht überraschend ist.

Dann war es schwierig, die Kollegen davon zu überzeugen, die neue Version doch zu installieren. Ich sage: „Schon gut, rollen Sie aus. Drückt die Daumen, alles wird klappen. Jetzt ist die Belastung der Charts gestiegen, aber alles ist in Ordnung. Festhalten." Im Allgemeinen haben wir dies getan, und das war’s – die Version wird auf der Produktionsseite veröffentlicht. Doch fast bei jeder Berechnung treten ähnliche Probleme auf.

Kill query soll Abfragen beenden, tut es aber nicht. Warum?

Ein Benutzer, eine Art Analyst, kam zu mir und erstellte eine bestimmte Anfrage, die meinen ClickHouse-Cluster platzierte. Ein Knoten oder ein ganzer Cluster, je nachdem, in welches Replikat oder Shard die Anfrage gelangt ist. Ich sehe, dass alle CPU-Ressourcen auf diesem Server im Regal sind, alles ist rot. Gleichzeitig reagiert ClickHouse selbst auf Anfragen. Und ich schreibe: „Zeigen Sie mir bitte die Prozessliste, welche Anfrage diesen Wahnsinn erzeugt hat.“

Ich finde diese Anfrage und schreibe kill dazu. Und ich sehe, dass nichts passiert. Mein Server steht im Regal, ClickHouse gibt mir dann einige Befehle, zeigt an, dass der Server aktiv ist, und alles ist in Ordnung. Aber ich habe eine Verschlechterung bei allen Benutzeranfragen, eine Verschlechterung durch den Eintrag in ClickHouse beginnt und meine Kill-Abfrage funktioniert nicht. Warum? Ich dachte, Kill Query sollte Abfragen beenden, aber das ist nicht der Fall.

Jetzt wird es eine ziemlich seltsame Antwort geben. Der Punkt ist, dass die Kill-Abfrage keine Anfragen tötet.

„Abfrage beenden“ fügt ein kleines Kontrollkästchen mit dem Namen „Ich möchte, dass diese Abfrage beendet wird“ ein. Und die Anfrage selbst prüft bei der Verarbeitung jedes Blocks dieses Flag. Wenn es gesetzt ist, funktioniert die Anfrage nicht mehr. Es stellt sich heraus, dass niemand die Anfrage tötet, er selbst muss alles überprüfen und aufhören. Und dies sollte in allen Fällen funktionieren, in denen sich die Anfrage in einem Blockverarbeitungsstatus befindet. Es verarbeitet den nächsten Datenblock, prüft das Flag und stoppt.

Dies funktioniert nicht, wenn die Anforderung bei einem Vorgang blockiert ist. Dies ist jedoch höchstwahrscheinlich nicht der Fall, da es Ihrer Meinung nach eine Menge Serverressourcen beansprucht. Es ist möglich, dass dies bei der externen Sortierung und in einigen anderen Details nicht funktioniert. Aber im Allgemeinen sollte das nicht so sein, das ist ein Fehler. Und das Einzige, was ich raten kann, ist, ClickHouse zu aktualisieren.

Wie berechnet man die Antwortzeit unter Leselast?

Es gibt eine Tabelle, in der Artikelaggregate – verschiedene Zähler – gespeichert werden. Die Anzahl der Zeilen beträgt etwa einhundert Millionen. Kann man mit einer vorhersehbaren Reaktionszeit rechnen, wenn man 1 RPS für 1 Artikel ausgibt?

Dem Kontext nach zu urteilen, handelt es sich um eine Lesebelastung, denn beim Schreiben gibt es keine Probleme – es können mindestens tausend, mindestens hunderttausend und manchmal mehrere Millionen Zeilen eingefügt werden.

Lesewünsche sind sehr unterschiedlich. In Auswahl 1 kann ClickHouse etwa Zehntausende Anfragen pro Sekunde ausführen, sodass selbst Anfragen nach einem einzelnen Schlüssel bereits einige Ressourcen erfordern. Und solche Punktabfragen werden schwieriger sein als in einigen Schlüsselwertdatenbanken, da für jeden Lesevorgang der Datenblock nach Index gelesen werden muss. Unser Index berücksichtigt nicht jeden Datensatz, sondern jeden Bereich. Das heißt, Sie müssen den gesamten Bereich lesen – standardmäßig sind dies 8192 Zeilen. Und Sie müssen den komprimierten Datenblock von 64 KB auf 1 MB dekomprimieren. Normalerweise dauern solche Punktabfragen einige Millisekunden. Dies ist jedoch die einfachste Option.

Versuchen wir es mit einfacher Arithmetik. Wenn man ein paar Millisekunden mit tausend multipliziert, erhält man ein paar Sekunden. Als ob es unmöglich wäre, tausend Anfragen pro Sekunde zu erfüllen, ist es tatsächlich möglich, da wir über mehrere Prozessorkerne verfügen. Im Prinzip kann ClickHouse also manchmal 1000 RPS halten, allerdings bei kurzen Anfragen, nämlich Punktanfragen.

Wenn Sie den ClickHouse-Cluster um die Anzahl einfacher Anfragen skalieren müssen, empfehle ich die einfachste Lösung: Erhöhen Sie die Anzahl der Replikate und senden Sie Anfragen an eine zufällige Replik. Wenn ein Replikat fünfhundert Anfragen pro Sekunde speichert, was völlig realistisch ist, dann werden drei Replikate eineinhalbtausend Anfragen enthalten.

Manchmal können Sie ClickHouse natürlich auch für die maximale Anzahl von Punktablesungen konfigurieren. Was wird dafür benötigt? Die erste besteht darin, die Granularität des Index zu reduzieren. Gleichzeitig sollte es nicht auf einen reduziert werden, sondern auf der Grundlage, dass die Anzahl der Datensätze im Index mehrere Millionen oder mehrere zehn Millionen pro Server beträgt. Wenn die Tabelle hundert Millionen Zeilen hat, kann 64 als Granularität festgelegt werden.

Sie können die Größe des komprimierten Blocks reduzieren. Hierfür gibt es Einstellungen. Min. Größe des Komprimierungsblocks, maximale Komprimierungsblockgröße. Sie können sie reduzieren, Daten neu laden und dann werden Punktabfragen schneller. Dennoch ist ClickHouse keine Schlüsselwertdatenbank. Eine große Anzahl kleiner Anfragen ist ein Last-Anti-Pattern.

Kirill Schwakow: Ich werde Ratschläge geben, falls es normale Buchhalter gibt. Dies ist eine ziemlich normale Situation, wenn in ClickHouse eine Art Zähler gespeichert ist. Ich habe einen Benutzer, er kommt aus diesem und jenem Land, aus einem anderen dritten Bereich, und ich muss etwas schrittweise erhöhen. Nehmen Sie MySQL, erstellen Sie einen eindeutigen Schlüssel – in MySQL ist es ein doppelter Schlüssel und in PostgreSQL ist es ein Konflikt – und fügen Sie ein Pluszeichen hinzu. Das wird viel besser funktionieren.

Wenn Sie nur über wenige Daten verfügen, macht die Verwendung von ClickHouse wenig Sinn. Es gibt reguläre Datenbanken, und sie leisten gute Arbeit.

Was muss in ClickHouse optimiert werden, damit sich mehr Daten im Cache befinden?

Stellen wir uns die Situation vor – die Server verfügen über 256 GB RAM, im Alltag benötigt ClickHouse etwa 60-80 GB, in der Spitze – bis zu 130. Was kann aktiviert und optimiert werden, damit sich mehr Daten im Cache befinden und dementsprechend , gibt es weniger Fahrten zur Festplatte?

In der Regel erledigt der Seitencache des Betriebssystems diese Aufgabe gut. Wenn Sie einfach die Oberseite öffnen, dort zwischengespeichert oder frei schauen – dort steht auch, wie viel zwischengespeichert ist – dann können Sie sehen, dass der gesamte freie Speicher für den Cache verwendet wird. Und wenn diese Daten gelesen werden, werden sie nicht von der Festplatte, sondern vom RAM gelesen. Gleichzeitig kann ich sagen, dass der Cache effektiv genutzt wird, da die komprimierten Daten zwischengespeichert werden.

Wenn Sie jedoch einige einfache Abfragen noch schneller durchführen möchten, können Sie in ClickHouse einen Cache für die dekomprimierten Daten aktivieren. Das heißt unkomprimierter Cache. Stellen Sie in der Konfigurationsdatei config.xml die Größe des unkomprimierten Caches auf den von Ihnen benötigten Wert ein – ich empfehle nicht mehr als die Hälfte des freien RAM, da der Rest im Seitencache landet.

Darüber hinaus gibt es zwei Einstellungen für die Anforderungsebene. Erste Einstellung - Verwenden Sie unkomprimierten Cache - schließt seine Verwendung ein. Es wird empfohlen, es für alle Anfragen zu aktivieren, mit Ausnahme schwerer Anfragen, die alle Daten lesen und diesen Cache leeren können. Und die zweite Einstellung ist so etwas wie die maximale Anzahl von Zeilen, die den Cache verwenden sollen. Es schränkt große Anfragen automatisch ein, sodass sie außerhalb des Caches liegen.

Wie kann ich storage_configuration für die Speicherung im RAM konfigurieren?

In der neuen ClickHouse-Dokumentation habe ich den entsprechenden Abschnitt gelesen mit Datenspeicherung. In der Beschreibung gibt es ein Beispiel mit einer schnellen SSD.

Ich frage mich, wie Sie dasselbe mit Volume-Hot-Memory konfigurieren können. Und noch eine Frage. Wie funktioniert „select“ mit dieser Datenorganisation? Wird der gesamte Satz oder nur der auf der Festplatte gelesen und werden diese Daten im Speicher komprimiert? Und wie funktioniert der Prewhere-Abschnitt bei einer solchen Datenorganisation?

Diese Einstellung wirkt sich auf die Speicherung von Daten aus und ihr Format ändert sich in keiner Weise.
Lass uns genauer hinschauen.

Sie können die Speicherung von Daten im RAM einrichten. Alles, was für eine Festplatte konfiguriert ist, ist ihr Pfad. Sie erstellen eine tmpfs-Partition, die in einem Pfad im Dateisystem bereitgestellt wird. Geben Sie diesen Pfad als Datenspeicherpfad für die heißeste Partition an. Die Daten beginnen dort anzukommen und geschrieben zu werden, alles ist in Ordnung.

Aufgrund der geringen Zuverlässigkeit empfehle ich dies jedoch nicht. Wenn Sie jedoch mindestens drei Replikate in verschiedenen Rechenzentren haben, ist dies möglich. Wenn ja, werden die Daten wiederhergestellt. Stellen Sie sich vor, der Server würde plötzlich ausgeschaltet und wieder eingeschaltet. Der Abschnitt wurde erneut montiert, es gibt jedoch eine Lücke. Beim Start stellt der ClickHouse-Server fest, dass diese Teile fehlen, obwohl dies laut ZooKeeper-Metadaten der Fall sein sollte. Er schaut, auf welchen Replikaten sie sich befinden, fordert sie an und lädt sie herunter. Somit werden die Daten wiederhergestellt.

In diesem Sinne unterscheidet sich das Speichern von Daten im RAM nicht grundsätzlich vom Speichern auf der Festplatte, denn wenn Daten auf die Festplatte geschrieben werden, fallen sie auch zuerst in den Seitencache und werden später physisch geschrieben. Es hängt davon ab, wie das Dateisystem gemountet ist. Aber nur für den Fall, ich möchte sagen, dass ClickHouse beim Einfügen keine Fsync-Funktion ausführt.

In diesem Fall werden die Daten im RAM im exakt gleichen Format wie auf der Festplatte gespeichert. Die Select-Abfrage wählt auf die gleiche Weise die zu lesenden Chunks aus, wählt die erforderlichen Datenbereiche in den Chunks aus und liest sie. Und prewhere funktioniert genauso, unabhängig davon, ob sich die Daten im RAM oder auf der Festplatte befanden.

Bis zu welcher Anzahl eindeutiger Werte ist die niedrige Kardinalität wirksam?

Eine niedrige Kardinalität ist schwierig. Es stellt Datenwörterbücher zusammen, diese sind jedoch lokal. Erstens sind die Wörterbücher für jedes Stück unterschiedlich, und zweitens können sie sogar innerhalb eines Stücks für jeden Bereich unterschiedlich sein. Wenn die Anzahl der eindeutigen Werte einen Schwellenwert erreicht – eine Million, glaube ich – wird das Wörterbuch einfach beiseite gelegt und ein neues erstellt.

Die Antwort lautet im Allgemeinen: Für jeden lokalen Bereich – beispielsweise für jeden Tag – bis zu einer Million eindeutiger Werte ist eine niedrige Kardinalität wirksam. Danach gibt es nur noch einen Fallback, bei dem viele verschiedene Wörterbücher verwendet werden und nicht nur eines. Es funktioniert ähnlich wie eine normale Spalte vom Typ String, vielleicht etwas weniger effizient, aber es wird keine ernsthafte Leistungseinbuße geben.

Was sind die Best Practices für die Volltextsuche in einer Tabelle mit fünf Milliarden Zeilen?

Es gibt unterschiedliche Antworten. Erstens ist ClickHouse keine Volltextsuchmaschine. Dafür gibt es spezielle Systeme, zum Beispiel Elasticsearch и Sphinx. Ich sehe jedoch immer mehr Leute, die sagen, dass sie von Elasticsearch zu ClickHouse wechseln.

Warum passiert das? Sie erklären dies damit, dass Elasticsearch die Belastung einiger Volumes nicht mehr bewältigen kann, beginnend mit der Erstellung von Indizes. Indizes werden zu umständlich und wenn man die Daten einfach an ClickHouse überträgt, stellt sich heraus, dass sie vom Volumen her um ein Vielfaches effizienter gespeichert werden. Gleichzeitig waren Suchanfragen oft nicht so, dass in der gesamten Datenmenge unter Berücksichtigung der Morphologie eine Phrase gefunden werden musste, sondern völlig andere. Zum Beispiel, um die letzten paar Stunden in den Protokollen für eine Teilsequenz von Bytes zu finden.

In diesem Fall erstellen Sie in ClickHouse einen Index, dessen erstes Feld das Datum mit der Uhrzeit enthält. Und der größte Datenausschnitt wird genau für den Datumsbereich gelten. Innerhalb des ausgewählten Datumsbereichs ist in der Regel bereits eine Volltextsuche auch im Brute-Force-Verfahren mit like möglich. Die Like-Anweisung in ClickHouse ist die effizienteste Like-Anweisung, die Sie finden können. Wenn Sie ein besseres finden, sagen Sie es mir.

Aber trotzdem, es handelt sich um einen vollständigen Scan. Und ein vollständiger Scan kann nicht nur auf der CPU, sondern auch auf der Festplatte langsam sein. Wenn Sie plötzlich ein Terabyte an Daten pro Tag haben und nach einem Wort pro Tag suchen, müssen Sie ein Terabyte scannen. Und es ist wahrscheinlich auf normalen Festplatten, und dadurch werden diese so geladen, dass Sie diesen Server nicht über SSH betreten.

In diesem Fall bin ich bereit, noch einen kleinen Trick anzubieten. Es gehört zur Kategorie „experimentell“ – es kann funktionieren oder auch nicht. ClickHouse verfügt über Volltextindizes in Form von Trigram-Bloom-Filtern. Unsere Kollegen bei Arenadata haben diese Indizes bereits ausprobiert und oft funktionieren sie genau wie vorgesehen.

Um sie richtig nutzen zu können, sollten Sie genau wissen, wie sie funktionieren: Was ein Trigram-Bloom-Filter ist und wie man seine Größe wählt. Ich kann sagen, dass sie bei Abfragen zu einigen seltenen Phrasen, Teilzeichenfolgen, die selten in den Daten vorkommen, hilfreich sind. In diesem Fall werden Teilbereiche durch Indizes ausgewählt und es werden weniger Daten gelesen.

ClickHouse hat kürzlich noch erweiterte Funktionen für die Volltextsuche hinzugefügt. Hierbei handelt es sich erstens um die gleichzeitige Suche nach einer Reihe von Teilzeichenfolgen in einem Durchgang, einschließlich Optionen mit Berücksichtigung der Groß-/Kleinschreibung, ohne Berücksichtigung der Groß-/Kleinschreibung, UTF-8-unterstützten oder reinen ASCII-Optionen. Wählen Sie die effizienteste Lösung, die Sie benötigen.

Es wurde auch nach mehreren regulären Ausdrücken in einem Durchgang gesucht. Sie müssen X nicht wie einen Teilstring oder X wie einen anderen Teilstring schreiben. Schreiben Sie sofort und alles wird so effizient wie möglich erledigt.

Drittens gibt es jetzt eine ungefähre Suche nach regulären Ausdrücken und eine ungefähre Suche nach Teilzeichenfolgen. Wenn jemand ein Wort mit einem Tippfehler geschrieben hat, wird nach der maximalen Übereinstimmung gesucht.

Wie kann der Zugriff auf ClickHouse für eine große Anzahl von Benutzern am besten organisiert werden?

Sagen Sie uns, wie wir den Zugang für eine große Anzahl von Verbrauchern und Analysten am besten organisieren können. Wie bildet man eine Warteschlange, priorisiert die maximale Anzahl gleichzeitiger Abfragen und mit welchen Tools?

Wenn der Cluster groß genug ist, wäre es eine gute Lösung, zwei weitere Server einzurichten, die als Einstiegspunkt für Analysten dienen. Das heißt, lassen Sie Analysten keinen Zutritt zu bestimmten Cluster-Shards, sondern erstellen Sie einfach zwei leere Server ohne Daten und legen Sie bereits Zugriffsrechte für diese fest. Gleichzeitig werden Benutzereinstellungen bei verteilten Anfragen an Remote-Server übertragen. Das heißt, Sie konfigurieren alles auf diesen beiden Servern und die Einstellungen wirken sich auf den gesamten Cluster aus.

Im Prinzip sind diese Server datenlos, die Menge an RAM auf ihnen ist jedoch für die Ausführung von Anfragen sehr wichtig. Die Festplatte kann auch für temporäre Daten verwendet werden, wenn externe Aggregation oder externe Sortierung aktiviert ist.

Es ist wichtig, sich die Einstellungen anzusehen, die mit allen möglichen Grenzwerten verbunden sind. Wenn ich jetzt als Analyst zum Yandex.Metrics-Cluster gehe und eine Abfrage stelle Wählen Sie die Anzahl der Treffer aus, dann erhalte ich sofort eine Ausnahme, dass ich der Bitte nicht nachkommen kann. Die maximale Anzahl der Zeilen, die ich scannen darf, beträgt einhundert Milliarden, und der Cluster in einer Tabelle enthält insgesamt fünfzig Billionen. Dies ist die erste Einschränkung.

Nehmen wir an, ich entferne die Begrenzung der Zeilenanzahl und führe die Abfrage erneut aus. Dann sehe ich die folgende Ausnahme: Die Einstellung ist aktiviert Index nach Datum erzwingen. Ich kann die Abfrage nicht ausführen, wenn ich keinen Datumsbereich angegeben habe. Sie müssen sich nicht auf die manuelle Eingabe durch Analysten verlassen. Ein typischer Fall: Ein Datumsbereich wird geschrieben, wenn das Ereignisdatum zwischen einer Woche liegt. Und dann haben sie dort einfach keine Klammer angegeben, und stattdessen stellte sich heraus, dass es sich um ein oder – oder eine URL-Übereinstimmung handelte. Wenn es keine Begrenzung gibt, wird die URL-Spalte gecrawlt und eine Menge Ressourcen verschwendet.

Darüber hinaus verfügt ClickHouse über zwei Prioritätseinstellungen. Leider sind sie sehr primitiv. Man heißt einfach Prioritätsliste. Wenn die Priorität ≠ 0 ist und Anfragen mit einer gewissen Priorität ausgeführt werden, aber eine Anfrage mit einem niedrigeren Prioritätswert, also einer höheren Priorität, ausgeführt wird, dann wird eine Anfrage mit einem höheren Prioritätswert, also einer niedrigeren Priorität, ausgeführt einfach ausgesetzt und funktioniert in dieser Zeit überhaupt nicht.

Dies ist eine sehr grobe Einstellung und eignet sich nicht für Situationen, in denen der Cluster ständig belastet wird. Wenn Sie jedoch kurze Impulsanfragen haben, die wichtig sind, und der Cluster größtenteils inaktiv ist, reicht diese Einstellung aus.

Die nächste Prioritätseinstellung wird aufgerufen Betriebssystem-Thread-Priorität. Es setzt einfach alle Anforderungsausführungsthreads dem netten Wert für den Linux-Scheduler aus. Es funktioniert mittelmäßig, funktioniert aber immer noch. Wenn Sie den minimalen Nice-Wert festlegen – es ist der größte Wert und daher die niedrigste Priorität – und -19 für Anforderungen mit hoher Priorität festlegen, verbraucht die CPU Anforderungen mit niedriger Priorität etwa viermal weniger als Anforderungen mit hoher Priorität.

Sie müssen auch die maximale Ausführungszeit der Abfrage festlegen, beispielsweise fünf Minuten. Die minimale Geschwindigkeit der Anforderungsausführung ist das Coolste. Diese Einstellung gibt es schon seit langem und sie ist nicht nur erforderlich, um sicherzustellen, dass ClickHouse nicht langsamer wird, sondern auch, um sie zu erzwingen.

Stellen Sie sich vor, Sie richten Folgendes ein: Wenn eine Abfrage weniger als eine Million Zeilen pro Sekunde verarbeitet, ist das nicht möglich. Das entehrt unseren guten Namen, unsere gute Datenbank. Lass es uns einfach verbieten. Eigentlich gibt es zwei Einstellungen. Einer heißt Mindestausführungsgeschwindigkeit – in Zeilen pro Sekunde, und die Sekunde wird als Timeout bezeichnet, bevor die minimale Ausführungsgeschwindigkeit überprüft wird – standardmäßig fünfzehn Sekunden. Das heißt, fünfzehn Sekunden sind möglich, und wenn es dann langsam ist, werfen Sie einfach eine Ausnahme aus – brechen Sie die Anfrage ab.

Sie müssen auch Quoten einrichten. ClickHouse verfügt über eine integrierte Quotenfunktion, die den Ressourcenverbrauch zählt. Aber leider nicht Eisenressourcen wie CPU, Festplatten, sondern logische – die Anzahl der verarbeiteten Anfragen, Zeilen und gelesenen Bytes. Und Sie können beispielsweise maximal einhundert Anfragen innerhalb von fünf Minuten und tausend Anfragen pro Stunde einrichten.

Warum ist es wichtig? Denn einige der Analyseanfragen werden manuell direkt vom ClickHouse-Client ausgeführt. Und alles wird gut. Wenn es in Ihrem Unternehmen jedoch erfahrene Analysten gibt, schreiben diese ein Skript, und es kann sein, dass im Skript ein Fehler vorliegt. Und dieser Fehler führt dazu, dass die Anfrage in einer Endlosschleife ausgeführt wird. Das ist es, was es zu schützen gilt.

Ist es möglich, die Ergebnisse einer Anfrage an zehn Kunden weiterzugeben?

Wir haben mehrere Benutzer, die gerne gleichzeitig mit sehr großen Anfragen kommen. Die Anfrage ist groß, im Prinzip wird sie schnell ausgeführt, aber aufgrund der Tatsache, dass es viele solcher Anfragen gleichzeitig gibt, wird es sehr schmerzhaft. Ist es möglich, dieselbe Anfrage, die zehnmal hintereinander eingegangen ist, einmal auszuführen und das Ergebnis an zehn Clients weiterzugeben?

Das Problem ist, dass wir keine Cache-Ergebnisse oder Zwischendaten-Cache haben. Es gibt einen Seitencache des Betriebssystems, der es Ihnen ermöglicht, Daten nicht erneut von der Festplatte zu lesen, aber leider werden die Daten trotzdem dekomprimiert, deserialisiert und erneut verarbeitet.

Ich möchte dies irgendwie vermeiden, indem ich entweder Zwischendaten zwischenspeichere oder ähnliche Abfragen in einer Art Warteschlange anordne und einen Ergebnis-Cache hinzufüge. Jetzt haben wir eine Pull-Anfrage in der Entwicklung, die einen Anfrage-Cache hinzufügt, allerdings nur für Unteranfragen in den Abschnitten „in“ und „join“ – das heißt, die Lösung ist minderwertig.

Allerdings haben wir auch eine solche Situation. Ein besonders kanonisches Beispiel sind Anfragen mit Paginierung. Es gibt einen Bericht, er hat mehrere Seiten und es gibt eine Anfrage mit einem Limit von 10. Dann das Gleiche, aber Limit 10,10. Dann noch eine Seite. Und die Frage ist, warum wir jedes Mal alles zählen? Aber jetzt gibt es keine Lösung und es gibt keine Möglichkeit, es zu vermeiden.

Es gibt eine alternative Lösung, die als Beiwagen neben ClickHouse platziert wird – ClickHouse-Proxy.

Kirill Schwakow: ClickHouse Proxy verfügt über einen integrierten Ratenbegrenzer und einen integrierten Ergebnis-Cache. Dort wurden viele Einstellungen vorgenommen, da eine ähnliche Aufgabe gelöst wurde. Mit Proxy können Sie Anfragen begrenzen, indem Sie sie in die Warteschlange stellen, und konfigurieren, wie lange der Anfrage-Cache aktiv bleibt. Wenn die Anfragen wirklich gleich waren, wird der Proxy sie mehrmals beantworten und nur einmal zu ClickHouse gehen.

Nginx hat in der kostenlosen Version auch einen Cache und das wird auch funktionieren. Nginx verfügt sogar über Einstellungen, sodass andere Anfragen blockiert werden, bis eine Anfrage abgeschlossen ist, wenn sie gleichzeitig eingehen. In ClickHouse Proxy werden die Einstellungen jedoch viel besser vorgenommen. Es wurde speziell für ClickHouse und speziell für diese Anforderungen entwickelt und ist daher besser geeignet. Nun, es ist einfach einzurichten.

Was ist mit asynchronen Vorgängen und materialisierten Ansichten?

Es besteht das Problem, dass Vorgänge mit der ersetzenden Engine asynchron sind – die Daten werden zuerst geschrieben, dann kollabieren sie. Wenn sich unter der Tafel eine materialisierte Tafel mit einigen Aggregaten befindet, werden Duplikate darauf geschrieben. Und wenn es keine komplexe Logik gibt, werden die Daten dupliziert. Was kann man dagegen tun?

Es gibt eine offensichtliche Lösung: Während eines asynchronen Kollapsvorgangs einen Trigger für eine bestimmte Matview-Klasse zu implementieren. Gibt es „Allheilmittel“-Pläne zur Implementierung einer solchen Funktionalität?

Es lohnt sich zu verstehen, wie die Deduplizierung funktioniert. Was ich gleich sagen werde, hat nichts mit der Frage zu tun, aber es lohnt sich, sich für alle Fälle daran zu erinnern.

Beim Einfügen in eine replizierte Tabelle erfolgt eine Deduplizierung der gesamten eingefügten Blöcke. Wenn Sie denselben Block mit derselben Anzahl derselben Zeilen in derselben Reihenfolge erneut einfügen, werden die Daten dedupliziert. Als Antwort auf die Einfügung erhalten Sie „Ok“, es wird jedoch tatsächlich ein Datenstapel geschrieben und nicht dupliziert.

Dies ist zur Gewissheit notwendig. Wenn Sie beim Einfügen „Ok“ erhalten, wurden Ihre Daten eingefügt. Wenn Sie von ClickHouse eine Fehlermeldung erhalten, werden sie nicht eingefügt und Sie müssen das Einfügen wiederholen. Wenn die Verbindung jedoch während des Einfügens unterbrochen wird, wissen Sie nicht, ob die Daten eingefügt werden oder nicht. Die einzige Möglichkeit besteht darin, die Einfügung noch einmal zu wiederholen. Wenn die Daten tatsächlich eingefügt wurden und Sie sie erneut eingefügt haben, liegt eine Blockdeduplizierung vor. Dies ist erforderlich, um Duplikate zu vermeiden.

Und es ist auch wichtig, wie es für materialisierte Ansichten funktioniert. Wenn die Daten beim Einfügen in die Haupttabelle dedupliziert wurden, werden sie auch nicht in die materialisierte Ansicht übernommen.

Nun zur Frage. Ihre Situation ist komplizierter, da Sie Duplikate einzelner Zeilen schreiben. Das heißt, nicht das gesamte Paket wird dupliziert, sondern bestimmte Zeilen, und diese werden im Hintergrund ausgeblendet. Tatsächlich werden die Daten in der Haupttabelle ausgeblendet, und die nicht ausgeblendeten Daten werden in die materialisierte Ansicht übernommen, und beim Zusammenführen geschieht nichts mit den materialisierten Ansichten. Denn eine materialisierte Ansicht ist nichts anderes als ein Auslöser beim Einfügen. Bei anderen Vorgängen passiert ihm nichts anderes.

Und ich kann hier nicht glücklich sein. Es muss lediglich nach einer konkreten Lösung für diesen Fall gesucht werden. Ist es beispielsweise möglich, es in einer materialisierten Ansicht zu ersetzen, und die Deduplizierungsmethode funktioniert möglicherweise genauso? Aber leider nicht immer. Wenn es aggregiert, funktioniert es nicht.

Kirill Schwakow: Wir hatten auch einmal Knochenaufbau. Es gab ein Problem mit Anzeigenimpressionen und es gibt einige Daten, die wir in Echtzeit anzeigen können – es handelt sich lediglich um Impressionen. Sie werden selten dupliziert, aber wenn doch, reduzieren wir sie trotzdem. Und es gab Dinge, die nicht dupliziert werden können – Klicks und diese ganze Geschichte. Ich wollte sie aber auch gleich zeigen.

Wie wurden materialisierte Ansichten gemacht? Es gab Ansichten, in denen direkt geschrieben wurde – es gibt einen Datensatz in Rohdaten und er wird in Ansichten geschrieben. Dort sind die Daten irgendwann nicht mehr ganz korrekt, sie werden dupliziert und so weiter. Und es gibt den zweiten Teil der Tabelle, in dem sie genauso aussehen wie die materialisierten Ansichten, das heißt, sie haben genau die gleiche Struktur. Hin und wieder berechnen wir die Daten neu, zählen die Daten ohne Duplikate und schreiben in diese Tabellen.

Wir sind die API durchgegangen – dies wird in ClickHouse nicht von Hand funktionieren. Und die API sieht aus: Wenn ich das Datum der letzten Ergänzung zur Tabelle habe, ist garantiert, dass die richtigen Daten bereits berechnet wurden, und sie stellt eine Anfrage an eine Tabelle und an eine andere Tabelle. Von einer Anfrage wählt er bis zu einer bestimmten Zeitspanne aus und von der anderen erhält er, was noch nicht berechnet wurde. Und es funktioniert, aber nicht mit einem ClickHouse.

Wenn Sie über eine Art API verfügen – für Analysten, für Benutzer – dann ist dies im Prinzip eine Option. Du zählst immer, zählst immer. Dies kann einmal am Tag oder zu einem anderen Zeitpunkt erfolgen. Sie wählen selbst den Bereich aus, den Sie nicht benötigen und der nicht kritisch ist.

ClickHouse verfügt über viele Protokolle. Wie kann ich in einem Moment alles sehen, was mit dem Server passiert?

ClickHouse verfügt über eine sehr große Anzahl verschiedener Protokolle, Tendenz steigend. In neuen Versionen sind einige davon sogar standardmäßig aktiviert, in älteren Versionen müssen sie beim Update aktiviert werden. Es gibt jedoch immer mehr davon. Ich würde gerne endlich sehen, was jetzt mit meinem Server passiert, vielleicht auf einem zusammenfassenden Dashboard.

Gibt es im ClickHouse-Team oder in den Teams Ihrer Freunde, die einige Funktionen vorgefertigter Dashboards unterstützen, die diese Protokolle als fertiges Produkt anzeigen würden? Letztendlich ist es großartig, sich nur die Protokolle in ClickHouse anzusehen. Aber es wäre sehr cool, wenn es schon in Form eines Dashboards vorbereitet wäre. Ich würde davon high werden.

Es gibt Dashboards, diese sind jedoch nicht standardisiert. Wir haben etwa 60 Teams in unserem Unternehmen, die ClickHouse verwenden, und das Seltsamste ist, dass viele von ihnen Dashboards haben, die sie selbst erstellt haben und die ein wenig anders sind. Einige Teams verwenden die interne Installation von Yandex.Cloud. Es gibt einige vorgefertigte Berichte, wenn auch nicht alle notwendigen. Andere haben ihre.

Meine Kollegen von Metrica haben ihr eigenes Dashboard in Grafana und ich habe eines für ihren eigenen Cluster. Ich schaue mir Dinge wie einen Cache-Hit für einen Serif-Cache an. Und noch schwieriger ist es, dass wir unterschiedliche Tools verwenden. Ich habe mein Dashboard mit einem sehr alten Tool namens Graphite-web erstellt. Er ist völlig hässlich. Und ich benutze es immer noch so, obwohl Grafana wahrscheinlich bequemer und schöner wäre.

Die grundlegende Sache bei Dashboards ist dieselbe. Dies sind Systemmetriken für den Cluster: CPU, Speicher, Festplatte, Netzwerk. Andere sind die Anzahl gleichzeitiger Anforderungen, die Anzahl gleichzeitiger Zusammenführungen, die Anzahl der Anforderungen pro Sekunde, die maximale Anzahl von Blöcken für MergeTree-Tabellenpartitionen, die Replikationsverzögerung, die Größe der Replikationswarteschlange, die Anzahl der pro Sekunde eingefügten Zeilen, die Anzahl der pro Sekunde eingefügten Blöcke. Das ist alles, was nicht aus den Protokollen, sondern aus den Metriken gewonnen wird.

Wladimir Kolobajew: Alexey, ich möchte ein wenig korrigieren. Es gibt Grafana. Grafana verfügt über eine Datenquelle, die ClickHouse ist. Das heißt, ich kann Anfragen von Grafana direkt an ClickHouse richten. ClickHouse verfügt über eine Tabelle mit Protokollen, die für alle gleich ist. Daher möchte ich in Grafana auf diese Protokolltabelle zugreifen und die Anforderungen sehen, die mein Server anwendet. Es wäre toll, ein solches Dashboard zu haben.

Ich bin selbst damit gefahren. Aber ich habe eine Frage: Wenn alles standardisiert ist und Grafana von allen verwendet wird, warum hat Yandex dann kein so offizielles Dashboard?

Kirill Schwakow: Tatsächlich unterstützt die Datenquelle von ClickHouse jetzt Altinity. Und ich möchte nur einen Überblick darüber geben, wo man graben und wen man schieben muss. Sie können sie fragen, denn Yandex macht immer noch ClickHouse und nicht die Geschichte darum herum. Altinity ist das Hauptunternehmen, das derzeit für ClickHouse wirbt. Sie werden ihn nicht im Stich lassen, sondern ihn unterstützen. Denn um ein Dashboard auf die Grafana-Website hochzuladen, muss man sich grundsätzlich nur registrieren und hochladen – es gibt keine besonderen Probleme.

Alexey Milovidov: Im vergangenen Jahr hat ClickHouse zahlreiche Funktionen zur Abfrageprofilierung hinzugefügt. Für jede Ressourcennutzungsanforderung gibt es Metriken. Und vor kurzem wurde ein Abfrageprofiler auf noch niedrigerer Ebene hinzugefügt, um zu sehen, wo die Abfrage jede Millisekunde verbringt. Um diese Funktionalität nutzen zu können, muss ich jedoch den Konsolenclient öffnen und eine Abfrage eingeben, die ich immer wieder vergesse. Ich habe es irgendwo gespeichert und vergesse immer, wo genau.

Ich wünschte, es gäbe ein Tool, das nur sagt: Hier sind Ihre umfangreichen Abfragen, gruppiert nach Abfrageklasse. Ich habe auf eines geklickt und sie sagten mir, dass es daher schwer sei. Jetzt gibt es keine solche Lösung. Und es ist wirklich ziemlich seltsam, dass ich, wenn Leute mich fragen: „Sagen Sie, gibt es fertige Dashboards für Grafana?“, antworte: „Gehen Sie auf die Grafana-Website, dort gibt es eine Dashboards-Community und es gibt ein Dashboard von Dimka.“ , dort von Kostyan. Ich weiß nicht, was es ist, ich habe es selbst nicht benutzt.

Wie kann man Merdzhi beeinflussen, damit der Server nicht in OOM fällt?

Ich habe eine Tabelle, es gibt nur eine Partition in der Tabelle, nämlich ReplacingMergeTree. Ich schreibe seit vier Jahren Daten darauf. Ich musste eine Änderung vornehmen und einige Daten löschen.

Ich habe dies getan und im Laufe der Verarbeitung dieser Anfrage wurde der gesamte Speicher auf allen Servern im Cluster verbraucht und alle Server im Cluster gingen zusammen in OOM. Dann standen sie alle zusammen auf, begannen mit der Zusammenführung desselben Vorgangs, dieses Datenblocks, und fielen erneut in OOM. Dann standen sie wieder auf und fielen wieder hin. Und das Ding hörte nicht auf.

Dann stellte sich heraus, dass es sich tatsächlich um einen Fehler handelte, den die Jungs behoben hatten. Das ist sehr cool, vielen Dank. Aber der Rückstand blieb. Und wenn ich jetzt über die Notwendigkeit nachdenke, eine bestimmte Zusammenführung in der Tabelle vorzunehmen, habe ich eine Frage: Warum kann ich diese Zusammenführungen nicht irgendwie beeinflussen? Begrenzen Sie sie beispielsweise durch die erforderliche RAM-Größe oder im Prinzip durch die Anzahl, die diese bestimmte Tabelle verarbeiten soll.

Ich habe eine Tabelle mit dem Namen „Metriken“, bitte verarbeiten Sie sie für mich in zwei Streams. Es ist nicht nötig, zehn oder fünf Zusammenführungen parallel durchzuführen, sondern in zwei Schritten. Ich denke, dass ich in zwei Fällen genug Speicher habe, aber es reicht möglicherweise nicht aus, um zehn zu verarbeiten. Warum bleibt die Angst bestehen? Weil die Tabelle wächst und ich eines Tages auf eine Situation stoßen werde, die im Prinzip nicht mehr auf einen Fehler zurückzuführen ist, sondern auf die Tatsache, dass sich die Daten in so großem Umfang ändern, dass ich einfach nicht genügend Speicher habe der Kellner. Und dann fällt der Server während der Zusammenführung in OOM. Außerdem kann ich die Mutation abbrechen, aber die Zusammenführung ist weg.

Sie wissen, dass der Server beim Zusammenführen nicht in OOM fällt, da beim Zusammenführen die RAM-Menge nur für einen kleinen Datenbereich verwendet wird. Es wird also unabhängig von der Datenmenge alles in Ordnung sein.

Wladimir Kolobajew: Bußgeld. Hier ist der Moment so, dass ich, nachdem wir eine Fehlerbehebung vorgenommen hatten, eine neue Version für mich selbst heruntergeladen habe und auf einer anderen, kleineren Tabelle, in der es viele Partitionen gibt, einen ähnlichen Vorgang durchgeführt habe. Und während der Zusammenführung wurden etwa 100 GB RAM auf dem Server verbrannt. Ich hatte 150 beschäftigt, habe 100 gegessen und es war noch ein 50-GB-Fenster übrig, sodass ich nicht in OOM geraten bin.

Was schützt mich derzeit davor, in OOM zu fallen, wenn es tatsächlich 100 GB RAM verbraucht? Was tun in einer Situation, wenn plötzlich der RAM auf dem Merdzh ausgeht?

Alexey Milovidov: Es besteht das Problem, dass der RAM-Verbrauch nicht auf Merdzhi beschränkt ist. Und das zweite Problem besteht darin, dass, wenn eine Zusammenführung zugewiesen wurde, diese ausgeführt werden muss, da sie in das Replikationsprotokoll geschrieben wird. Das Replikationsprotokoll enthält die Aktionen, die erforderlich sind, um das Replikat in einen konsistenten Zustand zu versetzen. Wenn Sie keine manuellen Manipulationen vornehmen, die dieses Replikationsprotokoll zurücksetzen, muss die Zusammenführung auf die eine oder andere Weise durchgeführt werden.

Natürlich wäre eine Begrenzung des Arbeitsspeichers, der „nur für den Fall“ vor OOM schützt, nicht überflüssig. Es wird der Zusammenführung nicht helfen, sie wird von vorne beginnen, einen bestimmten Schwellenwert erreichen, eine Ausnahme auslösen und dann erneut beginnen – es wird nichts Gutes dabei herauskommen. Grundsätzlich wäre es aber sinnvoll, diese Einschränkung einzuführen.

Wie wird die Entwicklung des Golang-Treibers für ClickHouse erfolgen?

Der von Kirill Shvakov geschriebene Golang-Treiber wird jetzt offiziell vom ClickHouse-Team unterstützt. Er im ClickHouse-Repository, er ist jetzt groß und echt.

Eine kleine Anmerkung. Es gibt eine wunderbare und beliebte Sammlung normaler Formen unendlicher Ordnung – das ist Vertica. Sie verfügen außerdem über einen eigenen offiziellen Python-Treiber, der von Vertica-Entwicklern gepflegt wird. Und mehrfach kam es vor, dass sich die Versionen des Speichers und die Versionen des Treibers ziemlich abrupt trennten und der Treiber irgendwann nicht mehr funktionierte. Und der zweite Punkt. Die Unterstützung für diesen offiziellen Treiber wird meines Erachtens durch das „Nippel“-System aufrechterhalten – man schreibt ihnen ein Problem, und es bleibt für immer hängen.

Ich habe zwei Fragen. Jetzt ist Kirills Golang-Treiber fast eine Standardmethode für die Kommunikation von Golang mit ClickHouse. Es sei denn, jemand kommuniziert noch über die http-Schnittstelle, weil ihm das so gut gefällt. Wie wird dieser Treiber entwickelt? Wird es mit einigen wichtigen Änderungen im Repository selbst synchronisiert? Und wie ist das Verfahren zur Prüfung des Problems?

Kirill Schwakow: Das erste ist, wie alles bürokratisch geregelt ist. Dieser Punkt wurde nicht besprochen, daher habe ich nichts zu antworten.

Um die Frage zu diesem Problem zu beantworten, benötigen wir eine kleine Geschichte des Fahrers. Ich habe für ein Unternehmen gearbeitet, das viele Daten hatte. Es handelte sich um einen Werbespinner mit einer riesigen Anzahl an Ereignissen, die irgendwo gespeichert werden mussten. Und irgendwann erschien ClickHouse. Wir haben Daten hineingeschüttet und zunächst war alles in Ordnung, aber dann ist ClickHouse zusammengebrochen. Damals entschieden wir, dass wir es nicht brauchten.

Ein Jahr später kamen wir wieder auf die Idee, ClickHouse zu verwenden, und mussten dort irgendwie Daten schreiben. Die Eingabe war folgende: Das Eisen ist sehr schwach, es gibt nur wenige Ressourcen. Aber wir haben schon immer so gearbeitet und deshalb haben wir uns für das native Protokoll entschieden.

Da wir an Go arbeiteten, war klar, dass wir einen Go-Treiber brauchten. Ich habe es fast Vollzeit gemacht – es war meine Arbeitsaufgabe. Bis zu einem gewissen Punkt haben wir es zur Sprache gebracht, und im Prinzip hat niemand damit gerechnet, dass jemand anders als wir es nutzen würde. Dann kam CloudFlare mit genau dem gleichen Problem und eine Zeit lang haben wir sehr reibungslos mit ihnen zusammengearbeitet, weil sie die gleichen Aufgaben hatten. Und wir haben es sowohl in ClickHouse selbst als auch im Treiber gemacht.

Irgendwann habe ich einfach damit aufgehört, weil sich meine Tätigkeit in Sachen ClickHouse und mit der Arbeit ein wenig verändert hat. Daher sind die Probleme nicht geschlossen. In regelmäßigen Abständen verpflichten sich Personen, die selbst etwas benötigen, zum Repository. Dann schaue ich mir den Pull-Request an und manchmal bearbeite ich sogar selbst etwas, aber das kommt selten vor.

Ich möchte zum Fahrer zurückkehren. Als das Ganze vor ein paar Jahren begann, war ClickHouse auch anders und mit anderen Funktionen. Jetzt gibt es ein Verständnis dafür, wie man den Treiber so umgestalten kann, dass er gut ist. In diesem Fall ist Version 2 aufgrund angesammelter Krücken ohnehin nicht kompatibel.

Ich weiß nicht, wie ich das arrangieren soll. Ich selbst habe nicht viel Zeit. Wenn einige Leute den Treiber fertig haben, kann ich ihnen helfen und ihnen sagen, was sie tun sollen. Es ist jedoch die aktive Beteiligung von Yandex an der Entwicklung des Projekts, die bisher in keiner Weise diskutiert wurde.

Alexey Milovidov: Tatsächlich gibt es für diese Fahrer noch keine Bürokratie. Das Einzige ist, dass sie zu einer offiziellen Organisation verschoben werden, das heißt, dieser Treiber wird als offizielle Standardlösung für Go anerkannt. Es gibt einige andere Treiber, die jedoch separat geliefert werden.

Wir haben keine Entwicklung für diese Treiber im Haus. Die Frage ist, ob wir eine Einzelperson einstellen können, nicht speziell für diesen Fahrer, sondern für die Entwicklung aller Community-Fahrer, oder ob wir jemanden außerhalb finden können.

Das externe Wörterbuch wird nach dem Neustart mit aktiviertem lazy_load nicht erstellt. Was zu tun ist?

Wir haben die Einstellung lazy_load aktiviert und nach dem Neustart des Servers wird das Wörterbuch selbst nicht aufgerufen. Es wird erst ausgelöst, nachdem der Benutzer auf dieses Wörterbuch zugreift. Und beim ersten Aufruf wird ein Fehler ausgegeben. Ist es möglich, Wörterbücher mit ClickHouse irgendwie automatisch zu laden, oder müssen Sie deren Bereitschaft immer selbst kontrollieren, damit Benutzer keine Fehler erhalten?

Möglicherweise haben wir eine alte Version von ClickHouse, sodass das Wörterbuch nicht automatisch geladen wurde. Könnte es sein?

Erstens können Wörterbücher mithilfe der Abfrage zwangsweise geladen werden System lädt Wörterbücher neu. Zweitens zum Fehler: Wenn das Wörterbuch bereits geladen ist, funktionieren die Abfragen mit den geladenen Daten. Wenn das Wörterbuch noch nicht geladen ist, wird es direkt zum Zeitpunkt der Anfrage geladen.

Für umfangreiche Wörterbücher ist dies nicht sehr praktisch. Beispielsweise müssen Sie eine Million Zeilen von MySQL abrufen. Jemand führt eine einfache Auswahl durch, aber diese Auswahl wartet auf dieselben Millionen Zeilen. Hier gibt es zwei Lösungen. Die erste besteht darin, lazy_load zu deaktivieren. Die zweite Möglichkeit besteht darin, den Server hochzufahren, bevor Sie ihn belasten System-Wörterbuch neu laden oder führen Sie einfach eine Abfrage aus, die ein Wörterbuch verwendet. Anschließend wird das Wörterbuch geladen. Sie müssen die Verfügbarkeit von Wörterbüchern mit aktivierter lazy_load-Einstellung kontrollieren, da ClickHouse sie nicht automatisch abruft.

Die Antwort auf die letzte Frage lautet: Entweder ist die Version alt oder sie muss debuggt werden.

Was ist mit der Tatsache, dass das System zum erneuten Laden von Wörterbüchern keines der vielen Wörterbücher lädt, wenn mindestens eines davon mit einem Fehler abstürzt?

Es gibt noch eine weitere Frage zum System-Neuladen von Wörterbüchern. Wir haben zwei Wörterbücher – eines ist nicht geladen, das zweite ist geladen. In diesem Fall lädt das System-Neuladen von Wörterbüchern kein Wörterbuch, und Sie müssen ein bestimmtes Wörterbuch anhand seines Namens Punkt-zu-Punkt laden, indem Sie das System-Neuladen-Wörterbuch verwenden. Hängt das auch mit der ClickHouse-Version zusammen?

Ich möchte gefallen. Dieses Verhalten hat sich geändert. Wenn Sie also ClickHouse aktualisieren, wird es sich auch ändern. Wenn Sie mit dem aktuellen Verhalten nicht zufrieden sind System lädt Wörterbücher neu, aktualisieren und hoffen wir, dass es sich zum Besseren ändert.

Gibt es eine Möglichkeit, die Details in der ClickHouse-Konfiguration zu konfigurieren, sie aber nicht bei Fehlern anzuzeigen?

Die nächste Frage betrifft Fehler im Zusammenhang mit dem Wörterbuch, nämlich Details. Wir haben die Verbindungsdetails in der ClickHouse-Konfiguration im Wörterbuch registriert und erhalten im Fehlerfall diese Details und das Passwort als Antwort.

Wir haben diesen Fehler behoben, indem wir Details zur ODBC-Treiberkonfiguration hinzugefügt haben. Gibt es eine Möglichkeit, die Details in der ClickHouse-Konfiguration zu konfigurieren, diese Details jedoch nicht auf Fehler hinzuweisen?

Hier besteht die Lösung tatsächlich darin, diese Anmeldeinformationen in odbc.ini anzugeben und in ClickHouse selbst nur den ODBC-Datenquellennamen anzugeben. Dies wird bei anderen Wörterbuchquellen nicht der Fall sein – weder bei einem Wörterbuch mit MySQL noch bei den anderen Quellen sollte das Passwort nicht in der Fehlermeldung angezeigt werden. Nach ODBC werde ich auch suchen – wenn es so etwas gibt, muss man es nur entfernen.

Bonus: Hintergründe für Zuma von Zusammenkünften

Durch Klicken auf das Bild werden für die hartnäckigsten Leser Bonushintergründe von Versammlungen geöffnet. Gemeinsam mit Avitos Technologie-Maskottchen das Feuer löschen, sich mit Kollegen aus dem Zimmer des Systemadministrators oder einem Computerclub der alten Schule beraten und vor dem Hintergrund von Graffiti eine tägliche Veranstaltung unter der Brücke abhalten.

ClickHouse für fortgeschrittene Benutzer in Fragen und Antworten

Source: habr.com

Kommentar hinzufügen