概念:
增加節點機器,效能沒有提公升反而下降了。以使用者為例: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為拷貝...