Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Da es sich bei ClickHouse um ein spezialisiertes System handelt, ist es wichtig, bei der Nutzung die Besonderheiten seiner Architektur zu berücksichtigen. In diesem Bericht wird Alexey über Beispiele typischer Fehler bei der Verwendung von ClickHouse sprechen, die zu ineffizientem Arbeiten führen können. Anhand praktischer Beispiele zeigen wir, wie die Wahl des einen oder anderen Datenverarbeitungsschemas die Leistung um Größenordnungen verändern kann.

Hallo alle! Mein Name ist Alexey, ich erstelle ClickHouse.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Erstens beeile ich mich, Ihnen gleich eine Freude zu machen, ich werde Ihnen heute nicht sagen, was ClickHouse ist. Ehrlich gesagt habe ich es satt. Ich sage dir jedes Mal, was es ist. Und wahrscheinlich weiß es bereits jeder.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Stattdessen verrate ich Ihnen, wie hoch der mögliche Rake ist, also wie ClickHouse missbraucht werden kann. Tatsächlich sollten Sie keine Angst haben, denn wir entwickeln ClickHouse als ein System, das einfach, bequem und sofort einsatzbereit ist. Alles installiert, kein Problem.

Dennoch muss man bedenken, dass dieses System spezialisiert ist und man leicht auf einen ungewöhnlichen Anwendungsfall stoßen kann, der dieses System aus seiner Komfortzone bringt.

Also, was sind die Rechen? Grundsätzlich werde ich über die offensichtlichen Dinge sprechen. Alles ist für jeden klar, jeder versteht alles und kann froh sein, dass er so schlau ist, und wer es nicht versteht, wird etwas Neues lernen.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Das erste einfachste Beispiel, das leider häufig vorkommt, ist eine große Anzahl von Beilagen mit kleinen Chargen, also eine große Anzahl kleiner Beilagen.

Wenn wir berücksichtigen, wie ClickHouse eine Einfügung durchführt, können Sie in einer Anfrage mindestens ein Terabyte an Daten senden. Das ist kein Problem.

Und mal sehen, wie die typische Leistung aussehen wird. Wir haben zum Beispiel eine Tabelle mit Yandex.Metrica-Daten. Treffer. 105 einige Spalten. 700 Byte unkomprimiert. Und wir werden auf gute Weise Chargen von einer Million Zeilen einfügen.

Wir fügen es in die MergeTree-Tabelle ein und erhalten eine halbe Million Zeilen pro Sekunde. Großartig. In einer replizierten Tabelle sind es etwas weniger, etwa 400 Zeilen pro Sekunde.

Und wenn Sie die Quorum-Einfügung aktivieren, erhalten Sie etwas weniger, aber immer noch eine ordentliche Leistung, 250 Mal pro Sekunde. Quorum Insertion ist eine undokumentierte Funktion in ClickHouse*.

* Stand 2020, bereits dokumentiert.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Was passiert, wenn Sie es falsch machen? Wir fügen eine Zeile in die MergeTree-Tabelle ein und erhalten 59 Zeilen pro Sekunde. Das ist 10 Mal langsam. In ReplicatedMergeTree – 000 Zeilen pro Sekunde. Und wenn das Quorum eingeschaltet ist, werden 6 Zeilen pro Sekunde erhalten. Meiner Meinung nach ist das völliger Mist. Wie kann man so langsamer werden? Auf meinem T-Shirt steht sogar, dass ClickHouse nicht langsamer werden sollte. Aber trotzdem kommt es manchmal vor.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Tatsächlich ist das unser Manko. Wir hätten dafür sorgen können, dass es ganz gut funktioniert, aber wir haben es nicht geschafft. Und wir haben es nicht getan, weil unser Drehbuch es nicht brauchte. Wir hatten bereits Chargen. Wir haben gerade am Eingang Chargen erhalten, und es gab keine Probleme. Anschließen und alles funktioniert einwandfrei. Aber natürlich sind alle möglichen Szenarien möglich. Zum Beispiel, wenn Sie über eine Reihe von Servern verfügen, auf denen Daten generiert werden. Und sie fügen Daten nicht so oft ein, werden aber dennoch häufig eingefügt. Und das muss man irgendwie vermeiden.

Aus technischer Sicht ist das Endergebnis, dass die Daten bei einer Einfügung in ClickHouse nicht in irgendeine Memtable gelangen. Wir haben nicht einmal eine echte MergeTree-Protokollstruktur, sondern nur einen MergeTree, da es weder Protokoll noch MemTable gibt. Wir schreiben die Daten einfach sofort in das Dateisystem, bereits in Spalten zerlegt. Und wenn Sie 100 Spalten haben, müssen mehr als 200 Dateien in ein separates Verzeichnis geschrieben werden. Das alles ist sehr umständlich.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Und es stellt sich die Frage: „Wie macht man es richtig?“ In einer solchen Situation müssen Sie die Daten trotzdem irgendwie in ClickHouse schreiben.

Methode 1. Dies ist der einfachste Weg. Verwenden Sie eine Art verteilte Warteschlange. Zum Beispiel Kafka. Sie entnehmen einfach Daten aus Kafka und wir bündeln sie einmal pro Sekunde. Und alles wird gut, Sie nehmen auf, alles funktioniert gut.

Die Nachteile bestehen darin, dass Kafka ein weiteres umständliches verteiltes System ist. Ich verstehe auch, wenn Sie Kafka bereits in Ihrem Unternehmen haben. Es ist gut, es ist praktisch. Wenn es jedoch nicht vorhanden ist, sollten Sie dreimal darüber nachdenken, bevor Sie ein anderes verteiltes System in Ihr Projekt ziehen. Es lohnt sich also, über Alternativen nachzudenken.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Methode 2. Hier ist so eine Old-School-Alternative und gleichzeitig sehr einfach. Haben Sie einen Server, der Ihre Protokolle generiert? Und es schreibt Ihre Protokolle einfach in eine Datei. Und einmal pro Sekunde benennen wir zum Beispiel diese Datei um und öffnen eine neue. Und ein separates Skript, entweder von Cron oder einem Daemon, nimmt die älteste Datei und schreibt sie in ClickHouse. Wenn Sie einmal pro Sekunde Protokolle schreiben, ist alles in Ordnung.

Der Nachteil dieser Methode besteht jedoch darin, dass, wenn Ihr Server, auf dem die Protokolle generiert werden, irgendwo verschwunden ist, auch die Daten verschwinden.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Methode 3. Es gibt noch einen anderen interessanten Weg, der ganz ohne temporäre Dateien auskommt. Sie haben beispielsweise eine Art Werbespinner oder einen anderen interessanten Daemon, der Daten generiert. Und Sie können eine Menge Daten direkt im RAM, im Puffer, ansammeln. Und wenn genügend Zeit verstrichen ist, legen Sie diesen Puffer beiseite, erstellen einen neuen und fügen das, was sich bereits angesammelt hat, in einem separaten Thread in ClickHouse ein.

