常見快取問題及解決方案

2021-09-26 04:16:15 字數 4526 閱讀 8496

概念:

增加節點機器,效能沒有提公升反而下降了。以使用者為例:user-133-age,user-133-name,user-133-height ... n個ke,當伺服器增多的時候,133號使用者的資訊,也被更散落在更多的節點上,所以,同樣是訪問個人主頁,得到相同的個人資訊,節點越多,要連線的節點也越多,對於memecached的連線數,並沒有隨著節點的增多,而降低。於是出現了無底洞現象。nosql與傳統的rdbms並不是水火不容,兩者在某些設計上,是可以相互參考的,對於memcacede、redis這種kv儲存,key的設計,可以參考mysql中表/列的設計

解決方案:

概念:

訪問乙個不存在的key,快取不起作用,請求會穿透到db,流量大時db會掛掉。

解決方案:

採用布隆過濾器,使用乙個足夠大的bitmap,用於儲存可能訪問的key,不存在的key直接被過濾;

訪問key未在db查詢到值,也將空值寫進快取,但可以設定較短過期時間。

<?php

/** * author: sai

* date: 2019/5/17

* time: 14:10

* **來自網路,有改動

*/class bloomfilterhash

// var_dump(($hash % 0xffffffff) & 0xffffffff);die;

return ($hash % 0xffffffff) & 0xffffffff;

}/**

* 該雜湊演算法基於at&t貝爾實驗室的peter j. weinberger的工作。

* aho sethi和ulman編寫的「編譯器(原理,技術和工具)」一書建議使用採用此特定演算法中的雜湊方法的雜湊函式。

*/public function pjwhash($string, $len = null)

$test = $hash & $highbits; if ($test != 0)

// var_dump(($hash % 0xffffffff) & 0xffffffff);die;

return ($hash % 0xffffffff) & 0xffffffff;

}/**

* 類似於pjw hash功能,但針對32位處理器進行了調整。它是基於unix的系統上的widley使用雜湊函式。

*/public function elfhash($string, $len = null)

$hash &= ~$x;

}// var_dump(($hash % 0xffffffff) & 0xffffffff);die;

return ($hash % 0xffffffff) & 0xffffffff;

}/**

* 這個雜湊函式來自brian kernighan和dennis ritchie的書「the c programming language」。

* 它是乙個簡單的雜湊函式,使用一組奇怪的可能種子,它們都構成了31 .... 31 ... 31等模式,它似乎與djb雜湊函式非常相似。

*/public function bkdrhash($string, $len = null)

// var_dump(($hash % 0xffffffff) & 0xffffffff);die;

return ($hash % 0xffffffff) & 0xffffffff;

}/**

* 這是在開源sdbm專案中使用的首選演算法。

* 雜湊函式似乎對許多不同的資料集具有良好的總體分布。它似乎適用於資料集中元素的msb存在高差異的情況。

*/public function sdbmhash($string, $len = null)

// var_dump(($hash % 0xffffffff) & 0xffffffff);die;

return ($hash % 0xffffffff) & 0xffffffff;

}/**

* 由daniel j. bernstein教授製作的演算法,首先在usenet新聞組comp.lang.c上向世界展示。

* 它是有史以來發布的最有效的雜湊函式之一。

*/public function djbhash($string, $len = null)

var_dump(($hash % 0xffffffff) & 0xffffffff);die;

return ($hash % 0xffffffff) & 0xffffffff;

}/**

* donald e. knuth在「計算機程式設計藝術第3卷」中提出的演算法,主題是排序和搜尋第6.4章。

*/public function dekhash($string, $len = null)

// var_dump((int)($hash % 0xffffffff) & 0xffffffff);die;

return ($hash % 0xffffffff) & 0xffffffff;

}/**

* 參考

*/public function fnvhash($string, $len = null)

// var_dump(($hash % 0xffffffff) & 0xffffffff);die;

