rypipe
Framework d'ingestion réutilisable. Cœur Rust, bindings Python. Ajouter un nouveau format en implémentant deux traits.
Les adaptateurs restent petits. Le moteur possède la planification, la mémoire limitée et l'exportation Arrow.
Chargement des derniers commits…
Essais
476
Parallèle (crxml)
7,63 Go/s
Documentation
15,9K lignes
Publié
PyPI + crates.io
Qu'est-ce que rypipe
rypipe est un framework d'ingestion réutilisable, pas un analyseur monoformat. Il sépare l'analyse spécifique au format de l'exécution indépendante du format. Ajoutez un nouveau format en implémentant deux petits traits : Splitter et RecordParser.
rypipe lui-même ne livre pas d'analyseurs. Ceux-ci vivent dans des packages d’adaptateurs séparés. Installez le moteur ainsi que les adaptateurs dont vous avez besoin. Le framework gère la planification parallèle, l'exécution limitée en mémoire, le refoulement des requêtes et un pipeline chaînable API.
Problème
L'analyse des flux d'octets orientés lignes dans des formats en colonnes (Apache Arrow) nécessite généralement l'écriture d'un moteur complet par format. Chaque format possède son propre planificateur parallèle, son propre gestionnaire de mémoire et sa propre infrastructure d'exécution. Le résultat est un effort dupliqué et des caractéristiques de performances incohérentes entre les formats.
Pourquoi c'est dur
La difficulté consiste à séparer l'analyse spécifique au format (deux petits traits) de l'exécution indépendante du format (planification parallèle, mémoire limitée, refoulement de requêtes, exportation Arrow sans copie) tout en maintenant le débit à la bande passante mémoire. La suite de tests de contrat d'adaptateur vérifie que tout adaptateur produit une sortie identique dans les modes d'exécution monothread, parallèle et limité.
Débit mesuré
Le débit dépend de l'adaptateur et de la charge. Derniers benchmarks sur un Ryzen 7 5800X : crxml atteint 4,23 Go/s en RAM complète et 7,63 Go/s en mode borné avec schéma explicite sur un rapport de 533 Mo ; xmlstreamer-ng atteint 2,12 Go/s en parallèle (8 threads) et 1,36 Go/s en parallèle borné sur un flux de 128 Mio.
Contraintes
- Mémoire limitée : impossible de charger des fichiers entiers dans RAM
- L'exécution parallèle doit évoluer linéairement avec les cœurs
- Les étapes du pipeline doivent fusionner dans la boucle d'analyse (pas d'aller-retour Python)
- L'adaptateur API doit être minimal : deux caractéristiques, pas un moteur complet
Décisions clés
Modèle d'adaptateur à deux traits
L'ajout d'un nouveau format nécessite l'implémentation de Splitter et RecordParser. Le moteur gère tout le reste.
Évaluation du prédicat en premier
Les filtres descendent dans la boucle d'analyse Rust. Les lignes qui échouent sont rejetées avant la création d'un objet Python.
Prédiction de mise en page via memcmp
Prédit la structure des lignes à partir des modèles d'octets, en ignorant la découverte des colonnes lorsque le schéma est connu.
Exportation Arrow sans copie
Les données sont déplacées des tampons d'analyse directement vers les tableaux Arrow sans copies intermédiaires.
Origine
rypipe a été initialement développé en tant que moteur d'ingestion pour crxml, un adaptateur Crystal Reports XML. La conception du moteur, les caractéristiques de performance et le API ont été façonnés par l'utilisation en production avec crxml. crxml est l'adaptateur de référence qui a fait ses preuves : schémas imbriqués complexes, fichiers volumineux, traitement parallèle et filtrage avancé.
Compromis
- Les adaptateurs doivent être écrits par format (pas un analyseur universel)
- Le noyau Rust ajoute de la complexité à la construction par rapport au Python pur
- Le schéma doit être connu à l'avance pour un débit maximal