Andererseits verschwinden die Daten auch mit kill -9. Wenn Ihr Server ausfällt, gehen diese Daten verloren. Und ein weiteres Problem besteht darin, dass sich Ihre Daten im RAM ansammeln, wenn Sie nicht in die Datenbank schreiben können. Und entweder geht der Arbeitsspeicher zur Neige oder Sie verlieren einfach Daten.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Methode 4. Ein weiterer interessanter Weg. Haben Sie einen Serverprozess? Und er kann Daten auf einmal an ClickHouse senden, aber über eine einzige Verbindung. Ich habe zum Beispiel eine http-Anfrage mit transfer-encoding: chunked with insert gesendet. Und es werden nicht allzu selten Chunks generiert. Sie können jede Zeile senden, obwohl für das Framen dieser Daten ein Mehraufwand anfällt.

In diesem Fall werden die Daten jedoch unverzüglich an ClickHouse übermittelt. Und ClickHouse selbst wird sie puffern.

Aber es gibt auch Probleme. Jetzt gehen Daten verloren, auch wenn Ihr Prozess abgebrochen wird und wenn der ClickHouse-Prozess abgebrochen wird, da es sich um eine unvollständige Einfügung handelt. Und in ClickHouse sind Einfügungen bis zu einem bestimmten Schwellenwert für die Zeilengröße atomar. Im Prinzip ist das ein interessanter Weg. Kann auch verwendet werden.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Methode 5. Hier ist ein weiterer interessanter Weg. Dabei handelt es sich um eine Art von der Community entwickelter Server für die Datenstapelverarbeitung. Ich habe es mir selbst nicht angeschaut, daher kann ich nichts garantieren. Es gibt jedoch keine Garantien für ClickHouse selbst. Dies ist ebenfalls Open Source, aber andererseits könnte man sich an einen gewissen Qualitätsstandard gewöhnen, den wir zu bieten versuchen. Aber für diese Sache – ich weiß nicht, gehen Sie zu GitHub und schauen Sie sich den Code an. Vielleicht haben sie etwas Gutes geschrieben.

*Stand 2020, sollte ebenfalls berücksichtigt werden Kätzchenhaus.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Methode 6. Eine andere Möglichkeit ist die Verwendung von Puffertabellen. Der Vorteil dieser Methode besteht darin, dass sie sehr einfach anzuwenden ist. Erstellen Sie eine Puffertabelle und fügen Sie sie ein.

Der Nachteil ist jedoch, dass das Problem nicht vollständig gelöst ist. Wenn Sie bei einer Rate vom Typ MergeTree Daten nach einem Batch pro Sekunde gruppieren müssen, müssen Sie bei einer Rate in einer Puffertabelle mindestens bis zu mehreren Tausend pro Sekunde gruppieren. Wenn es mehr als 10 pro Sekunde sind, ist es immer noch schlecht. Und wenn Sie stapelweise einfügen, dann haben Sie gesehen, dass dort hunderttausend Zeilen pro Sekunde erhalten werden. Und dies basiert bereits auf ziemlich umfangreichen Daten.

Und auch Puffertabellen haben kein Protokoll. Und wenn mit Ihrem Server etwas nicht stimmt, gehen die Daten verloren.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Und als Bonus hatten wir kürzlich die Möglichkeit, in ClickHouse Daten von Kafka zu sammeln. Es gibt eine Tabellen-Engine – Kafka. Du erschaffst einfach. Und man kann materialisierte Ansichten daran aufhängen. In diesem Fall entnimmt er die Daten aus Kafka und fügt sie in die von Ihnen benötigten Tabellen ein.

Und das Erfreuliche an dieser Chance ist vor allem, dass wir sie nicht genutzt haben. Dies ist eine Community-Funktion. Und wenn ich „Community-Feature“ sage, sage ich das ohne jegliche Verachtung. Wir haben den Code gelesen, eine Überprüfung durchgeführt, es sollte gut funktionieren.

* Ab 2020 gibt es eine ähnliche Unterstützung für RabbitMQ.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Was kann beim Einfügen von Daten sonst noch unangenehm oder unerwartet sein? Wenn Sie eine Abfrage zum Einfügen von Werten durchführen und einige berechnete Ausdrücke in Werte schreiben. now() ist beispielsweise auch ein ausgewerteter Ausdruck. Und in diesem Fall ist ClickHouse gezwungen, den Interpreter dieser Ausdrücke für jede Zeile zu starten, und die Leistung wird um Größenordnungen sinken. Es ist besser, es zu vermeiden.

* Im Moment ist das Problem vollständig gelöst, es gibt keine Leistungseinbußen mehr bei der Verwendung von Ausdrücken in VALUES.

Ein weiteres Beispiel, bei dem es zu Problemen kommen kann, ist, wenn Ihre Daten in einem Stapel zu mehreren Partitionen gehören. Standardmäßig partitioniert ClickHouse nach Monat. Und wenn Sie einen Stapel von einer Million Zeilen einfügen und Daten für mehrere Jahre vorhanden sind, dann haben Sie dort mehrere Dutzend Partitionen. Und das ist gleichbedeutend mit der Tatsache, dass es Chargen geben wird, die um ein Vielfaches kleiner sind, weil sie im Inneren immer zuerst in Partitionen unterteilt werden.

* Kürzlich wurde in ClickHouse im experimentellen Modus die Unterstützung für das kompakte Format von Chunks und Chunks im RAM mit Write-Ahead-Protokoll hinzugefügt, wodurch das Problem fast vollständig gelöst wird.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Betrachten Sie nun die zweite Art von Problem – die Datentypisierung.

Die Datentypisierung kann strikt sein und manchmal auch Zeichenfolgen. String – Dies ist der Zeitpunkt, an dem Sie gerade alle Felder vom Typ String genommen und deklariert haben. Es nervt. Das musst du nicht tun.

Lassen Sie uns herausfinden, wie wir es richtig machen, wenn Sie sagen möchten, wir hätten ein Feld, eine Zeichenfolge, und ClickHouse dies selbst herausfinden lassen möchte, aber ich werde kein Dampfbad nehmen. Aber es lohnt sich trotzdem, sich etwas anzustrengen.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Wir haben zum Beispiel eine IP-Adresse. In einem Fall haben wir es als Zeichenfolge gespeichert. Beispiel: 192.168.1.1. Andernfalls handelt es sich um eine Zahl vom Typ UInt32*. Für eine IPv32-Adresse reichen 4 Bit.

Erstens werden die Daten seltsamerweise ungefähr gleich komprimiert. Sicher wird es einen Unterschied geben, aber nicht so groß. Es gibt also keine besonderen Probleme mit der Festplatten-I/O.

Es gibt jedoch einen gravierenden Unterschied zwischen der CPU-Zeit und der Ausführungszeit der Abfrage.

Zählen wir die Anzahl der eindeutigen IP-Adressen, wenn diese als Zahlen gespeichert sind. Es ergeben sich 137 Millionen Zeilen pro Sekunde. Wenn dasselbe wie Zeilen, dann 37 Millionen Zeilen pro Sekunde. Ich weiß nicht, warum dieser Zufall passiert ist. Ich habe diese Anfragen selbst gestellt. Aber immerhin etwa viermal langsamer.

