Actionbase – die Datenbank für Likes, „Zuletzt angesehen“ und Follows
(github.com/kakao)Wir haben Actionbase, eine Datenbank für Likes, zuletzt angesehene Produkte und Follow-Funktionen, als Open Source veröffentlicht.
Hallo, ich bin ein Entwickler bei Kakao und arbeite mit am Aufbau von Actionbase.
Gestern Abend um 20 Uhr (am 27.) haben wir Actionbase auf Hacker News (Show HN) gepostet, und rund 1 Stunde und 30 Minuten nach der Veröffentlichung stand es auf Platz 1 der Startseite. Eigentlich war unser Ziel nur, uns auf der Startseite zu halten, aber die Resonanz war besser als erwartet.
Warum haben wir es gebaut?
Funktionen wie Likes, zuletzt angesehene Produkte oder Follows sehen je nach Service etwas unterschiedlich aus, aber man baut immer wieder ähnliche Datenstrukturen und Verarbeitungslogiken.
Das Problem ist, dass jedes Team Vorwärts-/Rückwärtslisten, Zähler und Indizes etwas anders implementiert. Auch Retry-Mechanismen und die Verarbeitung der Ereignisreihenfolge unterscheiden sich, wodurch Daten leicht auseinanderlaufen konnten. Selbst die Art, aggregierte Daten wie die Anzahl von Likes zu erzeugen, war unterschiedlich, was den Betrieb erschwerte.
Wie funktioniert es?
Actionbase definiert das als Beziehungsmodell nach dem Muster wer (actor) was (target) wie getan hat (action) und berechnet beim Schreiben alles im Voraus. Das Lesen ist dadurch nur noch eine einfache Abfrage und entsprechend schnell und vorhersehbar.
Einsatz in Production
Der erste Production-Einsatz war die KakaoTalk Gift Wish-Funktion. Damals gab es noch viele Schwächen, aber um die Erwartungen zu erfüllen, haben wir vieles verbessert, und diese Erfahrung hat das Projekt maßgeblich vorangebracht.
Inzwischen verarbeitet das System in mehreren Kakao-Services seit Jahren mehr als 1 Million Requests pro Minute. Das Storage basiert auf HBase, und um verschiedene Größenordnungen abzudecken, ist auch ein leichtgewichtiges Storage (auf Basis von SlateDB) in Vorbereitung.
Einstieg
Mit Docker kann man es direkt ausprobieren:
docker run -it ghcr.io/kakao/actionbase:standalone
- 📦 GitHub: https://github.com/kakao/actionbase
- 🚀 Quick Start: https://actionbase.io/quick-start/
Fragen, Feedback und Stars sind jederzeit willkommen.
Q&A
Q: Geht das nicht auch mit Redis?
Doch, das geht. Wir selbst nutzen Redis auch als Cache für Hot Data. Mit wachsender Skalierung hatten wir jedoch das Problem, dass Teams Dinge doppelt implementierten und Daten durch durcheinandergeratene Ereignisreihenfolgen inkonsistent wurden.
Q: Reicht nicht Sharding mit PostgreSQL/MySQL?
Viele Teams machen genau das. Die Probleme, die wir erlebt haben, waren Hot Entities, Cross-Shard-Abfragen und serviceabhängige Caching-Strategien. Wir brauchten ein Modell, das horizontal skaliert, ohne jedes Mal eine neue Sharding-Strategie entwerfen zu müssen.
Q: Wie funktioniert Write-time Precompute?
Zum Zeitpunkt des Schreibens läuft: WAL schreiben → Lock → Zustandsübergang → Zähler/Index berechnen → speichern → CDC publizieren. Beim Lesen genügt dann ein einzelnes GET oder SCAN.
Q: Was passiert, wenn die Ereignisreihenfolge durcheinandergerät?
Jede Mutation bekommt eine Version mit, in der Regel einen Zeitstempel. Selbst wenn Ereignisse in der Reihenfolge like(t=100) → like(t=300) → unlike(t=200) eintreffen, konvergiert der Endzustand anhand der Version korrekt. Ziel ist, dass selbst beim Replay desselben Ereignisses derselbe Zustand entsteht.
Q: Wie ist die tatsächliche Performance?
In der KakaoTalk-Gift-Production werden dauerhaft mehr als 1 Million Requests pro Minute verarbeitet, bei Spitzenwerten von etwa 2 Millionen. Die Leselatenz liegt bei p50 etwa 2–3 ms, p99 etwa 10 ms. Entscheidend ist weniger die absolute Zahl als die Tatsache, dass die Latenz bounded ist. Da Reads vorberechnete Lookups statt Aggregationen sind, verschlechtert sich die Performance auch bei wachsendem Datenvolumen nicht.
Q: Für welche Use Cases ist es geeignet?
Likes/Reactions, Follow/Follower und zuletzt angesehene Produkte sind die zentralen Use Cases. Für Recommendation/ML-Features kann über CDC Trainingsdaten bereitgestellt werden, aber Recommendation-Serving selbst ist nicht das Ziel. Für Chat-Nachrichten ist es vermutlich nicht die beste Wahl, weil dort andere Zugriffsmuster wie Pagination, Suche und Threading nötig sind. Auch für E-Commerce-Carts ist es nicht ideal, da dort Transaktionen gebraucht werden und Actionbase keine Cross-Edge-Transaktionen unterstützt.
Q: Ist das nicht Overengineering? / Braucht man das nicht nur in großen Unternehmen?
Das kann gut sein. Ehrlich gesagt ist bei kleinerem Maßstab ein gut abgestimmtes PostgreSQL + Redis oft die richtige Antwort. Die Probleme, die Actionbase löst – Sharding-Komplexität, Cache-Invalidierung und teamübergreifende Doppelarbeit – treten meist erst bei erheblicher Größenordnung oder dann auf, wenn mehrere Teams ähnliche Funktionen bauen. Wir haben diese Grenze mehrfach erreicht, deshalb haben wir es entwickelt. Deshalb bereiten wir auch ein leichtgewichtiges Backend (SlateDB) vor, damit es ebenso in kleineren Deployments nutzbar ist.
24 Kommentare
Ohhh … ich freue mich auch schon auf eine Lightweight-Backend-Version!!
Vielen Dank! Für das Lightweight-Backend habe ich die Richtung bereits auf eine auf SlateDB basierende Lösung festgelegt, für die nur S3 benötigt wird, aber ich konnte damit noch nicht richtig anfangen.
Darf ich fragen, in welcher Umgebung Sie es einsetzen möchten? Ein Side-Projekt? Eine kleine Produktionsumgebung? Ich würde das gern als Referenz für die Priorisierung nutzen.
Wenn Sie Zeit haben, stimmen Sie bitte auch für HBase/SlateDB ab. Das Feedback der Community dürfte hilfreich sein, um die Richtung festzulegen: https://github.com/kakao/actionbase/discussions/144
Ich halte das für ein äußerst praktisches Projekt.
Großartig!
Vielen Dank! Hier kann ich offenbar das Interesse nachholen, das ich bei Show HN nicht bekommen habe.
Mich würde interessieren, was Sie als praktisch empfunden haben. Hatten Sie schon einmal ein ähnliches Problem? Oder befinden Sie sich in einer Situation, in der Sie diese Funktionalität implementieren müssen?
Und weil ich jetzt die Gelegenheit habe, einen Kommentar zu hinterlassen, möchte ich noch etwas sagen. In der Dokumentation steht, dass wir keine unbounded traversal unterstützen, aber bounded multi-hop steht für dieses Jahr auf dem Plan. Also 2-Hop-Abfragen wie „Produkte, die Freunden gefallen“. https://actionbase.io/ko/stories/unified-graph/
Was ich daran praktisch fand, ist,
[dass] ich mir darüber selbst schon einmal ähnliche Gedanken gemacht habe und sogar auf Basis eines KV-Stores wie Redis eine Abstraktionsschicht auf Code-Ebene implementiert habe; deshalb halte ich sowohl das Ziel und die Stoßrichtung, die das Dokument vermitteln will, als auch den gesamten Aufbau für sehr praxisnah.
Außerdem finde ich es großartig, dass daraus unter Berücksichtigung der Anforderungen und Herausforderungen mehrerer Teams ein internes Produkt des Unternehmens entstanden ist und dieses als Open Source veröffentlicht wurde.
Und wenn ich noch unbedingt etwas ergänzen dürfte: Für alle, die es verwenden wollen, reicht die aktuelle Dokumentation zwar schon aus, aber ich denke, es wäre noch attraktiver, wenn Bereitstellungsbeispiele zum einfachen Nachmachen auf Copy-and-paste-Niveau sowie empfohlene Anwendungsfälle oder Infrastruktur-Referenzen als Beispiele eingearbeitet würden.
Viel Erfolg!
Oh, es freut mich wirklich sehr, dass Sie sich mit denselben Fragen beschäftigt haben. Und vielen Dank von Herzen dafür, dass Sie es als großartig bezeichnet haben.
Ich kann Ihren Punkt gut nachvollziehen. Auch ich möchte die Teile, die ich nur als Werkzeug nutze, bequem aufsetzen und mich auf die Probleme konzentrieren, die ich selbst lösen muss.
Allerdings befindet sich das Open-Source-Projekt derzeit noch in einer frühen Phase, und ich habe mich darauf konzentriert, wie ich diesen zentralen Wert mit begrenzter Zeit vermitteln kann. Wenn das nicht gelingt, werden auch diejenigen, die reale Probleme damit lösen könnten, dazu nicht in der Lage sein. Jetzt möchte ich in die von Ihnen genannte Richtung weitergehen. Ich würde jedoch gern Feedback dazu bekommen, ob wir mit dem internen Stack HBase + Kafka gehen sollten oder trotz zusätzlichem Entwicklungsaufwand eher mit SlateDB + S2. Bei uns betreiben HBase-Ingenieure das System, sodass wir es bequem nutzen können, aber an vielen anderen Orten ist das wohl nicht so. Ich wäre Ihnen für eine Meinung dankbar (notfalls auch nur per Vote):
https://github.com/kakao/actionbase/discussions/144
Ich finde auch Roadmaps wie die erwähnte 2-Hop-Query sehr attraktiv,
aber ich glaube, wenn man die Aussage der vorhandenen Dokumentation mit codeartigen Beispielen gut herausarbeitet, würde das eine deutlich stärkere Resonanz auslösen.
Da stimme ich zu: „Es ist gut, in Beispiele eingebettet zu sein.“ Aber das ist wohl doch nicht so einfach, wie es aussieht ... Ich werde aus verschiedenen Blickwinkeln darüber nachdenken. Vielen Dank!
Darf ich fragen, ob Sie sich den interaktiven Leitfaden angesehen haben, den unser Kollege mit großem Einsatz vorbereitet hat? https://actionbase.io/guides/build-your-social-media-app/ Das war ein solcher Versuch. Das bringt mich dazu, noch einmal zu prüfen, ob er der von Ihnen genannten Richtung entspricht. Wir werden uns weiter bemühen.
Ach, und noch ein Punkt, den ich beim neuen Kommentar übersehen habe: Man merkt, dass nicht nur in die Anleitungen, sondern insgesamt in die Struktur der Dokumentation viel Arbeit geflossen ist.
Allerdings fände ich es noch besser, wenn sich die als Beispiele vorbereitete Konfiguration, wie bereits erwähnt, per
git cloneleicht nachvollziehen ließe.Ich werde zusammen mit dem folgenden Kommentar antworten.
Ich dachte, ich hätte dazu schon einen Kommentar geschrieben, aber er war nicht zu sehen, also schreibe ich alles noch einmal von Anfang an ... (schnief)
Vielen Dank, dass Sie so aufmerksam und ausführlich geantwortet haben, obwohl mein Kommentar eher locker dahingeschrieben war. haha;;
Jedenfalls wollte ich sagen, dass die Umgebungen kleiner Teams, die so etwas einführen möchten, und großer Teams jeweils sehr unterschiedlich sein dürften. Wenn man also eher unverbindlich denkt: „Sollen wir das mal einführen?“, dann ist meiner Meinung nach die am leichtesten zu vermittelnde Form ein Beispielprojekt, das in der im Team verwendeten Sprache geschrieben ist.
Wenn man zunächst Beispielprojekte in den gängigen Sprachen erstellt und darauf aufbauend einen Schnellstart anbietet, kann man sich das viel unbefangener anschauen, und ich finde den Reiz groß, es einfach per
git clonekurz anzutesten.Außerdem denke ich, dass sich auf diese Weise Best Practices am besten erklären lassen.
Natürlich ist mir bewusst, dass das aufgrund der Besonderheiten des Projekts nicht einfach umzusetzen sein dürfte, aber trotzdem halte ich das für den attraktivsten Ansatz.
Und wenn möglich, wäre es noch besser, die Beispiele zusammen mit Tools wie pulumi oder terraform aufzubauen.
Das ist ein Blickwinkel, an den ich überhaupt nicht gedacht hatte. Vielen Dank für diesen Vorschlag. So etwas ist wirklich eine wertvolle Erfahrung, die man aus der Community gewinnen kann.
Ich werde mir Gedanken darüber machen, wie sich die von Ihnen genannte Richtung umsetzen lässt. Auch Beispiele für pulumi oder terraform. Vielleicht können wir die Ausrichtung ordnen und die Community um Unterstützung bitten. Wenn Sie dann etwas beitragen würden, wäre ich Ihnen umso dankbarer.
Außerdem denke ich darüber nach, wie wir im Zeitalter des Vibe Coding zur Grundlage dafür werden können. Wenn man sagt: "Erstelle mir eine Anwendung", wird sie mit React, Svelte usw. geschrieben. Genau diese Position. Gemeint ist eine Situation, in der Actionbase diese Rolle übernimmt, wenn man sagt: "Füge eine Like-Funktion hinzu".
Auch dieser Punkt geht mir weiterhin durch den Kopf. Deshalb habe ich viel Wert auf eine Dokumentation gelegt, die von AI-Tools gelesen werden kann, und sehe darin zuletzt ebenfalls Potenzial.
Referenz:
llms.txt - https://actionbase.io/llms-txt/
Versuch mit dem Rezept des Anthropic-Hackathon-Gewinners - https://github.com/kakao/actionbase/discussions/90
Ich denke, dass sich das an Orten mit einem ähnlichen Use Case gut einsetzen lässt. Vielen Dank, dass Sie es veröffentlicht haben!
Mich würde allerdings interessieren, ob es bei dem Teil, in dem bei der Ingestion Locks verwendet werden, keine Probleme gab. Wie hoch war der Traffic beim Schreiben der Daten ungefähr? Gab es Fälle, in denen Lock-Contention oder Ähnliches zu Problemen geführt hat?
Vielen Dank für die wertvolle Frage!
Locks werden auf Ebene des Edge-Paars
(source, target)gesetzt (z. B. Alice→Phone). Konkurrenz entsteht nur, wenn gleichzeitig auf dieselbe Edge geschrieben wird. In der Praxis kommt es jedoch kaum vor, dass ein Nutzer gleichzeitig für dasselbe Objekt ein Like setzt, daher ist die Konfliktrate niedrig. Das ist eine Besonderheit unseres Datenbank-Use-Cases.Der Write-Traffic liegt in Spitzenzeiten bei mehreren Hunderttausend Vorgängen pro Minute. Es gibt 1 Million+ Lesezugriffe, und die Zahl der Schreibzugriffe liegt darunter.
Benchmark-Referenz (85 % Lesen, 15 % Schreiben) - https://actionbase.io/ko/operations/benchmarks/
Bei Hot-Entitäten (beliebte Produkte usw.) kann es zu Lock-Konflikten kommen, und zwar wegen der Count-Aktualisierung (
HBase Increment). Diesen Teil optimieren und verarbeiten wir separat. Zu häufigen Schreibvorgängen: https://actionbase.io/ko/stories/kakaotalk-gift-recent-views/Oh.....
Vielen Dank! Wenn Sie interessiert sind, hinterlassen Sie bitte auch Ihre Meinung zur nächsten Richtung: https://github.com/kakao/actionbase/discussions/144
Wow, ich glaube, das wird extrem nützlich sein.
Vielen Dank! Mich würde interessieren, ob ihr bei der Umsetzung ähnlicher Funktionen auf Probleme gestoßen seid. Wir holen gerade Feedback aus der Community dazu ein, womit wir als Nächstes anfangen sollen: https://github.com/kakao/actionbase/discussions/144
Die Entwicklerdokumentation ist wirklich sehr gut geschrieben. Die als Stories präsentierten Use Cases, der Schnellstart und die FAQ waren so gehaltvoll, dass sie fast das Niveau eines technischen Blogs hatten.
Wow, vielen Dank. Von der Open-Source-Veröffentlichung am 5. Januar bis zur Community-Veröffentlichung am 27. haben wir viel Arbeit in die Dokumentation gesteckt, daher freue ich mich, dass das wahrgenommen wird.
Da es noch die frühe Phase von Open Source ist, haben wir uns darauf konzentriert, „was das ist und warum man es braucht“, und ich denke, so ist dieses Ergebnis entstanden. Wenn Ihnen beim Lesen der Dokumentation etwas fehlt oder Sie etwas schade finden, sagen Sie bitte ganz unkompliziert Bescheid!
Übrigens könnten Sie mit https://actionbase.io/llms-txt/ Ergebnisse erzielen, an die Sie gar nicht gedacht haben. Kürzlich habe ich gesehen, wie jemand, der Actionbase kaum kannte, mit diesem Prompt bei komplexen Anforderungen zur optimalen Schlussfolgerung gelangt ist, und da wurde mir wieder bewusst, wie sehr sich die Welt verändert hat.
Probieren Sie in ChatGPT, Claude, Gemini usw. Folgendes aus.
Das ist verständlicherweise verdächtig. Aber es ist kein Fake.
Ich habe im ersten Kommentar vier Links eingefügt und wurde dann für 30 Minuten shadowgebannt. In der Zeit war die Kontext-Erklärung nicht sichtbar, also sind die Leute einfach weitergegangen. In dem Moment war ich wirklich nervös. Ich hatte Angst, dass es untergeht. Nachdem ich die Links entfernt und den Kommentar erneut gepostet hatte, stieg er erst dann auf Platz 1, und es kamen auch Antworten darauf.
Den Kommentator, den Sie erwähnt haben, habe ich auch überprüft. Dass er noch nicht lange angemeldet ist. Trotzdem war ich dankbar. Es gab zumindest eine Reaktion. Deshalb habe ich sorgfältig geantwortet. "why not redis?" Darauf war ich vorbereitet. Das ist die Frage, die bei DB-Themen garantiert kommt. Ich dachte: Ich habe mich doch so ernsthaft vorbereitet — würde wirklich so eine Frage kommen? Aber am Vortag bei
s2-streamstorehabe ich es gemerkt. Da kam die Antwort: "Warum nicht über TCP?" Also habe ich mich vorbereitet.Übrigens habe ich unsere Teammitglieder ausdrücklich gebeten, auf keinen Fall Upvotes zu geben oder Kommentare zu schreiben. Ich habe sie sogar gebeten, sich auszuloggen, damit nicht versehentlich etwas passiert. Ich wusste im Voraus, dass HN bei so etwas empfindlich ist.
Wie auch immer, vielleicht glauben Sie mir selbst mit dieser Erklärung nicht ... Bitte schauen Sie sich einfach einmal unser Repo an. Das ist der Code, der überlebt hat. Ich schreibe das so ausführlich, weil ich nicht möchte, dass die Kolleginnen und Kollegen, die daran mitgearbeitet haben, durch diesen Beitrag verletzt werden. https://github.com/kakao/actionbase/discussions/32 Bitte schauen Sie es sich einmal an. Danke.
Und auch
https://actionbase.io/ko/stories/kakaotalk-gift-wish/ . Falls Sie sich schon einmal mit großen Systemen beschäftigt haben, könnte der Inhalt hilfreich sein; ich habe ihn mit großer Sorgfalt geschrieben.
Ach ja, und wie ihr unten auf meinem X sehen könnt: Platz 1 war vor diesem Kommentar. Der Kommentar wurde wahrscheinlich gepostet, als es schon auf Platz 2 oder 3 gefallen war. Genau in dem Moment, als ich es im Snackbereich aus dem Dozzonkku-Case genommen habe, kam der Kommentar rein, also bin ich hingelaufen und habe den Kommentar geschrieben. Danach wurde es 12 Stunden lang bis auf Platz 30 nach hinten gedrängt, und jetzt ist es auf der zweiten Seite schluchz
Ich habe es auch auf X gepostet: https://x.com/enmskim/status/2016412136482996689
x: https://x.com/enmskim/status/2016941043628097965