! From ‘Legacy' to ‘Edge' 2014 edition ! Hiroshi SHIBATA @hsbt RubyConfTaiwan 2014
Thank you! At first, Thank you so much for accept to my proposal. I love taiwan and taipei.
SHIBATA Hiroshi(@hsbt) My name is Hiroshi SHIBATA, Please call me hiroshi or shibata. my twitter and github handle name is hsbt.
Ruby Committer I’m ruby committer. I prevent that ruby break rails and your application. sometimes I fix ruby, fix rails, fix my code.
ruby-lang.org And I’m maintaining ruby-lang.org. I support ruby commiter and make easy to get rubies all over the world like CDN. ! Our site is hosted by github and heroku. If you find something to improve and documentation errors in www.ruby-lang.org, you can fix and send a pull request. we can merge it.
Rails Girls in Japan I’m one of organizers in RailsGirls in Japan.
asakusa.rb And I’m member of asakusa.rb. asakusa.rb is the most active meetup group in japan. we are talking about ruby and writing code every Tuesday.
I’m working for GMO pepabo in japan. we provide server hosting, blog service, shopping mall service etc. we have a lot of web services.
ミドルウェアのアップグレード Ruby/Rails アクセス解析基盤の構築 カンファレンス発表 セキュリティ監査 テスト基盤の構築 コードレビュー github リーンスタートアップ 新人教育 技術基盤チーム 社内開発基盤の構築 原稿執筆 開発プロセス JSOXの運用整備 Jenkins 統計基盤の構築 RDBMS OSS開発 サーバー構成管理の刷新 I’m at technical platform team on company. example for framework upgrade and opensource development, building to analysis platform etc.
http://30d.jp We are running photo sharing service named 30days album. Service concept of the service is private photo sharing.
from 2008/4 30days launched in April, two thousand eight.
380,000 users 230,000,000 photos we have three hundred eighteen thousand users, and two hundred thirteen million photos.
Our Rails app 46 models 5000 lines in controllers 400 lines in routes.rb 1:1.3 code to test ratio our rails is traditional rails. probably our rails is same as your rails.
system architecture but our system architecture is too complex system. I’m going to describe system architecture of 30days.
application server these are application servers. we separate to customer transaction database from application database.
storage server these are storage servers. we don’t use cloud platform. these are build on on-premises platform.
job server job servers handles to image manipulation workers. we have a lot of job pattern like rotate and resize.
transaction server we can access only office network to customer transaction server.
storage is over 450 TB our storage has over four hundred fifteen tera bytes of photos.
database size is over 250 GB our database has over 250GB of data. It use MySQL 5.5 with barracuda plugin.
Development Culture I’ll introduce the our team background and culture.
github workflow We use workflow like a github’s one. master branch is always to allow deployment and all-green test states. all of code is reviewed by others.
costomer’s contact github issue nagios IRC we are using IRC(Internet relay chat). we integrate all of alert and monitoring messages to it.
DevOps we are using modern operation tools. puppet and newrelic, munin, nagios and more.
4 deploy/day we are deploying one to four times per everyday.
I delete unused code. this figure is our team graph of github. deleting code is bigger than writing code. my main work is code vanishment.
How to migrate edge rails from legacy rails? It’s Today’s main theme, I’ll introduce the migration strategy.
Ruby 1.8.6 Rails 2.0.2 30days had been running under ruby 1.8.6 and rails 2.0.2 when I joined. I was very surprised. because latest rails was 3.2 at that time.
Ruby 1.8.6 Rails 2.0.2 Ruby 2.1.1 Rails 4.1.0 new! I decided to upgrade ruby and rails. and started thinking aboud migration strategy.
Why? Why we need to migrate and upgrade Ruby and Rails?
the answer is this tweet. he said “Ruby 2.1.1 is too fast. We can make faster our web application only upgrading language version, It seems joke to me.”
Ruby on Rails It’s true. Rails is Ruby code. We need to focus to Ruby.
Ruby 1.8.6 1.8.7 1.9.3 2.0.0 2.1 2.0/2.1 2.3 Rails 3.0 3.2 4.0 this matrix shows compatibility between ruby and rails.
Ruby 1.8.6 1.8.7 1.9.3 2.0.0 2.1 2.0/2.1 2.3 Fast Rails 3.0 3.2 Slow 4.0 In Generally, Upgrading Ruby give more faster experience for us, but Upgrading Rails give more slower experience for us.
Ruby 1.8.6 1.8.7 1.9.3 2.0.0 2.1 2.0/2.1 2.3 Rails 3.0 3.2 4.0 Red line shows big wall of Upgrading Rails, and Blue line shows big wall of Upgrading Ruby for us
Ruby 1.8.6 1.8.7 1.9.3 2.0.0 2.1 2.0/2.1 2.3 Rails 3.0 3.2 4.0 Our strategy is red arrows routes.
Ruby 1.8.6 1.8.7 1.9.3 2.0.0 2.1 2.0/2.1 2.3 Rails 3.0 3.2 4.0 At first we jumped Rails 2.3 and Ruby 1.8.7.
Rails 2.0 Rails 2.3 I’ll describing our branch strategy. we created Rails 2.3 branch such as above figure. master branch is rails 2.0 line.
hotfix A Rails 2.0 Rails 2.3 migration A we made hot fix branch from Rails 2.0 branch. and made a migration branch from Rails 2.3, migration branch contains to rewrite code adopting more rails way, etc.
hotfix A Rails 2.0 Rails 2.3 migration A hotfix branch is finished, we merge it to master branch and backport to rails 2.3 branch.
hotfix A Rails 2.0 Rails 2.3 migration A we finished migration branch, I merged it to rails 2.3 branch. I merged whole hotfixes and migrations to rails 2.3 branch.
It’s real branch status like rainbow line.
Zero Downtime Deploy one of the most offensive operation is “zero downtime deploy”
cookpad/kage well, I’ll introduce kage.
Kage (kah-geh) is an HTTP shadow proxy server that sits between clients and your server(s) to enable "shadow requests". kage is an http shadow proxy server that sits between clients and your server to enable “shadow requests”. kage is developed by cookpad. cookpad is best recipe sharing service in japan.
the basic of kage real request this figure is basic usage of kage. we put kage at the back of nginx. while kage proxies a request to production, it duplicate the request and pass though it to staging environment. we can test big changes with real request now. kage can build powerful test suites.
but sometimes kage caused trouble to our system.our service can receive big pictures. perhaps it caused this problem I guess ;)
Ruby 1.8.6 1.8.7 1.9.3 2.0.0 2.1 2.0/2.1 2.3 Rails 3.0 3.2 4.0 Next plan is very hard time for us, Upgrading Rails 3
rails 2.3 with bundler I finished to integrate to rails 2.3 and bundler. we can use a lot of gems. example for new relic, delayed_job, rack, and more
source 'https://rubygems.org'! ! gem 'rails', '~> 2.3.18'! gem 'rake', '~> 0.9.2'! gem 'rdoc'! gem 'rake-confirm'! ! gem 'mysql'! gem "mysql_retry_lost_connection"! gem 'acts_as_paranoid', :github => 'paperboy-30days/acts_as_paranoid'! gem 'passenger', '~> 3.0'! gem 'memcache-client', :require => 'memcache'! gem 'system_timer'! gem 'yajl-ruby', :require => 'yajl'! gem 'will_paginate', '~> 2.3'! gem 'mail'! ! gem 'sass'! gem 'compass-rails'! ! gem 'osaipo_client', :git => 'email@example.com:paperboy-all/ osaipo_client.git', :branch => 'legacy'! gem 'jugem_client', :git => 'firstname.lastname@example.org:paperboy-all/ jugem_client.git'! gem 'ppb_footer', :github => 'paperboy-all/ppb_footer'! We extracted some plugins, acts_as_paranoid was put vendor/plugin folder, now we moved on our github organization. and we moved our external service client in library folder to organization folder.
require "./config/environment"! ! use Rails::Rack::LogTailer! use Rails::Rack::Static! run ActionController::Dispatcher.new rack with rails 2.3 we are using rack with rails 2.3, it can be easily applied to rails 2.3. Because we need to migrate rack in the future.
can’t use hyphen 30days-front can’t use number can’t convert ! application.rb... but, I have one of big problem. our repository name can’t be converted to rails 3 style namespace. because our repository use hyphen and integer.
Reduce customer frustration. I did works only upgrading. We need to write a new code for customer requirements and business goal.
app1 app2 backgroundrb to dj I replaced old job worker named backgroundrb. backgroundrb is on-memory system, so it’s cleared when memory refresh. It means all job is deleted. We and our user got frustration on this situation. I replaced all of job system to persistent workers like delayed_job.
this is Pull Request of Upgrading branch. commits are over than two hundred commits. file changed are over the three hundred sixteen five.
Ruby 1.8.6 1.8.7 1.9.3 2.0.0 2.1 2.0/2.1 2.3 Rails 3.0 3.2 4.0 After Upgrading Rails 3, I started to upgrade Ruby runtime.
Use trunk everyday. Basically, I’m Ruby commiter. I use trunk and head of all branches builds.
It’s easy to find to defects Ruby, Rubygems, bundler. I report our tracking system. and fixed it quickly.
this is my rails fixes. I aimed to targeted version of Ruby is 2.1. I fixed all of interruptions for our Application with Ruby 2.1.
1.8 to 2.0 How to upgrade Ruby 1.8 to 2.0.
my friends named mrkn. he talked that how to upgrade Ruby 1.9.3. In this talk contains a lot of technics in the wild. Please read it later.
2.0 to 2.1 2.0 to 2.1 has no trouble. it cares backward compatible.
2.0 2.1 100 75 69 50 49 CPU Usage(%) 25 0 This is benchmark for new relic average score. CPU Usage is reduced twenty percents on Ruby 2.1
2.0 2.1 250 221 200 189 150 Resp. time(ms) 100 50 0 It’s Response Time comparison. Ruby 2.1 reduces twenty to thirty percents of response time.
2.0 2.1 4 3.8 3 3.2 2 y usage(giga byte) memor 1 0 But memory usage are increased 10-20% by Ruby 2.1. If you use PaaS service like heroku, you need to evaluate this situation before upgrading Ruby 2.1
Ruby 1.8.6 1.8.7 1.9.3 2.0.0 2.1 2.0/2.1 2.3 Rails 3.0 3.2 4.0 After Upgrade Ruby 2.1, I started Upgrading Rails 4.0 line.
Details of Upgrading Rails 4.0, they are written by this book. this book is free e-book. I recommended this book.
Use modern architecture I replaced modern architecher to upgrade Rails 4.
app1 app2 Our System used Kyoto Tycoon. Kyoto Tycoon is memcached compatible session storage, it have dual master function. but session client named dalli not support Kyoto tycoon on Rails 4.
kyoto tycoon is slower than mysql… And biggest problem is this. Kyoto Tycoon is slower than mysql. It’s caused by dual master mechanism
I replaced pure memcached. I solved all problem for upgrading Rails 4
3.2 4.0 300 287 240 180 189 Resp. time(ms) 120 60 0 This is benchmark of Rails4. rails 4 is slower than rails 3. it increased 100 micro seconds of response time.
Ruby 1.9.3 2.0.0 2.1 2.2 3.0 3.2 ? Rails 4.0 ? 4.1 ? this is upgraded version of Ruby and Rails combination matrix. I dropped Ruby 1.8 and Rails 2.3.
Ruby 1.9.3 2.0.0 2.1 2.2 3.0 3.2 ? Rails 4.0 ? New!! 4.1 ? I upgraded Rails 4.1 last week!
I recommend to official upgrade guides
1. Flash structure changes 2. Mutator methods called on Relation And I notice big incompatible things on Rails 4.1. One Flash structure changes. Rails changed key class of flash to String from Symbol. Two. Mutator methods called on Relation. before Rails 4.1 allows mutator methods like map exclamation on Relation objects. but Rails 4.1 raised this methods.
And changed namespace of Minitest. If you use ActionSupport::Testcase and test helper libraries like webmock. Probably Minitest broke these helpers. this is my Pull request of web mock, I already fixed it.
4.0 4.1 300 287 266 240 180 Resp. time(ms) 120 60 0 It’s benchmark of Rails 4.0 and 4.1. Rails 4.1 is faster than 4.0. but it’s slow than Rails 3.0 yet.
Ruby 1.9.3 2.0.0 2.1 2.2 3.0 3.2 ? Rails 4.0 ? 4.1 ? I started to evaluate Rails 4.1 with Ruby 2.2. Ruby 2.2 will be releasing December 2014 for us. I work hard to solve incompatible changes before releases.
class Bar! def bar(foo = foo())! foo! end! ! def buzz(foo = foo)! foo! end! ! def foo! :buzz! end! end! ! p Bar.new.bar! p Bar.new.buzz This is example of incompatible changes on Ruby 2.2. class Bar have foo equal foo method arguments. bar method called foo methods, buzz method doesn’t called foo methods.
% ruby -v r45272.rb! ruby 2.2.0dev (2014-04-13 trunk 45580) [x86_64-darwin13]! :buzz! nil! ! % ruby -v r45272.rb! ruby 2.1.2p80 (2014-03-01 revision 45231) [x86_64-darwin13.0]! :buzz! :buzz ruby 2.2. returns nil. it isn’t assignment same name of default value.
This changes break Rails. but it’s already fixed Rails 4.1 by Aaron Patterson. this patch is backported Rails 4.0. but didn’t fix 3.2 branch. If you still use Rails 3.2, You can’t use Ruby 2.2.
1. fix your code 2. fix gem 3. fix Rails 4. fix Ruby Fix your code. fix using gems. fix Rails. fix Ruby. You should get more controllable things. It’s expand your life!