2010-04-02 108 views
1

在我當前的項目(Rails 2.3)中,我們收集了120萬個關鍵字,每個關鍵字都與着陸頁相關聯,這實際上是一個給定關鍵字的搜索結果頁面。每個頁面都非常複雜,因此需要很長時間才能生成(中等負載時長達2秒,流量峯值期間更長,使用當前硬件)。問題是,對這些網頁的訪問量有99.9%是通過搜索引擎進行的新訪問,所以在第一次訪問時緩存它並沒有多大幫助:訪問仍然很慢,下次訪問可能會在幾周內。優化着陸頁

我真的想讓這些頁面更快,但我沒有太多的想法如何做到這一點。幾個想到的事情:

  • 預先爲所有關鍵字(具有很長的TTL,一個月左右)建立一個緩存。但是,構建和維護此緩存可能會非常痛苦,並且頁面上的搜索結果可能已過時,甚至不再可訪問;

  • 鑑於此數據的不穩定性,請不要試圖緩存任何內容,只是嘗試向外擴展以跟上流量。

我真的很感謝這個問題的任何反饋。

回答

1

有些東西並不完全與你的描述相加。當你說99.9%是新的訪問時,這實際上並不重要。當你緩存一個頁面時,你不僅僅爲一個訪問者緩存它。但是也許你認爲,對於99.9%的這些網頁,每隔幾周就只有一次。或者,也許你的意思是,99.9%的訪問次數是在一個很少受到攻擊的頁面上?

無論如何,我想知道的第一件事是,是否有相當比例的頁面可以從整頁緩存中受益?什麼將頁面定義爲受益於緩存?那麼,點擊率與更新率之間的比值是最重要的指標。例如,即使只有一天一次點擊的頁面,如果只需要每年更新一次,也可以從緩存中獲益。

在許多情況下頁面緩存不能做太多,所以你需要深入瞭解更多細節。首先,分析頁面...什麼是最慢的部分生成?哪些部件具有最頻繁的更新?是否有任何部分依賴於用戶的登錄狀態(聽起來不像你有用戶一樣?)?

最低的水果(以及將在整個系統中傳播的東西)是優秀的老式優化。爲什麼需要2秒鐘才能生成頁面?優化你的代碼和數據存儲。但不要去做所有的事情,像刪除所有的Rails助手。總是首先進行配置(NewRelic Silver and Gold對於從實際生產環境中獲取痕跡非常有用,絕對值得)優化數據存儲。這可能是通過非規範化或在極端情況下通過切換到不同的數據庫技術。

一旦你完成了所有合理的直接優化策略,看看片段緩存。可以將最常訪問的頁面中最昂貴的部分緩存起來,並具有良好的命中率?謹慎處理複雜或需要昂貴維護的解決方案。

如果有一個優化可擴展性成本的基本規則,那就是你需要足夠的內存來適應你需要定期提供的所有東西,因爲無論你嘗試多麼聰明,它總能讓你獲得比磁盤訪問更多的吞吐量是關於它。內存需要多少?好吧,我在極限尺度上沒有太多的經驗,但是如果你有任何磁盤IO競爭,那麼你肯定需要更多的RAM。你最不希望發生的事情是IO爭用應該快速的東西(例如,日誌記錄),因爲你正在等待一堆可能在RAM(頁面數據)中的東西。

最後一個注意事項。所有的可擴展性都是關於緩存(CPU寄存器> L1緩存> L2緩存> RAM> SSD驅動器>磁盤驅動器>網絡存儲)。這只是一個穀物問題。頁面緩存非常粗糙,簡單,並且可以擴展,如果你可以做到的話。然而,對於龐大的數據集(Google)或高度個性化的內容(Facebook),緩存必須在更加細化的層次上進行。在Facebook的情況下,他們必須優化到單個資產。實質上,他們需要做到這一點,以便在數據中心的任何地方只需幾毫秒即可訪問任何數據。每個頁面都是爲具有自定義資產列表的單個用戶單獨構建的。這一切都必須放在一起在< 500毫秒。

+0

感謝您的詳細解答。我的意思是99.9%的新訪問量,是指一個頁面平均每幾周訪問一次,所以它通常是一個緩存未命中,並且頁緩存需要非常長的TTL才能生效,所以數據在這個頁面上將不再相關。並沒有公共數據可以提取和分解緩存(至少沒有計算成本昂貴,只有一些靜態數據)。 – 2010-04-02 20:36:23

+0

關於性能分析:我使用NewRelic對這些頁面進行了一些性能分析,數據庫中沒有明顯的瓶頸,慢速的事務跟蹤顯示了請求生命週期中不同調用的完全隨機的時間消耗模式。 CPU燒錄也非常高,所以我認爲我們在服務器上的資源不足。實際上,與Passenger pool的大小玩起來有一點幫助。我也會嘗試擴展到另一臺服務器,我希望一些負載平衡會有所幫助。 – 2010-04-02 20:37:01