API Maker

The framework for AI era

Level 4 · ResilientArchitecture 09 of 13

Clustered Redis and databases

Redis Cluster, a MongoDB replica set and sharded data: a data tier with no single node to lose.

The data tier becomes clusters. Redis runs as masters with replicas, API Maker DB and its logs live on a replica set of three, and your own data can be sharded. When a node fails, a copy takes over and API Maker follows by itself.

See it live

Every request is drawn as it travels. Slow it down, pause, go step by step, or open the full canvas and zoom in.

api-maker/architectures/clustered-dataLive
  • Request
  • Response
  • Cache hit
  • Log writes
  • Replication
Redis masters
3/3serving
Redis replicas
3/3ready
Primary
mongo-1of rs0
Members
3/3of rs0 up

Redis as a cluster: the keys shared by three masters. List several nodes in redisInternal or redisExternal and API Maker connects in cluster mode. Each key lives on one master.

How it works

The same steps as the diagram, in more detail.

  1. Redis as a cluster: the keys shared by three masters.

    When redisInternal or redisExternal list more than one node, API Maker connects to them as a Redis Cluster. The cluster splits its 16,384 hash slots between the masters, so cached responses, locks, auto increments and WebSocket subscriptions are spread over three machines. When memory runs short, add a master and move a share of the slots to it.

  2. Every master has a replica.

    Each master streams its writes to a replica running on another VPS: redis-4 copies redis-1, redis-5 copies redis-2, redis-6 copies redis-3. Reads and writes stay on the masters, while the replicas keep a live copy of the same slots, ready to take over.

  3. A master fails, its replica takes over.

    When a master stops answering for longer than the node timeout of the cluster, the other masters promote its replica. The Redis client of API Maker receives the new map of the slots and sends their keys to the new master. Only the keys of the failed master wait during the switch: the other masters serve theirs all along.

  4. API Maker DB on a replica set of three.

    API Maker keeps its definitions and its logs in MongoDB, and needs a replica set anyway for its transactions. With three members on three VPS, every write lands on the primary and is copied to both secondaries. List the three members in the connection string: the driver finds the primary by itself.

  5. The primary fails, a new one is elected.

    When the primary stops, the two remaining members still form a majority and elect a new primary, typically within about twelve seconds with the default settings. The MongoDB driver of API Maker finds the new primary by itself and retries the writes that can be retried. Writes pause only during the election.

  6. Failed nodes come back as copies.

    Repair or replace the failed machines and start them again. A Redis master that comes back joins as a replica of the node that replaced it, and a MongoDB member catches up on what it missed before it serves again. API Maker needs no restart and no change of settings at any point.

Why choose this architecture

No single data node

Every Redis slot has a replica and API Maker DB lives on three machines: one failed node stops no API.

Automatic failover

Redis promotes a replica, MongoDB elects a new primary, and API Maker follows both without a restart.

Memory that adds up

Cached responses, locks and WebSocket subscriptions are spread over the masters. Add one when memory runs short.

A replica set that pays twice

The replica set API Maker needs for its transactions also keeps live copies of every definition and log.

Your data scales too

Point an instance at the mongos routers of a sharded MongoDB, or at any cluster your database offers.

Only settings change

A list of nodes for Redis, a list of hosts for MongoDB. No code, no plugin, the same APIs.

Server configuration

Plain VPS from any provider, or your own servers, with Ubuntu 22.04 LTS. Sizes are a starting point: measure and adjust.

Load balancer

×1
CPU
2 vCPU
Memory
2 GB
Storage
20 GB SSD

Runs

  • HAProxy or Nginx, HTTP and WebSocket
  • Health checks of the API servers

Ports

  • 443: HTTPS and secure WebSocket

API servers

×3 or more
CPU
4 – 8 vCPU
Memory
8 – 16 GB
Storage
40 GB SSD

Runs

  • API Maker, the same .env on every server
  • Connected to every node of the clusters

Ports

  • 38246 and 38245: from the load balancer only

Redis nodes

×6: 3 masters, 3 replicas
CPU
2 vCPU
Memory
4 – 16 GB
Storage
20 GB SSD

Runs

  • Redis 7, cluster-enabled yes
  • Cache, locks, events, auto increments, WebSocket subscriptions

