NOUVEAU : Helius acquiert Light Protocol
De ClickHouse à RocksDB : comment nous avons reconstruit la couche d’archivage de Solana
Blog/Ingénierie

De ClickHouse à RocksDB : comment nous avons reconstruit la couche d’archivage de Solana

Developer Experience Engineer0xIchigo sur X0xIchigo sur LinkedIn0xIchigo sur GitHub
Ingénieur logicielConnor Peticca sur LinkedIn
19 min de lecture

Lorsque nous expliquons que nous avons déplacé plus de 300 téraoctets de données d’archivage Solana de ClickHouse vers RocksDB, la réaction est presque toujours la même : Pourquoi faire une chose pareille ?

ClickHouse est le choix évident pour les charges de travail analytiques à l’échelle du pétaoctet, contrairement à RocksDB.

ClickHouse bénéficie de la confiance de certains des plus grands consommateurs de données au monde. 

Par exemple, Cloudflare l’exécute sur plus d’un millier de réplicas afin de traiter des centaines de millions d’insertions par seconde.

Anthropic exploite un déploiement ClickHouse personnalisé et isolé du réseau pour assurer l’observabilité de Claude. Uber, eBay et Bloomberg l’utilisent également en production depuis des années.

RocksDB, en revanche, est un magasin clé-valeur embarqué dont la documentation est limitée. Il sert principalement de moteur à d’autres bases de données (par exemple CockroachDB, TiKV et MyRocks), plutôt que de fondation directe à un service de données historiques destiné aux clients.

Cette migration a toutefois réduit notre empreinte de stockage compressé de ~330 To à ~190 To, corrigé la longue traîne de nos requêtes les plus lentes (par exemple, la latence p95 des appels getTransactionsForAddress est passée de 350 ms à 30 ms) et nous a permis d’innover sur la couche de lecture de Solana, ce qui aurait été impossible avec ClickHouse compte tenu des performances et de l’échelle exigées chez Helius.

Cet article explique pourquoi nous avons abandonné ClickHouse, ce que cette migration nous a appris sur notre charge de travail et comment nous utilisons RocksDB en production à grande échelle. 

Qu’est-ce que l’archivage de Solana et pourquoi est-il important ?

Fondamentalement, Solana est un réseau de nœuds qui communiquent afin de s’accorder sur de nouvelles informations sans devoir se faire confiance.

Un nœud est un ordinateur du réseau Solana qui exécute un client (par exemple Agave ou Firedancer) respectant un ensemble précis de règles afin de faciliter l’accord sur de nouvelles informations. 

Un validateur est un nœud Solana qui sécurise le réseau en produisant des blocs (c’est-à-dire en ajoutant des groupes de transactions au registre de Solana) et en votant sur la validité des autres blocs. 

Les nœuds RPC sont des validateurs qui ne participent ni à la production de blocs ni au vote. Ils observent plutôt le réseau et suivent toutes les nouvelles informations qu’il produit. Les RPC permettent aux utilisateurs d’interroger le réseau pour obtenir des données précises à l’aide de la spécification JSON-RPC. 

Cependant, ces nœuds ne conservent pas ces données indéfiniment. 

Pour respecter les exigences matérielles de Solana, les anciens blocs, transactions et états de comptes sont élagués, de sorte que les nœuds ne conservent que la vue la plus récente de l’historique de Solana. 

Cela pose problème lorsqu’il faut rechercher la signature d’une transaction datant d’un an, récupérer toutes les signatures ayant interagi avec un portefeuille au cours de son existence ou parcourir l’intégralité de l’historique d’exécution d’un programme.

L’archivage désigne globalement toute la couche qui stocke les données de Solana depuis sa genèse. Il journalise et indexe tout ce que produit la chaîne — chaque bloc, transaction, interaction avec un compte, invocation interprogramme (CPI) et journal de transaction — et permet de les interroger au-delà de la fenêtre standard de stockage à court terme de ~2 jours (soit 1 époque). 

