Skip to content

MrPoll0/geostreamdb

Repository files navigation

GeoStreamDB

CI

Distributed geospatial ping storage and query engine with area queries, a sharded architecture and full observability. Built with Go and Kubernetes (with a Docker Compose version).

A ping is a single point in space and time that lives for a fixed duration (TTL; currently 10 seconds). Pings can be stored by sending a HTTP request to the API with the location coordinates (lat/lng). They can also be queried by area, by sending a HTTP request to the API with a bounding box and a precision. The precision is the number of characters in the geohash prefix, which defines the granularity of the query.

GeoStreamDB is split into three core services:

  • gateway: HTTP API (/ping, /pingArea) and request routing
  • worker-node: shard storage/aggregation workers (gRPC)
  • registry: service discovery and heartbeat coordination (gRPC)

The repo also includes observability and test tooling:

  • Prometheus + Grafana + Alertmanager
  • Kubernetes manifests
  • Docker Compose local stack
  • k6 test scenarios

Architecture (high level)

GeoStreamDB architecture

Ping ingestion flow (POST /ping)

  1. Registry acts as a single point of truth for worker/gateway heartbeats for service discovery.
  2. Client sends a HTTP request to the Load Balancer entrypoint (Docker Compose: loadbalancer nginx on :8080; Kubernetes: Gateway API via NGINX Gateway Fabric).
  3. Load Balancer routes the request to a gateway replica.
  4. Gateway maps the ping to a worker node via consistent hashing (a ring with virtual nodes). The sharding key is the first SHARDING_PRECISION characters of the geohash.
  5. Gateway calls the selected worker node via gRPC (SendPing).
  6. Worker node stores the ping in a 10s TTL time-buffer, where each time slot contains a Trie keyed by geohash prefixes (with a dense leaf optimization at SHARDING_PRECISIONMAX_GH_PRECISION) with the ping count as value.

Area query flow (GET /pingArea)

  1. Client sends a HTTP request to the Load Balancer entrypoint.
  2. Load Balancer routes the request to a gateway replica.
  3. Gateway computes a geohash cover set for the bounding box and chooses an aggregated precision to bound fanout.
  4. Gateway either:
    • routes each covered geohash to its responsible worker(s) via gRPC (GetPingArea) when the aggregated precision is at/above the sharding precision, or
    • broadcasts the request to all workers (when the aggregated precision is below the sharding precision).
  5. Worker nodes traverse their TTL time-buffer and aggregate counts from the Trie for the requested area (with bbox intersection filtering), then return results.

Extras

  • Prometheus scrapes metrics from all components.
  • Grafana dashboards for monitoring and alerting.
  • Alertmanager with Prometheus alerting rules.

Repository layout

  • gateway/ - HTTP API and routing logic
  • worker-node/ - gRPC worker service
  • registry/ - gRPC registry/discovery service
  • proto/ - protobuf definitions
  • k8s/ - Kubernetes manifests (deployments, services, HPA, Gateway API)
  • overlays/ - Kustomize overlays (minikube, prod)
  • prometheus/ - Prometheus and Alertmanager configuration
  • grafana/ - dashboards and provisioning
  • test/ - test scripts and results. run-tests.ps1 orchestrates tests.
  • loadbalancer/ - NGINX configuration for Docker Compose version

Prerequisites

There are 2 versions for local development and testing:

  • Docker + Docker Compose (default)
  • Kubernetes + Minikube

Required tooling:

Quickstart (Docker Compose)

Start the stack:

docker compose up --build -d

Default local endpoints:

  • API entrypoint: http://localhost:8080
  • Grafana: http://localhost:3000
  • Prometheus: http://localhost:9090
  • Alertmanager: http://localhost:9093
  • Example web app: index.html

Web Sample Heatmap

Stop:

docker compose down

Quickstart (Kubernetes via test runner)

Run a k6 scenario and bootstrap infra automatically:

./test/run-tests.ps1 -UseKubernetes -Test sustained-load

This script uses:

  • Minikube
  • NGINX Gateway Fabric + Gateway API resources
  • App and observability manifests
  • Local port-forwards for API/Prometheus/Grafana/Alertmanager

API (current)

Gateway HTTP endpoints:

  • POST /ping with JSON body: { "lat": <float>, "lng": <float> }
  • GET /ping?lat=<float>&lng=<float>
  • GET /pingArea?minLat=...&maxLat=...&minLng=...&maxLng=...&precision=...
  • GET /metrics

Observability and alerts

Prometheus alerting is configured with Alertmanager.

Current baseline alert rules include:

  • target down (up == 0)
  • high node CPU/memory
  • high pod CPU/memory (namespace geostreamdb)
  • Prometheus-to-Alertmanager disconnect

Local UIs:

  • Prometheus: http://localhost:9090
  • Alertmanager: http://localhost:9093
  • Grafana: http://localhost:3000

Gateway Grafana Dashboard System Grafana Dashboard

Running tests

Examples:

# default (Docker Compose)
./test/run-tests.ps1 -Test sustained-load

# Kubernetes
./test/run-tests.ps1 -UseKubernetes -Test all-direct

# Orchestrated scenarios (includes known disruptive tests)
./test/run-tests.ps1 -UseKubernetes -Test all-orchestrated

Artifacts are written under k6/outputs.

Notes

No open-source license has been granted at this time. All rights reserved.

About

Distributed geospatial ping storage and query engine built with Go, gRPC, Kubernetes, and full observability

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors