R2DBC Sharding Example with Kotlin Coroutine

Overview

R2DBC Sharding Example with Kotlin Coroutine

  • A minimal sharding example with R2DBC and coroutine, where user table is divided into 2 different shards.
  • To which shard a user belongs is judged by modulo operation on its id.
  • Connection pool for each shard.
  • Following curl command makes a db entry to either shard in a round-robin manner
curl -X POST "http://localhost:8080/users" \
-H "Content-Type: application/json" \
-d '{"name": "foo"}'
  • And, and a user can be retrieved by their id:
curl -X POST "http://localhost:8080/users/1" # DB query is automatically routed to `shard1`.
curl -X POST "http://localhost:8080/users/2" # Routed to `shard0`.

Pre-requisite

  • MySQL or MariaDB instance running at 127.0.0.1:3306 and initialized with the following SQL.
CREATE DATABASE `shard0`;
CREATE DATABASE `shard1`;
CREATE TABLE shard0.`user`(
    id BIGINT PRIMARY KEY,
    name VARCHAR(20) NOT NULL
);
CREATE TABLE shard1.`user`(
    id BIGINT PRIMARY KEY,
    name VARCHAR(20) NOT NULL
);
CREATE USER 'foo' IDENTIFIED BY 'bar';
GRANT ALL PRIVILEGES ON * . * TO 'foo';
  • URI for each shard is configurable in application.yaml.

Tech Stack

  • Armeria
    • Server framework
    • Use kotlin coroutine integration - armeria-kotlin
    • Use Springboot integration - armeria-spring-boot2-starter
  • Springboot
    • Minimal use only for DI and to use spring-based libraries (e.g. spring-data-r2dbc)
  • R2DBC
    • spring-boot-starter-data-r2dbc
    • Driver - r2dbc-mariadb
    • Connection pool - r2dbc:pool
    • Sharding with AbstractRoutineConnectionFactory

How DB Routing Logic for Sharding Works?

  • AbstractRoutingConnectionFactory is R2DBC equivalent for AbstractRoutingDataSource in JDBC.
  • While typical AbstractRoutingDataSource implementations usually leverage ThreadLocal to store and retrieve DB routing context, AbstractRoutingConnectionFactory let users access Reactor's subscription context and store the routing context in there so that it's not lost in an asynchronous execution flow.
  • DB routing context can be written like..:
val dbClient: DatabaseClient

suspend fun findUserById(id: Long): User? = 
    dbClient
      .sql("SELECT * FROM `user` WHERE id = :id")
      .bind("id", id)
      .map { row -> row.toUser() }
      .one()
      // Write a routing context which will later be used in an
      // `AbstractRoutingConnectionFactory` implementation to judge the right `ConnectionFactory`.
      .contextWrite { context -> context.put(ROUTING_KEY, id % 1024) }
      .awaitFirstOrNull()
  • See RoutingConnectionFactory and UserModelMapper for more details.

Advanced Topics

Sharding with Master / Slave

  • Make your own routing rule by adding more context information to Reactor context. For instance, you may want to have isWriteQuery boolean flag in the context and use it as a hint to route the query to slave DB instances.

Logical Shards and Physical shards

  • This example already demonstrates sharding with 2 logical shards in 1 DB instance, but in a bit inefficient way since connections are made for each logical shard.

    In a real world example, you may want to have only 1 connection pool for each physical shard and this can also be achieved by modifying AbstractRoutingConnectionFactory implementation. ...

You might also like...
Example of Android project showing integration with Kotlin and Dagger 2

kotlin-dagger-example This project demonstrate how to setup an Android Project with Kotlin and Dagger 2. It's based on Dagger 2 example ##Known issues

🎓 Learning Kotlin Coroutines for Android by example. 🚀 Sample implementations for real-world Android use cases. 🛠 Unit tests included!
🎓 Learning Kotlin Coroutines for Android by example. 🚀 Sample implementations for real-world Android use cases. 🛠 Unit tests included!

Kotlin Coroutines - Use Cases on Android 🎓 Learning Kotlin Coroutines for Android by example. 🚀 Sample implementations for real-world Android use ca

A clean architecture example. Using Kotlin Flow, Retrofit and Dagger Hilt, etc.
A clean architecture example. Using Kotlin Flow, Retrofit and Dagger Hilt, etc.

android-clean-architecture A clean architecture example. Using Kotlin Flow, Retrofit and Dagger Hilt, etc. Intro Architecture means the overall design

Spring Boot Example with Kotlin and Domain Driven Design

Spring Boot Kotlin Domain Driven Design Example Just an example project where ddd is implemented with some other great patterns and architecture from

A Modern Kotlin-Ktor RESTful API example. Connects to a PostgreSQL database and uses Exposed framework for database operations.
A Modern Kotlin-Ktor RESTful API example. Connects to a PostgreSQL database and uses Exposed framework for database operations.