C’est l’archivage qui rend possibles les requêtes historiques.

Sur Solana, l’approche par défaut pour stocker les données d’archivage est Google BigTable. Anza gère une instance BigTable à laquelle les fournisseurs RPC peuvent accéder à la demande pour répondre aux requêtes historiques.

Cette solution fonctionne, mais BigTable coûte cher, les frais de sortie rendent l’exploitation de votre propre copie pénible et vous ne pouvez pratiquement rien faire de votre côté pour l’accélérer : vous dépendez du stockage de Google, avec toute sa structure de coûts et sans aucun contrôle. 

Old Faithful est un ensemble d’outils géré par Triton One qui permet de produire des archives adressables par contenu (CAR) à partir d’archives RocksDB du registre et de les servir via les interfaces RPC et gRPC standard de Solana. Il s’agit d’une avancée importante vers la décentralisation de la couche d’archivage de Solana, en fournissant une source précieuse d’historique redondant et vérifiable.

Cependant, ses compromis en matière d’expérience développeur et de performances (par exemple, la prise en main nécessite des outils personnalisés plutôt que des interfaces sur lesquelles les équipes peuvent s’appuyer, et la solution est optimisée pour un archivage durable plutôt que pour les performances et le passage à l’échelle) n’en font pas une véritable alternative pour les charges de travail sensibles à la latence. 

Le problème fondamental de l’archivage est que vous disposez de N pétaoctets de données brutes. Avec plus de 500 milliards de transactions, ~1 300 milliards de lignes d’index compte-transaction et des schémas d’accès aléatoires, comment obtenir des recherches en moins de 10 ms ? À quoi ressemblent des requêtes de bout en bout en moins de 50 ms ? Ni Google BigTable ni Old Faithful ne proposent de solution à ce problème.

De plus, si vous souhaitiez créer des options personnalisées de filtrage et de tri, ou améliorer l’expérience développeur en proposant des fonctionnalités plus riches que les méthodes JSON-RPC standard, vous auriez besoin de votre propre index d’archivage. 

C’est donc ce que nous avons créé.

ClickHouse : le premier choix pragmatique

ClickHouse était le point de départ le plus pragmatique pour construire notre nouveau système d’archivage. C’était le moyen le plus rapide de lancer un produit déjà meilleur qu’une solution reposant sur BigTable.

ClickHouse est une base de données en colonnes mature, dotée d’excellents outils et d’une documentation complète. Elle compresse efficacement les données de séries temporelles, ce qui est particulièrement utile pour Solana, puisque les données de ses blocs sont fondamentalement ordonnées dans le temps.

Il est facile de créer une base de données, d’écrire des requêtes SQL, de faire évoluer les schémas et d’optimiser le délai de mise sur le marché afin de proposer relativement vite une solution aux clients.

ClickHouse ne gérait pas seul le trafic. Il constituait plutôt le niveau inférieur de notre pile de stockage, organisée selon la récence des données. 

Les données les plus récentes (environ la ou les deux dernières minutes, soit quelques centaines de slots) résidaient dans un magasin en mémoire. Les données des deux dernières semaines environ se trouvaient dans Postgres. ClickHouse contenait le reste de l’historique de Solana.

Un routeur intelligent se trouvait devant ces trois sources : les recherches ponctuelles étaient envoyées au niveau le plus chaud contenant les données, tandis que les requêtes par plage étaient réparties entre les niveaux puis réassemblées en un seul résultat.

ClickHouse fonctionnait relativement bien pour les charges de travail auxquelles il était destiné. Par exemple : « donnez-moi tous les blocs compris dans cette plage de slots » ou « parcourez l’activité de ce compte au fil du temps ». 

Les requêtes de séries temporelles ne posaient aucun problème. Nous pouvions effectuer des remplissages rétrospectifs, exécuter des analyses ponctuelles et répondre à la plupart des besoins historiques des fournisseurs RPC. L’ingestion n’a jamais été mise à rude épreuve : nous n’écrivions que ~10 Mo/s dans notre index via LaserStream.

