ZAICOでは、Android・iOS・Rubyエンジニアを絶賛募集中です! 詳しくは、採用ページをご覧ください。
こんにちは!
私の地元では桜が散ったところがほとんどで、新緑の季節が待ち遠しいです。
ZAICOは全社員リモートワークということもあり、所々によって季節の移り変わりが少しずれていて(桜の見頃なんてまさにそう)、各地の話を聞くのもまた面白いですね。
今回はRails6.1の水平シャーディング機能を試します。なお、少し前に「モデルでのコネクション自動切り替えを試す」という記事を書いていますので、そちらもお読みいただけると幸いです。
前提条件
- Ruby 2.6.6
- Rails 6.1.3
- APIモードを利用
データベース・replicaの設定
database.yml
development: zaicodb: <<: *default database: zaicodb_development port: 3306 zaicodb_shard_one: <<: *default database: zaicodb_development port: 3307
$ bundle exec rails db:create
データベース接続先の設定
app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base self.abstract_class = true # 追記 connects_to shards: { default: { writing: :zaicodb, reading: :zaicodb }, shard_one: { writing: :zaicodb_shard_one, reading: :zaicodb_shard_one } } end
モデルやマイグレーションを用意(検証用)
$ bundle exec rails g model User name:string
$ bundle exec rails db:migrate
コントローラを用意(検証用)
class UsersController < ApplicationController def create user = User.new(users_params) user.save! ApplicationRecord.connected_to(role: :writing, shard: :shard_one) do user = User.new user.name = 'This is shard one' user.save! render json: user end end # ...その他省略 end
どのシャードを参照しているかログで確認できるようにする
各種記事でも紹介がある、arproxyというgemを利用します。
Gemfile
gem 'arproxy' # 追記
config/initializers/arproxy.rb
class QueryTracer < Arproxy::Base def execute(sql, name=nil) shard = ApplicationRecord.current_shard name = "#{name} [#{shard}]" super(sql, name) end end Arproxy.configure do |config| config.adapter = "mysql2" # A DB Apdapter name which is used in your database.yml config.use QueryTracer end Arproxy.enable!
current_shardメソッドで、どのシャードを指し示してるか確認することが可能で、今回ならdefault・shard_oneのどちらかがログに出力されます。
ActiveRecord::Core (api.rubyonrails.org)
動作確認
$ curl -X POST -H ‘Content-Type: application/json’ -d ‘{“name”: “zaico hanako”}’ localhost:3000/users
1つ目のinsertはdefaultを向き、2つ目のinsertではshard_oneを向いています。
【default】
【shard_one】
特に設定していない場合は、データベースのMySQLのAUTO_INCREMENTによってidが決まるので、それぞれのデータベースで採番されていくようです。そのためここは別途調整が必要かもしれません。
これがRails標準で備わるようになってとても驚いていますが、筆者が試していないRailsの機能はまだまだありますので、これからもこのブログで試していこうと思います。
以上、水平シャーディング機能を試した内容でした!
参考記事
Ruby on Rails 6.1 の水平シャーディング対応 & Octopusからの移行事例 – Akatsuki Hackers Lab | 株式会社アカツキ(Akatsuki Inc.)