新聞中心
Redis過期場景:實現(xiàn)有效的自動清理

赫章網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),赫章網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為赫章上千余家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站建設(shè)要多少錢,請找那個售后服務(wù)好的赫章做網(wǎng)站的公司定做!
Redis是一種非關(guān)系型數(shù)據(jù)庫,被廣泛使用于緩存、計數(shù)器、消息隊列等場景。在使用Redis時,為避免內(nèi)存過度占用,我們需要對數(shù)據(jù)進(jìn)行過期刪除,即當(dāng)數(shù)據(jù)過期后,Redis自動將其刪除。本文將介紹如何實現(xiàn)有效的自動清理Redis過期數(shù)據(jù)。
一、Redis過期策略
Redis提供了2種過期策略:定時刪除和惰性刪除。
1. 定時刪除
定時刪除是指Redis在設(shè)置鍵的過期時間時,同時創(chuàng)建一個定時器,到達(dá)過期時間時,由定時器主動清除。
該過期策略優(yōu)點是及時刪除過期鍵,不會出現(xiàn)過期鍵占用內(nèi)存的問題。但定時刪除需要在每個鍵上創(chuàng)建一個定時器,在鍵數(shù)較多時,會增加CPU壓力,影響Redis響應(yīng)速度。
2. 惰性刪除
惰性刪除是指Redis在訪問鍵時,首先檢查鍵是否過期,如果過期則刪除,否則繼續(xù)訪問。
該過期策略優(yōu)點是不需要為每個鍵創(chuàng)建定時器,避免了CPU壓力。但這也意味著過期鍵只有在訪問時才刪除,如果沒有被訪問到,則一直占用內(nèi)存,直到過期策略生效。
二、Redis過期實現(xiàn)方式
實現(xiàn)Redis過期需要用到Redis提供的過期機(jī)制:為鍵設(shè)置過期時間,到達(dá)過期時間時,Redis將自動刪除鍵。
我們需要為需要設(shè)置過期時間的鍵創(chuàng)建定時器,并將其添加到Redis過期時間字典中。定時器主要由Redis server.c中的expireifNeeded函數(shù)實現(xiàn)。
void expireIfNeeded(redisDb *db, robj *KEY) {
// 1. 獲取鍵的過期時間
mstime_t when = getExpire(db,key);
if (when
if (when
// 2. 刪除過期鍵
deleteKey(db,key);
} else {
// 3. 將過期鍵添加到過期時間字典中
if (activeExpireEnabled())
dictAdd(db->expires,key,(void*)when);
}
}
在Redis server.c中,expireIfNeeded函數(shù)被調(diào)用的地方主要有兩處:鍵值操作命令和定時器從定時器表中移除。
鍵值操作命令會調(diào)用lookupKey和expireIfNeeded函數(shù),獲取鍵的過期時間并添加到過期時間字典中;同時,當(dāng)鍵值操作命令執(zhí)行完畢后,還需要調(diào)用activeExpireCycle函數(shù),掃描過期時間字典,并刪除過期鍵。
int expireIfNeeded(redisDb *db, robj *key) {
if (expireIfNeededByType(db, key, getExpire(db, key), ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP) == 1)
return 1;
return 0;
}
void activeExpireCycle(void) {
int j;
dictEntry *de;
// 1. 記錄掃描次數(shù)
long long now = mstime();
server.expire_cursor = (server.expire_cursor+1) % ACTIVE_EXPIRE_CYCLE_SLOW_TICKS_PER_FAST;
if (server.expire_cursor == 0) server.current_tick = getLRUClock();
// 2. 計算隨機(jī)值
int samples = server.active_expire_cycle_lookups_per_tick;
if (dictSize(server.db[0]->expires)
samples = dictSize(server.db[0]->expires);
// 3. 遍歷過期時間字典,刪除過期鍵
while(samples--) {
de = dictGetRandomKey(server.db[0]->expires);
if (!de) break;
robj *key = dictGetKey(de);
if (lookupKey(server.db[0], key) != NULL) {
time_t t;
// 4. 獲取鍵的過期時間
mstime_t when = (time_t) dictGetVal(de);
// 5. 隨機(jī)清除過期鍵
if (when
server.stat_expiredkeys++;
activeExpireCycleTryExpire(&t, key, de);
// 6. 記錄刪除操作
server.dirty++;
/* always re-hash here */
signalModifiedKey(NULL,key);
notifyKeyspaceEvent(NOTIFY_GENERIC,"expired",key,server.dbnum);
// 7. 如果刪除的鍵為AOF未記錄的鍵,則在AOF文件中記錄刪除命令
if (server.aof_state != AOF_OFF)
feedAppendOnlyFile(server.delCommand,server.dbnum,&key,1);
}
}
}
}
三、 redis過期場景
1. 緩存清理
在進(jìn)行緩存設(shè)計時,我們通常將最近使用的數(shù)據(jù)緩存下來,以提升系統(tǒng)讀取速度。但當(dāng)緩存中的數(shù)據(jù)過期時,需要及時清除,否則會出現(xiàn)內(nèi)存占用過多的問題。因此,我們需要使用Redis的過期機(jī)制,設(shè)置過期時間,在過期時間到達(dá)后,Redis自動清除過期數(shù)據(jù)。
// 存入緩存數(shù)據(jù),并設(shè)定過期時間
redisTemplate.opsForValue().set("cache_key", "cache_value", 1, TimeUnit.MINUTES);
// 獲取緩存數(shù)據(jù)
String cacheValue = redisTemplate.opsForValue().get("cache_key");
2. 分布式鎖自動釋放
在分布式應(yīng)用場景中,我們通常使用分布式鎖來避免多個線程訪問共享資源的問題。但當(dāng)某個線程因為服務(wù)器故障或異常退出時,分布式鎖需要自動釋放,否則會導(dǎo)致死鎖等問題。因此,我們可以使用Redis的過期機(jī)制,為分布式鎖添加過期時間,當(dāng)分布式鎖過期時,Redis自動釋放分布式鎖。
// 獲取分布式鎖
Boolean locked = redisTemplate.execute(
new RedisCallback() {
@Override
public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException {
// SETNX命令: 嘗試獲取分布式鎖
Boolean locked = redisConnection.setNX("my_lock".getBytes(), "true".getBytes());
if (locked) {
// 當(dāng)獲取到鎖后,為鎖添加過期時間60秒
redisConnection.expire("my_lock".getBytes(), 60);
}
return locked;
}
}
);
四、總結(jié)
Redis的過期機(jī)制可以在數(shù)據(jù)過期時自動清除,避免了手動清除過期數(shù)據(jù)的煩惱。在實際應(yīng)用中,我們需要選擇合適的過期策略,并根據(jù)實際場景對Redis過期策略進(jìn)行調(diào)優(yōu)。同時,我們也需要注意分布式鎖的自動釋放問題,避免死鎖等問題。
成都創(chuàng)新互聯(lián)科技公司主營:網(wǎng)站設(shè)計、網(wǎng)站建設(shè)、小程序制作、成都軟件開發(fā)、網(wǎng)頁設(shè)計、微信開發(fā)、成都小程序開發(fā)、網(wǎng)站制作、網(wǎng)站開發(fā)等業(yè)務(wù),是專業(yè)的成都做小程序公司、成都網(wǎng)站建設(shè)公司、成都做網(wǎng)站的公司。創(chuàng)新互聯(lián)公司集小程序制作創(chuàng)意,網(wǎng)站制作策劃,畫冊、網(wǎng)頁、VI設(shè)計,網(wǎng)站、軟件、微信、小程序開發(fā)于一體。
網(wǎng)站題目:Redis過期場景實現(xiàn)有效的自動清理(redis過期場景)
分享路徑:http://m.fisionsoft.com.cn/article/dpoeipj.html


咨詢
建站咨詢