Und wenn Sie den Unterschied im Speicherplatz berechnen, dann gibt es auch einen Unterschied. Und der Unterschied beträgt etwa ein Viertel, da es ziemlich viele eindeutige IP-Adressen gibt. Und wenn es Zeilen mit einer kleinen Anzahl unterschiedlicher Werte gäbe, wären sie im Wörterbuch stillschweigend auf ungefähr das gleiche Volumen komprimiert worden.

Und der vierfache Zeitunterschied liegt nicht auf der Straße. Vielleicht ist es Ihnen natürlich egal, aber wenn ich einen solchen Unterschied sehe, bin ich traurig.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Betrachten wir verschiedene Fälle.

1. Ein Fall, in dem Sie nur wenige unterschiedliche eindeutige Werte haben. In diesem Fall verwenden wir eine einfache Vorgehensweise, die Sie wahrscheinlich kennen und für jedes DBMS anwenden können. Das alles macht nicht nur für ClickHouse Sinn. Schreiben Sie einfach die numerischen Bezeichner in die Datenbank. Und Sie können auf der Seite Ihrer Anwendung in Strings und zurück konvertieren.

Sie haben beispielsweise eine Region. Und Sie versuchen, es als Zeichenfolge zu speichern. Und dort wird geschrieben: Moskau und die Region Moskau. Und wenn ich sehe, dass dort „Moskau“ steht, dann ist das immer noch nichts, und wenn es MO ist, wird es irgendwie völlig traurig. So viele Bytes.

Stattdessen notieren wir einfach die Ulnt32-Nummer und 250. Wir haben 250 in Yandex, aber Ihre Nummer kann anders sein. Für alle Fälle möchte ich sagen, dass ClickHouse über eine integrierte Fähigkeit verfügt, mit einer Geobasis zu arbeiten. Sie schreiben einfach ein Verzeichnis mit Regionen, einschließlich eines hierarchischen Verzeichnisses, d. h. es wird Moskau, die Region Moskau und alles, was Sie brauchen, enthalten. Und Sie können auf Anfrageebene konvertieren.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Die zweite Option ist ungefähr gleich, jedoch mit Unterstützung innerhalb von ClickHouse. Es handelt sich um einen Enum-Datentyp. Sie schreiben einfach alle Werte, die Sie benötigen, in das Enum. Geben Sie beispielsweise den Gerätetyp ein und schreiben Sie dort: Desktop, Mobilgerät, Tablet, Fernseher. Nur 4 Optionen.

Der Nachteil besteht darin, dass Sie regelmäßig Änderungen vornehmen müssen. Es wurde nur eine Option hinzugefügt. Wir machen einen Altartisch. Tatsächlich ist die Änderung der Tabelle in ClickHouse kostenlos. Besonders kostenlos für Enum, da sich die Daten auf der Festplatte nicht ändern. Allerdings erhält alter eine Sperre * für die Tabelle und muss warten, bis alle Auswahlen abgeschlossen sind. Und erst nachdem diese Änderung durchgeführt wird, gibt es noch einige Unannehmlichkeiten.

* In neueren Versionen von ClickHouse ist ALTER vollständig nicht blockierend.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Eine weitere für ClickHouse einzigartige Möglichkeit ist die Anbindung externer Wörterbücher. Sie können Nummern in ClickHouse schreiben und Ihre Verzeichnisse in jedem für Sie geeigneten System speichern. Sie können beispielsweise Folgendes verwenden: MySQL, Mongo, Postgres. Sie können sogar Ihren eigenen Microservice erstellen, der diese Daten über http sendet. Und auf der ClickHouse-Ebene schreiben Sie eine Funktion, die diese Daten von Zahlen in Zeichenfolgen umwandelt.

Dies ist eine spezielle, aber sehr effiziente Möglichkeit, einen Join für eine externe Tabelle durchzuführen. Und es gibt zwei Möglichkeiten. Bei einer Option werden diese Daten vollständig zwischengespeichert, vollständig im RAM vorhanden und in bestimmten Abständen aktualisiert. Und wenn diese Daten nicht in den RAM passen, können Sie sie bei einer anderen Option teilweise zwischenspeichern.

Hier ist ein Beispiel. Es gibt Yandex.Direct. Und es gibt eine Werbefirma und Banner. Es gibt wahrscheinlich Dutzende Millionen Werbeunternehmen. Und ungefähr in den RAM passen. Und es gibt Milliarden Banner, die passen nicht. Und wir verwenden ein zwischengespeichertes Wörterbuch von MySQL.

Das einzige Problem besteht darin, dass das zwischengespeicherte Wörterbuch einwandfrei funktioniert, wenn die Trefferquote nahe bei 100 % liegt. Wenn es kleiner ist, müssen Sie bei der Verarbeitung von Anforderungen für jedes Datenpaket tatsächlich die fehlenden Schlüssel übernehmen und Daten von MySQL abrufen. Was ClickHouse betrifft, kann ich das immer noch garantieren – ja, es wird nicht langsamer, ich werde nicht über andere Systeme sprechen.

Und als Bonus sind Wörterbücher eine sehr einfache Möglichkeit, Daten in ClickHouse rückwirkend zu aktualisieren. Das heißt, Sie hatten einen Bericht über Werbefirmen, der Benutzer hat einfach die Werbefirma gewechselt und in allen alten Daten, in allen Berichten, haben sich diese Daten auch geändert. Wenn Sie Zeilen direkt in die Tabelle schreiben, können Sie diese nicht aktualisieren.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Eine andere Möglichkeit, wenn Sie nicht wissen, wo Sie die Bezeichner für Ihre Zeichenfolgen erhalten. Sie können einfach hashen. Und die einfachste Möglichkeit besteht darin, einen 64-Bit-Hash zu verwenden.

Das einzige Problem besteht darin, dass es bei einem 64-Bit-Hash mit ziemlicher Sicherheit zu Kollisionen kommt. Denn wenn es eine Milliarde Zeilen sind, dann wird die Wahrscheinlichkeit bereits greifbar.

Und es wäre nicht sehr sinnvoll, die Namen von Werbefirmen auf diese Weise zu hashen. Wenn die Werbekampagnen verschiedener Unternehmen durcheinander geraten, entsteht etwas Unverständliches.

Und es gibt einen einfachen Trick. Es ist zwar auch nicht sehr geeignet für seriöse Daten, aber wenn etwas nicht sehr seriös ist, dann fügen Sie einfach eine weitere Client-ID zum Wörterbuchschlüssel hinzu. Und dann kommt es zu Kollisionen, aber nur innerhalb eines Mandanten. Und wir verwenden diese Methode für die Link-Map in Yandex.Metrica. Wir haben dort URLs, wir speichern Hashes. Und wir wissen natürlich, dass es Konflikte gibt. Aber wenn eine Seite angezeigt wird, dann ist die Wahrscheinlichkeit, dass auf einer Seite für einen Benutzer einige URLs zusammenkleben und dies bemerkt wird, dann kann dies vernachlässigt werden.

