MySQL/MariaDB Replication Cache with Redis API
msec is a disk cache with a Redis compatible API using MySQL/MariaDB replication to remain consistent. Inserts, updates or deletes in the database are replicated in real time and persisted to a local store.
Architecture
msec is a docker container with these major components:
- Protocol emulator, providing a Redis compatible API
- Storage engine, responding to read and write requests
- K/V plugin uses the
/data
directory for persistent storage, which should be mounted as a Docker volume. - Database replica, implementing the binary replication protocol for both MySQL and MariaDB
- Telemetry, providing a Prometheus compatible scraping endpoint
Replication
Both MySQL and MariaDB support replication where log events are streamed to a replica in real-time. Both databases have similar terminology, but use different implementations of Global Transaction Identifiers (GTID), msec uses the correct dialect when using either database.
Each table is mapped into a local key-value store identified using the primary or composite key fields. Delete, update and insert events are replicated into the local store. The current GTID is also persisted for recovery on restart.
Redis Compatible API
msec understands the Redis protocol providing a compatible API.
The Redis API keys used by msec have the following format:
database.table.key
For example, the following key:
shortishly.grades.234-56-7890
The above key represents the record identified by 234-56-7890
, found
in the grades
table in the shortishly
database.
For composite keys a “/” is used to separate the different elements:
shortishly.cities.Tulsa/OK
The above key represents the city Tusla
in the state of OK
found
in the cities
table in the shortishly
database.
Getting Started
Follow the Docker installation instructions to get Docker running on your system.
Clone the msec repository for the docker compose.yaml with a MySQL my.cnf (or MariaDB my.cnf) setup for replication, and some sample data included:
git clone https://github.com/shortishly/msec.git
Alternatively, with the Github CLI installed use:
gh repo clone shortishly/msec
Change to the newly cloned directory:
cd msec
Start everything up with MySQL 8.1:
./bin/up
To use MariaDB instead use:
MYSQL_IMAGE=mariadb:11.1 ./bin/up
Or Percona 8:
MYSQL_IMAGE=percona:8 ./bin/up
From the sample data, we will be using the
grades
table in the shortishly
database which uses the SSN
as
the primary key:
"Last name","First name","SSN","Test1","Test2","Test3","Test4","Final","Grade"
"Alfalfa","Aloysius","123-45-6789",40.0,90.0,100.0,83.0,49.0,"D-"
"Alfred","University","123-12-1234",41.0,97.0,96.0,97.0,48.0,"D+"
"Gerty","Gramma","567-89-0123",41.0,80.0,60.0,40.0,44.0,"C"
"Android","Electric","087-65-4321",42.0,23.0,36.0,45.0,47.0,"B-"
"Bumpkin","Fred","456-78-9012",43.0,78.0,88.0,77.0,45.0,"A-"
"Rubble","Betty","234-56-7890",44.0,90.0,80.0,90.0,46.0,"C-"
"Noshow","Cecil","345-67-8901",45.0,11.0,-1.0,4.0,43.0,"F"
"Buff","Bif","632-79-9939",46.0,20.0,30.0,40.0,50.0,"B+"
"Airpump","Andrew","223-45-6789",49.0,1.0,90.0,100.0,83.0,"A"
"Backus","Jim","143-12-1234",48.0,1.0,97.0,96.0,97.0,"A+"
"Carnivore","Art","565-89-0123",44.0,1.0,80.0,60.0,40.0,"D+"
"Dandy","Jim","087-75-4321",47.0,1.0,23.0,36.0,45.0,"C+"
"Elephant","Ima","456-71-9012",45.0,1.0,78.0,88.0,77.0,"B-"
"Franklin","Benny","234-56-2890",50.0,1.0,90.0,80.0,90.0,"B-"
"George","Boy","345-67-3901",40.0,1.0,11.0,-1.0,4.0,"B"
"Heffalump","Harvey","632-79-9439",30.0,1.0,20.0,30.0,40.0,"C"
In this example, using hgetall, we get all the hash
members in the shortishly
database, from the grades
table,
identified by 234-56-7890
(Betty Rubble).
redis-cli hgetall shortishly.grades.234-56-7890
1) "test4"
2) "90.0"
3) "test3"
4) "80.0"
5) "test2"
6) "90.0"
7) "test1"
8) "44.0"
9) "ssn"
10) "234-56-7890"
11) "last"
12) "Rubble"
13) "grade"
14) "C-"
15) "first"
16) "Betty"
17) "final"
18) "46.0"
Or using hget, we get just Betty’s grade:
redis-cli hget shortishly.grades.234-56-7890 grade
"C-"
A ‘C-‘ seems harsh, lets give her a ‘C’ instead:
./bin/db-sql \
--execute="update shortishly.grades set grade='C' where ssn='234-56-7890'"
(./bin/db-sql
will use either mysql
or mariadb
depending on the
database that you’ve chosen).
The cache is automatically updated:
redis-cli hget shortishly.grades.234-56-7890 grade
"C"
Any updates to the MySQL/MariaDB database are replicated through to
msec
in real-time. Unless deleted, a row remains in the disk based
storage, updated when required by the database replication process.