Wie wir bei Sportmaster das Caching-System ausgewÀhlt haben. Teil 1

Hallo! Ich bin Alexey Pjankov, ein Entwickler bei Sportmaster. In diesem haben wir erlĂ€utert, wie wir standardisierte Kundenvirtualmaschinen vorbereiten, und am Beispiel unseres neuen Tarifs Ultralight fĂŒr 120 Rubel gezeigt, wie wir ein standardmĂ€ĂŸiges Abbild von Windows Server 2019 Core erstellt haben. Bericht habe ich erzĂ€hlt, wie die Arbeit an der Sportmaster-Website im Jahr 2012 begann, welche Initiativen wir erfolgreich durchsetzen konnten und welche Herausforderungen wir bewĂ€ltigt haben.

Heute möchte ich meine Gedanken zu einem anderen Thema teilen – der Auswahl eines Caching-Systems fĂŒr das Java-Backend im Admin-Bereich der Website. Dieses Thema liegt mir besonders am Herzen – obwohl die Geschichte nur 2 Monate dauerte, haben wir in diesen 60 Tagen 12-16 Stunden am Tag ohne einen einzigen freien Tag gearbeitet. Ich hĂ€tte nie gedacht, dass man so viel arbeiten kann.

Deshalb teile ich den Text in 2 Teile auf, um es nicht zu ĂŒberladen. Im Gegenteil, der erste Teil wird sehr leicht sein – eine Vorbereitung, eine EinfĂŒhrung und einige Überlegungen zum Thema Caching. Wenn Sie bereits ein erfahrener Entwickler sind oder mit Caches gearbeitet haben, wird es in diesem Artikel aus technischer Sicht wahrscheinlich nichts Neues geben. FĂŒr einen Junior könnte jedoch eine kleine Übersicht hilfreich sein, in welche Richtung man schauen sollte, falls man an einem solchen Scheideweg steht.

Wie wir bei Sportmaster das Caching-System ausgewÀhlt haben. Teil 1

Als die neue Version der Sportmaster-Website in die Produktion ging, war der Datenfluss, um es vorsichtig auszudrĂŒcken, alles andere als ideal. Die Grundlage bildeten Tabellen, die fĂŒr die vorherige Website-Version (Bitrix) erstellt wurden. Diese mussten in das ETL-System integriert, an das neue Format angepasst und mit verschiedenen zusĂ€tzlichen Informationen aus einer Handvoll anderer Systeme angereichert werden. Um sicherzustellen, dass ein neues Bild oder eine Produktbeschreibung auf der Website erscheint, musste man bis zum nĂ€chsten Tag warten — die Aktualisierungen fanden nur nachts einmal tĂ€glich statt.

Anfangs gab es in den ersten Wochen nach dem Produktionsstart so viele Herausforderungen, dass die Unannehmlichkeiten der Content-Manager eher nebensĂ€chlich waren. Doch sobald sich alles stabilisierte, entwickelte sich das Projekt weiter – Anfang 2015 begannen wir aktiv an der AdministrationsoberflĂ€che zu arbeiten. In den Jahren 2015 und 2016 lief alles gut, wir veröffentlichten regelmĂ€ĂŸig Updates, die Admin-OberflĂ€che umfasste zunehmend mehr Bereiche der Datenaufbereitung, und wir bereiteten uns darauf vor, bald das Wichtigste und Schwierigste zu ĂŒbernehmen – die Produktlinie (komplette Vorbereitung und Verwaltung der Daten fĂŒr alle Produkte). Doch im Sommer 2017, kurz vor dem Start der Produktlinie, befand sich das Projekt in einer sehr schwierigen Lage – gerade wegen Problemen mit dem Caching. Über diesen Vorfall möchte ich im zweiten Teil dieser zweiteiligen Veröffentlichung berichten.

In diesem Beitrag möchte ich jedoch von ganz hinten anfangen und einige Gedanken zur Vorstellung vom Caching zusammenfassen, die vor einem großen Projekt im Voraus hilfreich gewesen wĂ€ren.

Wenn die Aufgabe des Cachings entsteht

Caching-Probleme tauchen nicht einfach so auf. Wir sind Entwickler, die Softwareprodukte erstellen, und wir möchten, dass diese gefragt sind. Wenn das Produkt gefragt und erfolgreich ist, kommen die Nutzer. Immer mehr Nutzer. Und wenn die Nutzerzahl stark ansteigt, wird das Produkt hochbelastet.