Als Bonus reichen für viele Operationen nur Hashes aus und die Strings selbst können nirgendwo gespeichert werden.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Ein weiteres Beispiel für kurze Zeichenfolgen, z. B. Website-Domains. Sie können unverändert gespeichert werden. Oder zum Beispiel beträgt die Browsersprache ru 2 Bytes. Natürlich tun mir die Bytes leid, aber keine Sorge, 2 Bytes sind nicht schade. Bitte lassen Sie es so, wie es ist, keine Sorge.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Ein anderer Fall ist, wenn es im Gegenteil viele Zeichenfolgen und gleichzeitig viele eindeutige Zeichenfolgen gibt und sogar die Menge potenziell unbegrenzt ist. Ein typisches Beispiel sind Suchbegriffe oder URLs. Suchbegriffe, auch aufgrund von Tippfehlern. Mal sehen, wie viele eindeutige Suchphrasen pro Tag vorhanden sind. Und es stellt sich heraus, dass sie fast die Hälfte aller Ereignisse ausmachen. Und in diesem Fall denken Sie vielleicht, dass Sie die Daten normalisieren, die Bezeichner zählen und sie in eine separate Tabelle einfügen müssen. Aber das musst du nicht tun. Behalten Sie diese Zeilen einfach bei.

Besser – erfinden Sie nichts, denn wenn Sie es separat speichern, müssen Sie einen Join durchführen. Und dieser Join ist bestenfalls ein Direktzugriff auf den Speicher, sofern er noch in den Speicher passt. Wenn es nicht passt, wird es generell Probleme geben.

Und wenn die Daten an Ort und Stelle gespeichert sind, werden sie einfach in der richtigen Reihenfolge aus dem Dateisystem gelesen und alles ist gut.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Wenn Sie URLs oder eine andere komplexe lange Zeichenfolge haben, sollten Sie darüber nachdenken, dass Sie einen gewissen Squeeze im Voraus berechnen und in eine separate Spalte schreiben können.

Für URLs können Sie beispielsweise die Domain separat hinterlegen. Und wenn Sie wirklich eine Domain benötigen, dann verwenden Sie einfach diese Spalte, und die URLs werden lügen, und Sie werden sie nicht einmal berühren.

Mal sehen, was der Unterschied ist. ClickHouse verfügt über eine spezielle Funktion, die die Domain berechnet. Es ist sehr schnell, wir haben es optimiert. Und um ehrlich zu sein: Es entspricht nicht einmal dem RFC, berücksichtigt aber dennoch alles, was wir brauchen.

Und in einem Fall rufen wir einfach die URLs ab und berechnen die Domain. Es stellt sich heraus, dass es 166 Millisekunden sind. Und wenn Sie eine vorgefertigte Domain nehmen, sind es nur 67 Millisekunden, also fast dreimal schneller. Und schneller, nicht weil wir einige Berechnungen durchführen müssen, sondern weil wir weniger Daten lesen.

Aus irgendeinem Grund erhält eine langsamere Anfrage eine höhere Geschwindigkeit in Gigabyte pro Sekunde. Weil es mehr Gigabyte liest. Das sind völlig redundante Daten. Die Anfrage scheint schneller zu laufen, dauert aber länger.

Und wenn man sich die Datenmenge auf der Festplatte ansieht, stellt sich heraus, dass die URL 126 Megabyte groß ist und die Domain nur 5 Megabyte. Es fällt 25-mal weniger aus. Allerdings ist die Abfrage immer noch nur viermal schneller. Aber das liegt daran, dass die Daten heiß sind. Und wenn es kalt wäre, wäre es aufgrund der Festplatten-E/A wahrscheinlich 4-mal schneller.

Übrigens, wenn wir auswerten, wie viel weniger Domains als URLs haben, sind es etwa viermal weniger. Aus irgendeinem Grund werden jedoch 4-mal weniger Daten auf der Festplatte benötigt. Warum? Aufgrund der Komprimierung. Und die URL wird komprimiert, und die Domäne wird komprimiert. Aber oft enthält die URL eine Menge Müll.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Und natürlich lohnt es sich, die richtigen Datentypen zu verwenden, die speziell auf die richtigen Werte ausgelegt sind oder passen. Wenn Sie IPv4 verwenden, speichern Sie UInt32*. Wenn IPv6, dann FixedString(16), da eine IPv6-Adresse 128 Bit lang ist, also direkt im Binärformat gespeichert wird.

Was aber, wenn Sie manchmal IPv4-Adressen und manchmal IPv6 haben? Ja, Sie können beide behalten. Eine Spalte für IPv4, eine andere für IPv6. Natürlich besteht die Möglichkeit, IPv4 auf IPv6 abzubilden. Das wird auch funktionieren, aber wenn Sie in Ihren Anfragen häufig eine IPv4-Adresse benötigen, wäre es schön, diese in eine separate Spalte einzutragen.

* Jetzt verfügt ClickHouse über separate IPv4- und IPv6-Datentypen, die Daten genauso effizient speichern wie Zahlen, sie aber so bequem wie Zeichenfolgen darstellen.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Wichtig ist auch zu beachten, dass es sich lohnt, die Daten im Vorfeld vorzuverarbeiten. Beispielsweise kommen einige Rohprotokolle zu Ihnen. Und vielleicht sollten Sie sie nicht gleich in ClickHouse einfügen, obwohl es sehr verlockend ist, nichts zu tun und alles wird funktionieren. Dennoch lohnt es sich, die möglichen Berechnungen durchzuführen.

Zum Beispiel Browserversion. In irgendeiner benachbarten Abteilung, auf die ich nicht mit dem Finger zeigen möchte, ist die Browserversion dort so hinterlegt, also als String: 12.3. Und um dann einen Bericht zu erstellen, nehmen sie diese Zeichenfolge und dividieren durch ein Array und dann durch das erste Element des Arrays. Natürlich verlangsamt sich alles. Ich fragte, warum sie das tun. Sie sagten mir, dass sie eine vorzeitige Optimierung nicht mögen. Und ich mag keinen voreiligen Pessimismus.

In diesem Fall wäre es also richtiger, in 4 Spalten zu unterteilen. Haben Sie hier keine Angst, denn das ist ClickHouse. ClickHouse ist eine Spaltendatenbank. Und je mehr hübsche kleine Säulen, desto besser. Es wird 5 BrowserVersionen geben, 5 Spalten erstellen. Es ist in Ordnung.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Überlegen Sie nun, was zu tun ist, wenn Sie viele sehr lange Strings und sehr lange Arrays haben. Sie müssen überhaupt nicht in ClickHouse gespeichert werden. Stattdessen können Sie in ClickHouse nur einen bestimmten Bezeichner speichern. Und diese langen Schlangen drängen sie in ein anderes System.

Beispielsweise verfügt einer unserer Analysedienste über einige Ereignisparameter. Und wenn viele Parameter zu Ereignissen kommen, speichern wir einfach die ersten 512, die auftauchen. Denn 512 ist nicht schade.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Und wenn Sie sich nicht für Ihre Datentypen entscheiden können, können Sie Daten auch in ClickHouse schreiben, allerdings in eine temporäre Tabelle vom Typ Log, was speziell für temporäre Daten gilt. Anschließend können Sie analysieren, welche Werteverteilung Sie dort haben, was generell vorhanden ist und die richtigen Typen bilden.