L’erreur n’était pas d’avoir choisi ClickHouse. Elle était de supposer que notre charge de travail conserverait une forme que ClickHouse pourrait gérer à grande échelle. 

Les limites de ClickHouse

Les méthodes historiques Solana qui nous intéressent ne relèvent pas toutes des séries temporelles. Une signature sur Solana (l’identifiant universel d’une transaction) correspond essentiellement à 64 octets de données aléatoires. 

Lorsqu’une personne appelle getTransaction pour une signature donnée, il s’agit d’une recherche ponctuelle uniformément aléatoire. Il n’existe ni slot, ni plage temporelle, ni aucune forme de localité à exploiter. 

Il en va de même pour d’autres requêtes, telles que « récupérer toutes les signatures ayant interagi avec ce compte », car la clé du compte est elle aussi effectivement aléatoire. Ce problème survient chaque fois qu’une clé primaire est un UUID, un hachage ou un autre identifiant à forte entropie.

Les moteurs en colonnes ne sont pas conçus pour résoudre ce problème. 

ClickHouse stocke les données dans des parties triées et utilise des index primaires clairsemés. Pour une recherche sur une clé aléatoire, il y a donc peu de données à éliminer. Vous finissez inévitablement par lire davantage de granules que souhaité. Une seule recherche de signature peut toucher 20 granules — soit environ 10 000 lignes et ~60 opérations d’E/S disque — avant même toute recherche binaire ou surcharge CPU. 

Rien qu’en E/S, cela représente environ 5 ms pour une recherche. Comme le stockage est en colonnes, lire une transaction implique de lire ~15 colonnes sous forme d’E/S distinctes dans un granule de 512 lignes.

Ainsi, un appel getTransactionsForAddress demandant les détails complets des transactions peut déclencher jusqu’à 100 de ces recherches, ce qui porte le plancher de latence à près de 100 ms avant même la sérialisation du moindre octet. 

Un grand lot getTransaction (jusqu’à 1 000) faisait monter ce plancher à près d’une seconde entière.

Les abstractions qui accélèrent les analyses (par exemple l’exécution vectorisée et la matérialisation tardive) ne résolvent pas entièrement ce problème. Les recherches étaient déjà optimisées au maximum. Il ne nous manquait aucun index. Nous ne pouvions ajouter aucune projection. 

En termes simples, l’organisation fondamentale des données était inadaptée à ce que nous lui demandions.

Les méthodes les plus coûteuses que nous avions ajoutées (par exemple getTransactionsForAddress et getTransfersByAddress) suivaient précisément les schémas de clés aléatoires que ClickHouse gérait le moins bien. 

Certaines de ces requêtes prenaient 2 à 3 secondes, alors qu’elles auraient dû ne prendre que quelques millisecondes. Nous recevions des alertes pour des dégradations de performances sur des charges de travail qu’il nous était fondamentalement impossible de corriger. 

Puisque des institutions et des entreprises clientes utilisent Helius à grande échelle, cette situation est totalement inacceptable à long terme.

Adapter ClickHouse à cette charge de travail nécessitait d’augmenter le nombre de machines et, à notre échelle, de multiplier plusieurs fois la charge. Dépenser davantage en matériel n’allait pas résoudre le problème à lui seul.

La pile RPC de Solana arrive à maturité. L’écosystème a atteint un point d’inflexion où les méthodes JSON-RPC standard ne suffisent plus. Les clients exigent des requêtes historiques riches, et personne d’autre n’allait les construire sur BigTable. 

Pour repousser cette frontière, nous devions changer la couche de stockage. 

RocksDB : pas une base de données

Malgré son nom, RocksDB n’est pas une base de données. C’est une bibliothèque.