In den frĂŒhen Phasen denken wir nicht ĂŒber Code-Optimierung und Leistung nach. Das Wichtigste ist die FunktionalitĂ€t, das schnelle Bereitstellen eines Prototyps und die ÜberprĂŒfung von Hypothesen. Wenn die Last steigt, verbessern wir die Hardware. Wir verdoppeln, verdreifachen, verzehnfachen die Ressourcen. Irgendwo hier wird das Budget nicht mehr mitspielen. Und um wie viel wird die Anzahl der Nutzer steigen? Es wird nicht nur 2-5-10 sein, sondern im Erfolgsfall von 100 bis 1000 und bis zu 100.000. Das heißt, irgendwann wird es unumgĂ€nglich sein, sich intensiv mit der Optimierung zu befassen.

Nehmen wir an, ein bestimmter Teil des Codes (wir nennen ihn Funktion) benötigt unverhĂ€ltnismĂ€ĂŸig lange, und wir möchten die AusfĂŒhrungszeit verkĂŒrzen. Eine Funktion kann der Datenbankzugriff sein oder die AusfĂŒhrung komplexer Logik – entscheidend ist, dass die AusfĂŒhrung lange dauert. Wie viel kann die AusfĂŒhrungszeit verkĂŒrzt werden? Im besten Fall – sie kann bis auf null reduziert werden, nicht weiter. Und wie kann man die AusfĂŒhrungszeit auf null reduzieren? Antwort: Indem man die AusfĂŒhrung vollstĂ€ndig ausschließt. Stattdessen – geben Sie sofort das Ergebnis zurĂŒck. Aber wie bekommt man das Ergebnis? Antwort: Entweder berechnen oder irgendwo nachsehen. Berechnen ist zeitaufwĂ€ndig. Nachsehen hingegen bedeutet zum Beispiel, das Ergebnis zu speichern, das die Funktion beim letzten Aufruf mit denselben Parametern geliefert hat.

Das bedeutet, dass die Implementierung der Funktion fĂŒr uns nicht entscheidend ist. Es reicht aus, die Parameter zu kennen, von denen das Ergebnis abhĂ€ngt. Wenn wir dann die Werte der Parameter in einem Objekt darstellen, das als SchlĂŒssel in einem Speicher verwendet werden kann, können wir das Berechnungsergebnis speichern und bei der nĂ€chsten Abfrage abrufen. Wenn diese Speicherung und Abfrage schneller erfolgt als die AusfĂŒhrung der Funktion, erzielen wir einen Geschwindigkeitsvorteil. Der Vorteil kann bis zu 100, 1000 oder sogar 100.000-fach (10^5 – dies ist eher die Ausnahme, aber im Fall einer stark verzögerten Datenbank durchaus möglich) betragen.

Die grundlegenden Anforderungen an ein Caching-System

Die erste Anforderung an ein Caching-System ist die schnelle Lesegeschwindigkeit, und in etwas geringerem Maße die Schreibgeschwindigkeit. Das ist so, aber nur bis wir das System in die Produktion bringen.

Lassen Sie uns einen solchen Fall durchspielen.

Angenommen, wir haben die aktuelle Belastung mit entsprechender Hardware gedeckt und fĂŒhren nun schrittweise Caching ein. Die Nutzerzahl steigt allmĂ€hlich, die Last wĂ€chst – wir fĂŒgen einige Caches hinzu und integrieren sie hier und da. So verlĂ€uft es eine Zeit lang, und schon werden die ressourcenintensiven Funktionen kaum noch aufgerufen – die gesamte Hauptlast liegt auf dem Cache. In dieser Zeit ist die Nutzeranzahl um das N-Fache gestiegen.

Und wenn das anfĂ€ngliche Hardware-Setup vielleicht das 2- bis 5-Fache ausmachen konnte, so konnten wir mit Hilfe des Caching die Leistung um das 10-Fache steigern oder im besten Fall sogar um das 100-Fache, in einigen FĂ€llen möglicherweise sogar um das 1000-Fache. Das heißt, mit derselben Hardware verarbeiten wir 100-mal mehr Anfragen. Großartig, das haben wir verdient!

Doch nun, eines schönen Tages, gab das System zufĂ€llig den Geist auf und der Cache fiel aus. Nichts Außergewöhnliches – schließlich hatten wir den Cache mit dem Kriterium „hohe Lese- und Schreibgeschwindigkeit, alles andere ist unwichtig“ ausgewĂ€hlt.

Im Hinblick auf die anfĂ€ngliche Last verfĂŒgten wir ĂŒber eine Hardwarereserve von 2-5 Mal, wĂ€hrend die Last in der Zwischenzeit auf das 10- bis 100-Fache gestiegen ist. Mithilfe des Caches konnten wir die Aufrufe fĂŒr rechenintensive Funktionen vermeiden, sodass alles reibungslos lief. Aber jetzt, ohne Cache – um wie viel wird unser System einbrechen? Was wird mit uns geschehen? Das System wird ausfallen.

