DBCharmer를 사용하고 있었는데, 더 이상 업데이트를 안한다고 해서 다른 걸 찾다보니 이거 밖에 없네요 레일즈4에서 사용해야 하는데, DBCharmer는 3.X버전밖에 지원하지 않아요. 그래서 옮길 겸 정리!

물론 Replication(Master/Slave) 외에 Shard도 지원하는데, 그냥 여러 개의 Database를 정의하고 그 중 원하는 걸로 쓰게 하는 형식으로 되어있어요. 즉 키별로 샤드를 나누려면 직접 구현해야할 것 같아요. 그냥 Database를 선택해서 쓸 수 있다 정도로만 되어 있는 것 같네요. 샤드는 잘 안해봐서 잘 모르겠지만 대충 그런 느낌이네요.

일단 나의 정리의 목적은 Replication이니까 이것만-_-

젬 깃허브입니다.
https://github.com/tchandy/octopus


1. Master/Slave DB준비

보통은 시스템팀이 있는 회사라면 다 알아서 해주지만 한 번 해보는 것도 나쁘진 않아요. 이거 보고 따라하세요. 두 번 따라하세요-_-
http://oqlid.blogspot.kr/2013/05/mariadb-masterslave-replication-tutorial.html


2. Rails4 프로젝트 생성.

루비와 레일즈는 셋팅이 되어있다는 가정하에...

rails new ReplicationTest


3. Gemfile에 Octopus 및 필요한 것 추가.

Gemfile

gem 'ar-octopus'
gem 'mysql2'

옥토퍼스랑 mysql만 있으면 돼요.


4. database 설정

DBCharmer에서는 database.yml에 master slave를 한단계 더 만들어서 설정해서 한 파일에 다 넣었는데요. 얘는 database.yml에는 마스터디비정보만 넣고, shards.yml파일을 새로 만들어서 slave디비정보를 넣어줍니다.

master는 그대로 database.yml에 설정합니다. 

database.yml

default: &default adapter: mysql encoding: utf8 database: mudchobo username: root password: 1234 host: 마스터주소 port: 3306 pool: 5 timeout: 5000 development: <<: *default test: <<: *default database: mudchobo_test production: <<: *default database: mudchobo_production


slave들은 따로 파일을 만들어서 관리합니다.

config/shards.xml

default: &default adapter: mysql2 encoding: utf8 username: root password: 1234 host: 슬레이브주소 port: 3306 pool: 5 timeout: 5000 octopus: replicated: true environments: - development - production development: slave1: <<: *default database: mudchobo production: slave1: <<: *default database: mudchobo_production

설정은 비슷한데, 멀티 slave를 둘 수 있어서 환경 아래 slave1, slave2 등 여러 개를 두개 되면 select하는 것들에 대해서 알아서 선택해서 접속해서 데이터를 가져옵니다.

replicated: true로 사용해야 가능하고, 혹시 특정 모델에만 리플리케이션을 하고 싶으면 fully_replicated: false를 추가하고, 리플리케이션 허용 하는 것에 대해서는 모델에서 아래와 같이 넣어주면 됩니다.

#This class is replicated, writes to master and reads to slave.
class Cat < ActiveRecord::Base
  replicated_model()
end


5. db migration 생성 및 INSERT SELECT 테스트.

테이블 생성해서 테스트 해봅시다. 모델은 간단히 그냥 dummy라는 테이블을 만들고, name칼럼을 하나 넣어봅시다.

$ rails g model dummy name:string
      invoke  active_record
      create    db/migrate/20150403162358_create_dummies.rb
      create    app/models/dummy.rb
      invoke    test_unit
      create      test/models/dummy_test.rb
      create      test/fixtures/dummies.yml
$ rake db:migrate
== 20150403162358 CreateDummies: migrating - Shard: master ====================
-- create_table(:dummies)
   -> 0.0061s
== 20150403162358 CreateDummies: migrated (0.0062s) - Shard: master ===========

그러면 마스터에 테이블이 하나 생성이 되는데요. 물론 리플이 되어있으면 슬레이브에도 있겠죠. 데이터를 넣어보고 가져와봅시다.

$ rails c
Loading development environment (Rails 4.1.7)
irb(main):001:0> Dummy.create(name: 'fucking')
   (0.3ms)  BEGIN
  SQL (1.2ms)  INSERT INTO `dummies` (`created_at`, `name`, `updated_at`) VALUES ('2015-04-03 16:29:27', 'fucking', '2015-04-03 16:29:27')
   (0.6ms)  COMMIT
=> #<Dummy id: 2, name: "fucking", created_at: "2015-04-03 16:29:27", updated_at: "2015-04-03 16:29:27">
irb(main):002:0> Dummy.find(2)
[Shard: slave1]  Dummy Load (0.6ms)  SELECT  `dummies`.* FROM `dummies`  WHERE `dummies`.`id` = 2 LIMIT 1
=> #<Dummy id: 2, name: "fucking", created_at: "2015-04-03 16:29:27", updated_at: "2015-04-03 16:29:27">
irb(main):003:0> 

잘 되는데....슬레이브에서 가져오는지 잘 모르겠네요... 슬레이브 서버를 죽여버릴까......-_-

irb(main):008:0* Dummy.create(name: 'yes!')
   (1.0ms)  BEGIN
  SQL (0.9ms)  INSERT INTO `dummies` (`created_at`, `name`, `updated_at`) VALUES ('2015-04-03 16:31:55', 'yes!', '2015-04-03 16:31:55')
   (1.2ms)  COMMIT
=> #<Dummy id: 3, name: "yes!", created_at: "2015-04-03 16:31:55", updated_at: "2015-04-03 16:31:55">
irb(main):009:0> Dummy.find(3)
[Shard: slave1]  Dummy Load (0.2ms)  SELECT  `dummies`.* FROM `dummies`  WHERE `dummies`.`id` = 3 LIMIT 1
Mysql2::Error: closed MySQL connection: SELECT  `dummies`.* FROM `dummies`  WHERE `dummies`.`id` = 3 LIMIT 1

아 잘되네요.

그 외에도 slave서버를 선택해서 사용할 수 있는 using메소드도 있어요. 

뭔가 별거 아니지만 장황하게 썼다-_-

PS. 한 프로젝트에서 멀티 디비를 사용하는 프로젝트에서도 유용하게 사용할 수 있어요. 그 Octopus_establish가 있는데, 그걸 통해서 해당 모델에서는 그것에 대한 슬레이브만 접근할 수 있는 설정도 할 수 있어요! 유용하게 쓰세요!

 
Posted by 머드초보
,