kotlin-ktor-rest-api A Modern Kotlin-Ktor RESTful API example. Connects to a PostgreSQL database and uses Exposed framework for database operations. F

📌This repo contains the kotlin implementation of TensorflowLite Example Android Apps🚀
📌This repo contains the kotlin implementation of TensorflowLite Example Android Apps🚀

TensorflowLite Examples Kotlin This repo contains the kotlin implementation of TensorflowLite Example Apps here, which are mostly implemented in java

Example project for using the Selenium toolkit with Kotlin, Maven, TestNg and the config is managed via a property file.

Selenium-Java-Toolkit-TestNg-Playground This is the sample-Project and show you how to use the Selenium-Toolkit. The Selenium-Toolkit is a Java based

Spring for Kotlin Example
Spring for Kotlin Example

Spring for Kotlin Example This project is for studying the spring using by kotlin. Required docker-compose Running project docker-compose -f docker-co

grpc stream fullstack example(spring+kotlin / next.js + typescript)

grpc-stream-fullstack chat application build with grpc named qhat Prerequisites server sync .proto files on src/main/proto/grpc/qhat/ $ ./gradlew sync

Owner
K.S. Yim
K.S. Yim
Reactive setup with Spring WebFlux , Kotlin, Postgres and Spring Data R2DBC

Reactive Spring with Kotlin and Pg Spring WebFlux with Netty instead of Spring Web with Tomcat Mono and Flux in all layers (controller, service, repo)

Bimal Raj Gyawali 7 Dec 9, 2022
This repository demonstrates Spring GraphQL + RSocket + WebFlux + R2DBC + H2

Reactive GraphQL with Spring This repository demonstrates Spring GraphQL + RSocket + WebFlux + R2DBC + H2 O__ +-----------+

Maksim Kostromin 1 Nov 27, 2021
Liquibase R2DBC Spring Boot starter

This repository demonstrates how 2 implement Liquibase R2DBC Spring Boot starter. Stack: Liquibase R2DBC Spring Boot starter with next technology stack: Liquibase, R2DBC, Spring Boot, Kotlin, Junit Jupiter 5, MySQL, MariaDB, PostgreSQL, MS SQL Server, H2, r2dbc-pool, r2dbc-proxy, Test-containers, Maven, Bash

Maksim Kostromin 6 Dec 25, 2022
Event-driven application uses React, reactive Spring Boot WebFlux, R2DBC, MySQL and Liquibase

Product delivery Event-driven application uses React, reactive Spring Boot WebFlux, R2DBC, MySQL and Liquibase Status: IN PROGRESS if [[ "" != `docker

Maksim Kostromin 2 Aug 17, 2022
New Relic Kotlin Instrumentation for Kotlin Coroutine. It successfully handles thread changes in suspend states.

new-relic-kotlin-coroutine New Relic Kotlin Instrumentation for Kotlin Coroutine. It successfully handles thread changes in suspend states. Usage 1- U

Mehmet Sezer 7 Nov 17, 2022
Android Multi Theme Switch Library ,use kotlin language ,coroutine ,and so on ...

Magic Mistletoe Android多主题(换肤)切换框架 背景 时隔四年,在网易换肤之前的思路下,做了几点改进,现在完全通过反射创建View,并且在SkinLoadManager中提供一个configCustomAttrs以支持自定义View的属性插队替换 摈弃了之前的AsyncTask

Mistletoe 18 Jun 17, 2022
Kreds - a thread-safe, idiomatic, coroutine based Redis client written in 100% Kotlin

Kreds Kreds is a thread-safe, idiomatic, coroutine based Redis client written in 100% Kotlin. Why Kreds? Kreds is designed to be EASY to use. Kreds ha

Abhijith Shivaswamy 117 Dec 23, 2022
Demonstration of Object Pool Design Pattern using Kotlin language and Coroutine

Object Pool Design Pattern with Kotlin Demonstration of Thread Safe Object Pool Design Pattern using Kotlin language and Coroutine. Abstract The objec

Enes Kayıklık 7 Apr 12, 2022
🚀 🥳 MVVM based sample currency converter application using Room, Koin, ViewModel, LiveData, Coroutine

Currency Converter A demo currency converter app using Modern Android App Development techniques Tech stack & Open-source libraries Minimum SDK level

Abinash Neupane 2 Jul 17, 2022
MVVM ,Hilt DI ,LiveData ,Flow ,SharedFlow ,Room ,Retrofit ,Coroutine , Navigation Component ,DataStore ,DataBinding , ViewBinding, Coil

RickMorty This is a simple app which has been implemented using Clean Architecture alongside MVVM design to run (online/offline) using : [ MVVM ,Hilt

Ali Assalem 13 Jan 5, 2023