* Jetzt hat ClickHouse einen Datentyp Niedrige Kardinalität Dadurch können Sie Saiten mit weniger Aufwand effizient speichern.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Betrachten wir nun einen weiteren interessanten Fall. Manchmal funktionieren die Dinge für Menschen auf seltsame Weise. Ich gehe und sehe mir das an. Und es scheint sofort, dass dies von einem sehr erfahrenen, klugen Administrator durchgeführt wurde, der über umfassende Erfahrung bei der Einrichtung von MySQL Version 3.23 verfügt.

Hier sehen wir tausend Tabellen, von denen jede den Rest der Division durch Tausend enthält. Es ist nicht klar, was.

Grundsätzlich respektiere ich die Erfahrung anderer Menschen, einschließlich des Verständnisses, welches Leid diese Erfahrung mit sich bringen kann.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Und die Gründe sind mehr oder weniger klar. Dabei handelt es sich um alte Klischees, die sich möglicherweise bei der Arbeit mit anderen Systemen angesammelt haben. MyISAM-Tabellen verfügen beispielsweise nicht über einen geclusterten Primärschlüssel. Und diese Art der Datenfreigabe kann ein verzweifelter Versuch sein, die gleiche Funktionalität zu erhalten.

Ein weiterer Grund besteht darin, dass es schwierig ist, Änderungsoperationen für große Tabellen durchzuführen. Alles wird blockiert. Obwohl dieses Problem in modernen Versionen von MySQL nicht mehr so ​​gravierend ist.

Oder zum Beispiel Microsharding, aber dazu später mehr.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

In ClickHouse ist dies nicht erforderlich, da zunächst der Primärschlüssel geclustert wird und die Daten nach dem Primärschlüssel sortiert werden.

Und manchmal fragen mich Leute: „Wie ändert sich die Leistung von Bereichsabfragen in ClickHouse mit der Größe der Tabelle?“ Ich sage, es ändert sich überhaupt nicht. Sie haben beispielsweise eine Tabelle mit einer Milliarde Zeilen und lesen einen Bereich von einer Million Zeilen. Alles ist gut. Wenn die Tabelle eine Billion Zeilen hat und Sie eine Million Zeilen lesen, ist es fast dasselbe.

Und zweitens sind keine Teile wie manuelle Partitionen erforderlich. Wenn Sie sich das Dateisystem ansehen, werden Sie feststellen, dass eine Tabelle eine ziemlich ernste Sache ist. Und da drinnen gibt es so etwas wie Trennwände. Das heißt, ClickHouse erledigt alles für Sie und Sie müssen nicht leiden.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Die Änderung in ClickHouse ist kostenlos, wenn Sie eine Spalte hinzufügen/löschen.

Und Sie sollten keine kleinen Tabellen erstellen, denn ob Ihre Tabelle 10 Zeilen oder 10 Zeilen enthält, spielt keine Rolle. ClickHouse ist ein System, das den Durchsatz und nicht die Latenz optimiert. Daher macht es keinen Sinn, 000 Zeilen zu verarbeiten.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Es ist richtig, einen großen Tisch zu verwenden. Befreien Sie sich von den alten Stereotypen, alles wird gut.

Und als Bonus haben wir in der neuesten Version die Möglichkeit, einen beliebigen Partitionierungsschlüssel zu erstellen, um alle möglichen Wartungsvorgänge an einzelnen Partitionen durchzuführen.

Beispielsweise benötigen Sie viele kleine Tabellen. Wenn beispielsweise einige Zwischendaten verarbeitet werden müssen, erhalten Sie Blöcke und müssen eine Transformation für diese durchführen, bevor Sie in die endgültige Tabelle schreiben. Für diesen Fall gibt es eine wunderbare Tabellen-Engine – StripeLog. Es ist wie TinyLog, nur besser.

* Jetzt hat ClickHouse mehr Tabellenfunktionseingabe.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Ein weiteres Anti-Pattern ist Microsharding. Sie müssen beispielsweise Daten teilen und haben 5 Server, und morgen werden es 6 Server sein. Und Sie überlegen, wie Sie diese Daten wieder ins Gleichgewicht bringen können. Und stattdessen teilen Sie nicht in 5 Shards, sondern in 1 Shards auf. Und dann ordnen Sie jeden dieser Microshards einem separaten Server zu. Und Sie werden beispielsweise auf einem Server erfolgreich sein, beispielsweise 000 ClickHouse. Separate Instanz auf separaten Ports oder separaten Datenbanken.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Aber in ClickHouse ist das nicht sehr gut. Denn bereits eine Instanz von ClickHouse versucht, alle verfügbaren Serverressourcen zu nutzen, um eine Anfrage zu bearbeiten. Das heißt, Sie haben eine Art Server und dort beispielsweise 56 Prozessorkerne. Sie führen eine Abfrage aus, die eine Sekunde dauert und 56 Kerne verwendet. Und wenn Sie dort 200 ClickHouses auf einem Server platzieren, dann werden 10 Threads gestartet. Im Allgemeinen wird alles sehr schlecht sein.

Ein weiterer Grund besteht darin, dass die Arbeitsverteilung auf diese Instanzen ungleichmäßig sein wird. Einige werden früher fertig sein, andere später. Wenn dies alles in einem einzigen Fall geschehen wäre, hätte ClickHouse selbst herausgefunden, wie die Daten korrekt auf die Streams verteilt werden.

Und ein weiterer Grund ist, dass die Kommunikation zwischen den Prozessoren über TCP erfolgt. Die Daten müssen serialisiert und deserialisiert werden, und das ist eine riesige Anzahl von Microshards. Es wird einfach nicht funktionieren.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Ein weiteres Antimuster, obwohl man es kaum als Antimuster bezeichnen kann. Dies ist eine große Menge an Voraggregation.

Im Allgemeinen ist die Voraggregation gut. Sie hatten eine Milliarde Zeilen, haben sie aggregiert und daraus wurden 1 Zeilen, und jetzt wird die Abfrage sofort ausgeführt. Alles ist ganz toll. So können Sie es machen. Und dafür verfügt sogar ClickHouse über einen speziellen Tabellentyp AggregatingMergeTree, der beim Einfügen von Daten eine inkrementelle Aggregation durchführt.

Aber es gibt Zeiten, in denen man denkt, dass wir Daten wie diese aggregieren und Daten wie diese aggregieren. Und in einigen benachbarten Abteilungen, ich möchte auch nicht sagen, welche, dort werden SummingMergeTree-Tabellen zum Summieren nach dem Primärschlüssel verwendet, und als Primärschlüssel werden 20 Spalten verwendet. Nur für den Fall, dass ich die Namen einiger Kolumnen aus Verschwörungsgründen geändert habe, aber das war’s auch schon.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Und solche Probleme entstehen. Erstens wird die Datenmenge, die Sie haben, nicht zu stark reduziert. Beispielsweise wird sie um das Dreifache reduziert. Dreimal wäre ein guter Preis, um sich die unbegrenzten Analysen leisten zu können, die mit nicht aggregierten Daten einhergehen. Wenn die Daten aggregiert werden, erhalten Sie statt Analysen nur miserable Statistiken.

