天天看點

Ruby企業版(REE)調優

 本篇文章如果有訂閱Ruby5的童鞋們應該知道的。

最近國外的一個同行Bryan Liles做過一個對RubyEE下執行測試的的評測:

未調優前:

<code>410 scenarios (410 passed)</code>

<code>3213 steps (3213 passed) </code>

<code>9m29.685s</code>

 調優後:

<code>410 scenarios (410 passed) </code>

<code>5m58.661s</code>

差距怎麼這麼大呢?

可以去看看REE官方文檔關于GC性能調整的章節。隻需要設定5個參數,我們也可以得到上面的效果:

<code>export RUBY_HEAP_MIN_SLOTS=1000000</code>

<code>export RUBY_HEAP_SLOTS_INCREMENT=1000000</code>

<code>export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1 </code>

<code>export RUBY_GC_MALLOC_LIMIT=1000000000</code>

<code>export RUBY_HEAP_FREE_MIN=500000</code>

下面我們來解釋一下這些變量的意義:

<dl></dl>

<dt>RUBY_HEAP_MIN_SLOTS</dt>

<dd></dd>

This specifies the initial number of heap slots. The default is 10000.

專門聲明堆棧的初始資料的,預設是10000.

這個預設配置太小了。因為我們測試可能用到更多的堆,是以我們把它設定的大點。這就意味着我們要消耗更多的記憶體。

<dt>RUBY_HEAP_SLOTS_INCREMENT</dt>

The number of additional heap slots to allocate when Ruby needs to allocate new heap slots for the first time. The default is 10000.

For example, suppose that the default GC settings are in effect, and 10000 Ruby objects exist on the heap (= 10000 used heap slots). When the program creates another object, Ruby will allocate a new heap with 10000 heap slots in it. There are now 20000 heap slots in total, of which 10001 are used and 9999 are unused.

當Ruby需要開辟一片新的堆棧所需的數,預設是10000.

例如, 假如實際堆棧就隻有預設配置的那麼多,有10000個Ruby對象已經占滿了堆棧, 當你的程式建立另一個對象的時候, Ruby會配置設定一個新的堆,包含10000個棧。 那麼現在就一共有20000 個堆棧, 其中有10001個是被占的, 而有9999空閑。

<dt></dt>

從這裡我們可以看出來, 當所有的桟都被耗盡,一片新的桟會被開辟出來。 預設配置的數字太低了,可能時不時的開辟堆,是以上面的配置把它增加了100倍。

<dt>RUBY_HEAP_SLOTS_GROWTH_FACTOR</dt>

Multiplicator used for calculating the number of new heaps slots to allocate next time Ruby needs new heap slots. The default is 1.8.

Take the program in the last example. Suppose that the program creates 10000 more objects. Upon creating the 10000th object, Ruby needs to allocate another heap. This heap will have 10000 * 1.8 = 18000 heap slots. There are now 20000 + 18000 = 38000 heap slots in total, of which 20001 are used and 17999 are unused.

The next time Ruby needs to allocate a new heap, that heap will have 18000 * 1.8 = 32400 heap slots.

 當ruby需要新的堆棧的時候, 此參數做為一個乘數被用來計算這片新的堆棧的大小。

 拿上個例子來說, 假設程式又建立了10000個對象。Ruby需要配置設定另一個堆。這個堆将會是這麼多堆棧:

 10000 * 1.8 = 18000。 那麼這裡一共就有20000+18000個堆棧, 其中有20001個被用,而有17999個空閑。

<dt>RUBY_GC_MALLOC_LIMIT</dt>

The amount of C data structures which can be allocated without triggering a garbage collection. If this is set too low, then the garbage collector will be started even if there are empty heap slots available. The default value is 8000000.

這是不觸發垃圾回收的C資料結構的數量。如果它設定的太低就會觸發垃圾回收,即使還有很多可用的空閑堆棧。預設是8000000.

<dt>RUBY_HEAP_FREE_MIN</dt>

The number of heap slots that should be available after a garbage collector run. If fewer heap slots are available, then Ruby will allocate a new heap according to the RUBY_HEAP_SLOTS_INCREMENTand RUBY_HEAP_SLOTS_GROWTH_FACTOR parameters. The default value is 4096.

       在垃圾回收運作以後可用的堆棧數。 如果可用的堆棧太少, 那麼Ruby會按照UBY_HEAP_SLOTS_INCREMENT  和RUBY_HEAP_SLOTS_GROWTH_FACTOR的配置參數配置設定一個新的堆。預設是4096. 

值得注意的是,以上的配置請不要在生産環境下使用。 當然你可以參考37signals 和 Twitter 提供的REE配置來調優你的應用。

37signals 在生産環境的配置:

RUBY_HEAP_MIN_SLOTS=600000

RUBY_GC_MALLOC_LIMIT=59000000 

RUBY_HEAP_FREE_MIN=100000

Twitter 用在生産環境的配置:

RUBY_HEAP_MIN_SLOTS=500000 

RUBY_HEAP_SLOTS_INCREMENT=250000 

RUBY_HEAP_SLOTS_GROWTH_FACTOR=1 

RUBY_GC_MALLOC_LIMIT=50000000

關于Twitter配置的說明:

Start with enough memory to hold the application (Ruby’s default is very low, lower than what a Rails application typically needs).

讓你的應用保持足夠的記憶體(Ruby預設的非常低, 低于典型Rails應用所需)

Increase it linearly if you need more (Ruby’s default is exponential increase).

如果你需要更多堆棧,請保證它線性增長(Ruby預設的是指數級增長)

Only garbage-collect every 50 million malloc calls (Ruby’s default is 6x smaller).

每5000萬個malloc被調用才啟動垃圾回收(Ruby預設的數比這個數小6倍)

繼續閱讀