当前位置 - 股票行情交易網 - 裝修設計 - Rails內存優化

Rails內存優化

我們知道Rails應用的內存占用通常都是比較高的,尤其是比較重型的全棧應用內存使用更接近1G(當然同時也包括想sidekiq這樣加載整個Rails應用的ruby進程),所以我們通常對應這種情況都采取壹種比較tricky的方式,使用像 puma_worker_killer 這樣的監控程序,監控rails進程達到壹定內存占用後將其重啟。也就是說應用壹開始的內存占用通常都在100~300MB之間,隨著時間的推移進程會創建大量的『對象』內部又會進行數次內存分配和回收,所以內存就會不斷飆升。

在我們知道了基本情況之後,那就該說說正題如何優化Rails的內存占用,解決方案有若種,我們這裏講解壹個最容易實施而且見效最快的方式,就是從內存分配入手。ruby使用glibc的malloc(3)進行內存分配,這是壹個比較古老的內存分配器,性能比較低分配時會產生大量碎片。所以真的這壹點,現在由很多性能比較出色由兼容原有API和以及被驗證過的特性的新分配器,如jemalloc和tmalloc,這裏我們就使用jemalloc作為Ruby應用的內存分配器,來看看能達到什麽樣的優化效果。

jemalloc是facebook出品的,最早用於FreeBSD中的內存分配器,後來像firefox從3.0也開始使用它,redis從2.4之後默認在linux上使用jemalloc。既然有這麽多性能敏感型的軟件都使用了jemalloc那它壹定有過人之處。

jemalloc的特別之處在於它融合了其他內存分配技術的優勢,並且采用多級內存分配,線程池緩存tcache還有劃分內存區來減少線程間鎖的爭用。

jemalloc結構:

多級內存分配 :jemalloc根據對象的大小,將其歸為劃分為 small object, large object和huge object三類

Arena : jemalloc 沒有像malloc那樣對內存的劃分都幾種在壹個區域中管理,而是使用多個小塊的內存區域來分別管理,內個小塊稱為"arena" 。

線程池緩存thread cache :tcache是分配線程的緩存空間,jemalloc使用tcache來減少線程內存分配中鎖競爭,從而提升分配效率,每個tcache對應壹個arena。

這壹步我們來看看應用Jemalloc到我們的ruby進程中到底能有多大的提升呢。

安裝

我們選擇在2.4.1版本上進行測試。除了上面這種安裝方式外,也可以通過gem包來安裝 jemalloc-rb

內存使用

我們在同壹個應用運行的兩臺服務器中的壹個上面安裝的jemalloc,而另壹套作為對照組沒有安裝。

這裏就貼出性能差距最明顯的壹個進程 rails應用的sidekiq進程

沒有使用jemalloc的服務器上面的sidekiq進程

使用jemalloc的服務器上面的sidekiq進程

可以看到差距是很明顯的,當然不是每個進程都有這樣的優化效果,這個我們總結的時候再說。

從上面的jemalloc的前後對比圖中我們能夠看出jemalloc的優化還是有明顯效果的。至於為什麽sidekiq和puma之前的差距這麽大,這就引出了,其實jemalloc僅是從內存分配的程度去優化和改進內存使用和性能,在妳的應用程序大量產生對象,並且長久運行下去的情況時,效果就比較明顯,而如果應用本身做的就比較精簡,從程序角度優化的比較好的話,jemalloc的提示就不明顯。所以說jemalloc可以為妳的應用內存性能解燃眉之急,但是從系統性的角度出發,還是從自身出發優化好應用本身的性能。