Ports

  • 6379: from the API servers and the other nodes
  • 16379: cluster bus, between the nodes only

Never put a master and its own replica on the same VPS.

MongoDB members

×3
CPU
4 vCPU
Memory
8 – 16 GB
Storage
100 GB+ NVMe

Runs

  • MongoDB, replica set rs0
  • api_maker_db and api_maker_logs

Ports

  • 27017: from the API servers and the other members

Keep an odd number of members, three or five, so a majority remains after a failure.

Your data

as needed
CPU
8+ vCPU
Memory
32 GB+
Storage
500 GB+ NVMe

Runs

  • Sharded MongoDB: mongos, config servers and shards
  • Or a TiDB, Percona XtraDB or MariaDB Galera cluster

Ports

  • From the API servers only
Every API server: the nodes of the clusters.env
# API Maker DB and logs: the three members of the replica setam__mongo_db_connection="mongodb://api_maker:***@10.0.3.11:27017,10.0.3.12:27017,10.0.3.13:27017/api_maker_db?authSource=admin&replicaSet=rs0"am__logs__mongo_db_connection_logs="mongodb://api_maker:***@10.0.3.11:27017,10.0.3.12:27017,10.0.3.13:27017/api_maker_logs?authSource=admin&replicaSet=rs0"# More than one node: API Maker connects in cluster mode and finds the replicas by itselfam__redisInternal='{"nodes": [{host: "10.0.2.11", port: 6379, pass: "***"}, {host: "10.0.2.12", port: 6379, pass: "***"}, {host: "10.0.2.13", port: 6379, pass: "***"}]}'am__redisExternal='{"nodes": [{host: "10.0.2.11", port: 6379, pass: "***"}, {host: "10.0.2.12", port: 6379, pass: "***"}, {host: "10.0.2.13", port: 6379, pass: "***"}], redisValueExpireInSeconds: 7200}'

redisInternal and redisExternal can list the same cluster, or a cluster each.

Create the Redis Clusterredis.conf · redis-cli
# redis.conf on each of the 6 nodescluster-enabled yescluster-config-file nodes.confcluster-node-timeout 5000     # ms before a silent master is replacedrequirepass ***masterauth ***# Once, from any node: 3 masters with 1 replica eachredis-cli -a *** --cluster create \    10.0.2.11:6379 10.0.2.12:6379 10.0.2.13:6379 \    10.0.2.14:6379 10.0.2.15:6379 10.0.2.16:6379 \    --cluster-replicas 1
Start the replica set, oncemongosh
rs.initiate({    "_id": "rs0",    "members": [        { "_id": 0, "host": "10.0.3.11:27017" },        { "_id": 1, "host": "10.0.3.12:27017" },        { "_id": 2, "host": "10.0.3.13:27017" }    ]})

Start each mongod with replSetName rs0 and a shared keyFile, then run this on one of them.

Good to know

  • More machines to run and watch: six Redis nodes and three MongoDB members instead of one of each.
  • Redis copies to its replicas asynchronously: a failover can lose the last writes of the failed master.
  • Spread the copies well: a master and its replica, or two members of the replica set, on one VPS fail together.
  • The load balancer is still a single machine here. The High availability architecture doubles it.
When you outgrow itThe load balancer and the servers must survive the loss of a machine, or of a data center. High availability

Questions

How do I make Redis fail over automatically?

Run a Redis Cluster and list its nodes in redisInternal and redisExternal. API Maker connects to a single node when one is listed, and to the cluster when there are several. Even three masters with one replica each give every key a copy ready to take over.

Should redisInternal and redisExternal share a cluster?

They can. On busy setups, give each its own cluster: cached responses in redisExternal may be evicted when memory runs short, while redisInternal holds locks, events, auto increments and WebSocket subscriptions that must stay.

Which clusters can hold my own data?

Whatever your database offers behind a connection string: MongoDB replica sets and sharded clusters through mongos, TiDB, Percona XtraDB and MariaDB Galera clusters, or a primary with standbys behind a virtual IP for PostgreSQL, MySQL, SQL Server and Oracle. API Maker generates the same APIs on each of them.

What do the apps notice during a failover?

Requests that need the keys of the failed Redis master, and writes during a MongoDB election, wait or fail for the seconds the switch takes. Everything else is served as usual, and API Maker needs no restart before or after.