"Octopus"를 만든 클론 "Tako"가 Rails5에서 sharding을 하는 이야기입니다.

10864 단어 RubyRails
이 글은 Ruby on Rails 달력을 부가한 지 5일째다.

Rails로 DB의 sharding을 하면...


부하를 분산하기 위해 Rails로 DB 필터링을 하려고 할 때 이용할 수 있는 젬이 몇 개 있다.
예를 들다
  • activerecord-sharding
  • db-charmer
  • Octopus
  • switch_point
  • 잠깐... 좀 있긴 한데, 여기에 적혀있는 지금 Rails5 ready는 activerecord-shardingswitch_point밖에 없는 것 같아요.

    그래서 Octopus를 사용했습니다.


    Rails4.2를 이용해서 Octopus를 사용하고 Rails5로 업그레이드, 응, 머리...
    Octopus 액티브 Record의 표준 기능을 확장하고 닫기 기능을 제공할 수 있지만 역으로 액티브 Record를 설치할 수 있기 때문에 Rails의 버전 업그레이드 비용이 매우 높다는 것이 단점이다.
    코드가 많이 차이가 나지 않아서 지금 다른 젬으로 갈아타기가 어려울 것 같아요.activerecord-sharding 등은 액티브 레코드에서 독자적인 방법과 DSL을 생성하는 방식으로 이뤄지기 때문에 액티브 레코드의 원래 설치에는 영향을 주지 않는다.대신 코드 마이그레이션이 필요함)

    단도직입적으로 말하자면, 나는 단지 재단을 하고 싶을 뿐, 그렇게 많은 기능이 없는 Gem은 정말 다행이다


    Rails5ready의 octopus를 원하는... 본가 issue라는 댓글이 있어요.

    옥토퍼스 유지보수가 없는 것 같은데... 기회...!?
    ※ 그렇게 생각하지만 젬이 만들어진 이후로 이 기사를 쓸 때 이런 댓글이 있었어요.

    아아.. 헛수고다...!?하지만, 이미 여기까지 왔으니 나는 계속할 것이다

    어쩌면 옥토퍼스는 이미 안 될지도... 타코 프로듀싱...


    그래서 옥토퍼스의 복제Tako를 만들어 봤다.
    MIT 라이센스로 공개 중입니다.
    총괄Tako에서 실현하고자 하는 일의 요건은 다음과 같다.
  • Octopus의 #using 방법처럼 주어진 블록이나 이 방법은 지정된 디스크에 들어가서 SQL을 발행한다.
  • 이 경우 Active Record 구현에 대한 의존도를 최소화하고자 합니다.
  • 가능한 한 Rails 표준의 마이그레이션을 활용하고자 합니다.
  • 완전히 수평으로 분할하면 되기 때문에 섀시에서 지정한 마이그레이션이 필요 없음
  • Rails 버전이 업그레이드되면 가능한 한 빨리 대응하시기 바랍니다.
  • Rails의 해당 버전<= 4.0에서 5개 시스템이 지원됩니다.3종은 다 됐는데...
  • 사용법


    설치하다.


    Gemfile
    gem 'tako'
    
    bundle install
    
    or
    gem install tako
    
    사용

    DB 설정

    config/shards.yml.읽을 때 ERB를 사용하여 한 번 지웁니다.config/shards.yml의 내용은 Tako.config를 통해 얻을 수 있다.
    config/shards.yml
    default: &default
      adapter: mysql2
      encoding: utf8
      charset: utf8
      collation: utf8_general_ci
      reconnect: false
      username: <%= ENV['MYSQL_USER_NAME'] %>
      password: <%= ENV['MYSQL_ROOT_PASSWORD'] %>
      host: <%= ENV['MYSQL_HOST'] %>
      port: <%= ENV['MYSQL_PORT'] %>
      database: tako_<%= Rails.env %>
    
    tako:
      <%= Rails.env %>:
        shard1:
          <<: *default
          host: <%= ENV['MYSQL_SHARD1_HOST'] %>
          database: tako_<%= Rails.env %>_shard1
        shard2:
          <<: *default
          host: <%= ENV['MYSQL_SHARD2_HOST'] %>
          database: tako_<%= Rails.env %>_shard1
    
    다음과 같이 마이그레이션을 수행할 수 있습니다.
    $ bundle exec rake db:tako:create
    $ bundle exec rake db:tako:migrate
    
    shards.yml부터 모든 캐비닛 정보를 읽고, 각 캐비닛에db:migrate를 추가합니다.
    각shard 간의 이전 버전이 다르면 좋은 느낌으로 처리할 수 있습니다.

    응용 프로그램 사용

    rake db:tako:<command>에 해당하는 방법은Octopus.using이다.
    using을 사용하지 않는 이유는 이름과 Tako.shard가 중복되기 때문이다.
    User.shard(:slave_one).where(:name => "Thiago").limit(3)
    # => :slave_oneでクエリ実行
    
    User.create(name: "Bob")
    # => database.ymlに記載されているデフォルトのDBでクエリ実行
    
    Tako.shard(:slave_two) do
      User.create(name: "Mike")
      # => :slave_twoでクエリ実行
    end
    
    User.shard(:slave_two) do
      User.shard(:slave_one).create(name: "Mike")
      # => :slave_oneでクエリ実行
    end
    

    연관의 대응


    한 마디로 하면ActiveRecord:Base 실례가 생성한 역할 영역의 디스크는 저장된 디스크입니다.
    user = User.shard(:shard01).create(name: "Jerry")
    
    user.logs.create
    # => この場合は、userと同じシャードである:shard01でlogが作成される
    
    user.logs << Log.shard(:shard02).new
    # => ただし、この場合は:shard02
    
    life = user.build_life
    life.save!
    # => buildしてsaveの場合は、親?と同じ:shard01になる。
    

    모든 프로그램에서 실행

    Module#using에서 블록 내의 코드는 모든 섀시에서 수행됩니다.
    # 全シャードでMikeさんがお見えになる
    Tako.with_all_shards do
      User.create(name: "Mike")
    end
    

    Octopus에서 마이그레이션하려는 경우


    우선 감사합니다!
    다음 단계에 따라 마이그레이션할 수 있습니다.
    migration 등에서 Octopus 기능을 사용할 때는 사용을 피하거나 Tako에 PR을 보냅니다.
  • Tako.with_all_shards(&block) 또는 Octopus.usingModel.using 또는 Tako.shard
  • 로 교체
  • Model.shard를 Tako용으로 변경
  • 힘든 척/타협하는 곳


    prepend를 사용할 수 없습니다.


    ActiveRecord를 확장하는 다른 gem을 사용하는 경우(예: save!config/shards.ymlalias_method 방법 같은gem를 입력하면prepend에서alias호출super되어stack level too deep된다.따라서 이번Tako의 설치도 마찬가지로aliasmethod 사용...

    마계


    Rails의 소스를 읽을 때 가장 힘든 것은 Migrator의 코드를 쫓는 것입니다.
    Rails 내부에서 활용한 구상으로 썼기 때문에 밖에서 불러내는 게 고통스러웠던 기억이 납니다.

    Connection Pool을 사용할 수 없습니다.


    개인적으로 Thread를 쓰면 괜찮을 것 같아서 설치가 비교적 수월한 것을 선택했다.
    Tako중,connectionpool을 사용할 수 없습니다.

    총결산


    이상은 웨딩드레스에 대한 시가지와 타코의 소개입니다.

    좋은 웹페이지 즐겨찾기