Il n’y a ni langage de requête, ni protocole client/serveur, ni moteur SQL, ni jointures, ni index au sens traditionnel des bases de données. Son interface dit simplement : « Voici une clé (des octets), voici une valeur (également des octets), conservez-la sur le disque ; plus tard, renvoyez-moi la valeur associée à cette clé. » Rien de plus.

C’est une primitive. Sans doute même la primitive permettant de construire des moteurs de stockage. 

Tout ce que l’on attend d’une base de données traditionnelle (par exemple un planificateur de requêtes, un protocole réseau, la réplication et l’observabilité) doit être construit.

Cela peut sembler être un inconvénient, jusqu’à ce que vous compreniez ce que cette approche apporte. Un magasin clé-valeur pur reposant sur un arbre LSM (Log-Structured Merge) sur disque possède exactement la structure adaptée aux recherches de clés uniformément aléatoires à haut débit. Aucun planificateur de requêtes n’ajoute de surcharge, aucune hypothèse liée à une organisation en colonnes n’est à concilier et aucun frontend SQL n’est à prendre en compte.

Vous stockez des octets, vous les relisez et vous placez des filtres de Bloom et des caches aux bons endroits afin de limiter le coût des lectures aléatoires.

C’est précisément là que l’idée d’un anti-pattern s’effondre. 

Nous n’avons pas remplacé ClickHouse par RocksDB : nous avons remplacé ClickHouse par une base de données personnalisée dont le moteur de stockage est RocksDB. La différence est significative.

C’est aussi le modèle utilisé en interne par la plupart des bases de données de production. Par exemple, CockroachDB, TiKV, MyRocks et les magasins d’état de Kafka Streams reposent tous sur RocksDB.

La différence est qu’ils l’encapsulent d’abord dans une autre base de données, tandis que nous avons nous-mêmes construit la base de données autour de RocksDB et l’avons ajustée aux schémas d’accès précis exigés par l’archivage.

Comment RocksDB répond aux limites de ClickHouse

Alors, comment un magasin clé-valeur résout-il concrètement le problème des clés aléatoires auquel un moteur en colonnes ne pouvait pas répondre ? Tout dépend de la manière dont les octets sont stockés sur le disque.

RocksDB utilise un compactage par niveaux. Les nouvelles écritures arrivent au niveau 0, une zone de dépôt non triée — soit pratiquement la même situation que dans ClickHouse — où les parties d’une partition ne sont pas triées globalement. 

Toutefois, les niveaux 1 à N sont des séquences entièrement triées. Une fois les données compactées, les métadonnées min/max permettent réellement d’élaguer la recherche, même pour des clés uniformément aléatoires, car le niveau est ordonné globalement. En un sens, tout se comporte dans ClickHouse comme le niveau 0 de RocksDB.

Nous nous appuyons sur cette propriété pour nos remplissages rétrospectifs. 

Lorsque nous construisons l’index des signatures, nous trions d’abord l’intégralité de l’historique et le chargeons directement dans le niveau inférieur. Ensuite, seules les données récentes arrivent au niveau 0, avant de fusionner rapidement vers les niveaux inférieurs. 

Ainsi, presque chaque recherche lit une seule séquence triée. Avec RocksDB, nous avons en pratique trié des données aléatoires.

Ce que nous avons construit par-dessus

ClickHouse fournit de nombreuses fonctionnalités prêtes à l’emploi : un moteur de requêtes, un protocole réseau, un client et un moyen de servir les données. RocksDB n’en fournit aucune ; il se contente de stocker des octets. Nous avons dû construire tout le reste.

Nous avons donc créé notre propre base de données sur RocksDB, spécialisée dans les schémas d’accès aux archives de Solana.

Deux index résident aujourd’hui dans RocksDB :

  1. Signature -> Emplacement (c’est-à-dire l’index des signatures, qui associe la signature de 64 octets d’une transaction au slot et à la position qu’elle occupe dans le bloc).
  2. Slot -> Bloc (c’est-à-dire l’index slot-bloc, qui associe l’emplacement ci-dessus aux données de la transaction).