Selbst wenn unser Cache nicht abgestĂŒrzt ist, sondern nur vorĂŒbergehend geleert wurde, muss er wieder aufgeheizt werden, und das wird einige Zeit in Anspruch nehmen. WĂ€hrend dieser Zeit wird die Hauptlast auf die FunktionalitĂ€t fallen.

Fazit: Hochbelastete Projekte in der Produktion erfordern von einem Systemspeicher nicht nur hohe Lese- und Schreibgeschwindigkeiten, sondern auch Datensicherung und Ausfallsicherheit.

Die Qual der Wahl

Im Projekt mit dem Admin-Bereich stellte sich die Auswahl so dar: Zuerst setzten wir Hazelcast ein, da wir bereits durch die Erfahrungen mit der Hauptseite mit diesem Produkt vertraut waren. Doch diese Wahl stellte sich als nicht gĂŒnstig heraus – unter unserem Lastprofil arbeitet Hazelcast nicht nur langsam, sondern schrecklich langsam. Zu diesem Zeitpunkt hatten wir bereits einen Termin fĂŒr den Produktionsstart festgelegt.

Spoiler: Ich werde im zweiten Teil erzĂ€hlen, wie es zu den UmstĂ€nden kam, dass wir so eine Pleite erlebt haben und uns in eine schwierige und angespannte Situation gebracht haben – und wie wir da herausgekommen sind. Aber jetzt kann ich nur sagen, dass es ein großer Stress war, und ‚denken – geht irgendwie nicht, wir schĂŒtteln die Flasche‘. ‚Wir schĂŒtteln die Flasche‘ ist auch ein Spoiler, dazu spĂ€ter mehr.

Was wir gemacht haben:

  1. Wir erstellen eine Liste aller Systeme, die Google und StackOverflow vorschlagen. Etwas mehr als 30.
  2. Wir schreiben Tests mit der fĂŒr die Produktion typischen Last. DafĂŒr haben wir Daten erfasst, die im Produktionsumfeld durch das System laufen – eine Art Sniffer fĂŒr Daten, die nicht im Netzwerk, sondern innerhalb des Systems sind. In die Tests haben wir genau diese Daten eingesetzt.
  3. Das gesamte Team wĂ€hlt nacheinander das nĂ€chste System aus der Liste aus, konfiguriert es und fĂŒhrt die Tests durch. Wenn der Test nicht besteht und die Last nicht trĂ€gt – werfen wir es weg und gehen zum nĂ€chsten in der Reihe.
  4. Beim 17. System wurde klar, dass alles hoffnungslos war. Genug mit dem ‚Flasche schĂŒtteln‘, es ist Zeit, ernsthaft nachzudenken.

Aber das ist eine Option, wenn man ein System auswĂ€hlen muss, das in bereits durchgefĂŒhrten Tests hinsichtlich Geschwindigkeit "besteht". Und wenn es noch keine solchen Tests gibt und man möchte etwas Schnelleres wĂ€hlen?

Lass uns dieses Szenario durchspielen (es ist schwer vorstellbar, dass ein mittelmĂ€ĂŸiger Entwickler in einem Vakuum lebt und zu dem Zeitpunkt der Auswahl noch keine PrĂ€ferenz geĂ€ußert hat, welches Produkt er als erstes ausprobieren möchte – daher handelt es sich bei den weiteren Überlegungen eher um theoretische Überlegungen/philosophische Betrachtungen ĂŒber Junioren).

Sobald wir uns ĂŒber die Anforderungen einig sind, beginnen wir mit der Auswahl einer fertigen Lösung. Warum das Rad neu erfinden: wir greifen auf ein bestehendes Caching-System zurĂŒck.

Wenn Sie gerade erst anfangen und googeln, wird es mehr oder weniger in dieser Reihenfolge sein, aber insgesamt werden die Anhaltspunkte wie folgt aussehen. ZunĂ€chst werden Sie auf Redis stoßen, das ist in aller Munde. Dann erfahren Sie, dass es EhCache gibt, das als eines der Ă€ltesten und bewĂ€hrtesten Systeme gilt. Danach wird ĂŒber Tarantool geschrieben – eine heimische Entwicklung, die einen einzigartigen Aspekt der Lösung bietet. Und auch Ignite, da es derzeit an PopularitĂ€t gewinnt und von SberTech unterstĂŒtzt wird. Am Ende kommt noch Hazelcast, da es in der Enterprise-Welt hĂ€ufig in großen Unternehmen auftaucht.

