Scalable package delivery logistics simulator built using SingleStore and Vectorized Redpanda

Reference Architecture using SingleStore and Redpanda for global logistics

📯 INFO: For the story behind this code (and epic dashboards), check out the blog post!

This repository provides a reference architecture which simulates the parcel tracking system of a hypothetical global logistics company using SingleStore and Redpanda.

Architecture overview

architecture diagram

Data model

data model

Running locally

  1. Sign up for a free SingleStore license. This allows you to run up to 4 nodes up to 32 gigs each for free. Grab your license key from SingleStore portal and set it as an environment variable.
export SINGLESTORE_LICENSE="<<singlestore license>>"
  1. Run the simulation locally using make and then check that everything is running correctly using docker-compose ps
$ make
...SNIP output...
Successfully built fad3bf30af1d
Successfully tagged singlestore-logistics-simulator:latest
Creating simulator ... done

$ docker-compose ps
   Name                 Command               State
---------------------------------------------------
grafana      /run.sh                          Up
prometheus   /bin/prometheus --config.f ...   Up
rp-node-0    /usr/bin/rpk redpanda star ...   Up
rp-setup     /bin/bash -c rpk --brokers ...   Exit 0
s2-agg-0     /startup                         Up
simulator    ./simulator --config confi ...   Up

NOTE: If you are running the above on a mac you may need to increase the docker system resources. We have found that 6 GB of RAM and 2 CPUs is sufficient to run this demo - but the more you provide to docker the faster things will go. :)

  1. You can also check the logs using
make logs

# or specify a specific service like so:
make logs SERVICE=simulator

At this point you can open up any of the services below to view dashboards, cluster information or run queries against the dataset:

service url user password
Grafana http://localhost:3000 root root
SingleStore http://localhost:8080 root root
Prometheus http://localhost:9090

NOTE: The node exporter is not run locally, so the node exporter dashboard will not work out of the box.

Deploying into Google Cloud

This repo contains a full Terraform based deployment solution which will result in this simulator running at nearly unlimited scale in the cloud.

WARNING: Before running this in your own environment be cautious to read the variables carefully and tune it to your own appetite. It's easy to burn a lot of money very quickly. SingleStore and Vectorized do not take responsibility for any costs or issues you may have while using this repository. Please be careful.

Without going into too much detail (if you want to do this, you need to understand how Terraform works), follow these steps to run everything in Google Cloud:

  1. Create deploy/terraform-gcp/terraform.tfvars to set variables. You will need at least these variables set to continue:
project_name = "YOUR PROJECT NAME"
region = "THE REGION YOU WANT TO USE"
zone = "THE ZONE YOU WANT TO USE: i.e. a, b, c"

s2_license = "YOUR SINGLESTORE LICENSE KEY - GET THIS FROM THE PORTAL"
  1. Deploy! (make sure to read everything carefully)
cd deploy/terraform-gcp
terraform apply
  1. Grafana, Studio, and Prometheus are running locally on the logistics-dashboard which you can access via the following port forwarding options:
gcloud compute ssh logistics-dashboard -- -L 9090:localhost:9090 -L 3000:localhost:3000 -L 8080:localhost:8080

Redpanda topic schemas

The simulator is a go program which generates package histories and writes them into Redpanda topics.

There are two topics:

  • packages
  • transitions

Packages topic

The packages topic contains a record per package. The record is written when we receive the package in question.

Avro schema:

{
    "type": "record",
    "name": "Package",
    "fields": [
        { "name": "PackageID", "type": { "type": "string", "logicalType": "uuid" } },
        { "name": "SimulatorID", "type": "string" },
        { "name": "Received", "type": { "type": "long", "logicalType": "timestamp-millis" } },
        { "name": "DeliveryEstimate", "type": { "type": "long", "logicalType": "timestamp-millis" } },
        { "name": "OriginLocationID", "type": "long" },
        { "name": "DestinationLocationID", "type": "long" },
        { "name": "Method", "type": { "name": "Method", "type": "enum", "symbols": [
            "standard", "express"
        ] } }
    ]
}