Il est important de noter qu’il n’existe aucun chemin direct entre une signature et les données de sa transaction. C’est précisément pour contourner cette contrainte que ces deux index existent. 

Une signature est essentiellement un identifiant aléatoire de 64 octets. Ce qui indique réellement où se trouve une transaction, c’est son slot et son index dans ce bloc. La récupération d’une transaction nécessite donc deux étapes (l’une pour convertir la signature en emplacement donné et l’autre pour récupérer les détails de la transaction à cet emplacement), tandis que la récupération d’un bloc n’en nécessite qu’une, puisque l’appelant fournit déjà le slot.

Ensemble, ces index alimentent certaines des méthodes les plus intensives servies par Helius (par exemple getBlock, getTransaction et getTransactionsForAddress, notamment lorsque details sont définis sur full).

Le chemin de lecture ressemble beaucoup à celui utilisé avec ClickHouse. Une requête arrive, notre client interne effectue un appel à la base de données, puis le résultat est renvoyé. Ce qui change, c’est le moteur sous-jacent. Chaque méthode suit un chemin codé en dur et optimisé manuellement. Lorsqu’un utilisateur recherche une transaction, un chemin getTransaction dédié mène directement aux octets.

Ce chemin est rapide parce que nous contrôlons chacune de ses couches. Nous utilisons io_uring pour les E/S de fichiers et de réseau afin de diffuser les données depuis RocksDB. Lorsque les données sont stockées sans compression sur le disque, nous les copions directement du disque vers la carte réseau, sans aucun détour par l’espace utilisateur.

Les méthodes sont codées en dur, les E/S sont optimisées de bout en bout et aucun élément superflu ne s’intercale.

Les bénéfices sont évidents en production. 

Récemment, nous avons maintenu un trafic getBlock de 150 Gbit/s pendant cinq à six heures consécutives, en saturant la plupart de nos cartes réseau. Aucun problème, aucune alerte, toujours les mêmes performances brutes. 

Sur tous les plans,

  • Le stockage compressé a été presque divisé par deux, passant de ~330 To à ~190 To
  • La latence P95 des appels getTransaction est passée de 7 ms à 1 ms
  • La latence P95 des appels getTransactionsForAddress est passée de 350 ms à 30 ms
  • La latence P95 des appels getBlock est passée de 50 ms à 35 ms

Comme prévu, les appels getBlock se sont le moins améliorés. ClickHouse stocke déjà les transactions par groupes de 512 lignes, ce qui amortit la pénalité du stockage en colonnes pour les lectures de la taille d’un bloc. Une grande partie du temps de bout en bout de getBlock est consacrée à l’encodage Base58 et JSON ainsi qu’au réassemblage du bloc. Remplacer le moteur de stockage n’accélère donc pas ce processus.

L’histoire plus approfondie — comment nous avons fait coopérer io_uring, Rust asynchrone et une bibliothèque synchrone comme RocksDB sous une charge réseau à haut débit — mérite un prochain article dédié.

La section suivante présente toutefois quelques optimisations qui nous ont été utiles avec RocksDB. 

Optimiser RocksDB à grande échelle

Il n’existe pas de configuration RocksDB universellement « rapide ». Les réglages appropriés dépendent entièrement du schéma d’accès de l’index optimisé.

Notre index signature -> emplacement et notre index slot -> bloc s’exécutent dans le même processus sur le même matériel, mais nécessitent des réglages presque diamétralement opposés.

Plutôt que de vous fournir un fichier de configuration dont les paramètres ne conviendraient pas nécessairement à votre charge de travail, cette section explique comment nous raisonnons sur les compromis transposables.

Optimisez par index, pas par base de données

Chacun de nos index est une famille de colonnes distincte avec ses propres options. L’un sert à effectuer des recherches ponctuelles uniformément aléatoires ; l’autre contient de grandes valeurs compressibles récupérées dans l’ordre. Les traiter de la même manière nous aurait privés de nombreuses optimisations de performances. Presque chaque décision décrite ci-dessous doit se lire comme suit : « pour ce schéma d’accès, faites X ».

