Actionbase – une base de données pour les likes, les éléments récemment vus et le follow
(github.com/kakao)Nous avons publié en open source Actionbase, une base de données pour les fonctionnalités de likes, de produits récemment vus et de follow.
Bonjour, je suis l’un des développeurs de Kakao qui travaillent sur Actionbase.
Hier à 20 h (le 27), nous avons publié Actionbase sur Hacker News (Show HN), et en environ 1 h 30 après la publication, il a atteint la 1re place de la première page. En réalité, notre objectif était simplement de rester sur la première page, mais l’accueil a été meilleur que prévu.
Pourquoi l’avoir créé ?
Les fonctionnalités comme les likes, les produits récemment vus ou le follow ont des formes légèrement différentes selon les services, mais on finit toujours par reconstruire les mêmes structures de données et les mêmes modes de traitement.
Le problème, c’est que chaque équipe implémente un peu différemment les listes directes/inversées, les compteurs et les index. Comme les stratégies de retry ou de gestion de l’ordre des événements varient elles aussi, il arrivait que les données divergent subtilement, et les méthodes de calcul de données agrégées comme le nombre de likes différaient également, ce qui rendait l’exploitation compliquée.
Comment ça fonctionne ?
Actionbase définit cela comme un modèle de relation qui(actor) a fait quoi(action) sur quoi(target), et précalcule tout au moment de l’écriture. La lecture se limite à de simples consultations, ce qui la rend rapide et prévisible.
Déploiement en production
Le premier déploiement en production a été la wishlist de KakaoTalk Gift. À l’époque, il y avait encore beaucoup de lacunes, mais pour être à la hauteur des attentes, nous avons corrigé énormément de choses, et cette expérience a servi de moteur à la croissance du projet.
Aujourd’hui, le système traite depuis plusieurs années plus d’un million de requêtes par minute sur plusieurs services de Kakao. Le stockage repose sur HBase, et un stockage léger (basé sur SlateDB) est également en préparation pour s’adapter à différentes échelles.
Pour commencer
Vous pouvez l’exécuter immédiatement avec Docker :
docker run -it ghcr.io/kakao/actionbase:standalone
- 📦 GitHub: https://github.com/kakao/actionbase
- 🚀 Démarrage rapide: https://actionbase.io/quick-start/
Nous vous remercions d’avance pour vos questions, vos retours et vos étoiles.
Q&R
Q : Est-ce que Redis ne suffit pas ?
Si, c’est possible. Nous aussi, nous utilisons Redis comme cache pour les données chaudes. Mais à mesure que l’échelle augmentait, nous avons rencontré des implémentations dupliquées selon les équipes et des problèmes de données incorrectes lorsque l’ordre des événements se désorganisait.
Q : Il ne suffit pas de faire du sharding avec PostgreSQL/MySQL ?
Beaucoup d’équipes font ainsi. Les problèmes que nous avons rencontrés concernaient les hot entities, les lectures cross-shard et des stratégies de cache différentes selon les services. Nous avions besoin d’un modèle capable de s’étendre horizontalement sans devoir redéfinir une stratégie de sharding à chaque fois.
Q : Comment fonctionne le write-time precompute ?
Au moment de l’écriture : enregistrement dans le WAL → verrouillage → transition d’état → calcul des compteurs/index → stockage → publication CDC. Pour la lecture, il suffit d’un seul GET ou SCAN.
Q : Et si l’ordre des événements se mélange ?
Chaque mutation reçoit une version (généralement un timestamp). Même si les événements arrivent dans l’ordre like(t=100) → like(t=300) → unlike(t=200), l’état final converge correctement selon la version. L’objectif est d’obtenir le même état final même en rejouant le même événement.
Q : Quelles sont les performances réelles ?
En production sur KakaoTalk Gift, le système traite durablement plus d’un million d’opérations par minute, avec un pic d’environ deux millions. La latence de lecture est de p50 autour de 2 à 3 ms, p99 autour de 10 ms. Le point essentiel n’est pas tant le chiffre absolu que le fait que la latence soit bornée. Comme la lecture repose sur des lookups précalculés plutôt que sur de l’agrégation, les performances ne se dégradent pas quand le volume de données augmente.
Q : Pour quels cas d’usage est-ce adapté ?
Les likes/réactions, le follow/les followers et les produits récemment vus sont les cas d’usage principaux. Pour les fonctionnalités de recommandation/ML, des données d’entraînement peuvent être fournies via CDC, mais il ne sert pas directement les recommandations. Pour les messages de chat, ce n’est probablement pas le meilleur choix, car il faut d’autres patterns d’accès comme la pagination, la recherche ou les threads. Les paniers e-commerce nécessitent également des transactions, or Actionbase ne prend pas en charge les transactions cross-edge.
Q : N’est-ce pas de l’overengineering ? / Est-ce que seules les grandes entreprises en ont besoin ?
C’est possible. Honnêtement, à petite échelle, la bonne réponse est un PostgreSQL bien optimisé + Redis. Les problèmes qu’Actionbase résout — complexité du sharding, invalidation du cache, duplication entre équipes — apparaissent surtout à grande échelle ou quand plusieurs équipes construisent des fonctionnalités similaires. Nous l’avons créé parce que nous nous sommes heurtés plusieurs fois à cette limite. C’est aussi pour cela que nous préparons un backend léger (SlateDB) afin qu’il puisse être utilisé sur de petits déploiements.
24 commentaires
Oh oh... J’attends aussi avec impatience une version backend légère !!
Merci ! J’ai déjà arrêté une direction basée sur SlateDB, où un backend léger ne nécessite que S3, mais je n’ai pas encore vraiment commencé.
Je me demande dans quel environnement vous envisagez de l’utiliser. Un side project ? Une petite production ? J’aimerais m’en servir comme référence pour définir les priorités.
Si vous avez un moment, n’hésitez pas non plus à voter pour HBase/SlateDB. L’avis de la communauté pourrait aider à définir la direction : https://github.com/kakao/actionbase/discussions/144
Je trouve que c’est un projet extrêmement pratique.
C’est génial !
Merci ! Je rattrape ici la frustration du peu d’attention que je n’ai pas reçue sur Show HN.
Je suis curieux de savoir quels aspects vous ont semblé pratiques. Avez-vous déjà rencontré un problème similaire ? Ou êtes-vous dans une situation où vous avez besoin d’implémenter ce type de fonctionnalité ?
Et puisque j’ai enfin l’occasion de laisser un commentaire, il y a quelque chose que je voulais dire. J’ai écrit dans la documentation que nous ne faisions pas de traversée non bornée, mais le multi-hop borné fait partie de nos plans pour cette année. Par exemple, des requêtes à 2 sauts comme « les produits aimés par des amis ». https://actionbase.io/ko/stories/unified-graph/
Ce que j’ai trouvé particulièrement pratique, c’est que j’ai moi aussi déjà eu des réflexions similaires, et que j’ai déjà implémenté au niveau du code une couche d’abstraction basée sur un KV store comme Redis ; j’ai donc trouvé que l’objectif visé par la documentation, sa direction, ainsi que sa structure d’ensemble, étaient tous très pragmatiques.
Et je trouve aussi remarquable d’avoir rassemblé et synthétisé les besoins et les préoccupations de plusieurs équipes pour en faire un produit interne à l’entreprise, puis de l’avoir publié en open source. Haha.
Enfin, si je devais vraiment ajouter un petit mot, ceux qui vont l’utiliser auront sans doute déjà largement de quoi faire avec la documentation actuelle, mais je pense que ce serait encore plus attractif si vous y intégriez, sous forme d’exemples, des cas de déploiement qu’on peut suivre presque en copier-coller, ainsi que des usages recommandés ou des références d’infrastructure.
Bon courage !
Je suis sincèrement ravi de voir que vous vous êtes posé les mêmes questions. Et merci du fond du cœur pour votre appréciation.
Je comprends tout à fait ce que vous voulez dire. Moi aussi, je veux configurer simplement ce qui doit l’être comme outil, puis me concentrer sur les problèmes que je dois réellement résoudre.
Cela dit, le projet n’en est encore qu’à ses débuts en open source, et avec un temps limité, nous nous sommes concentrés sur la manière de transmettre cette valeur essentielle. Si cela n’est pas bien communiqué, même les personnes capables de résoudre de vrais problèmes risquent de ne pas y parvenir. Nous allons maintenant avancer dans la direction que vous avez évoquée. En revanche, j’aimerais avoir des retours sur le choix entre partir sur notre stack interne HBase + Kafka, ou aller vers SlateDB + S2 malgré l’effort de développement supplémentaire que cela implique. Chez nous, des ingénieurs HBase assurent l’exploitation, donc nous l’utilisons sans difficulté, mais ce n’est probablement pas le cas partout. Je vous serais reconnaissant de partager votre avis (même juste en votant) :
https://github.com/kakao/actionbase/discussions/144
Je trouve moi aussi la feuille de route, avec par exemple des requêtes à 2 sauts comme celles que vous avez mentionnées, très séduisante.
Mais je pense que si vous arriviez à mieux intégrer, dans la documentation actuelle, ce que vous voulez faire passer à travers des exemples concrets comme du code, vous auriez une réaction bien plus explosive.
Je suis d’accord. « Bien l’intégrer dans des exemples ». Mais en fait, ce n’est pas aussi simple que ça en a l’air, hélas. Nous allons y réfléchir sous plusieurs angles. Merci !
Je me demande aussi si vous avez vu le guide interactif que notre collègue a préparé avec beaucoup de soin : https://actionbase.io/guides/build-your-social-media-app/ . C’était justement une tentative dans ce sens. Cela nous amène à nous demander si cela correspond bien à la direction que vous évoquez. Nous allons continuer à faire de notre mieux.
Ah, et c’est un point que j’ai oublié d’évoquer dans mon nouveau commentaire, mais on sent un vrai travail sur l’organisation de la documentation dans son ensemble, pas seulement sur le guide.
En revanche, comme je le disais plus haut, ce serait encore mieux si la configuration préparée pour l’exemple pouvait être reproduite facilement via
git clone.Je vais répondre dans le commentaire ci-dessous.
Je pensais avoir déjà posté ce commentaire, mais comme je ne le vois pas, je le réécris depuis le début... (snif)
Merci pour votre réponse si soignée à un commentaire que j’avais laissé assez légèrement.. haha;;
Quoi qu’il en soit, ce que je voulais dire, c’est que j’imagine que l’environnement d’une petite équipe qui voudrait essayer d’adopter ça et celui d’une grande équipe seront très différents, et que la forme la plus facile à faire accepter quand on se dit à la légère « Et si on essayait d’adopter ça ? », c’est selon moi un projet d’exemple écrit dans le langage utilisé par l’équipe.
Commencer par créer des projets d’exemple dans les langages les plus répandus, puis construire un quickstart rapide à partir de là permettrait de le lire beaucoup plus facilement, et je pense que le côté « un
git cloneet c’est parti » est très attractif.Et je pense aussi que cette approche est la meilleure pour expliquer les best practices.
Bien sûr, je sais que, vu la nature du projet, ce n’est probablement pas simple à mettre en place, mais malgré cela, je pense que c’est ce qu’il y a de plus séduisant.
En plus, si possible, ce serait encore mieux de proposer les exemples avec des outils comme pulumi ou terraform.
C’est un point de vue auquel je n’avais pas du tout pensé. Merci beaucoup pour ce type de suggestion. C’est vraiment une belle expérience que l’on peut tirer de la communauté.
Je vais réfléchir à la manière de concrétiser la direction que vous avez évoquée. Y compris avec des exemples
pulumiouterraform. Il est même possible que nous clarifiions cette orientation et demandions du soutien à la communauté. Si vous pouviez y contribuer à ce moment-là, nous vous en serions d’autant plus reconnaissants.Par ailleurs, je réfléchis aussi à la manière dont cela pourrait devenir une base à l’ère du vibe coding. Quand on dit « crée-moi une application », elle est écrite en React, en Svelte, etc. La même position, en quelque sorte. C’est-à-dire une situation où, quand on dit « ajoute-moi une fonctionnalité de likes », Actionbase remplit ce rôle.
Cet aspect continue lui aussi de me trotter dans la tête. C’est pourquoi j’ai accordé beaucoup d’attention à la documentation pour qu’elle puisse être lue par des outils d’IA, et je commence aussi à voir des possibilités récentes.
Référence :
llms.txt - https://actionbase.io/llms-txt/
Tentative de recette du gagnant du hackathon Anthropic - https://github.com/kakao/actionbase/discussions/90
Je pense que cela pourrait être très utile dans des cas d’usage similaires. Merci de l’avoir rendu public !
En revanche, je me demande s’il n’y a pas eu de problème avec la partie de l’ingestion où vous utilisez des verrous. Dans le cas des écritures de données, quel était à peu près le niveau de trafic ? N’y a-t-il pas eu de problèmes dus à la contention des verrous, par exemple ?
Merci pour cette excellente question !
Le lock est pris au niveau de la paire d’edges (source, target) (par ex. : Alice→Phone). La contention n’apparaît que lorsqu’il y a des écritures simultanées sur le même edge, mais en pratique, il est très rare qu’un même utilisateur clique sur « J’aime » pour la même cible exactement au même moment, donc la contention reste faible. C’est une caractéristique de notre cas d’usage de base de données.
Le trafic d’écriture atteint, au pic, plusieurs centaines de milliers d’opérations par minute. Les lectures dépassent 1 million+, et les écritures restent inférieures.
Référence benchmark (85 % lecture, 15 % écriture) - https://actionbase.io/ko/operations/benchmarks/
Les entités chaudes (produits populaires, etc.) peuvent entraîner une contention sur les locks, à cause des mises à jour de compteur (HBase Increment). Nous traitons ce point avec des optimisations dédiées. À propos des écritures à haute fréquence : https://actionbase.io/ko/stories/kakaotalk-gift-recent-views/
Oh.....
Merci ! Si le sujet vous intéresse, n'hésitez pas à laisser également votre avis sur les orientations suivantes : https://github.com/kakao/actionbase/discussions/144
Waouh, ça a l’air vraiment très utile.
Merci ! Je me demande si vous avez rencontré des problèmes en implémentant des fonctionnalités similaires. Nous recueillons l’avis de la communauté sur ce que nous devrions faire en priorité ensuite : https://github.com/kakao/actionbase/discussions/144
La documentation développeur est vraiment très bien rédigée. Les cas d’usage présentés sous forme de stories, le démarrage rapide et la FAQ étaient si riches qu’on aurait dit un véritable blog technique.
Waouh, merci beaucoup. Entre la publication en open source le 5 janvier et l’ouverture à la communauté le 27, nous avons énormément travaillé sur la documentation, donc cela me fait plaisir que vous l’ayez remarqué.
Comme c’était le tout début de l’open source, nous nous sommes concentrés sur « ce que c’est » et « pourquoi c’est nécessaire », et je pense que c’est ce qui a donné ce résultat. Si vous voyez des points perfectibles dans la documentation, n’hésitez pas à nous le dire !
À titre de référence, si vous utilisez https://actionbase.io/llms-txt/, vous pourriez obtenir des résultats auxquels vous ne vous attendiez pas. Récemment, en voyant quelqu’un qui ne connaissait pas bien Actionbase parvenir à la meilleure conclusion pour des besoins complexes avec ce prompt, j’ai de nouveau eu le sentiment que le monde avait vraiment changé.
Essayez ce qui suit dans ChatGPT, Claude, Gemini, etc.
C’est suspect, je sais. Mais ce n’est pas truqué.
J’ai mis 4 liens dans mon premier commentaire, et j’ai pris un shadowban pendant 30 minutes. Pendant ce temps, comme l’explication du contexte n’apparaissait pas, les gens ont juste passé leur chemin. À ce moment-là, j’étais vraiment anxieux. J’avais peur que ça soit complètement noyé. J’ai retiré les liens et reposté le commentaire, et c’est seulement là que c’est remonté en 1re place, avec des réponses en plus.
Le commentateur dont vous parliez, je l’ai vérifié aussi. Oui, son compte était récent. Malgré tout, je lui étais reconnaissant. Au moins, il y avait une réaction. Donc je lui ai répondu avec soin. Le "why not redis?", je l’avais préparé à l’avance. C’est le genre de question qui sort systématiquement dès qu’on parle de DB. Je me suis dit : j’ai quand même préparé ça sérieusement, ils ne vont pas vraiment poser une question aussi attendue, si ? Mais la veille, avec s2-streamstore, j’avais vu ça. Quelqu’un avait répondu "pourquoi pas en TCP". Donc je m’y suis préparé.
Au passage, j’ai demandé aux membres de l’équipe de ne surtout pas upvoter ni commenter, et je leur ai même dit de se déconnecter au cas où ils fassent une erreur. Je savais déjà que HN est sensible à ce sujet.
Quoi qu’il en soit, je comprends que vous puissiez ne pas me croire même après ces explications... Alors je vous demande juste de jeter un œil à notre repo. C’est le code qui a survécu. J’écris ça en détail parce que je ne voudrais pas que les collègues qui ont travaillé avec moi soient blessés en voyant ce post. Merci de regarder au moins une fois. https://github.com/kakao/actionbase/discussions/32
Et aussi,
https://actionbase.io/ko/stories/kakaotalk-gift-wish/. Si vous vous êtes déjà penché sur les systèmes à grande échelle, j’y ai mis beaucoup de soin pour écrire quelque chose qui pourrait vous être utile.
Ah, et comme vous pouvez le voir sur mon X ci-dessous, la 1re place, c’était avant que ce commentaire soit posté. Ce commentaire a probablement été posté quand c’était retombé à la 2e ou 3e place. Au moment même où je le sortais de son étui Doojjonku dans l’espace où l’on mange les snacks, le commentaire est arrivé, donc j’ai accouru pour répondre. Ensuite, en 12 heures, c’est tombé jusqu’à la 30e place, et maintenant c’est sur la 2e page T_T
Je l’ai aussi publié sur X : https://x.com/enmskim/status/2016412136482996689
x : https://x.com/enmskim/status/2016941043628097965