Diese Liste ist nicht abschließend; es gibt Dutzende von Systemen. Wir betrachten lediglich eines davon. Nehmen wir die fĂŒnf ausgewĂ€hlten Systeme zum „Schönheitswettbewerb“ und fĂŒhren eine Auswahl durch. Wer wird der Gewinner sein?

Redis

Lassen Sie uns lesen, was auf der offiziellen Website steht.
Redis — ein Open-Source-Projekt. Es bietet ein In-Memory-Datenbankspeicher, die Möglichkeit zum Speichern auf Festplatte, automatische Partitionierung, hohe VerfĂŒgbarkeit und Wiederherstellung nach Netzwerkunterbrechungen.

Scheint alles großartig zu sein, man könnte es einfach verwenden – es erfĂŒllt alle Anforderungen. Aber lassen Sie uns der VollstĂ€ndigkeit halber auch die anderen Kandidaten betrachten.

EhCache

EhCache — "der am hĂ€ufigsten verwendete Cache fĂŒr Java" (Übersetzung des Slogans von der offiziellen Website). Auch Open-Source. Hier erkennen wir, dass Redis nicht fĂŒr Java gedacht ist, sondern allgemein, und zur Interaktion ein Wrapper erforderlich ist. EhCache ist dabei handlicher. Was verspricht dieses System noch? ZuverlĂ€ssigkeit, Erprobtheit, volle FunktionalitĂ€t. Und es ist das am weitesten verbreitete System. Es cached Terabytes an Daten.

Redis ist vergessen, ich bin bereit, EhCache zu wÀhlen.

Aber mein Patriotismus drÀngt mich, zu schauen, was Tarantool zu bieten hat.

Tarantool

Tarantool — wird mit dem Begriff „Echtzeit-Datenintegrationsplattform“ bezeichnet. Klingt komplex, also lesen wir die Seite grĂŒndlich und stoßen auf die kĂŒhne Behauptung: „Caching von 100 % der Daten im Arbeitsspeicher“. Das sollte Fragen aufwerfen — denn es könnte deutlich mehr Daten geben als Speicher. Die Interpretation hier ist, dass Tarantool beim Schreiben von Daten auf die Festplatte aus dem Speicher keine Serialisierung durchfĂŒhrt. Stattdessen nutzt es die niedrigstufigen Eigenschaften des Systems, bei denen der Speicher einfach auf das Dateisystem abgebildet wird, was hervorragende I/O-Leistungen bietet. Insgesamt haben sie das bemerkenswert und großartig gemacht.

Schauen wir uns die Implementierungen an: Mail.ru Unternehmensnetzwerk, Avito, Beeline, Megafon, Alfa-Bank, Gazprom


Wenn ich noch irgendwelche Zweifel an Tarantool hatte, zerstreitet der Implementierungsfall bei Mastercard meine letzten Bedenken. Ich wÀhle Tarantool.

Aber letztendlich


Ignite


 gibt es noch weitere Ignite, angegeben als „in-memory Rechenplattform
 in-memory Geschwindigkeiten bei Petabytes von Daten“. Hier gibt es viele Vorteile: verteilte in-memory Caches, das schnellste Key-Value-Speichersystem und Cache, horizontale Skalierung, hohe VerfĂŒgbarkeit, strenge Konsistenz. Insgesamt ist Ignite also das schnellste.

Implementierungen: Sberbank, American Airlines, Yahoo! Japan. Und dann erfahre ich, dass Ignite nicht nur bei Sberbank implementiert ist, sondern dass das SberTech-Team eigene Leute in das Ignite-Team entsendet, um das Produkt weiterzuentwickeln. Das ĂŒberzeugt mich vollkommen und ich bin bereit, Ignite zu wĂ€hlen.

Ganz unklar, warum, schaue ich mir den fĂŒnften Punkt an.

Hazelcast

Ich besuche die Website Hazelcast, lese. Und es stellt sich heraus, dass die schnellste Lösung fĂŒr verteiltes Caching – das ist Hazelcast. Es ist um ein Vielfaches schneller als alle anderen Lösungen und generell ist es der MarktfĂŒhrer im Bereich in-memory Data Grid. Vor diesem Hintergrund etwas anderes zu wĂ€hlen – wĂ€re sich nicht wertzuschĂ€tzen. Außerdem nutzt es redundante Datenspeicherung, um den Cluster kontinuierlich ohne Datenverluste zu betreiben.

Das war's, ich bin bereit, Hazelcast zu wÀhlen.

Der Vergleich

Doch wenn man genau hinsieht, dann sind alle fĂŒnf Kandidaten so dargestellt, dass jeder von ihnen der Beste ist. Wie wĂ€hlt man aus? Wir können schauen, welcher am beliebtesten ist, Vergleiche suchen, und der Kopfweh wird verschwinden.

