Skip to content

Makeph/gorilla-tsc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gorilla-tsc

Compresser la télémétrie temps-réel jusqu'à ~1 bit par point — sans rien perdre. Timestamps en delta-of-delta + floats en XOR, l'algorithme Gorilla de Facebook (Pelkonen et al., VLDB 2015), en Python pur stdlib, sans dépendance.

  capteur / PLC        flux (ts, valeur)        GorillaEncoder            transport
  ┌──────────┐  ───────────────────────────▶  ┌───────────────────┐  ───────────────▶  edge → cloud
  │ 21.3°C   │   (1700000001, 21.3)            │  ts: delta-of-delta│   ~1–8 bits/pt
  │ 21.3°C   │   (1700000002, 21.3)            │  val: XOR + frame  │   (vs 128 bits
  │ 21.4°C   │   (1700000003, 21.4)            │  → bitstream        │    en brut)
  └──────────┘                                 └───────────────────┘

Une donnée de série temporelle brute, c'est 16 octets par point : 8 pour l'horodatage, 8 pour le double. Sur une passerelle edge qui pousse des milliers de capteurs vers le cloud, c'est le poste de coût numéro un — bande passante, stockage TSDB, facture. Gorilla exploite deux régularités physiques pour faire fondre ça sans perte.

Les deux idées

1. Timestamps → delta-of-delta. La télémétrie est échantillonnée sur une horloge : les deltas successifs sont quasi constants. On encode donc la variation du delta. Échantillonnage parfaitement régulier → 1 seul bit par point. Une gigue est rangée dans des buckets de plus en plus larges (7 / 9 / 12 / 64 bits).

2. Valeurs → XOR. Deux lectures consécutives d'un capteur physique partagent l'essentiel de leurs bits IEEE-754. Le XOR des voisins laisse une courte plage de bits utiles encadrée de zéros ; on ne stocke que cette plage, et on réutilise le cadre précédent tant qu'il tient. Valeur inchangée → 1 seul bit.

Le tout est strictement sans perte : decompress(compress(points)) == points, bit pour bit sur les double (NaN, ±inf, ±0.0 et subnormaux compris — c'est testé).

Démarrage rapide

pip install -e .
python -m gorilla bench --points 20000
points                20,000
raw (16 B/pt)        320,000 B
gorilla-tsc           48,932 B
ratio                   6.5x
bits / point           19.57
round-trip       lossless OK

En Python :

from gorilla import compress, decompress

points = [(1700000000, 21.3), (1700000001, 21.3), (1700000002, 21.4)]
blob = compress(points)            # -> bytes, prêt à pousser sur MQTT / S3 / TSDB
assert decompress(blob) == points  # round-trip sans perte

API streaming (un point à la fois, mémoire constante) :

from gorilla import GorillaEncoder

enc = GorillaEncoder()
for ts, value in bridge.stream(...):   # ex. la sortie d'industrial-retrofit
    enc.add(ts, value)
payload = enc.to_bytes()

Ce que ça donne vraiment

Mesures réelles sur 50 000 points (16 B/point en brut). Gorilla excelle quand les valeurs se répètent ou dérivent lentement — le cas normal d'un capteur — et dégrade gracieusement (jamais en dessous du brut) sur du bruit haute entropie.

forme du signal brut gorilla-tsc ratio bits/point
lecture constante 800 KB 12.5 KB 63.9x 2.00
capteur lent, résolution 0.1 800 KB 125 KB 6.4x 20.05
bruité, 2 décimales (pire cas) 800 KB 329 KB 2.4x 52.67

Pas de promesse marketing « 100x » : sur du signal réel à résolution finie on est typiquement entre 6x et 16x, et le pire cas reste gagnant.

Format & CLI

Le blob commence par un magic GOR1 + le nombre de points (uint32 big-endian), suivi du bitstream. Outils en ligne de commande :

gorilla bench --points 100000        # mesure le ratio sur de la télémétrie synthétique
gorilla compress in.csv out.gor      # CSV (timestamp,value) -> blob compressé
gorilla decompress out.gor           # blob -> CSV sur stdout (ou un fichier)

Pourquoi c'est solide

  • Zéro dépendance — tourne sur une passerelle edge contrainte, un Raspberry Pi, une Lambda. Les primitives bit-level (BitWriter/BitReader) sont incluses.
  • Sans perte, prouvé — suite de tests round-trip, dont du fuzzing pseudo-aléatoire et les cas IEEE-754 limites (NaN, ±inf, subnormaux, gros sauts d'horloge).
  • StreamingGorillaEncoder.add() encode en O(1) mémoire ; pas besoin de charger toute la série.
pip install -e ".[dev]"
pytest -q        # 36 tests

Compagnon

Pensé pour s'enchaîner avec industrial-retrofit : celui-ci transforme des registres Modbus legacy en télémétrie SI propre, gorilla-tsc la compresse pour le transport edge → cloud.

Licence

MIT — voir LICENSE.

About

Pure-stdlib Gorilla time-series compression: delta-of-delta timestamps + XOR floats for industrial/IoT telemetry. Lossless, zero-dependency.

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages