Régie · en cours, plus de 12 mois
Groupe bancaire national
Des ingénieurs embarqués dans les équipes du client, sur leur dépôt et leur chaîne de production. Ce qui se faisait à la main est décrit, versionné et relu.
Ce que nous faisons · expertise
Des données que l'on peut interroger, tracer et déplacer.
Nous concevons et exploitons des socles de données ouverts : formats de table ouverts, moteur de requête découplé du stockage, lignée et catalogue. Le critère qui guide chaque choix est la réversibilité — pouvoir partir sans réécrire.
Méthode
Un socle de données se juge à ce qu'il en coûte d'en sortir. Tant que le format de table, le catalogue et le moteur appartiennent au même fournisseur, la question « combien coûterait un changement » n'a pas de réponse : elle a un devis. Nous construisons dans l'autre sens — des tables Iceberg posées sur un stockage objet que vous possédez, un moteur découplé de ce stockage, un catalogue lisible sans licence.
Ce que nous savons faire de plus que la moyenne du marché commence un étage plus bas. Nous n'utilisons pas seulement Trino : nous écrivons le client Trino. trino-rust-client est un fork de prusto repris en décembre 2024 — support Presto retiré, fonctionnalités Trino avancées ajoutées — soit quarante-cinq fichiers Rust et 6 374 lignes, publiées sous licence MIT.
Le protocole de spooling est l'exemple qui rend la nuance concrète. Dans le protocole historique, chaque page de résultat remonte par le coordinateur, sérialisée en JSON : sur un gros export, c'est le coordinateur qui porte les octets, la mémoire et le processeur de tout le monde, et les requêtes interactives des autres équipes en pâtissent. Avec le spooling, le coordinateur ne renvoie plus les lignes — il renvoie des descripteurs de segments : une adresse sur le stockage objet, un décalage de ligne, un nombre de lignes, une taille.
Le client fait le reste, et c'est le code ci-contre. Il va chercher les segments directement sur le stockage, en parallèle borné, les décompresse — zstd ou lz4 selon ce que le coordinateur annonce — puis acquitte chaque segment pour que le stockage soit libéré au lieu d'attendre l'expiration. Descendre à ce niveau n'est pas un raffinement de bibliothèque : c'est la différence entre un export massif qui coexiste avec les requêtes du reste de l'entreprise et un export qui les fait tomber.
Ce type de socle traite 100s To (1) en pointe sur une plateforme que nous exploitons. Le chiffre est une pointe observée, pas un plafond garanti : il figure ici avec son périmètre, et nulle part sans lui. Ce que le format ouvert et le client ne règlent pas, en revanche, c'est la qualité de ce qui entre et le coût de ce qui calcule. ▪
Le dépôt d'où vient ce code
trino-rust-client
Client Trino en Rust. Fork de prusto repris en décembre 2024 : support Presto retiré, fonctionnalités Trino avancées ajoutées, dont le protocole de spooling.
github.com/nudibranches-tech/trino-rust-client
Mesures relevées sur src/, hors tests et exemples.
// Segment is a part of a query result when using the spooling protocol
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase", untagged)]
pub enum Segment {
// Inlined segment
Inlined {
#[serde(rename = "type")]
segment_type: String,
data: String,
metadata: DataAttributes,
},
// Spooled segment
Spooled {
#[serde(rename = "type")]
segment_type: String,
uri: String,
#[serde(rename = "ackUri")]
#[serde(skip_serializing_if = "Option::is_none")]
ack_uri: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
headers: Option<HashMap<String, Vec<String>>>,
metadata: DataAttributes,
},
} /// Fetch a single segment and return the decoded data
pub async fn fetch_segment(&self, segment: &Segment) -> Result<Vec<u8>> {
match segment {
Inlined { data, .. } => self.fetch_inline_segment(data).await,
Segment::Spooled {
uri,
ack_uri,
headers,
..
} => {
let data = self.fetch_spooled_segment(uri, headers.as_ref()).await?;
// Acknowledge the segment if ackUri is provided
if let Some(ack) = ack_uri {
if let Err(e) = self.acknowledge_segment(ack, headers.as_ref()).await {
tracing::warn!("Failed to acknowledge segment {}: {}", ack, e);
}
}
Ok(data)
}
}
}Périmètre
Le critère qui tranche est le coût du départ, calculé le jour de l'entrée.
Missions
Décrits par le dispositif mis en place et par ce qu'il a produit.
Régie · en cours, plus de 12 mois
Des ingénieurs embarqués dans les équipes du client, sur leur dépôt et leur chaîne de production. Ce qui se faisait à la main est décrit, versionné et relu.
Conseil et mise en œuvre · en cours
Un socle Kubernetes sur système immuable, décrit intégralement dans un dépôt GitOps qui porte quatorze applications. Ce dépôt est le seul point d'entrée : il tient l'infrastructure comme les services qui tournent dessus.
Prendre contact
Trente minutes suffisent pour situer une pile de données sur un seul axe : ce qu'il en coûterait d'en changer. Nous vous le dirons aussi quand la réponse est qu'il n'y a rien à changer — c'est arrivé, et cela ne se facture pas.