Wir finden einen solchen Testbericht, wÀhlen unsere 5 Systeme aus.

Wie wir bei Sportmaster das Caching-System ausgewÀhlt haben. Teil 1

Hier sind sie sortiert: an erster Stelle Redis, an zweiter Stelle — Hazelcast, wĂ€hrend Tarantool und Ignite an PopularitĂ€t gewinnen, bleibt EhCache wie es war.

Aber schauen wir uns die Berechnungsmethode: Links zu Websites, allgemeines Interesse an dem System, Stellenangebote — großartig! Das heißt, wenn mein System ausfĂ€llt, sage ich: „Nein, es ist doch zuverlĂ€ssig! Da gibt es viele Stellenangebote...“. Ein so einfacher Vergleich eignet sich nicht.

All diese Systeme sind nicht nur Caching-Systeme. Sie haben auch viel mehr FunktionalitĂ€t, einschließlich der Tatsache, dass nicht die Daten an den Kunden zur Verarbeitung ĂŒbertragen werden, sondern umgekehrt: der Code, der auf den Daten ausgefĂŒhrt werden muss, wird auf den Server ĂŒbertragen, dort ausgefĂŒhrt und das Ergebnis zurĂŒckgegeben. Und als separates Caching-System werden sie nicht allzu oft betrachtet.

Gut, wir geben nicht auf und suchen nach einem direkten Vergleich der Systeme. Wir nehmen die zwei besten Optionen — Redis und Hazelcast. Uns interessiert die Geschwindigkeit, nach diesem Kriterium vergleichen wir sie.

Hz vs Redis

Wir finden das Folgende heraus. Vergleich:
Wie wir bei Sportmaster das Caching-System ausgewÀhlt haben. Teil 1

Blau steht fĂŒr Redis, Rot fĂŒr Hazelcast. Hazelcast hat in allen Aspekten die Nase vorn und hier gibt es einen guten Grund: Es ist Multithreading-fĂ€hig und hochoptimiert, wobei jeder Thread mit seiner eigenen Partition arbeitet, was zu keiner Blockierung fĂŒhrt. Redis hingegen ist ein Single-Thread-System und kann von modernen Mehrkern-CPUs nicht profitieren. Hazelcast nutzt asynchrones I/O, wĂ€hrend Redis-Jedis blockierende Sockets verwendet. Außerdem verwendet Hazelcast ein binĂ€res Protokoll, wĂ€hrend Redis textbasiert ist, was es ineffizient macht.

Zur Sicherheit schauen wir uns eine weitere Vergleichsquelle an. Was wird uns das zeigen?

Redis vs Hz

Noch ein weiterer Vergleich. Vergleich:
Wie wir bei Sportmaster das Caching-System ausgewÀhlt haben. Teil 1

Hier ist es umgekehrt, Rot steht fĂŒr Redis. Das bedeutet, dass Redis in Bezug auf die Leistung Hazelcast ĂŒbertrifft. Im ersten Vergleich war Hazelcast ĂŒberlegen, im zweiten hingegen Redis. Hier wird klar erklĂ€rt, warum Hazelcast im vorherigen Vergleich gewonnen hat. Es stellt sich heraus, dass das Ergebnis des ersten Vergleichs praktisch manipuliert wurde: Redis wurde in der Basisversion getestet, wĂ€hrend Hazelcast auf den Testfall optimiert wurde. Das fĂŒhrt uns zu der Erkenntnis: Erstens, niemandem kann man trauen, und zweitens, wenn wir uns schließlich fĂŒr ein System entscheiden, mĂŒssen wir es richtig konfigurieren. Diese Einstellungen bestehen aus Dutzenden, fast Hunderten von Parametern.

SchĂŒtteln wir die Flasche.

ĐąŃ€ŃŃĐ”ĐŒ Đ±ŃƒŃ‚Ń‹Đ»Đșу

Und den gesamten Prozess, den wir gerade durchlaufen haben, kann ich mit der Metapher "Die Flasche schĂŒtteln" erklĂ€ren. Das bedeutet, dass man jetzt nicht unbedingt programmieren muss; das Wichtigste ist, Stack Overflow lesen zu können. In meinem Team gibt es einen Profi, der genau so in kritischen Momenten arbeitet.