Und was ist besonders gut? Dass diese Leute aus der nächsten Abteilung manchmal hingehen und darum bitten, dem Primärschlüssel eine weitere Spalte hinzuzufügen. Das heißt, wir haben die Daten so aggregiert, und jetzt wollen wir noch etwas mehr. In ClickHouse gibt es jedoch keinen alternativen Primärschlüssel. Daher müssen Sie einige Skripte in C++ schreiben. Und ich mag keine Skripte, selbst wenn sie in C++ sind.

Und wenn Sie sich ansehen, wofür ClickHouse geschaffen wurde, dann sind nicht aggregierte Daten genau das Szenario, für das es geboren wurde. Wenn Sie ClickHouse für nicht aggregierte Daten verwenden, machen Sie alles richtig. Wenn Sie aggregieren, ist das manchmal verzeihlich.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Ein weiterer interessanter Fall sind Anfragen in einer Endlosschleife. Manchmal gehe ich zu einem Produktionsserver und schaue mir dort die Prozessliste an. Und jedes Mal entdecke ich, dass etwas Schreckliches passiert.

Hier ist zum Beispiel das hier. Es ist sofort klar, dass alles in einer Anfrage erledigt werden konnte. Geben Sie einfach die URL und die Liste dort ein.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Warum sind viele solcher Anfragen in einer Endlosschleife schlecht? Wenn der Index nicht verwendet wird, müssen Sie viele Durchgänge mit denselben Daten durchführen. Wenn aber beispielsweise ein Index verwendet wird, hat man einen Primärschlüssel auf ru und schreibt dort url = irgendetwas. Und Sie denken, dass eine URL punktuell aus der Tabelle gelesen wird, alles wird gut. Aber wirklich nein. Weil ClickHouse alles stapelweise erledigt.

Wenn er einen bestimmten Datenbereich lesen muss, liest er etwas mehr, da der Index in ClickHouse spärlich ist. Mit diesem Index können Sie nicht eine einzelne Zeile in der Tabelle finden, sondern nur einen Bereich. Und die Daten werden in Blöcken komprimiert. Um eine Zeile zu lesen, müssen Sie den gesamten Block dekomprimieren. Und wenn Sie eine Reihe von Abfragen ausführen, werden Sie viele Schnittmengen davon haben und eine Menge Arbeit wird immer wieder erledigt.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Und als Bonus können Sie sehen, dass Sie in ClickHouse keine Angst haben sollten, sogar Megabyte und sogar Hunderte von Megabyte in den IN-Bereich zu übertragen. Ich erinnere mich aus unserer Praxis, dass, wenn wir beispielsweise in MySQL eine Reihe von Werten im IN-Abschnitt übergeben, wir dort 100 Megabyte einiger Zahlen übergeben, MySQL 10 Gigabyte Speicher verbraucht und nichts anderes passiert es funktioniert alles schlecht.

Und die zweite Sache ist, dass in ClickHouse Ihre Abfragen, wenn sie einen Index verwenden, immer nicht langsamer sind als ein vollständiger Scan, d. h. wenn Sie fast die gesamte Tabelle lesen müssen, wird die gesamte Tabelle nacheinander gelesen. Im Allgemeinen wird er es herausfinden.

Allerdings gibt es einige Schwierigkeiten. Beispielsweise verwendet IN mit einer Unterabfrage den Index nicht. Aber das ist unser Problem und wir müssen es lösen. Hier gibt es nichts Grundsätzliches. Lass es uns tun*.

Und eine weitere interessante Sache ist, dass, wenn Sie eine sehr lange Anfrage haben und eine verteilte Anfrageverarbeitung stattfindet, diese sehr lange Anfrage ohne Komprimierung an jeden Server gesendet wird. Zum Beispiel 100 Megabyte und 500 Server. Und dementsprechend werden 50 Gigabyte über das Netzwerk übertragen. Es wird übertragen und dann wird alles erfolgreich ausgeführt.

* wird bereits verwendet; Alles wurde wie versprochen repariert.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Und es ist durchaus üblich, dass die Anfragen von der API kommen. Sie haben zum Beispiel eine Dienstleistung erbracht. Und wenn jemand Ihren Service benötigt, dann haben Sie die API geöffnet und buchstäblich zwei Tage später sehen Sie, dass etwas Unverständliches passiert. Alles ist überlastet und es gehen schreckliche Anfragen ein, die es nie hätte geben dürfen.

Und es gibt nur eine Lösung. Wenn Sie die API geöffnet haben, müssen Sie sie ausschneiden. Zum Beispiel, um einige Quoten einzugeben. Es gibt keine anderen sinnvollen Optionen. Andernfalls schreiben sie sofort ein Skript und es gibt Probleme.

Und ClickHouse hat eine Besonderheit – die Berechnung von Quoten. Darüber hinaus können Sie Ihren Kontingentschlüssel übertragen. Dies ist beispielsweise eine interne Benutzer-ID. Und die Quoten werden für jeden von ihnen unabhängig berechnet.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Nun noch eine interessante Sache. Dies ist eine manuelle Replikation.

Ich kenne viele Fälle, in denen ClickHouse trotz integrierter Replikationsunterstützung manuell repliziert wird.

Was ist das Prinzip? Sie verfügen über eine Datenverarbeitungspipeline. Und es funktioniert unabhängig, beispielsweise in verschiedenen Rechenzentren. Sie schreiben sozusagen dieselben Daten auf die gleiche Weise in ClickHouse. Die Praxis zeigt zwar, dass die Daten aufgrund einiger Besonderheiten in Ihrem Code immer noch voneinander abweichen. Ich hoffe das bei dir.

Und von Zeit zu Zeit müssen Sie immer noch manuell synchronisieren. Beispielsweise führen Administratoren einmal im Monat rsync durch.

Tatsächlich ist es viel einfacher, die integrierte Replikation in ClickHouse zu verwenden. Es kann jedoch einige Kontraindikationen geben, da Sie hierfür ZooKeeper verwenden müssen. Ich werde nichts Schlechtes über ZooKeeper sagen, im Prinzip funktioniert das System, aber es kommt vor, dass Leute es aus Java-Phobie nicht verwenden, weil ClickHouse ein so gutes in C++ geschriebenes System ist, das Sie verwenden können und Alles wird gut. Und ZooKeeper in Java. Und irgendwie möchte man nicht einmal hinsehen, aber dann kann man die manuelle Replikation verwenden.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

ClickHouse ist ein praktisches System. Es berücksichtigt Ihre Bedürfnisse. Wenn Sie über eine manuelle Replikation verfügen, können Sie eine verteilte Tabelle erstellen, die Ihre manuellen Replikate überprüft und ein Failover zwischen ihnen durchführt. Und es gibt sogar eine spezielle Option, mit der Sie Flops vermeiden können, selbst wenn Ihre Linien systematisch divergieren.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Darüber hinaus kann es zu Problemen kommen, wenn Sie primitive Tabellen-Engines verwenden. ClickHouse ist ein solcher Konstruktor, der über eine Reihe verschiedener Tabellen-Engines verfügt. Für alle schwerwiegenden Fälle, wie in der Dokumentation beschrieben, verwenden Sie Tabellen der MergeTree-Familie. Und alles andere gilt sowohl für Einzelfälle als auch für Tests.

