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. 本日のセッションの位置づけ 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編
  2. これまでの対応案の難しさ • 読み込み/書き込み分割 ◦ 必要なデータの「新鮮さ」に応じて接続先を切り替える必要 • シャーディング ◦ テーブルの列にシャーディングキーを追加する設計が必要 ◦

    アプリケーションがどのインスタンスにどのデータがあるか知る必要 ◦ マスターデータはすべてのインスタンスにコピーする必要あり ◦ DDLもすべてのインスタンスに個別に実行する必要あり • データベースサーバーのスケールアップ ◦ 利用できるスペックの上限に達する可能性あり
  3. スケールアウト可能な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)
  4. TiDBによってできること • 読み込み/書き込み分割 ◦ どのTiDBサーバーに接続しても最新のデータを読み書き可能 • シャーディング ◦ TiKVが内部的にテーブルをRegionという単位で分割する ◦

    テーブルにシャーディング用のキーは不要 ◦ DDLも一度実行すれば、すべてのサーバーに自動的に伝播されます • データベースサーバーのスケールアップ ◦ クエリー数の増加に応じてTiDBをスケールアウト可能 ◦ 容量、IO要件の増加に対してTiKVをスケールアウト可能
  5. 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がサポートしていない機能がある場合(例 外部キーなど)
  6. 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 以上に対応
  7. 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のため
  8. 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 “モデル”
  9. 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文で複数のカラムを変更できるか
  10. 例 - 暗黙的なソートと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
  11. 例: ユニットテストとセーブポイント • Rails(Minitest/RSpec)でのテストがセーブポイントを実行する ◦ テスト終了時にseedデータの状態を元に戻すためsavepointを利用している • 対応方法 ◦ Minitestの場合

    ▪ self.use_transactional_tests = falseにして、毎回seedデータを再作成する ◦ RSpecの場合 ▪ config.use_transactional_fixtures = false ▪ Database Cleaner の DatabaseCleaner.strategy = :truncation または :deletion を設定する
  12. 例: マイグレーションの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)
  13. 例: マイグレーションと外部キー • 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
  14. 例: マイグレーションとアドバイザリーロック • 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()実行がエラーを返さないようにする ▪ ロックはしないのでユーザー側で同時にマイグレーションを実行しないようにする
  15. 非互換性対応の取り組み • セーブポイント ◦ 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
  16. Q&A

  17. 今後のセミナー予定 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編
  18. Free Trialのご案内 TiDB Cloud Free Trialはこちら https://tidbcloud.com/signup Developer Tierでは TiDB

    Cloudを無償で1年間ご利用頂けます。 容量制限はありますが、 本番と同等の機能を提供しているため、 アプリとの接続試験などが容易に。 *現在はAWSのみ対応