Was macht er? Er sieht ein defektes GerĂ€t, erkennt den Stacktrace, nimmt einige Wörter daraus (welche genau – das ist seine Expertise in der Software), sucht bei Google und findet unter den Antworten Stack Overflow. Ohne zu lesen oder darĂŒber nachzudenken, wĂ€hlt er etwas, das dem Satz „Das und das tun“ am Ă€hnlichsten ist (diese Auswahl ist sein Talent, denn es ist nicht immer die Antwort mit den meisten Likes), wendet es an und sieht: Wenn sich etwas geĂ€ndert hat, ist das großartig. Wenn sich nichts geĂ€ndert hat – zurĂŒcksetzen. Und wir wiederholen Start-Test-Suche. Auf diese intuitive Weise schafft er es, dass der Code nach einer Weile funktioniert. Er weiß nicht warum, er weiß nicht, was er gemacht hat, kann es nicht erklĂ€ren. Aber! Das Ding funktioniert. Und „das Feuer ist gelöscht“. Jetzt klĂ€ren wir, was wir gemacht haben. Wenn das Programm lĂ€uft, ist es um ein Vielfaches einfacher. Und es spart erheblich Zeit.

Diese Methode lÀsst sich sehr gut durch folgendes Beispiel erklÀren.

Es war einmal sehr populĂ€r, ein Segelschiff in einer Flasche zu bauen. Dabei ist das Segelschiff groß und zerbrechlich, wĂ€hrend der Flaschenhals sehr schmal ist, man kann es nicht einfach reinstecken. Wie baut man es also zusammen?

Wie wir bei Sportmaster das Caching-System ausgewÀhlt haben. Teil 1

Es gibt eine Methode, die sehr schnell und Ă€ußerst effektiv ist.

Ein Schiff besteht aus vielen kleinen Teilen: Sticks, SchnĂŒren, Segeln und Kleber. All dies legen wir in eine Flasche.
Wir nehmen die Flasche mit beiden HĂ€nden und beginnen zu schĂŒtteln. Wir schĂŒtteln sie und schĂŒtteln sie. Und normalerweise – es wird natĂŒrlich nichts Gescheites dabei herauskommen. Aber manchmal. Manchmal wird es ein Schiff! Genauer gesagt, etwas, das wie ein Schiff aussieht.

Wir zeigen dieses Etwas jemandem: „Siehst du, Serjoga!?“. Und wirklich, aus der Ferne sieht es fast wie ein Schiff aus. Aber weiter darf man es nicht lassen.

Es gibt auch eine andere Möglichkeit. Es verwenden Leute, die fortgeschrittener sind, so genannte Hacker.

Habe einem Typen eine Aufgabe gegeben, er hat alles erledigt und ist gegangen. Und man sieht – es scheint erledigt zu sein. Aber nach einer Weile, wenn man den Code nachbessern muss – da fĂ€ngt das Durcheinander wegen ihm an... Gut, dass er sich schon weit genug entfernt hat. Das sind solche Typen, die an einem Beispiel mit der Flasche Folgendes machen: Seht ihr, wo der Boden ist – das Glas biegt sich. Und es ist nicht ganz klar, ob es durchsichtig ist oder nicht. Dann schneiden die „Hacker“ diesen Boden ab, stecken das Schiff hinein, kleben den Boden wieder fest, und es sieht so aus, als wĂ€re es so gedacht.

Aus der Sicht der Aufgabenstellung scheint alles korrekt zu sein. Doch nehmen wir als Beispiel Schiffe: Warum sollte man ĂŒberhaupt dieses Schiff bauen, wer braucht es wirklich? Es hat keine FunktionalitĂ€t. Solche Schiffe sind normalerweise Geschenke an hochrangige Persönlichkeiten, die es als ein Symbol, eine Art Zeichen, auf einem Regal ausstellen. Und wenn ein solcher Mensch, der Chef eines großen Unternehmens oder ein hochrangiger Beamter, ein solches Werk als Flaggschiff hat, bei dem der Hals abgeschnitten ist? Es wĂ€re besser, wenn er niemals davon erfĂ€hrt. Aber wie werden schließlich diese Schiffe hergestellt, die man einer wichtigen Person schenken kann?

Der einzige Punkt, mit dem man wirklich nichts anfangen kann, ist der Rumpf. Und der Rumpf des Schiffes passt genau durch den Flaschenhals. WĂ€hrend das Schiff außerhalb der Flasche zusammengebaut wird. Aber es ist nicht nur eine Frage des Zusammenbaus; es ist ein echtes Kunsthandwerk. In die einzelnen Teile werden spezielle Hebel integriert, die es ermöglichen, sie spĂ€ter anzuheben. Zum Beispiel werden die Segel zusammengelegt, sorgfĂ€ltig hineingeschoben, und dann werden sie mit einer Pinzette Ă€ußerst prĂ€zise angehoben und positioniert. Am Ende entsteht ein Kunstwerk, das man mit reinem Gewissen und Stolz verschenken kann.