In einer MergeTree-Tabelle benötigen Sie kein Datum und keine Uhrzeit. Sie können es weiterhin verwenden. Wenn kein Datum und keine Uhrzeit vorhanden sind, schreiben Sie, dass der Standardwert 2000 ist. Es wird funktionieren und erfordert keine Ressourcen.

Und in der neuen Version des Servers können Sie sogar eine benutzerdefinierte Partitionierung ohne Partitionsschlüssel festlegen. Es wird das Gleiche sein.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Andererseits können primitive Tabellen-Engines verwendet werden. Geben Sie beispielsweise die Daten einmal ein und sehen, drehen und löschen Sie. Sie können Protokoll verwenden.

Oder die Speicherung kleiner Mengen zur Zwischenverarbeitung ist StripeLog oder TinyLog.

Speicher kann verwendet werden, wenn nur eine kleine Datenmenge vorhanden ist und einfach etwas im RAM verdreht wird.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

ClickHouse mag renormalisierte Daten nicht besonders.

Hier ist ein typisches Beispiel. Das ist eine riesige Anzahl von URLs. Sie tragen sie in die nebenstehende Tabelle ein. Und dann haben wir beschlossen, JOIN mit ihnen zu machen, aber das wird in der Regel nicht funktionieren, da ClickHouse nur Hash JOIN unterstützt. Wenn nicht genügend RAM für viele Daten zur Verbindung vorhanden ist, funktioniert JOIN nicht *.

Wenn die Daten eine hohe Kardinalität haben, machen Sie sich keine Sorgen, speichern Sie sie in denormalisierter Form. Die URLs sind direkt in der Haupttabelle vorhanden.

* und jetzt verfügt ClickHouse auch über einen Merge-Join, der auch unter Bedingungen funktioniert, bei denen die Zwischendaten nicht in den RAM passen. Dies ist jedoch wirkungslos und die Empfehlung behält ihre Gültigkeit.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Noch ein paar Beispiele, aber ich bezweifle bereits, ob es sich dabei um Anti-Patterns handelt oder nicht.

ClickHouse hat einen bekannten Nachteil. Er weiß nicht, wie man * aktualisiert. In gewisser Weise ist das sogar gut. Wenn Sie wichtige Daten haben, zum Beispiel aus der Buchhaltung, kann Ihnen niemand diese zusenden, da es keine Aktualisierungen gibt.

* Unterstützung für Aktualisierung und Löschung im Batch-Modus ist seit langem hinzugefügt.

Es gibt jedoch einige spezielle Möglichkeiten, die es ermöglichen, dass Updates im Hintergrund angezeigt werden. Zum Beispiel Tabellen vom Typ „ReplaceMergeTree“. Sie führen Aktualisierungen während Hintergrundzusammenführungen durch. Sie können dies mit der Funktion „Tabelle optimieren“ erzwingen. Tun Sie dies jedoch nicht zu oft, da dadurch die Partition vollständig überschrieben wird.

Verteilte JOINs in ClickHouse – auch dies wird vom Abfrageplaner schlecht gehandhabt.

Schlecht, aber manchmal ok.

Verwenden Sie ClickHouse nur zum Zurücklesen von Daten mit select*.

Ich würde ClickHouse nicht für umfangreiche Berechnungen empfehlen. Dies ist jedoch nicht ganz richtig, da wir uns bereits von dieser Empfehlung entfernen. Und wir haben kürzlich die Möglichkeit hinzugefügt, Modelle für maschinelles Lernen in ClickHouse – Catboost anzuwenden. Und es macht mir Sorgen, weil ich denke: „Was für ein Horror. So viele Zyklen pro Byte ergeben sich! Es ist schade für mich, Taktzyklen auf Bytes zu starten.

Effektiver Einsatz von ClickHouse. Alexey Milovidov (Yandex)

Aber keine Angst, installieren Sie ClickHouse, alles wird gut. Wenn überhaupt, dann haben wir eine Gemeinschaft. Die Community bist du übrigens. Und wenn Sie Probleme haben, können Sie zumindest unseren Chat besuchen, und ich hoffe, dass Ihnen geholfen wird.

Fragen

Danke für den Bericht! Wo kann man sich über den ClickHouse-Absturz beschweren?

Sie können sich jetzt persönlich bei mir beschweren.

Ich habe vor kurzem angefangen, ClickHouse zu verwenden. Die CLI-Schnittstelle wurde sofort entfernt.

Sie haben Glück gehabt.

Etwas später ließ ich den Server mit einem kleinen Select fallen.

Du hast Talent.

Ich habe einen GitHub-Bug geöffnet, der jedoch ignoriert wurde.

Wir werden sehen.

Aleksey hat mich dazu gebracht, dem Bericht beizuwohnen, indem er mir versprochen hat, mir zu sagen, wie Sie die darin enthaltenen Daten unterdrücken.

Ganz einfach.

Das ist mir gestern klar geworden. Weitere Einzelheiten.

Es gibt keine schrecklichen Tricks. Es handelt sich lediglich um eine Block-für-Block-Komprimierung. Der Standardwert ist LZ4, Sie können ZSTD* aktivieren. Blöcke von 64 Kilobyte bis 1 Megabyte.

* Es gibt auch Unterstützung für spezielle Komprimierungscodecs, die in Kette mit anderen Algorithmen verwendet werden können.

Sind die Blöcke nur Rohdaten?

Nicht gerade roh. Es gibt Arrays. Wenn Sie eine numerische Spalte haben, werden die Zahlen in einer Zeile in einem Array gestapelt.

Löschen.

Alexey, ein Beispiel, das mit uniqExact über IPs war, d. h. die Tatsache, dass uniqExact länger braucht, um nach Zeichenfolgen zu zählen als nach Zahlen, und so weiter. Was wäre, wenn wir im Moment des Korrekturlesens eine Finte mit unseren Ohren und unserem Wurf anwenden? Das heißt, Sie scheinen gesagt zu haben, dass es auf der Festplatte keine großen Unterschiede gibt. Wenn wir Zeilen von der Festplatte lesen und umwandeln, erhalten wir dann schnellere Aggregate oder nicht? Oder sind wir hier noch leicht auf dem Vormarsch? Es scheint mir, dass Sie es getestet haben, es aber aus irgendeinem Grund im Benchmark nicht angegeben haben.

Ich denke, es wird langsamer sein als keine Besetzung. In diesem Fall muss die IP-Adresse aus der Zeichenfolge geparst werden. Natürlich ist in ClickHouse auch das Parsen von IP-Adressen optimiert. Wir haben uns sehr viel Mühe gegeben, aber an der gleichen Stelle sind die Zahlen in Zehntausendstelform geschrieben. Sehr ungemütlich. Andererseits arbeitet die uniqExact-Funktion bei Strings langsamer, nicht nur weil es sich um Strings handelt, sondern auch weil eine andere Spezialisierung des Algorithmus gewählt wurde. Strings werden einfach anders gehandhabt.