Déterminez si vous avez réellement besoin du WAL

Les données d’archivage peuvent être reconstruites. Elles arrivent en continu depuis LaserStream et sont dérivées de la chaîne elle-même.

Nous effectuons nos écritures avec le Write Ahead Log (WAL) désactivé, afin de ne pas payer le coût d’une durabilité du journal d’écriture anticipée dont nous n’avons pas besoin. 

La subtilité est que la désactivation du WAL désactive également la cohérence par défaut de RocksDB entre les familles de colonnes en cas de panne. La cohérence doit donc être rétablie autrement. La leçon à retenir est que les paramètres de durabilité doivent correspondre à la capacité de récupération de vos données. Des données pouvant être reconstruites à partir d’une source en amont ne répondent pas du tout aux mêmes exigences qu’un système de référence.

Adaptez les filtres de Bloom à votre ratio succès/échec

Les filtres de Bloom rentabilisent leur mémoire en déterminant à moindre coût si une clé est absente lors d’une recherche. Ils ne sont donc utiles qu’en cas d’échec. 

La recherche d’une signature aboutit presque toujours, car l’appelant possède une signature et souhaite obtenir les données de transaction correspondantes.

Le niveau LSM le plus bas contient l’immense majorité de nos données. Lorsque l’essentiel de vos données se trouve sur un seul niveau et que votre charge de travail est dominée par les recherches fructueuses, les filtres de ce niveau consomment le plus de mémoire tout en effectuant le moins de travail. Dans ce cas, il est pertinent de se demander si vous en avez réellement besoin à cet endroit.

Compressez ce qui est compressible, pas ce qui est chaud

La compression se décide pour chaque index. Les données à forte entropie, comme une signature de 64 octets, ne se compressent pas en dessous d’un ratio de 1,0. La compression ne ferait donc qu’ajouter un coût de décompression au chemin critique de chaque recherche. C’est pourquoi nous définissons la compression sur None.

À l’inverse, les données de blocs se compressent bien, car elles sont plus volumineuses et plus répétitives. Notre index slot -> bloc utilise donc zstd. Remarquez que nos deux index utilisent la même base de données, mais bénéficient de choix différents. Ces choix dépendent entièrement de la compressibilité des octets et du fait que l’index soit limité par la latence ou par le stockage.

Cette séparation par index explique en grande partie comment nous avons réduit notre empreinte de ~330 To à ~190 To sans dégrader la latence des recherches ponctuelles.

Envisagez les E/S directes

Nous utilisons les E/S directes pour les lectures, les vidages et le compactage. À cette échelle, le cache de pages du système d’exploitation et notre propre cache de blocs se disputent la même RAM. Pour les recherches ponctuelles aléatoires, cette double mise en cache est largement inutile : nous préférons disposer nous-mêmes d’un seul grand cache de blocs offrant une latence prévisible.

Notez que cela dépend de la charge de travail :

Les E/S directes peuvent pénaliser les configurations axées sur l’analyse ou sous-dimensionnées. Il est donc préférable d’effectuer des tests A/B plutôt que de les adopter aveuglément. 

Choisissez un cache qui résiste à la contention

Sous une forte charge concurrente sur des clés chaudes, le cache LRU partagé standard devient un goulot d’étranglement en raison de la contention des verrous. Pour les index chauds, nous utilisons HyperClockCache de RocksDB, qui résiste bien mieux lorsque de nombreux threads sollicitent simultanément les mêmes entrées populaires.

Parallélisez les recherches multiclés au lieu de les sérialiser

Au lieu de sérialiser N lectures, RocksDB peut lancer simultanément de nombreuses E/S via io_uring et les laisser s’exécuter en parallèle. Pour une méthode comme getTransactionsForAddress, qui déclenche de nombreuses recherches ponctuelles sous-jacentes, c’est ce qui distingue une latence augmentant avec le nombre de clés d’une latence qui reste à peu près constante.