Und wenn wir wollen, dass das Projekt erfolgreich ist, sollte im Team mindestens eine Person wie ein Juwelier sein. Jemand, der sich um die QualitĂ€t des Produkts kĂŒmmert und alle Aspekte berĂŒcksichtigt, ohne in stressigen Momenten, in denen die UmstĂ€nde dringendes Handeln erfordern, auf wichtige Dinge zu verzichten. Alle erfolgreichen Projekte, die Bestand haben und die Zeit ĂŒberstehen, basieren auf diesem Prinzip. In ihnen gibt es etwas sehr PrĂ€zises und Einzigartiges, etwas, das alle verfĂŒgbaren Möglichkeiten nutzt. Im Beispiel des Schiffs in der Flasche wird illustriert, wie der Rumpf des Schiffs durch den Hals passt.

ZurĂŒck zu der Aufgabe, unseren Caching-Server auszuwĂ€hlen: Wie könnte man diese Methode anwenden? Ich schlage vor, die Systeme, die es gibt, so auszuwĂ€hlen, dass wir die Flasche nicht schĂŒtteln, sondern darauf achten, was prinzipiell darin vorhanden ist, worauf wir bei der Auswahl des Systems achten sollten.

Wo nach EngpÀssen suchen?

Wir versuchen, die Flasche nicht zu schĂŒtteln und alles der Reihe nach zu durchzugehen. Stattdessen schauen wir, welche Aufgaben sich ergeben, wenn wir eigenstĂ€ndig solch ein System entwerfen. Wir werden natĂŒrlich kein Fahrrad neu erfinden, sondern nutzen dieses Schema, um uns zu orientieren, auf welche Aspekte wir in den Produktbeschreibungen achten sollten. Lassen Sie uns so ein Schema entwerfen.

Wie wir bei Sportmaster das Caching-System ausgewÀhlt haben. Teil 1

Wenn das System verteilt ist, bedeutet das, dass wir mehrere Server haben werden (6). Angenommen, wir haben vier (das lĂ€sst sich bequem auf dem Bild darstellen, aber es können natĂŒrlich beliebig viele sein). Wenn die Server auf verschiedenen Knoten sind, lĂ€uft auf ihnen allen ein gewisser Code, der sicherstellt, dass diese Knoten ein Cluster bilden und sich im Falle einer Unterbrechung wieder verbinden und einander erkennen.

ZusĂ€tzlich benötigen wir die Logik (2), die sich mit dem Caching befasst. Dieser Code interagiert ĂŒber eine bestimmte API mit den Clients. Der Client-Code (1) kann sowohl innerhalb derselben JVM als auch ĂŒber das Netzwerk darauf zugreifen. Die interne Logik besteht darin, zu entscheiden, welche Objekte im Cache bleiben und welche entfernt werden. Wir verwenden den Speicher (3) zur Speicherung des Caches, aber je nach Bedarf können wir auch einen Teil der Daten auf der Festplatte speichern (4).

Lassen Sie uns untersuchen, in welchen Bereichen die Last entstehen wird. Im Grunde genommen werden jede Verbindung und jeder Knoten belastet. Erstens kann es, wenn die Kommunikation zwischen dem Client-Code und der API erfolgt und wenn diese Netzwerkinteraktionen beinhaltet, zu merklichen Verzögerungen kommen. Zweitens, innerhalb der API selbst – wenn wir zu komplexe Logik implementieren, könnten wir an die CPU-Grenzen stoßen. Es wĂ€re gut, wenn die Logik nicht unnötig auf den Arbeitsspeicher zugreift. Und schließlich bleibt die Interaktion mit dem Dateisystem – normalerweise bedeutet dies, dass wir Daten serialisieren/wiederherstellen und schreiben/lesen mĂŒssen.

Als NĂ€chstes betrachten wir die Interaktion mit dem Cluster. Höchstwahrscheinlich wird er im selben System sein, es könnte aber auch separat sein. Auch hier muss die DatenĂŒbertragung zu ihm, die Geschwindigkeit der Datenserialisierung und die Interaktion zwischen dem Cluster berĂŒcksichtigt werden.

Jetzt können wir einerseits visualisieren, „welche ZahnrĂ€der sich im Cache-System drehen“ wĂ€hrend die Anfragen von unserem Code verarbeitet werden, und andererseits können wir abschĂ€tzen, welche und wie viele Anfragen unser Code an dieses System generieren wird. Das ist ausreichend, um eine mehr oder weniger fundierte Entscheidung zu treffen – um ein System entsprechend unserem Anwendungsfall auszuwĂ€hlen.

Hazelcast

Schauen wir uns an, wie diese Struktur auf unsere Liste angewendet werden kann. Zum Beispiel Hazelcast.