Transitions topic

The transitions topic is written to whenever a package changes states. A normal package goes through the following transitions during it's lifetime:

  1. arrival scan - the package has been received
  2. departure scan - the package has been scanned and put in transit to another location
    • arrival scan and departure scan can occur multiple times as the package moves through our global logistics network
  3. delivered - the package has been delivered

NOTE: We don't currently model last-mile delivery, but it's an interesting problem space for a future iteration on this project.

Avro schema:

{
    "type": "record",
    "name": "PackageTransition",
    "fields": [
        { "name": "PackageID", "type": { "type": "string", "logicalType": "uuid" } },
        { "name": "Seq", "type": "int" },
        { "name": "LocationID", "type": "long" },
        { "name": "NextLocationID", "type": ["null", "long"] },
        { "name": "Recorded", "type": { "type": "long", "logicalType": "timestamp-millis" } },
        { "name": "Kind", "type": { "name": "Kind", "type": "enum", "symbols": [
            "arrival_scan", "departure_scan", "delivered"
        ] } }
    ]
}

Interesting queries

Please contribute interesting queries on the dataset as you find them!

Show the full history of a single package

Replace the package id with a package you want to track.

SELECT
    pt.seq,
    pt.kind,
    current_loc.city,
    current_loc.country,
    GEOGRAPHY_DISTANCE(current_loc.lonlat, destination.lonlat) / 1000 AS distance_to_destination,
    pt.recorded
FROM package_transitions pt
INNER JOIN locations current_loc ON pt.locationid = current_loc.locationid
INNER JOIN packages p ON pt.packageid = p.packageid
INNER JOIN locations destination ON p.destination_locationid = destination.locationid
WHERE pt.packageid = '516aa045-d8df-4363-b250-da335df82269'
ORDER BY seq DESC;
Owner
SingleStore Labs
The home of SingleStore community content
SingleStore Labs
Similar Resources

Experiments using Go 1.18beta1's Generic typings and the Segmentio kafka-go consumer client

Experiments using Go 1.18beta1's Generic typings and the Segmentio kafka-go consumer client

Jan 28, 2022

Package notify provides an implementation of the Gnome DBus Notifications Specification.

go-notify Package notify provides an implementation of the Gnome DBus Notifications Specification. Examples Display a simple notification. ntf := noti

Dec 27, 2022

The official Go package for NSQ

go-nsq The official Go package for NSQ. Docs See godoc and the main repo apps directory for examples of clients built using this package. Tests Tests

Jan 5, 2023

A simple pubsub package for go.

Package pubsub implements a simple multi-topic pub-sub library. Install pubsub with, go get github.com/cskr/pubsub This repository is a go module and

Dec 31, 2022

Simple synchronous event pub-sub package for Golang

event-go Simple synchronous event pub-sub package for Golang This is a Go language package for publishing/subscribing domain events. This is useful to

Jun 16, 2022

An opinionated package that helps you print user-friendly output messages from your Go command line applications.

github.com/eth-p/clout (Command Line Output) clout is a package that helps you print user-friendly output messages from your Go command line applicati

Jan 15, 2022

Redis as backend for Queue Package

Redis as backend for Queue Package

redis Redis as backend for Queue package Setup start the redis server redis-server start the redis cluster, see the config # server 01 mkdir server01

Oct 16, 2022

NSQ as backend for Queue Package

NSQ as backend for Queue Package

NSQ as backend for Queue Package

Jul 4, 2022

Package htmltopdf implements wkhtmltopdf Go bindings.

htmltopdf Package htmltopdf implements wkhtmltopdf Go bindings. It can be used to convert HTML documents to PDF files. The package does not use the wk

