我有一個從MySQL數據庫提供服務的web服務。我想創建緩存文件來提高性能。這個想法有一次我們從數據庫讀取數據並生成一個文本文件。我的問題是:服務器文件讀/寫併發問題
如果客戶端用戶在生成文件時訪問該文件會怎麼樣?
我們使用LAMP。在PHP中,flock()處理併發問題,但我的理解是隻有當2個PHP進程同時訪問文件時。我們的情況是不同的。
我不知道這是否會導致問題。如果是這樣,我該如何預防呢?
感謝,
我有一個從MySQL數據庫提供服務的web服務。我想創建緩存文件來提高性能。這個想法有一次我們從數據庫讀取數據並生成一個文本文件。我的問題是:服務器文件讀/寫併發問題
如果客戶端用戶在生成文件時訪問該文件會怎麼樣?
我們使用LAMP。在PHP中,flock()處理併發問題,但我的理解是隻有當2個PHP進程同時訪問文件時。我們的情況是不同的。
我不知道這是否會導致問題。如果是這樣,我該如何預防呢?
感謝,
不使用鎖定; 如果你的緩存文件是/tmp/cache.txt,那麼你應該總是重新生成緩存到/ tmp/cache2。TXT,然後執行
mv /tmp/cache2.txt /tmp/cache.txt
或
rename('/tmp/cache2.txt','/tmp/cache.txt')
的MV /重命名操作是原子的,如果它發生在同一文件系統內部;沒有鎖定需要
當一個客戶端訪問該文件,它讀取它,因爲它是在那一刻。 flock()用於2個PHP進程同時訪問文件。
各種各樣的優化選項在這裏;
1)您是否正在使用MySQL queryCache - 這可能會使數據庫承受巨大負載。
2)您可以通過像squid這樣的網絡代理(或配置爲反向緩存代理的Apache)來獲取文件。我一直這樣做,這是一個非常方便的技術 - 通過使用wget從url中獲取文件來生成文件(例如,您可以在cron作業中使用它)。 Web代理負責交付之前存在的相同文件,或者在需要時重新生成。
3)您不希望在這種情況下滾動您自己的文件鎖定解決方案。
根據您的場景,您也可以考慮緩存頁面,如memcache,這對於高流量場景來說很棒,但可能超出了這個問題的範圍。
您可以使用A - > B切換來避免此問題。
E.g. :讓這個緩存文件A和B有兩個副本,程序應該通過符號鏈接C讀取這些文件。當程序正在構建緩存時,它將修改不是「當前」的文件即,如果C鏈接到A,則更新B.一旦更新完成,將符號鏈接切換到B.
下次更新A並且在更新完成後將符號鏈接切換到A.
這樣,客戶端永遠不會讀取正在更新的文件。
我會解決這個問題是這樣的:
瑣碎,但應該做伎倆