Hallo! Ich bin Alexey Pjankov, ein Entwickler bei Sportmaster. In diesem 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.
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:
- Wir erstellen eine Liste aller Systeme, die Google und StackOverflow vorschlagen. Etwas mehr als 30.
- 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.
- 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.
- 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.
â 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
â "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
â 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 , 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 , 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 , wÀhlen unsere 5 Systeme aus.

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 : 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. :

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. :

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. 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?

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.

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.

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
