1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

R2DBCでNon-BlockingなDBアクセスを実現しよう!

Posted at

はじめに

チーム内で R2DBC についての勉強会を開催することになったので、
自分の理解を整理するためにも、R2DBC の概要をまとめておきます。

本記事では、「そもそも R2DBC とは何か?」という点や特徴をまとめていきます。
具体的な実装についてはここでは触れません。

選定条件と背景

今回R2DBCを採用したプロジェクトでは SpringBoot(Kotlin) + gRPC + MySQL を利用した構成です。
要件として大量のリクエストを捌く必要があり、アプリケーション全体を通して可能な限りスレッドをブロックしないノンブロッキング構成を目指しています。

当初は JDBC の利用も検討していましたが、
JDBC では クエリ実行中にスレッドが占有される(ブロックされる) という特性があります。
このブロッキング処理は、高負荷時のスループット低下を招く恐れがあります。

そのため、MySQL を利用しつつもノンブロッキングなデータアクセスを実現できる方法を比較し、R2DBC を検討する流れになりました。

ライブラリ選定

R2DBC を採用する前にいくつか候補を絞ってライブラリを比較しました。

# ライブラリ アクセス方式 ノンブロッキング 特徴 選定観点での評価
1 Spring Data JDBC JDBC ❌ ブロッキング シンプル・軽量 ブロッキングであるため、要件と不一致
2 Exposed JDBC(内部) ❌ ブロッキング Kotlinとの相性が良いDSL。当初最有力候補だったが、内部的にJDBCを利用しており、ブロッキング処理となるため非採用 同上
3 Spring Data R2DBC R2DBC ✅ 非ブロッキング Non-Blocking、且つ、Springとの統合が容易 要件を満たすため採用

最終的には、
完全ノンブロッキングで Spring との親和性が高い Spring Data R2DBC を採用することになりました。

R2DBCとは?

ここからが本題となりますが、R2DBCの概要について説明していきます。

R2DBC(Reactive Relational Database Connectivity)は、
RDB に Non-Blocking でアクセスするための 仕様(SPI)と、それに準拠したドライバ群 の総称です。

従来の JDBC はBlocking I/O のため、1 リクエストごとにスレッドを占有してしまうという制約がありました。
R2DBC はこの問題を解消し、Non-BlockingなI/Oを実現しています。

R2DBC の特徴

Reactive Streams準拠

Based on the Reactive Streams specification. R2DBC is founded on the Reactive Streams specification, which provides a fully-reactive non-blocking API.

訳: データの流れにBackpressure(処理速度に応じてデータ流量を制限する)を導入したリアクティブプログラミングの仕様を基盤としています。

Kotlin Flow や Java Stream と組み合わせたリアクティブな処理が自然に書ける

リレーショナルデータベース対応

Works with relational databases. In contrast to the blocking nature of JDBC, R2DBC allows you to work with SQL databases using a reactive API.

訳: JDBCのようなブロッキングI/Oとは異なり、SQLデータベースにリアクティブにアクセス可能です。

R2DBC では待ち時間にスレッドを保持しないため、少ないスレッド数でも高い並行処理が可能

スケーラブルな設計

Supports scalable solutions. With Reactive Streams, R2DBC enables you to move from the classic “one thread per connection” model to a more powerful and scalable approach.

訳: 従来の「1接続につき1スレッド」というモデルから脱却し、少数のスレッドで多数の接続を効率的に扱えます。

R2DBC は I/O 操作をノンブロッキングで実行するため、大量のリクエストが同時に来てもスレッドが枯渇しにくく、アプリケーション全体のスループット向上が期待できる

オープンスペックで拡張性が高い

Provides an open specification. R2DBC is an open specification and establishes a Service Provider Interface (SPI) for driver vendors to implement and clients to consume.

訳: ドライバベンダーはSPI(Service Provider Interface)に則って実装し、クライアントはこれを利用する形で拡張性が確保されています。

Spring Boot との統合

Spring Data R2DBC を利用することにより、Repository パターンや設定周りをシンプルに利用でき、既存の Spring エコシステムにそのまま馴染ませることができます。

  • @Transactional を用いた宣言的なトランザクション管理を利用できる
    • ※ R2DBC のトランザクションは JDBC のものとは実装が異なるため、R2dbcTransactionManager を利用する
  • R2DBCリポジトリ を利用することでSQLを極力書かなくても抽象的にデータアクセスを実現できる

おわりに

本記事では R2DBC の概要について解説しました。
理論上のメリットについて多く記載しましたが、実際には、ノンブロッキングだからといって必ずしも性能が向上するわけではなく、チューニングで苦労する場面も多くありました。
機会(と気力)があれば、その辺りの話も書いてみたいと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?