return ($hash % 0xffffffff) & 0xffffffff;

}}/**

* 使用redis實現的布隆過濾器

*/abstract class bloomfilterredis

$this->hash = new bloomfilterhash;

$this->redis = self::getredis(); //假設這裡你已經連線好了

}public static function getredis()

/*** 新增到集合中

*/public function add($string)

return true;

}/**

* 查詢是否存在, 不存在的一定不存在, 存在有一定機率會誤判(hash衝突)

*/public function exists($string)

$res = $pipe->exec();

// var_dump($res);

foreach ($res as $bit)

}return true;

}}/**

* 重複內容過濾器

* 該布隆過濾器總位數為2^32位, 判斷條數為2^30條. hash函式最優為3個.(能夠容忍最多的hash函式個數)

* * 注意, 在儲存的資料量到2^30條時候, 誤判率會急劇增加, 因此需要定時判斷過濾器中的位為1的的數量是否超過50%, 超過則需要清空.

*/class filterepeatedcomments extends bloomfilterredis

var_dump((new filterepeatedcomments())->add('abc')); //true

var_dump((new filterepeatedcomments())->add('bcd'));//true

var_dump((new filterepeatedcomments())->add('dfg'));//true

var_dump((new filterepeatedcomments())->exists('dfg'));//true

var_dump((new filterepeatedcomments())->exists('dgg'));//false

概念:

大量的key設定了相同的過期時間,導致在快取在同一時刻全部失效,造成瞬時db請求量大、壓力驟增,引起雪崩。

解決方案:

概念:

乙個存在的key,在快取過期的一刻,同時有大量的請求,這些請求都會擊穿到db,造成瞬時db請求量大、壓力驟增。

解決方案:

後台設定定時任務,主動地去更新快取資料。這種方案容易理解,但是當key比較分散的時候,操作起來還是比較複雜的。

分級快取。比如設定兩層快取保護層,1級快取失效時間短,2級快取失效時間長。有請求過來優先從1級快取中去查詢,如果在1級快取中沒有找到相應資料,則對該執行緒進行加鎖,這個執行緒再從資料庫中取到資料,更新至1級和2級快取。其他執行緒則直接從2級執行緒中獲取。

提供乙個攔截機制,內部維護一系列合法的key值。當請求的key不合法時,直接返回。

利用加鎖或者佇列方式避免過多請求同時對伺服器進行讀寫操作

概念:

當前 key 是乙個熱點 key( 例如乙個熱門的娛樂新聞),併發量非常大。重建快取不能在短時間完成,可能是乙個複雜計算,例如複雜的sql、多次 io、多個依賴等。

解決思路

解決方案:

快取常見問題及解決方案

使用快取可以緩解大流量壓力,顯著提高程式的效能。我們在使用快取系統時,尤其是大併發情況下,經常會遇到一些 疑難雜症 本文總結了一些使用快取時常見的問題及解決方案,以後在遇到這類問題時可以作為參考,在設計快取系統的時候也應該考慮這些常見的情況。為了表述方便,本文以資料庫查詢快取為例,使用快取可以減小對...

快取中常見的問題及解決方案

快取技術是 服務端經常用到的一種技術,在讀多寫少的業務場景中,通過使用快取可以有效地提高 的效能,支撐高併發的訪問量,對資料庫做到很好的保護。我們在使用快取的時候,如redis memcached,基本上都遇到以下幾個問題 快取穿透 快取併發 快取失效 快取雪崩 熱點key db快取一致性。本案例結...

redis快取常見問題及解決方案

快取雪崩 當快取伺服器重啟或者大量快取集中在某乙個時間段失效,這樣在失效的時候,會給後端系統帶來很大壓 力。導致系統崩潰。解決方案 在快取失效後,通過加鎖或者佇列來控制讀資料庫寫快取的執行緒數量。比如對某個key只允許乙個線 程查詢資料和寫快取,其他執行緒等待。做二級快取,a1為原始快取,a2為拷貝...