Upgrade to Pro — share decks privately, control downloads, hide ads and more …

【NewSQL】アプリケーション開発観点からのTiDB - Ruby編その1

【NewSQL】アプリケーション開発観点からのTiDB - Ruby編その1

このスライドでは、アプリケーション開発者やアーキテクトの方々に対して、TiDBというデータベースをアプリケーションからどのように利用するのか、他データベースからの移行にあたって、アプリケーション開発者の観点から考慮するべきかについてご紹介します。

PingCAP-Japan

April 22, 2022
Tweet

More Decks by PingCAP-Japan

Other Decks in Technology

Transcript

  1. Ruby と Railsを例に
    アプリケーション開発視点からのTiDB
    Yasuo Honda / 本多康夫
    Technical Support Engineer
    PingCAP株式会社

    View full-size slide

  2. 本日のセッションの位置づけ
    https://pingcap.co.jp/event/
    日時 内容
    2022年4月12日(木) 14-15:30 TiDB ソフトウェアの紹介・デモ
    2022年4月21日(木) 14-15 アプリケーション開発観点からのTiDB - Ruby編
    2022年5月12日(木) 14-15:30 TiDB Cloudの紹介・デモ
    2022年5月19日(木) 14-15 最新TiDB 6.0のポイント(仮)
    2022年5月26日(木) 14-15 アプリケーション開発観点からのTiDB - Java編

    View full-size slide

  3. アジェンダ
    ● TiDBを利用することでアプリケーション開発者が得られるメリット
    ● TiDBと動作する各プログラミング言語、フレームワークの紹介
    ● プログラミング言語Rubyで広く利用されているWebアプリケーションフレームワーク
    Ruby on RailsへのTiDB対応状況

    View full-size slide

  4. TiDBを利用することでアプリケーション開発者が得られ
    るメリット

    View full-size slide

  5. データベースにおいて悩ましいこと
    ● データベースのスケーラビリティーに課題がある
    ● これまでの対応案:
    ○ レプリケーションの導入する
    ○ シャーディングの導入する
    ○ データベースサーバーをスケールアップする

    View full-size slide

  6. これまでの対応案の難しさ
    ● 読み込み/書き込み分割
    ○ 必要なデータの「新鮮さ」に応じて接続先を切り替える必要
    ● シャーディング
    ○ テーブルの列にシャーディングキーを追加する設計が必要
    ○ アプリケーションがどのインスタンスにどのデータがあるか知る必要
    ○ マスターデータはすべてのインスタンスにコピーする必要あり
    ○ DDLもすべてのインスタンスに個別に実行する必要あり
    ● データベースサーバーのスケールアップ
    ○ 利用できるスペックの上限に達する可能性あり

    View full-size slide

  7. スケールアウト可能なMySQLプロトコル互換
    TiDB
    クエリの増加
    ノード追加で対応
    TiDB
    TiDB Cluster

    TiKV Cluster

    負荷分散・領域管理
    3ノードのみ必要
    PD Cluster
    TiDB
    TiKV TiKV TiKV TiKV
    容量拡張
    ノード追加で対応
    TSO / Data Location
    Metadata

    PD
    PD PD
    Application
    via MySQL Protocol
    Application
    via MySQL Protocol
    Application
    via MySQL Protocol
    Application
    via MySQL Protocol
    データストアレイヤー
    アプリケーション
    (MySQL Client利用可能)
    - TiDB : クエリーの増加に対してTiDBサーバーのスケールアウト可能
    - TiKV : データ容量/IO要件の増加に対してTiKVサーバーのスケールアウト可能
    SQL解析レイヤー
    (Parser, Optimizer)

    View full-size slide

  8. TiDBによってできること
    ● 読み込み/書き込み分割
    ○ どのTiDBサーバーに接続しても最新のデータを読み書き可能
    ● シャーディング
    ○ TiKVが内部的にテーブルをRegionという単位で分割する
    ○ テーブルにシャーディング用のキーは不要
    ○ DDLも一度実行すれば、すべてのサーバーに自動的に伝播されます
    ● データベースサーバーのスケールアップ
    ○ クエリー数の増加に応じてTiDBをスケールアウト可能
    ○ 容量、IO要件の増加に対してTiKVをスケールアウト可能

    View full-size slide

  9. TiDBと動作する各プログラミング言語、フレームワーク
    の紹介

    View full-size slide

  10. TiDBへの疑問
    ● TiDBがスケールアウトできるのはわかったけれど、そもそも利用しているフレーム
    ワークはTiDBに対応しているのだろうか。
    ● TiDBとMySQLの互換性ついて知りたい。

    View full-size slide

  11. TiDBと各開発言語、フレームワーク
    ● MySQLプロトコルレベル : “Connectors” → “Full support”
    ○ Java: MySQL Connector/J
    ○ Ruby: mysql2 gem
    ● SQLレベル : “ORM Frameworks” → “Verified support”
    ○ Java: Hibernate
    ○ Ruby: Ruby on Rails / Active Record
    ● App Development Overview | PingCAP Docs
    ○ 一覧にないコネクター、アダプターやフレームワークをご利用の場合はお知らせください
    ● Full support : 既知の問題が存在しない
    ● Verified Support : TiDBがサポートしていない機能がある場合(例 外部キーなど)

    View full-size slide

  12. Ruby on RailsへのTiDB対応状況

    View full-size slide

  13. Ruby on Railsとは
    ● Ruby on Rails
    ○ Rubyで書かれたWebアプリケーションフレームワーク
    ● Active Record
    ○ Ruby on Railsを構成する一要素
    ○ ORM (Object Relational Mapping)としてアプリケーションとデータベースの橋渡し
    ○ アプリケーションは「モデル」を操作し、フレームワークがモデルへの操作を「テーブル」への処理に変換する
    ● Active Recordが対応するデータベース
    ○ データベースごとの差異はadapterとして実装
    ○ Railsに標準で含まれるアダプターは、SQLite3 (sqlite3), MySQL(mysql2) と PostgreSQL(postgresql)
    ○ MySQL 5.5.8 以上に対応

    View full-size slide

  14. Active Record TiDB Adapterとは
    ● 最新のRuby on Rails 7.0に対応
    ● Apache-2.0 Licenseで公開
    ○ https://github.com/pingcap/activerecord-tidb-adapter
    ● Active Recordのmysql2アダプターを継承して作成
    ○ 主な役割
    ■ TiDBがサポートするsequenceへの対応
    ■ MySQLとの互換性がない部分でメソッドの戻り値の変更
    ○ Active Record TiDB Adapterテストのため、Ruby on Rails本体のテストを修正している
    ■ 互換性がない部分のテストのskipのため

    View full-size slide

  15. Active Recordダイアグラム
    TiDB MySQL
    TiDB
    Adapter
    MySql2
    Adapter
    PostgreSQ
    LAdapter
    Postgre
    SQL
    AbstractAdapter
    MySQL2
    Adapter
    Active Record diagram
    Active Record
    “モデル”
    libmysqlcli
    ent
    libmysqlcli
    ent
    libpq コネクター(C言語など)
    データベース
    データベースアダプター
    Active Record “モデル”

    View full-size slide

  16. Ruby on RailsへのTiDB対応状況(詳細)

    View full-size slide

  17. Rails利用時のMySQLとの非互換性
    ● Ruby on Railsなどのフレームワークの機能という観点から紹介します
    ○ AUTO_INCREMENT
    ○ セーブポイント
    ○ 外部キー
    ○ bulk DDL
    ○ Advisory lock
    ● 互換性一覧
    ○ MySQL Compatibility | PingCAP Docs

    View full-size slide

  18. Rails利用時のMySQLとの非互換性
    ● AUTO_INCREMENTで発番される値
    ○ TiDBサーバーごとに値をキャッシュします
    ○ 全体として値は一意だが、TiDBサーバーをまたがった場合の順序は担保されません
    ● MySQL(mysql2 adapter)ではTrueだがTiDBではFalse
    ○ supports_savepoints?
    ■ セーブポイントに対応しているか
    ○ supports_advisory_locks?
    ■ アドバイザリーロック(GET_LOCK())に対応しているか
    ○ supports_foreign_keys?
    ■ 外部キー(foreign key)に対応しているか
    ○ supports_bulk_after?
    ■ 1つのALTER文で複数のカラムを変更できるか

    View full-size slide

  19. 例 - 暗黙的なソートとAUTO_INCREMENT
    ● Railsでの.firstや.lastではカラムを指定せず暗黙的なソートを行う、そのときのデフォルトはidを利用する
    ● TiDBのauto_incrementでの発番はTiDBサーバーごとにキャッシュされるため、下記のコードは正しくない結果を返す場合
    がある
    irb(main):001:0> first_user = User.first
    User Load (0.2ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1
    ● 対応方法: 暗黙的なソートのカラムを変更可能 `updated_at` でソートする
    class User < ApplicationRecord
    self.implicit_order_column = "updated_at"
    end
    User Load (0.3ms) SELECT `users`.* FROM `users` ORDER BY `users`.`updated_at` ASC, `users`.`id` ASC
    LIMIT 1

    View full-size slide

  20. 例: ユニットテストとセーブポイント
    ● Rails(Minitest/RSpec)でのテストがセーブポイントを実行する
    ○ テスト終了時にseedデータの状態を元に戻すためsavepointを利用している
    ● 対応方法
    ○ Minitestの場合
    ■ self.use_transactional_tests = falseにして、毎回seedデータを再作成する
    ○ RSpecの場合
    ■ config.use_transactional_fixtures = false
    ■ Database Cleaner の DatabaseCleaner.strategy = :truncation または :deletion を設定する

    View full-size slide

  21. 例: マイグレーションのbulk: true
    ● マイグレーションでbulk: trueであっても非対応として分割して実行されます
    class AddColumnsToUser < ActiveRecord::Migration[7.0]
    def change
    change_table :users, bulk: true do |t|
    add_column :users, :email, :string
    add_column :users, :nickname, :string
    end
    end
    end
    ● bulk: trueであってもsupports_bulk_after?がfalseを返すため、下記のように分割して実行されます
    ALTER TABLE `users` ADD `email` varchar(255)
    ALTER TABLE `users` ADD `nickname` varchar(255)

    View full-size slide

  22. 例: マイグレーションと外部キー
    ● TiDBはforeign keyのSQLを理解し、テーブル定義として保持するが、実際には外部キーは作成されない (効果がない)
    create_table "users", charset: "utf8mb4", collation: "utf8mb4_bin", force: :cascade do |t|
    end
    create_table "projects", charset: "utf8mb4", collation: "utf8mb4_bin", force: :cascade do |t|
    t.bigint "user_id"
    end
    add_foreign_key "projects", "users"
    ● テーブル定義
    mysql> show create table projects\G
    *************************** 1. row ***************************
    Table: projects
    Create Table: CREATE TABLE `projects` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT,
    KEY `index_projects_on_user_id` (`user_id`),
    CONSTRAINT `fk_rails_b872a6760a` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

    View full-size slide

  23. 例: マイグレーションとアドバイザリーロック
    ● RailsのマイグレーションAdvisory lock(GET_LOCK(), RELEASE_LOCK())を活用している
    ○ マイグレーションが同時に実行されないため
    SELECT GET_LOCK('2946838989811228680', 0)
    SELECT RELEASE_LOCK('2946838989811228680')
    ○ JavaScriptでのPrisma、elixirのEctoでも同様にマイグレーション時にAdvisory lockを利用します
    ● 現状の回避策
    ○ `tidb_enable_noop_functions`を`ON`にして、get_lock()実行がエラーを返さないようにする
    ■ ロックはしないのでユーザー側で同時にマイグレーションを実行しないようにする

    View full-size slide

  24. 非互換性対応の取り組み
    ● セーブポイント
    ○ please support savepoint · Issue #6840 · pingcap/tidb · GitHub
    ● マルチスキーマ変更
    ○ https://github.com/pingcap/tidb/issues/14766
    ● 外部キー
    ○ https://github.com/pingcap/tidb/issues/18209
    ● アドバイザリーロック
    ○ UCP: Support `get_lock` and `release_lock` functions · Issue #14994 · pingcap/tidb · GitHub
    ○ https://github.com/pingcap/tidb/pull/33947

    View full-size slide

  25. まとめ
    ● TiDBを利用することでアプリケーション開発者が得られるメリット
    ● TiDBと動作する各プログラミング言語、フレームワークの紹介
    ● プログラミング言語Rubyで広く利用されているWebアプリケーションフレームワーク
    Ruby on RailsへのTiDB対応状況

    View full-size slide

  26. 今後のセミナー予定
    https://pingcap.co.jp/event/
    2022年4月12日(木) 14-15:30 TiDB ソフトウェアの紹介・デモ
    2022年4月21日(木) 14-15 アプリケーション開発観点からのTiDB - Ruby編
    2022年5月12日(木) 14-15:30 TiDB Cloudの紹介・デモ
    2022年5月19日(木) 14-15 最新TiDB 6.0のポイント(仮)
    2022年5月26日(木) 14-15 アプリケーション開発観点からのTiDB - Java編

    View full-size slide

  27. Free Trialのご案内
    TiDB Cloud Free Trialはこちら
    https://tidbcloud.com/signup
    Developer Tierでは
    TiDB Cloudを無償で1年間ご利用頂けます。
    容量制限はありますが、
    本番と同等の機能を提供しているため、
    アプリとの接続試験などが容易に。
    *現在はAWSのみ対応

    View full-size slide

  28. お問い合わせ先
    お問い合わせ先
    [email protected]
    製品に関する問い合わせ以外にも
    ハンズオンや製品デモはじめ、
    勉強会などの実施も可能です。
    気兼ねなくご相談、ご連絡ください。
    *右の画像はCyberAgent様向けに実施したハンズオンの様子
    https://developers.cyberagent.co.jp/blog/archives/33416/

    View full-size slide

  29. Thank You!
    https://www.pingcap.com/
    [email protected]

    View full-size slide