在 redis 中,允許使用者設定最大使用記憶體大小 server.maxmemory,在記憶體限定的情況下是很有用的。譬如,在一台 8g 機子上部署了 4 個 redis 服務點,每乙個服務點分配 1.5g 的記憶體大小,減少記憶體緊張的情況,由此獲取更為穩健的服務。
redis 記憶體資料集大小上公升到一定大小的時候,就會施行資料淘汰策略。redis 提供 6種資料淘汰策略:
volatile-lru:從已設定過期時間的資料集(server.db[i].expires)中挑選最近最少使用的資料淘汰
volatile-ttl:從已設定過期時間的資料集(server.db[i].expires)中挑選將要過期的資料淘汰
volatile-random:從已設定過期時間的資料集(server.db[i].expires)中任意選擇資料淘汰
allkeys-lru:從資料集(server.db[i].dict)中挑選最近最少使用的資料淘汰
allkeys-random:從資料集(server.db[i].dict)中任意選擇資料淘汰
no-enviction(驅逐):禁止驅逐資料
redis 確定驅逐某個鍵值對後,會刪除這個資料並,並將這個資料變更訊息發布到本地(aof 持久化)和從機(主從連線)。
在伺服器配置中儲存了 lru 計數器 server.lrulock,會定時(redis 定時程式 servercorn())更新,server.lrulock 的值是根據 server.unixtime 計算出來的。
另外,從 struct redisobject 中可以發現,每乙個 redis 物件都會設定相應的 lru。可以想象的是,每一次訪問資料的時候,會更新 redisobject.lru。
lru 資料淘汰機制是這樣的:在資料集中隨機挑選幾個鍵值對,取出其中 lru 最大的鍵值對淘汰。所以,你會發現,redis 並不是保證取得所有資料集中最近最少使用(lru)的鍵值對,而只是隨機挑選的幾個鍵值對中的。
// redisserver 儲存了 lru 計數器struct redisserver ;
// 每乙個 redis 物件都儲存了 lru
#define redis_lru_clock_max ((1<<21)-1) /* max value of obj->lru */
#define redis_lru_clock_resolution 10 /* lru clock resolution in seconds */
typedef struct redisobject robj;
// redis 定時執行程式。聯想:linux cron
int servercron(struct aeeventloop *eventloop, long long id, void *clientdata)
// 更新伺服器的 lru 計數器
void updatelruclock(void)
redis 資料集資料結構中儲存了鍵值對過期時間的表,即 redisdb.expires。和 lru 資料淘汰機制類似,ttl 資料淘汰機制是這樣的:從過期時間的表中隨機挑選幾個鍵值對,取出其中 ttl 最大的鍵值對淘汰。同樣你會發現,redis 並不是保證取得所有過期時間的表中最快過期的鍵值對,而只是隨機挑選的幾個鍵值對中的。
redis 每服務客戶端執行乙個命令的時候,會檢測使用的記憶體是否超額。如果超額,即進行資料淘汰。
// 執行命令int processcommand(redisclient *c)
}......
}// 如果需要,是否一些記憶體
int freememoryifneeded(void)
}// server.aof_buf && server.aof_rewrite_buf_blocks
if (server.aof_state != redis_aof_off)
// 記憶體是否超過設定大小
/* check if we are over the memory limit. */
if (mem_used <= server.maxmemory) return redis_ok;
// redis 中可以設定記憶體超額策略
if (server.maxmemory_policy == redis_maxmemory_no_eviction)
return redis_err; /* we need to free memory, but policy forbids. */
/* compute how much memory we need to free. */
mem_tofree = mem_used - server.maxmemory;
mem_freed = 0;
while (mem_freed < mem_tofree) else
// 資料集為空,繼續下乙個資料集
if (dictsize(dict) == 0) continue;
// 隨機淘汰隨機策略:隨機挑選
/* volatile-random and allkeys-random policy */
if (server.maxmemory_policy == redis_maxmemory_allkeys_random ||
server.maxmemory_policy == redis_maxmemory_volatile_random)
// lru 策略:挑選最近最少使用的資料
/* volatile-lru and allkeys-lru policy */
else if (server.maxmemory_policy == redis_maxmemory_allkeys_lru ||
server.maxmemory_policy == redis_maxmemory_volatile_lru)}}
// ttl 策略:挑選將要過期的資料
/* volatile-ttl */
else if (server.maxmemory_policy == redis_maxmemory_volatile_ttl) }}
// 刪除選定的鍵值對
/* finally remove the selected key. */
if (bestkey)
}// 未能釋放空間,且此時 redis 使用的記憶體大小依舊超額,失敗返回
if (!keys_freed) return redis_err; /* nothing to free... */
}return redis_ok;
}
redis資料淘汰策略
redis 每服務客戶端執行乙個命令的時候,會檢測使用的記憶體是否超額。如果超額,即進行資料淘汰。在 redis 中,允許使用者設定最大使用記憶體大小 server.maxmemory,在記憶體限定的情況下是很有用的。譬如,在一台 8g 機子上部署了 4 個 redis 服務點,每乙個服務點分配 1...
redis資料淘汰策略
在 redis 中,允許使用者設定最大使用記憶體大小 server.maxmemory,在記憶體限定的情況下是很有用的。譬如,在一台 8g 機子上部署了 4 個 redis 服務點,每乙個服務點分配 1.5g 的記憶體大小,減少記憶體緊張的情況,由此獲取更為穩健的服務。redis 記憶體資料集大小上...
Redis 資料淘汰策略
redis記憶體資料到達一定數量時就會執行資料淘汰策略,它提供了6種資料淘汰策略。voltile lru 從已經設定過期時間的資料集 server.db i expires 挑選最近最少使用的資料淘汰。voltile ttl 從已經設定過期時間的資料集 server.db i expires 中挑選...