1)通用性:全量屬性更好。數據庫
2)佔用空間:部分屬性更好。數組
3)代碼維護:表面上全量屬性更好。緩存
定義:大量請求不命中。bash
1)業務代碼自身問題。服務器
2)惡意攻擊、爬蟲等等。網絡
1)業務的相應時間。函數
2)業務自己問題。性能
3)相關指標:總調用數、緩存層命中數、存儲層命中數。優化
1)緩存空對象。ui
一、須要更多的鍵。
二、緩存層和存儲層數據「短時間」不一致。
2)布隆過濾器攔截。
所謂的布隆過濾器是一個很長的二進制向量,存放0或者1。通過幾回hash計算,獲得5,9,2三個數字,那麼存放結果以下圖所示:
僅僅從布隆過濾器自己而言,根本沒有存放完整的數據,只是運用一系列隨機映射函數計算出位置,而後填充二進制向量。所以,可使用固定的計算方式 ,來判斷一個數據是否存在。可是因爲相似哈希衝突的緣由存在誤判的可能性,也就是說,布隆過濾器只能判斷數據不存在,而不能判斷數據必定存在。
public class RedisTest {
static final int expectedInsertions = 100;//要插入多少數據
static final double fpp = 0.01;//指望的誤判率
//bit數組長度
private static long numBits;
//hash函數數量
private static int numHashFunctions;
static {
numBits = optimalNumOfBits(expectedInsertions, fpp);
numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, numBits);
}
public static void main(String[] args) {
Jedis jedis = new Jedis("你的ip", 6379);
for (int i = 0; i < 100; i++) {
long[] indexs = getIndexs(String.valueOf(i));
for (long index : indexs) {
jedis.setbit("codebear:bloom", index, true);
}
}
for (int i = 0; i < 100; i++) {
long[] indexs = getIndexs(String.valueOf(i));
for (long index : indexs) {
Boolean isContain = jedis.getbit("codebear:bloom", index);
if (!isContain) {
System.out.println(i + "確定沒有重複");
}
}
System.out.println(i + "可能重複");
}
}
/**
* 根據key獲取bitmap下標
*/
private static long[] getIndexs(String key) {
long hash1 = hash(key);
long hash2 = hash1 >>> 16;
long[] result = new long[numHashFunctions];
for (int i = 0; i < numHashFunctions; i++) {
long combinedHash = hash1 + i * hash2;
if (combinedHash < 0) {
combinedHash = -combinedHash;
}
result[i] = combinedHash % numBits;
}
return result;
}
private static long hash(String key) {
Charset charset = Charset.forName("UTF-8");
return Hashing.murmur3_128().hashObject(key, Funnels.stringFunnel(charset)).asLong();
}
//計算hash函數個數
private static int optimalNumOfHashFunctions(long n, long m) {
return Math.max(1, (int) Math.round((double) m / n * Math.log(2)));
}
//計算bit數組長度
private static long optimalNumOfBits(long n, double p) {
if (p == 0) {
p = Double.MIN_VALUE;
}
return (long) (-n * Math.log(p) / (Math.log(2) * Math.log(2)));
}
}
複製代碼
定義:某一個時間段,緩存集中過時失效。
1)集中設置統一的過時時間,到了必定時間時,便所有懟到數據庫上了。
2)服務器某個結點宕機或斷網。
1)使用隨機因子儘量分散過時時間。
2)使用集羣高可用化。
問題描述:2010年,Facebook有了3000個Memcache節點,發現增長機器性能沒能提高,反而降低。
1)更多的機器!=更高的性能。
2)批量接口需求(mget, mset等)。
3)數據增加與水平擴展等。
1)命令自己優化:例如慢查詢keys、hgetall bigkey。
2)減小網絡通訊次數。
3)下降接入成本:例如客戶端長鏈接/鏈接池、NIO等。
問題描述:熱點key+較長的重建時間
可能會存在多個線程共同執行查詢數據源與重建緩存的操做。
1)減小重建緩存的次數。
2)數據儘量一致。
3)減小潛在風險。
在重建時開始加鎖,完成重建後進行解鎖。
代碼:
優勢:
1)思路簡單。
2)保證一致性。
缺點:
1)代碼複雜度增長。
2)存在死鎖的風險。
1)緩存層面:沒有設置過時時間。
2)功能層面:爲每一個value添加邏輯過時時間,但發現超過邏輯過時後,會使用單獨的線程去構建緩存。
代碼:
優勢:
基本杜絕熱點key重建問題。
缺點:
1)不保證一致性。
2)邏輯過時時間增長維護成本和內存成本。