問題描述
我仔細看了一下 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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。