問題描述
我仔細看了一下 Wordpress 內存消耗。在我的網站上,似乎每個頁面都有 20MB 的 RAM 被分配,只是為了準備好所有的插件運行環境,我繪製了它:
http://zenka.net/roman/wordpress_memory_consumption.gif
沒有一個優點,沒有一個壞傢伙吃大部分的記憶。消費遍佈許多很多 php 模塊。
我們如何使 Wordpress 在內存中初始化其環境一次,然後每次重複使用多次?我不想慢慢的 PHP 吃每個用户點擊 20 MB – 即使在服務器上有大量的內存,需要幾秒鐘才能完成所有的工作。您將基本上需要可重複使用的 read-only 內存塊。
還… 為什麼 20MB?任何人都可以提供洞察力嗎?
編輯:這是在我的開發機器上運行的 Wordpress 上的 WinCacheGrind 輸出 (比共享主機快得多) 。正如你所看到的,它需要一秒鐘的時間才能生成主頁的 HTML 。通過共享託管緩慢下來,你有一個麻煩的秘方。我選擇了大部分時間需要的方法。你會如何優化這個?
http://zenka.net/roman/wordpress_cpu_usage.gif
編輯:這裏是 this fantastic functions.php profiling tool 的查詢統計信息。
Load: 12 queries - 532ms - 19.1MB - 43 cache hits / 53
Query: 15 queries - 563ms - 19.0MB - 72 cache hits / 86
Display: 21 queries - 705ms - 19.2MB - 234 cache hits / 257
編輯:你想看到有什麼可以嚇倒你的嗎?在 index.php 的末尾插入這些行:
echo "<pre>n";
print_r(get_defined_vars());
echo "</pre>n";
我試圖計算當前帖子的身體存儲在內存中的次數。我算了 20 個例子。然後我意識到 PHP 有引用計數,所以拷貝的數量減少到只有三個:兩個似乎在 WP_Query 中,一個在對象緩存中。我正在進一步調查。
這就是為什麼我認為 WordPress 需要重構針對內存問題。您不能再將其內存消耗歸咎於其所做的複雜程度。它只是做了一堆事情錯了。
編輯:經過一天的嘗試,這是我的發現:
1)88%的內存來自 require 或 include 或 include_once 類型的呼叫:
http://zenka.net/roman/wordpress_memory_requires.gif
2)php 文件主要發生在服務請求的第一部分 (不奇怪),這也是所有內存被吃掉的地方:
http://zenka.net/roman/wordpress_includes.gif
3) 繪製請求時正在執行的所有功能非常有趣。共有 12000 多個電話。我激動他們使它更加明顯 (水平軸基本上是堆疊的深度):
http://zenka.net/roman/wordpress_functions.gif
4) 我可以想到的唯一的方法是最小化包含的.php 文件的數量。如果我們從每個文件中分離出來的功能,你可以看到很多文件最多被擊中一次或兩次。我們需要一種如何在不需要時跳過的方式。例如我的遠程數據庫備份插件被加載和註冊,只是從來沒有使用過。以上是以文件名分割的上述情節:
http://zenka.net/roman/wordpress_functions_files.gif
我提供一個值得我所有聲譽的賞金:),用於重構,這將導致我的博客的內存佔用減少 30%以上。
編輯:我安裝了 WP 3.1,這裏比較了舊版本。
http://zenka.net/roman/wordpress_memory_usage_comparison.png
藍色是 WP 3.1,紅色是 3.0.4 。新的 WP 更快,但也佔用更多的內存。
這是一個包含文件的列表。
http://zenka.net/roman/wordpress_3.1_vs_3.0.4_mem_by_file.png
這讓我意識到 「一個一個 SEO 包」 中吃了多少內存 – 一個方法是使用插件的一小部分功能來獲得我想要的東西。而且,我自己的插件似乎還是很糟糕的。
我想嘗試在例如 comment.php(我不允許對我的博客發表評論) 和其他幾個。我刪除了所有已棄用的代碼。我修剪了 kses.php,只能按需加載其全局表。我簡化了 l10n(我沒有本地化),使其函數立即返回字符串,無需查找。我仍然遠離我任意設立的 30%的標記。
編輯:我下載並啓用 APC 與默認設置 (32MB 的操作碼緩存) 。這是比較:
http://zenka.net/roman/3.1_without_with_apc.png
您可以看到代碼加載大量加速,代碼也佔用更少的內存空間 (可能是因為我們只處理操作碼而不是原始源) 。然而,內存消耗仍然相當高。
最佳解決方案
不值得的麻煩。 WordPress 不吃大量的內存 just-because 。它吃了很多內存,因為它運行着很多功能。
使用靜態緩存插件來緩存結果 (頁面生成) 更為簡單和高效。這樣大多數訪客甚至不會打 WP 。
次佳解決方案
And this is why I think WordPress is
in serious need of a rewrite. You can
no longer blame its memory consumption
on sheer complexity of what it does.
It simply does things wrong.
一個天真的結論。閲讀 Things You Should Never Do, Part I 。
謝謝你的內存使用情況。
稍後編輯:Automatic 已經發布了一個名為 prefork 的庫,似乎可以做你所要求的:將 RAM 中的 WordPress 代碼加載一次。
第三種解決方案
從 WordPress 3.2 開始,PHP 5.2 將是最低要求。我認為,在我們的腰帶下,核心的一些可以開始重組,並使用與 auto-loading 的課程。這將讓我們避免加載一些代碼塊,除非實際需要它們。例如,如果在頁面瀏覽中沒有嵌入或畫廊,我們可能會避免加載大量的媒體代碼。
然而,即使他們決定走這條路線,我也希望它是一個緩慢的進化 (像其他 under-the-hood 發生的變化) 。它將需要在許多文件和代碼的位置周圍進行洗牌,這可能會破壞一些插件的反向兼容性。
問題的一部分 (如果真的可以這樣稱呼) 就是沒有這種條件加載,核心框架就不能提前知道為了生成內容視圖而需要或不需要的功能。所以很多功能必須加載,以防萬一他們需要。
第四種方案
How can we make WordPress initialize
its environment in memory only once,
and then reuse it many times for each
hit?
它叫做 opcode-caching 。
http://en.wikipedia.org/wiki/PHP_accelerator
第五種方案
你可能不會減少 ram 的用法。但是,如果您使用 mod_php,則可能需要切換到 mod_fcgid 。
而 mod_php 稍慢,即使不需要加載 php,例如提供圖像,靜態文件,甚至緩存。如果你有很多的請求,這是很多的 ram 。
使用 fcgid 會減少這麼多。
同樣,使用靜態緩存 (如 w3total 緩存) 將避免調用 php,這是一個非常好的優勢:更少的 RAM 使用,更少的數據庫連接。
第六種方案
哈。我現在正在開發一個網絡應用程序,我完全打算超出我的共享託管帳户可以處理的數據和用法,所以我決定 – 雖然這將是非常容易構建在 WP – 嘗試從 BackPress 工作作為一個框架,僅構建我需要的具體的 use-cases 框架。
所以我已經能夠將我的核心環境從 WP 中的數百個 PHP 文件中減少到我實際需要的二十個,同時仍然能夠利用所有的 db,HTTP,user-management,格式化和 cron 函數我喜歡 WordPress 。
問題是它的工作很多,我絕對不會相信我的 hackjob 超出我自己的個人用途。如果要使用完整的 WP 環境,請按原樣進行操作。它是因為數以百計的開發商 fine-tuning 幾年來一樣好。像所有人都説過,通過找到一個更好的託管計劃和研究緩存技術,你可以獲得更多的東西,而不是通過黑客攻擊核心來獲得。
第七種方案
是的,WordPress 首先加載一切,然後做我們要求它做的事情。我可以回憶一下,我們可以在 RAM 中創建一個虛擬池,我們可以放入文件。我把這個想法放在了整個 WordPress 的記憶中 (< 10MB)& 那麼我們可以節省大量的 I / O,這個 I / O 單獨應該提高速度。但是我從來沒有機會去嘗試,而且我也不是那麼精通這樣的東西。但這看起來值得一試。
第八種方案
幾個基本建議:
- w3 緩存插件用於緩存
- 獲取 memcache 安裝和啓用,也啓用從 w3 總緩存設置 (操作碼緩存是一個很好的選擇,但它不太好,w3 總緩存插件)
- 最小化查詢主題文件中的直接鏈接..
- 禁用所有額外的未使用的插件並刪除。
- 優化數據庫。
我正在運行一個知名的 wordpress 網站,每天巨大的流量.. 我不是專門的,甚至為我做的很好:)
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。