RocksDB offre toutes les possibilités, mais ne prend aucune décision concernant vos données. Nos gains proviennent de notre compréhension des schémas d’accès et de l’optimisation de chaque index selon ses propres caractéristiques, plutôt que de la recherche d’une configuration globale unique adaptée à tous les cas.

Notre prochain objectif

Aujourd’hui, l’archivage fonctionne depuis nos plus grandes régions, comme EWR, FRA et Tokyo. Maintenant que le moteur de stockage répond aux recherches en quelques microsecondes et sature nos cartes réseau, la base de données n’est plus ce qui nous réveille la nuit. Résoudre un goulot d’étranglement tend à révéler le suivant.

Une fois qu’une recherche devient pratiquement gratuite, le coût dominant ne vient plus du logiciel, mais de la distance entre l’utilisateur et la machine. Une requête doit toujours voyager de l’emplacement de l’utilisateur jusqu’à notre backend, puis revenir. À ce stade, vous luttez contre les lois de la physique.

C’est le problème auquel s’attaque Gatekeeper.

Gatekeeper est notre passerelle edge interne, écrite en Rust sur Hyper. Elle termine les connexions à proximité des utilisateurs et achemine chaque requête vers notre backend par le chemin disponible le plus court. C’est désormais là que se joue la bataille de la latence : regroupement des connexions, réglage de TLS et des sockets, routage tenant compte de la proximité et de l’état de santé, et déploiements sans interruption sur notre infrastructure mondiale. Tout cela vise à gagner quelques millisecondes sur le chemin vers des octets que l’archivage sert déjà en quelques microsecondes.

Accélérer une seule requête est un problème de base de données. Accélérer chaque requête, partout dans le monde, sans fenêtre de maintenance ni connexion interrompue, est un problème totalement différent. C’est aussi celui auquel nous nous consacrons maintenant. 

Voilà ce que nous entendons par innover sur la couche de lecture de Solana : optimiser chaque couche, du moteur de stockage qui répond aux recherches jusqu’à la passerelle edge qui détermine la vitesse à laquelle cette réponse atteint l’utilisateur final.

L’archivage se résume à des recherches ponctuelles sur des clés aléatoires. C’est ce schéma d’accès qui, pour des raisons structurelles, met en échec un moteur en colonnes. Ce n’est pas une question de réglage, de partitionnement ni de tri des vues. Les contraintes rencontrées avec ClickHouse sont inhérentes à ce choix et non accidentelles à la configuration. La charge de travail historique de Solana est définie par son schéma d’accès le plus difficile, et non par le plus simple. 

À l’échelle d’un réseau qui ambitionne de devenir la couche de règlement de la finance mondiale, la couche de lecture ne peut pas se limiter à une version mieux réglée de celle que nous avons déjà dépassée. Les institutions et les applications qui dépendent de requêtes historiques riches ont besoin de méthodes, d’une couverture et de latences que la pile par défaut ne peut pas fournir. La couche de lecture de Solana doit reposer dès le départ sur une fondation adaptée au cas le plus difficile. C’est le pari que nous avons fait avec RocksDB, et la norme à laquelle nous soumettons tout le reste.

Si vous souhaitez construire l’avenir de la finance à grande échelle, venez le construire avec nous. Solana avance à toute vitesse pour devenir la couche de règlement de la finance mondiale, et l’archivage n’est qu’une pièce d’un puzzle bien plus vaste. Si le compactage LSM, l’optimisation par index ou la résolution de problèmes système complexes sur certains des meilleurs matériels disponibles vous intéressent, vous vous sentirez chez vous ici.

Nous recrutons dans toute notre équipe d’ingénierie. Consultez tous nos postes à pourvoir sur helius.dev/careers.

Abonnez-vous à Helius

Suivez les dernières actualités du développement sur Solana et recevez une notification à chaque publication

Image agrandie