Um Daten in Hazelcast zu speichern oder abzurufen, greift der Client-Code (1) auf die API zu. Hz ermöglicht es, den Server als Embedded zu starten, und in diesem Fall ist der Zugriff auf die API ein Methodenausruf innerhalb der JVM, was als kostenlos betrachtet werden kann.

Damit die Logik in (2) funktioniert, stĂŒtzt sich Hz auf den Hash des byte-Arrays des serialisierten SchlĂŒssels – das heißt, die Serialisierung des SchlĂŒssels findet in jedem Fall statt. Dies ist ein unvermeidlicher Overhead fĂŒr Hz.
Die Eviction-Strategien sind gut implementiert, aber fĂŒr spezielle FĂ€lle können eigene Strategien hinzugefĂŒgt werden. Um diesen Teil muss man sich keine Sorgen machen.

Der Speicher (4) kann angeschlossen werden. Hervorragend. Die Interaktion (5) fĂŒr Embedded kann als sofort betrachtet werden. Der Datenaustausch zwischen den Knoten im Cluster (6) – ja, der findet statt. Dies trĂ€gt zur Redundanz bei, jedoch auf Kosten der Geschwindigkeit. Die Hz-Funktion Near-cache ermöglicht es, dass Daten, die von anderen Knoten im Cluster erhalten werden, zwischengespeichert werden.

Was kann in solchen Situationen zur Geschwindigkeitssteigerung getan werden?

Um die Serialisierung des SchlĂŒssels in (2) zu vermeiden, könnte man ĂŒber Hazelcast einen weiteren Cache fĂŒr die heißesten Daten anbringen. Bei Sportmaster haben wir dafĂŒr Caffeine ausgewĂ€hlt.

FĂŒr die Anpassung auf Ebene (6) werden in Hz zwei Speichertypen angeboten: IMap und ReplicatedMap.
Wie wir bei Sportmaster das Caching-System ausgewÀhlt haben. Teil 1

Es ist erwÀhnenswert, wie Hazelcast in den Technologie-Stack von Sportmaster integriert wurde.

Im Jahr 2012, als wir an dem ersten Prototyp der zukĂŒnftigen Website arbeiteten, war Hazelcast der erste Link, den die Suchmaschine anzeigte. Der Kontakt entstand 'auf Anhieb' – wir waren begeistert, dass es nur zwei Stunden dauerte, bis wir Hz ins System integriert hatten – es funktionierte. Und es funktionierte gut. Bis zum Ende des Tages schrieben wir einige Tests und waren zufrieden. Und dieser Schwung reichte aus, um die Herausforderungen zu meistern, die Hz im Laufe der Zeit brachte. Jetzt gibt es fĂŒr das Sportmaster-Team keinen Grund, auf Hazelcast zu verzichten.

Aber Argumente wie 'der erste Link in der Suchmaschine' und 'schnell HelloWorld erstellt' sind natĂŒrlich Ausnahmen und besondere UmstĂ€nde, die die Auswahl beeinflussten. Die wirklichen PrĂŒfungen fĂŒr das gewĂ€hlte System beginnen mit der MarkteinfĂŒhrung, und genau auf diese Phase sollte man achten, wenn man ein System, einschließlich Caches, wĂ€hlt. In unserem Fall kann man sagen, dass wir Hazelcast zufĂ€llig ausgewĂ€hlt haben, sich aber spĂ€ter herausstellte, dass die Wahl die richtige war.

FĂŒr Produktionsumgebungen sind folgende Punkte viel wichtiger: Monitoring, Fehlerbehandlung an einzelnen Knoten, Datenreplikation und Skalierungskosten. Es gilt, auf die Herausforderungen zu achten, die speziell bei der Systemwartung auftreten – wenn die Last um ein Vielfaches die geplante Belastung ĂŒbersteigt, wenn versehentlich falsche Daten hochgeladen werden und wenn es notwendig ist, eine neue Version des Codes auszurollen, Daten zu ersetzen und dies unbemerkt fĂŒr die Kunden zu erledigen.

FĂŒr all diese Anforderungen ist Hazelcast zweifellos geeignet.

Fortsetzung folgt

Aber Hazelcast ist keine Universallösung. Im Jahr 2017 wĂ€hlten wir Hazelcast fĂŒr den Cache im Admin-Bereich, einfach basierend auf unseren positiven Erfahrungen aus der Vergangenheit. Dies war entscheidend fĂŒr einen sehr bösartigen Scherz, der uns in eine schwierige Lage brachte, aus der wir uns „heldenhaft“ in 60 Tagen herausarbeiteten. Doch mehr dazu im nĂ€chsten Teil.

Und bis dahin
 Happy New Code!

Quelle: habr.com

Kaufen Sie zuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz, VPS VDS-Server đŸ”„ Kaufen Sie zuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster