2009-09-18 47 views
4

我有這個類似博客的系統(LAMP),我想跟蹤每篇文章的瀏覽次數。現在,每次查看文章或使用一些臨時表時,更新文章的視圖列是最好的,在這裏我只存儲文章ID,然後(假設每小時)運行一個查詢,數據來自臨時表並更新文章中的行表?我接受完全不同的解決方案。如何以最有效的方式跟蹤視圖數量?

請注意,我不能使用任何分析工具,因爲我需要使用這些數字(最受歡迎等)。

+0

你沒有說明你有多少個Web服務器,以及它們是否都與數據庫位於同一位置,但是我的答案可能相當有效,即使它們相當多,而且其中一些不是很「噸。 – MarkR 2009-09-18 22:16:34

回答

2

每次讀取文章時更新文章表格將意味着更多地鎖定此表格(或行,具體取決於您使用的引擎)

使用臨時表可能是一個更好的解決方案,在我看來:

  • 要麼做原料插入每一篇文章被觀看的時間,並沒有更新
  • 或更新每篇文章的計數器,在那個臨時表
  • (如果您使用像InnoDB這樣的引擎支持行鎖並且不使用表鎖)使用類似於每篇文章100行的內容,並且每次文章是隨機更新其中之一查看
    • 這樣,鎖的併發性就會降低(如果你有5個用戶在同一時間閱讀同一篇文章,他們會嘗試更新100條中同一行的風險不大! )
    • 只需記住,當您要計算文章被查看的次數時,您必須對每篇文章的100行進行總和,以獲得「總計」。

最後的解決辦法可能是最好的一個存在,在併發方面 - 再次,如果你使用的是支持行鎖(即不MyISAM數據)發動機。

然後,偶爾運行一個cron作業,該作業將從該臨時表中計數,並更新文章表。

2

這可能是一個過早優化的情況嗎? 在進入具有單獨表格和運行cron作業的極端之前,我會確保在調整正確時簡單的方法是一個問題。

此外,你的問題是寫鎖定爭用,通過寫入另一個表,你剛剛移動該爭用到該表,並將具有相同的阻塞。

我建議:

  1. 讓你讀不鎖(NOLOCK),只有你用鎖寫入。因此,您只能同時更新查看次數,而不能讀取文章數據。
  2. 如果這還不夠好,並且可以忍受一些邊緣案例的視圖計數丟失,請異步執行視圖計數更新,並且不要等到它返回以顯示頁面。

(按觀看次數的邊緣情況下的損失,我的意思情況下,您提供的網頁後,因爲你的DB走下文章數據讀取剛過,但觀看計數被更新前的非同步寫入失敗)

1

「最有效的方式」是相當主觀的;您必須啓發我們解決您的特定性能問題。

我可能會將頁面瀏覽量追加到本地日誌文件(當然是原子性的),然後有一個過程定期輪換並將其彙總到數據庫中(當然,處理併發訪問正確;這是作爲讀者的練習)。

摘要計算器會記錄一段時期內日誌文件中每篇文章的視圖數(例如每兩分鐘運行一次),然後在單個事務中執行,但是需要多次更新,每篇文章一次。這些可能不會導致太多的問題,因爲您每個Web服務器只查看一個進程,每分鐘處理一個事務(或者2個,或5個或者多個),而不是每個Web請求一個事務。數據庫上的負載會減少很多。

相關問題