Für Ruby 1.9.3 sind diverse Performance Tweaks bekannt die jedoch in der standard RVM Version nicht vorhanden sind. Dieser Blogpost wird aufzeigen wie man diese auf einem Citrin Rails Server anwendet.
Die Optimierungen zusammengefasst
- GCC Flags für Binary Optimization
- Falcon patch
- Ruby 1.9.3 Environment Variabeln
Die Auswirkungen und Performance Messungen findet man in den Quellen. Hier wird nur die Anwendung auf einem Rails Server gezeigt.
Als Beispiel nehmen wir das auf einem Rails Server Standard gehostete vereine.ch. Hier haben die Tweaks einen Performance Gewinn von 20%-30% über die 5 meist genutzten URLs gebracht.
Ruby ruby-1.9.3-p327 mit Optimierungen installieren
Zuerst kommt das Update auf die aktuelle RVM Version.
rvm get head --auto rvm reload
Nun kann man Datei ~/.rvmrc erstellen mit dem Inhalt
rvm_configure_env=(CFLAGS="-march=native -O3")
Nun noch automake installieren und danach die neue Ruby Version mit dem Patch kompilieren.
aptitude install automake rvm install 1.9.3-p327 --patch falcon
Um einen reibungslosen Übergang für die bestehenden Apps zu garantieren kann man das gemset der alten Ruby version in die neue kopieren.
rvm gemset copy ruby-1.9.2-p290 ruby-1.9.3-p327
Nun noch das Passenger Apache Modul unter der neuen Version kompilieren.
rvm use ruby-1.9.3-p327 passenger-install-apache2-module
Danach noch den Passenger auf die richtige Ruby version konfigurieren:
In /etc/apache2/mods-enabled/passenger.load und /etc/apache2/mods-enabled/passenger.conf z.B.
PassengerRoot /usr/local/rvm/gems/ruby-1.9.3-p327/gems/passenger-3.0.9 # PassengerRoot /usr/local/rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.9
Nach dem Webserver Neustart verwenden alle Rails Applikationen das neue Ruby.
service apache2 restart
Ruby Umgebungsvariabeln
Mit einem besseren Memory Allocator kann nochmal mehr Performance rausgeholt werden.
apt-get install libtcmalloc-minimal0 export LD_PRELOAD=/usr/lib/libtcmalloc_minimal.so.0.1.0
Zudem kann man in Ruby 1.9.3 das Verhalten des GC und mehr über Umgebungsvariabeln optimieren
export RUBY_HEAP_MIN_SLOTS=800000 export RUBY_HEAP_FREE_MIN=100000 export RUBY_HEAP_SLOTS_INCREMENT=300000 export RUBY_GC_MALLOC_LIMIT=79000000 export RUBY_FREE_MIN=200000 export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1.8
Mit einem Wrapperscript kann man diese auch für die vom Passenger gestarteten Ruby Prozesse verfügbar machen.
vi /usr/local/my_ruby_wrapper_script
Das Script soll so aussehen.
#!/bin/sh export RUBY_HEAP_MIN_SLOTS=800000 export RUBY_HEAP_FREE_MIN=100000 export RUBY_HEAP_SLOTS_INCREMENT=300000 export RUBY_GC_MALLOC_LIMIT=79000000 export RUBY_FREE_MIN=200000 export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1.8 export LD_PRELOAD=/usr/lib/libtcmalloc_minimal.so.0.1.0 exec "/usr/local/rvm/wrappers/ruby-1.9.3-p327/ruby" "$@"
Nun noch ausführbar machen…
chmod +x /usr/local/my_ruby_wrapper_script
und in der Passenger Konfiguration angeben indem man in /etc/apache2/mods-enabled/passenger.conf
PassengerRoot /usr/local/rvm/gems/ruby-1.9.3-p327/gems/passenger-3.0.9
ersetzt mit
PassengerRuby /usr/local/my_ruby_wrapper_script