相對我們對於redis的使用場景都已經想當的熟悉。對於大量的資料,為了緩解介面(資料庫)的壓力,我們對查詢的結果做了快取的策略。一開始我們的思路是這樣的。
1.執行查詢
2.快取中存在資料 -> 查詢快取
3.快取中不存在資料 -> 查詢實時介面
對此,我簡單模擬了我們的快取機制 。
這是乙個查詢實時的服務
package yyf.jedis.toolsbyredis.cachecachetools;
/** * 模擬服務
* @author yuyufeng
* */
public class baseservice
}
從**中我們可以看到,這個服務反應應該是非常快的。
package yyf.jedis.toolsbyredis.cachecachetools;
import redis.clients.jedis.jedis;
import redis.clients.jedis.jedispool;
import redis.clients.jedis.jedispoolconfig;
public class cachecachetooltest
public static void main(string args) }.start();
}} public static void query() else
system.out.println(res);
jedispool.returnresource(jedis); }}
當5個併發進來的時候,第乙個查詢實時服務,其餘的查詢快取。
##查詢介面服務
hello:test123
##查詢快取
##查詢快取
##查詢快取
hello:test123
hello:test123
hello:test123
##查詢快取
hello:test123
看到結果,我們似乎覺得這個查詢非常的合理,當時當我們的實時介面查詢速度很慢的時候,就暴露出問題來了。
package yyf.jedis.toolsbyredis.cachecachetools;
/** * 模擬服務
* @author yuyufeng
* */
public class baseservice catch (interruptedexception e)
return "hello:" + req; }}
##查詢介面服務
##查詢介面服務
##查詢介面服務
##查詢介面服務
##查詢介面服務
hello:test123
hello:test123
hello:test123
hello:test123
hello:test123
結果是,全部都查詢的介面服務。這樣會導致併發一高,快取就相當於作用非常小了。
如果在查詢實時過程時,對於相同的請求,能夠讓其等待,那麼效率會有大大的提公升:(為了模擬,加鎖處理)
public static void main(string args)
}}.start();
}}
##查詢快取
hello:test123
##查詢快取
hello:test123
##查詢快取
hello:test123
##查詢快取
hello:test123
##查詢快取
hello:test123
現在就都是查詢快取了。其實對於查詢併發這樣做是比好的。打個比方:
一堆人需要從乙個出口出去,這個出口有乙個小門已經可以通過,還有乙個大門未開啟,需要從小門出去開啟。這個大門非常大(redis查詢速度非常快)。如果大批的人同時出去(高併發),那麼必然在小門擠很長的時間。此時,如果現有乙個人去把大門先開啟,那麼後面的人(包括本來要擠小門的人)可以直接從大門出去,效率肯定是後面的划算。
對於查詢實時一次比較慢的情況下,可以先讓乙個執行緒進去。讓其它執行緒等待。
當然,這樣並不完美。當快取失效,那麼查詢就會卡頓一下。為了保證使用者能一直流暢的查詢,我有如下兩種方案:
1.在快取存在的時間裡的進行非同步查詢去更新快取。
2.使用二級快取,並且當一級快取失效的時候,會去讀取二級快取,二級快取非同步更新。(二級快取的時間可以很長)
下面是第一種策略的**模擬:
public static void query() else
}.start();
}} system.out.println(res);
jedispool.returnresource(jedis);
}
執行結果:
##查詢快取
hello:test123
##查詢快取
hello:test123
##查詢快取
hello:test123
##查詢快取
hello:test123
##查詢快取
hello:test123
非同步更新資料:test123
非同步更新資料:test123
非同步更新資料:test123
非同步更新資料:test123
非同步更新資料:test123
為了保證一段時間內,更新乙個快取只執行一次,做如下鎖
public static void main(string args)
}.start();
} }public static void query() else
}}.start();
}} jedispool.returnresource(jedis);
}
執行兩次,間隔10秒。執行結果:
hello:test123
##查詢快取
hello:test123
hello:test123
hello:test123
hello:test123
##查詢快取
##查詢快取
##查詢快取
##查詢快取
非同步更新資料:test123
這樣,即可保證一次查詢比較耗時的情況下,使用者能流暢的查詢。使用者體驗大大提公升
基於redis的快取機制的思考和優化
package yyf.jedis.toolsbyredis.cachecachetools 模擬服務 author public class baseservice package yyf.jedis.toolsbyredis.cachecachetools import redis.client...
基於redis的快取機制的思考和優化
相對我們對於redis的使用場景都已經想當的熟悉。對於大量的資料,為了緩解介面 資料庫 的壓力,我們對查詢的結果做了快取的策略。一開始我們的思路是這樣的。1.執行查詢 2.快取中存在資料 查詢快取 3.快取中不存在資料 查詢實時介面 對此,我簡單模擬了我們的快取機制 這是乙個查詢實時的服務 pack...
Redis快取過期機制
redis可以通過設定乙個過期時間expire來處理快取,其中處理方式有兩種 主動 定期刪除,redis會抽查隨機的key,預設1秒十次,一旦抽查的key過期了,就會給刪除,配置的屬性在redis.conf中,hz等於10,表示1秒抽查10次 hz 10 被動 惰性刪除,key到期後不去主動檢測,而...