Sep 19, 2022
Comments
  • adding metrics

    adding metrics

    This PR updates docker-compose to run prometheus + grafana and wire everything together. In addition we enable all the exporters in order to expose metrics. Finally, this PR adds a couple dashboards for some basic monitoring.

    We're getting ready for prime-time tv folks.

  • add parallelism!

    add parallelism!

    This CR modifies the simulator so it we can run many instances of it in the cluster. This was decided as the easiest way to scale out - versus having each simulator binary attempt to consume 100% of the machine.

    In addition this CR upgrades the number of singlestore partitions per leaf as well as the number of paritions per topic on the redpanda side.

  • Working simulator

    Working simulator

    First pass on a fully functioning simulator.

    Shortcuts I took on purpose:

    • more use of reflection than I would like
    • magic numbers
    • inline unit conversions - eventually should replace with nicer unit aware types
    • extremely inprecise distance calculations

    Hopefully the code is somewhat straight forward. Plan on landing then iterating tomorrow morning assuming there isn't anything horrible in here.

  • fix: hadolint fixes for Dockerfile

    fix: hadolint fixes for Dockerfile

    Add basic usage section to readme (snipped from other labs).

    Identified some minor nits from hadolint by running:

    cd simulator
    docker run --rm -i ghcr.io/hadolint/hadolint < Dockerfile
    

    In README, may also want to mention the other related projects, e.g.

    • https://github.com/singlestore-labs/singlestore-avro-sample
    • https://github.com/memsql/pipelines-twitter-demo
    • https://github.com/memsql/singlestore-kafka-connector
The Bhojpur MDM is a software-as-a-service product used as a Mobile Device Manager based on Bhojpur.NET Platform for application delivery.

Bhojpur MDM - Mobile Device Manager The Bhojpur MDM is a software-as-a-service product used as a Mobile Device Manager based on Bhojpur.NET Platform f

Dec 31, 2021
💨 A real time messaging system to build a scalable in-app notifications, multiplayer games, chat apps in web and mobile apps.
💨 A real time messaging system to build a scalable in-app notifications, multiplayer games, chat apps in web and mobile apps.

Beaver A Real Time Messaging Server. Beaver is a real-time messaging server. With beaver you can easily build scalable in-app notifications, realtime

Jan 1, 2023
Scalable real-time messaging server in language-agnostic way
Scalable real-time messaging server in language-agnostic way

Centrifugo is a scalable real-time messaging server in language-agnostic way. Centrifugo works in conjunction with application backend written in any

Jan 2, 2023
A simple visits tracker built using Go and Redis

visits-tracker A simple visits tracker built using Go and Redis Let me note that this is a really bad idea if you are not backing up Redis since it li

Jan 13, 2022
Kafka implemented in Golang with built-in coordination (No ZooKeeper, single binary install, Cloud Native)

Jocko Distributed commit log service in Go that is wire compatible with Kafka. Created by @travisjeffery, continued by nash. Goals: Protocol compatibl

Aug 9, 2021
⚡ HTTP/2 Apple Push Notification Service (APNs) push provider for Go — Send push notifications to iOS, tvOS, Safari and OSX apps, using the APNs HTTP/2 protocol.

APNS/2 APNS/2 is a go package designed for simple, flexible and fast Apple Push Notifications on iOS, OSX and Safari using the new HTTP/2 Push provide

Jan 1, 2023
pubsub controller using kafka and base on sarama. Easy controll flow for actions streamming, event driven.

Psub helper for create system using kafka to streaming and events driven base. Install go get github.com/teng231/psub have 3 env variables for config

Sep 26, 2022
Insta API using Go and Mongodb
Insta API using Go and Mongodb

Insta-API HTTP JSON API that can be used to perform basic tasks of Creating User, Creating Post, Getting User & Post details through their Unique ID.

May 1, 2022
A quick introduction to how Apache Kafka works and differs from other messaging systems using an example application.
A quick introduction to how Apache Kafka works and differs from other messaging systems using an example application.

Apache Kafka in 6 minutes A quick introduction to how Apache Kafka works and differs from other messaging systems using an example application. In thi

Oct 27, 2021
Producer x Consumer example using Kafka library and Go.

Go - Kafka - Example Apache Kafka Commands First of all, run the docker-compose docker-compose up, than run docker exec -it kafka_kafka_1 bash Topics

Dec 8, 2021