Und wenn wir einen primitiveren Datentyp nehmen? Sie haben zum Beispiel die Benutzer-ID, die wir haben, aufgeschrieben, sie als Zeile aufgeschrieben und sie dann umgewandelt. Wird es mehr Spaß machen oder nicht?

Ich bezweifle. Ich denke, es wird noch trauriger sein, denn schließlich ist das Parsen von Zahlen ein ernstes Problem. Es scheint mir, dass dieser Kollege sogar einen Bericht darüber hatte, wie schwierig es ist, Zahlen in Zehntausendstelform zu analysieren, aber vielleicht auch nicht.

Alexey, vielen Dank für den Bericht! Und vielen Dank für ClickHouse! Ich habe eine Frage zu Plänen. Gibt es in den Plänen eine Funktion zur unvollständigen Aktualisierung von Wörterbüchern?

d.h. teilweiser Neustart?

Ja Ja. Wie zum Beispiel die Möglichkeit, dort ein MySQL-Feld festzulegen, d. h. danach zu aktualisieren, sodass nur diese Daten geladen werden, wenn das Wörterbuch sehr groß ist.

Sehr interessante Funktion. Und mir scheint, jemand hat es in unserem Chat vorgeschlagen. Vielleicht warst es sogar du.

Das glaube ich nicht.

Super, jetzt stellt sich heraus, dass es zwei Anfragen gibt. Und Sie können langsam damit beginnen. Ich möchte Sie jedoch sofort warnen, dass diese Funktion recht einfach zu implementieren ist. Das heißt, theoretisch müssen Sie nur die Versionsnummer in die Tabelle schreiben und dann schreiben: Die Version ist kleiner als diese und jene. Und das bedeutet, dass wir es höchstwahrscheinlich Enthusiasten anbieten werden. Sind Sie ein Enthusiast?

Ja, aber leider nicht in C++.

Können Ihre Kollegen in C++ schreiben?

Ich werde jemanden finden.

Großartig*.

* Die Funktion wurde zwei Monate nach dem Bericht hinzugefügt – sie wurde vom Autor der Frage entwickelt und von ihm eingereicht Pull-Anforderung.

Vielen Dank!

Guten Tag! Danke für den Bericht! Sie haben erwähnt, dass ClickHouse alle ihm zur Verfügung stehenden Ressourcen sehr gut nutzt. Und der Redner neben Luxoft erzählte von seiner Entscheidung für die Russische Post. Er sagte, dass ihnen ClickHouse wirklich gefiel, sie es jedoch nicht anstelle ihres Hauptkonkurrenten verwendeten, gerade weil es den gesamten Prozessor verschlang. Und sie konnten es nicht in ihre Architektur integrieren, in ihren ZooKeeper mit Hafenarbeitern. Ist es möglich, ClickHouse irgendwie einzuschränken, sodass es nicht alles verbraucht, was ihm zur Verfügung steht?

Ja, es ist möglich und ganz einfach. Wenn Sie weniger Kerne verbrauchen möchten, schreiben Sie einfach set max_threads = 1. Und das ist alles, die Anfrage wird in einem Kern ausgeführt. Darüber hinaus können Sie für verschiedene Benutzer unterschiedliche Einstellungen festlegen. Also kein Problem. Und sagen Sie Ihren Kollegen von Luxoft, dass es nicht gut ist, dass sie diese Einstellung nicht in der Dokumentation gefunden haben.

Alexey, hallo! Ich möchte diese Frage stellen. Dies ist nicht das erste Mal, dass ich höre, dass viele Leute anfangen, ClickHouse als Repository für Protokolle zu verwenden. Im Bericht haben Sie gesagt, dass Sie dies nicht tun sollen, das heißt, Sie müssen keine langen Schlangen speichern. Was denkst du darüber?

Erstens sind Protokolle normalerweise keine langen Zeilen. Es gibt natürlich Ausnahmen. Beispielsweise löst ein in Java geschriebener Dienst eine Ausnahme aus, die protokolliert wird. Und das in einer Endlosschleife, und der Speicherplatz auf der Festplatte geht zur Neige. Die Lösung ist ganz einfach. Wenn die Linien sehr lang sind, schneiden Sie sie ab. Was bedeutet lang? Zehn Kilobyte sind schlecht *.

* In neueren Versionen von ClickHouse ist die „adaptive Indexgranularität“ aktiviert, wodurch das Problem der Speicherung langer Zeichenfolgen größtenteils beseitigt wird.

Ist ein Kilobyte normal?

Es ist normal.

Guten Tag! Danke für den Bericht! Ich habe im Chat bereits danach gefragt, kann mich aber nicht erinnern, ob ich eine Antwort erhalten habe. Gibt es Pläne, den WITH-Bereich im CTE-Stil zu erweitern?

Noch nicht. Der WITH-Abschnitt ist etwas unseriös. Für uns ist es wie ein kleines Feature.

Ich habe verstanden. Danke!

Danke für den Bericht! Sehr interessant! globale Frage. Ist eine Änderung der Datenlöschung geplant, vielleicht in Form von Stubs?

Notwendig. Dies ist unsere erste Aufgabe in unserer Warteschlange. Wir denken jetzt aktiv darüber nach, wie wir alles richtig machen können. Und Sie sollten anfangen, die Tastatur* zu drücken.

* die Tasten auf der Tastatur gedrückt und alles war erledigt.

Wird es die Systemleistung irgendwie beeinträchtigen oder nicht? Wird die Einfügung so schnell sein wie jetzt?

Möglicherweise sind die Löschvorgänge selbst und die Aktualisierungen selbst sehr umfangreich, aber die Leistung von Auswahlen und Einfügungen wird dadurch in keiner Weise beeinträchtigt.

Und noch eine kleine Frage. Bei der Präsentation haben Sie über den Primärschlüssel gesprochen. Dementsprechend haben wir eine Partitionierung, die standardmäßig monatlich erfolgt, oder? Und wenn wir einen Datumsbereich festlegen, der in einen Monat passt, lesen wir nur diese Partition, oder?

Ja.

Eine Frage. Wenn wir keinen Primärschlüssel auswählen können, ist es dann richtig, dies genau nach dem Feld „Datum“ zu tun, damit im Hintergrund eine kleinere Umstrukturierung dieser Daten erfolgt, damit sie besser geordnet zusammenpassen? Wenn Sie keine Bereichsabfragen haben und nicht einmal einen Primärschlüssel auswählen können, lohnt es sich dann, ein Datum in den Primärschlüssel einzugeben?

Ja.

Möglicherweise ist es sinnvoll, in den Primärschlüssel ein Feld einzufügen, nach dem die Daten besser komprimiert werden, wenn sie nach diesem Feld sortiert werden. Zum Beispiel Benutzer-ID. Der Benutzer geht beispielsweise auf dieselbe Site. Geben Sie in diesem Fall die Benutzer-ID und die Uhrzeit ein. Und dann werden Ihre Daten besser komprimiert. Was das Datum betrifft: Wenn Sie wirklich keine Bereichsabfragen für Datumsangaben haben und nie haben, können Sie das Datum nicht in den Primärschlüssel einfügen.

Okay, vielen Dank!

Source: habr.com

Kommentar hinzufügen