首頁 > 系統教程 > Linux > 詳解Redis內部運作機制

詳解Redis內部運作機制

WBOY
發布: 2024-03-10 09:13:09
轉載
510 人瀏覽過

詳解Redis內部運作機制

Redis資料庫(Redis 如何表示一個資料庫,資料庫操作是如何實現的)

當Redis伺服器初始化的時候會建立 redis.h/REDIS_DEFAULT_DBNUM(後面簡寫N ) 個資料庫,且資料庫的id是從0 到 N-1 , 所有的資料庫儲存到redis.h/redisServer.db 陣列中。

在客戶端可以透過 “SELECT” 指令進行切換,其中程式是直接用 redis.h/redisServer.db[number] 進行切換。但是,一些內部程式,例如AOF 程式、複製程式和RDB 程式,需要知道目前資料庫的號碼, 如果沒有id 網域的話,程式就只能在目前使用的資料庫的指標,和redisServer.db 陣列中所有資料庫的指針進行比較,以此來弄清楚自己正在使用的是那個資料庫。

Redis資料庫的結構:
#
typeof  struct   redisDb{
int id ;   // 数据库的id

dict *dict ; // 保存着该数据库的所有键值对 也被称为键空间

dict *expires ; // 保存着键的过期时间

…..

} redisDb ;
 Redis 是一个键值对 字典表,同样Redis数据库存储形式也是键值对 字典表
 键是字符串
 值可以是字符型、list 列表、 hash、集合以及 有序集合其中之一
登入後複製
Redis 資料庫增、刪、改、查等操作的鍵空間操作:

#新增:
Redis會在鍵空間字典中增加一個鍵-值對,其中鍵為一個字串,值為任一個值類型。
刪除:
Redis會在鍵空間字典中刪除對應鍵的鍵-值對
更新:
Redis會在鍵空間字典中釋放先前對應鍵的值對象,並讓鍵指向新的值對象
查詢:
Redis會在鍵空間字典中查詢對應鍵的值物件:
鍵不存在,回傳NULL
鍵存在,且類型正確,傳回正確的值
鍵存在,但類型不正確,回傳類型錯誤
其他操作:
除了上面展示的鍵值操作之外,還有很多針對資料庫本身的命令,也是透過對鍵空間進行處理 來完成的:
FLUSHDB              刪除鍵空間中的所有鍵值對上
RANDOMKEY        從鍵空間中隨機傳回一個鍵
DBSIZE                  返回鍵空間中鍵值對的數量
EXISTS                  檢查給定鍵是否存在於鍵空間中
RENAME               在鍵空間中,使用給定鍵鍵定名

鍵的過期時間

#在Redis資料庫中,所有鍵的過期時間都保存在RedisDb結構體的expires字典中,其中鍵為一個指向dict 字典(鍵空間)裡某個鍵的指針,值為改建的過期時間,用long long型表示。

Redis 有四個指令可以設定鍵的生存時間(可以存活多久)和過期時間(什麼時候到期):
EXPIRE 以秒為單位設定鍵的生存時間;
PEXPIRE 以毫秒為單位設定鍵的生存時間;
EXPIREAT 以秒為單位,設定鍵的過期 UNIX 時間戳;
PEXPIREAT 以毫秒為單位,設定鍵的過期 UNIX 時間戳記。

雖然有那麼多不同單位和不同形式的設定方式,但是expires 字典的值只保存「以毫秒為單位的過期UNIX 時間戳」 ,這就是說,透過進行轉換,所有指令的效果最後都和PEXPIREAT 指令的效果一樣。

過期鍵的清除
#

定时清除:
在创建KEY的时候创建一个定时任务,在KEY到期时定时任务会被触发,第一时间清除过期KEY。
此种操作对内存最友好,不会有垃圾数据占用内存情况存在
缺点是会造成很大的服务器负载,特别是CPU负载高的时候,CPU很大一部分负载用在了删除不必要的KEY上了

惰性清除:
放任键空间的键不管,每次查询KEY的时候先去校验KEY是否过期,过期则删除,不过期则正常返回相应的VALUE。
此种操作对CPU最友好,这种策略仅限于当前KEY,相关不必要的KEY不会造成CPU负载
缺点是:容易造成内存空间浪费,特别是当系统中存在大量过期KEY且很少被用到,这十分影响非常依赖于内存大小Redis的性能

定期删除:
由定时脚本cron定时对expires的键扫描判断是否有过期的KEY存在,如存在,将其删除掉。
这是一种折中方案,既不会过多消耗CPU,又可以定时清楚惰性删除忽略到的不必要的内存消耗

Redis采用的“惰性清除”和“定期清楚”相结合的方式,其中定期删除模式是在规定的时间限制内,尽 可能地遍历各个数据库的 expires 字典,随机地检查一部分键的过期时间,并删除其中的过期键。

伪代码如下:

def activeExpireCycle():
# 遍历数据库(不一定能全部都遍历完,看时间是否足够)
for db in server.db:
# MAX_KEY_PER_DB 是一个 DB 最大能处理的 key 个数 # 它保证时间不会全部用在个别的 DB 上(避免饥饿) i=0                                    while (i 
<p>Redis 过期键删除的主从同步问题(Redis的机制是由主节点统一控制)</p>
<p>如果服务器是主节点,当它删除一个过期键之后,会显式的向所有附属节点发送一条DEL命令<br>
如果服务器是附属节点,当它判断到当前KEY已经过期,会将该键过期的消息发送给主服务器,主服务器删除后向所有的从服务器节点发送DEL命令。</p>
<p>从服务器节点不自主的对键进行删除是为了保持和主服务器数据的绝对一致性,即当一个过期键还存在主服务器上,这个键在所有的从服务器上也不会被删除。</p>
登入後複製

以上是詳解Redis內部運作機制的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:linuxprobe.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板