当前位置:网站首页>Redis (7) -- database and expiration key
Redis (7) -- database and expiration key
2022-07-02 18:39:00 【cb414】
1, Database in server
Redis Corresponding concepts in :
Simple dynamic string
Linked list
Dictionaries
Set of integers
Compressed list
object
Redis The server keeps all databases in the server state :redisServer Structural db Array ,db Every element in an array is a redisDb structure , Each structure represents a database
struct redisServer{
//...
// An array , Save all databases in the service
redisDb *db;
// Number of databases on the server
int dbnum;
//...
};
dbnum The value of the property is configured by the server database The choice decides , The default is 16, So by default 16 A database 
2, Switch database
Every Redis Clients all have their own target databases , Whenever you write a command on the client or execute a command in the database , The target database will become the operation object of these commands . By default , The target database of the client is 0 The database , Can pass SELECT Command switch database .
redis> SET msg "hello world"
OK
redis> GET msg
"hello world"
redis> SELECT 2
OK
redis[2]> GET msg
(nil) # because 2 Database No msg This key ,msg It exists in 0 In database
redis[2]> SET msg "another world"
OK
redis[2]> GET msg
"another msg"
Client status redisClient Structural db Property records the current target database of the client , This property is a point redisDb Pointer to structure .
typedef struct redisClent{
//...
// Record the database that the client is currently using
redisDb *db;
//...
} redisClient;
redisClient.db Pointer to redisServer.db Elements in an array , This element represents the database currently being used by the client
For example, the current client is using 1 The database , that redisClient and redisServer The schematic diagram of the relationship is as follows :

perform SELECT 2 after :

By modifying the redisClient.db The pointer , Let it point to different elements in the array , So as to realize the function of switching target database , This is it. SELECT Command implementation principle .
3, Database key space
Redis Is a key value pair server , Each database consists of a redisDb Structural representation , among redisDb Structural dict All key value pairs in the dictionary , We call it bond space (key space)
typedef struct redisDb{
//...
// Database key space , Save all key value pairs in the database
dict *dict;
//...
} redisDb;
The key space corresponds directly to the database seen by the user :
- The key of the key space is also the key of the database , Each key is a string object
- The value of the key space is the value of the database , Each value can be a string object 、 List objects 、 Hash table object 、 Any of a collection object and an ordered collection object
Redisobject
If you execute the following command :
redis> SET message "hello world"
OK
redis> RPUSH alphabet "a" "b" "c"
(integer) 3
redis> HSET book name "Redis in Action"
(integer) 1
redis> HSET book author "Josian L. Carlson"
(integer) 1
redis> HSET book publisher "Manning"
(integer) 1
After execution , The key space of the database will be like this :【 It is worth noting that , there StringObject Represents a string object ,HashObject Represents a hash table object ,ListObject Represents a list object , These are to simplify the expression 】

alphabetIs a list key , The name of the key is a string containingalphabetString object of , The value of the key is a list object containing three elementsbookIs a hash table key , The name of the key is a string containingbookString object of , The value of the key is a hash table object containing three key value pairsmessageIs a string key , The name of the key is a string containingmessageString object of , The value of the key is a containing stringhello worldString object of
Because the key space of the database is a dictionary , So all operations against the database , In fact, it is realized by operating the key space dictionary .
3.1, Add new key
Add a new key , In fact, it is to add a new key value pair to the key space dictionary , Where the key is a string object , The value is of any type Redis object
For example, the key space diagram in the current situation is shown below :
After adding a new key value pair to the key space :
redis> SET date "2013.12.1"
OK
After adding the diagram :
The key of this new key value pair is a string object , Value is a containing string “2013.12.1” String object of
3.2, Delete key
Delete a key in the database , In fact, it is to delete the key value pair object corresponding to the key in the key space .
Suppose the state of the key space is as shown in Figure 9-4 Shown , Execute the following command :
redis> DEL book
(integer) 1
The key space state after executing the command is :

3.3, Update key
Update a database key , In fact, it is to update the value object corresponding to the key in the key space , Depending on the type of value object , The specific method of updating will also be different
Suppose the state of the current key space is as shown in Figure 9-4 Shown , Execute the following command :
redis> SET message "blah blah"
OK
After executing the command , The key space state should be :

3.4, Value the key
Value a database key , In fact, it is to take out the value object corresponding to the key in the key space , Depending on the type of value object , The specific value taking methods will also be different
Suppose the state of the current key space is as shown in Figure 9-4 Shown , Execute the following command :
redis> GET message
"hello world"
Then the value taking process will be like this :

3.5, Maintenance operations when reading and writing key space
When performing corresponding read and write operations on the key space ,Redis Some additional maintenance operations will be performed , Include :
- After reading a key ( Both read and write operations require read keys ), The server will update the key space hit of the server according to whether the key exists (
hit) Number of times or key space misses (miss) frequency - After reading a key , The server will update the key
LRUTime , This value can be used to calculate the idle time of the key - If you find that this key has expired when reading , Then the server will delete the expired key first , Then do the rest
- If there is a client using
WATCHCommand to monitor a key , After the server modifies this key , Will mark this key as dirty (dirty), This allows the transaction program to notice that the key has been modified - After the server changes one key at a time , Will increase the value of the dirty key counter 1, This counter triggers persistence and replication operations on the server
- If the database turns on the database notification function , After modifying the key , The server will send the corresponding database notification according to the configuration
4, Set the key's lifetime or expiration time
4.1, Set expiration time
Redis There are four different commands that can be used to set the lifetime of the key ( How long can the key last ) Or expiration time ( When is the key deleted )
EXPIRE <key> <ttl>: The command is used to keykeyThe lifetime of is set tottlsecondPEXPIRE <key> <ttl>: The command is used to keykeyThe lifetime of is set tottlmillisecondEXPIREAT <key> <timestamp>: The command is used to keykeyThe expiration time for is set totimestampThe time stamp of the specified number of secondsPEXPIREAT <key> <timestamp>: The command is used to keykeyThe expiration time for is set totimestampThe specified number of milliseconds timestamp
Although there are many different units and different forms of setting commands , But actually EXPIRE、PEXPIRE、EXPIREAT All three commands use PEXPIREAT Command implemented
# EXPIRE command
def EXPIRE(key,ttl_in_sec):
# take TTL Convert from seconds to milliseconds
ttl_in_ms=sec_to_ms(ttl_in_sec)
PEXPIRE(key,ttl_in_ms)
######################################
# PEXPIRE It can be converted into PEXPIREAT
def PEXPIRE(key,ttl_in_ms):
# Gets the current value in milliseconds UNIX Time stamp
now_ms=get_current_unix_timestamp_in_ms()
# The current time plus TTL, Get the key expiration time in milliseconds
PEXPIREAT(key,now_ms+ttl_in_ms)
######################################
# EXPIREAT Commands can be converted to PEXPIREAT
def EXPIREAT(key,expire_time_in_sec):
# Convert expiration time from seconds to milliseconds
expire_time_in_ms=sec_to_ms(expire_time_in_sec)
PEXPIREAT(key,expire_time_in_ms)

4.2, Save expiration time
redisDb Structural expires The dictionary stores the expiration time of all keys in the database , We call this an expired dictionary
- The key of an overdue dictionary is a pointer , Point to a key object in the key space
- The value of the expired dictionary is a
long longType integer , This integer holds the expiration time of the database key that the key points to ( One millisecond precisionUNIXTime stamp )
typedef struct redisDb{
//...
// Out of date Dictionary , Save the expiration time of the key
dict *expires;
//...
}redisDb;

It is worth mentioning that : Keys in the out of date dictionary are key objects that point to the key space , chart 9-12 This expression is for the convenience of display
As mentioned earlier PEXPIREAT The pseudo code of the command is as follows :
def PEXPIREAT(key,expire_time_in_ms):
# If the given key does not exist in the key space , Then you cannot set the expiration time
if key not in redisDb.dict:
return 0
# Associate key and expiration time in expiration dictionary
redisDb.expires(key)=expire_time_in_ms
# Expiration time set successfully
return 1
4.3, Remove expiration time
PERSIST The command can remove the expiration time of a key
redis> PEXPIREAT message 1391234400000
(integer) 1
redis> TTL message
(integer) 13893281
redis> PERSIST message
(integer) 1
redis> TTL message
(integer) -1
PERSIST The order is PEXPIREAT Anti operation of :PERSIST The command looks for the given key in the out of date dictionary , And disassociate the key and value in the expiration dictionary ( That is, the expiration time of the removal key )
Assume that the current state of the database is as shown in Figure 9-12 Shown , After executing the following command :
redis> PERSIST book
(integer) 1

PERSIST Pseudo definition of command :
def PERSIST(key):
# If the key doesn't exist , Or the key does not set the expiration time , Then go straight back
if key not in redisDb.expires:
return 0
# Removes the key value pair Association for the given key in the out of date dictionary
redisDb.expires.remove(key)
# The expiration time of the key was removed successfully
return 1
4.4, Calculate and return the remaining survival time
TTL: Return the remaining lifetime of the key in secondsPTTL: Returns the remaining lifetime of the key in milliseconds
PTTL Pseudo code
def PTTL(key):
# The key does not exist in the database
if key not in redisDb.dict:
return -2
# Try to get the expiration time of the key
# If the key doesn't set the expiration time , that expire_time_in_ms Will be for none
expire_time_in_ms=redisDb.expires.get(key)
# The key does not set an expiration time
if expire_time_in_ms is None:
return -1
# Get the current time
now_ms=get_current_unix_timestamp_in_ms()
# The expiration time minus the current time , The difference is the remaining lifetime of the bond
return(expire_time_in_ms - now_ms)
TTL Pseudo code
def TTL(key):
# Gets the remaining lifetime in milliseconds
ttl_in_ms=PTTL(key)
if ttl_in_ms <0 :
# The processing return value is -2 and -1 The situation of
return ttl_in_ms
else:
# Convert milliseconds to seconds
return ms_to_sec(ttl_in_ms)
4.5, Expired key determination
Through out of date dictionaries , The program uses the following steps to check whether a key is expired
- Check whether the given key exists in the expired Dictionary , If it is , Get its expiration time ( No expiration dictionary means no expiration time is set )
- Check current
UNIXWhether the time stamp is greater than the expiration time of the key : If so , Then the key has expired ; conversely
4.6, Expiration key deletion policy
If a key is out of date , So when will it be deleted ?
There are three possible answers to this question , It represents three different deletion strategies :
- Delete regularly : While setting the key expiration time , Create a timer , Let the timer when the key expiration time comes , Delete the key immediately
- Lazy deletion : Every time you get a key from the key space , Judge whether it is overdue . Delete the key if it is out of date ; conversely
- Delete periodically : Every once in a while , Check the database once , Delete the expiration key inside , As for how many expiration keys to delete 、 How many databases to check is determined by the algorithm
Delete regularly
The scheduled deletion strategy is very memory friendly : Because using a timer , Every time the key expires, it will be deleted immediately . But if there are a lot of expired keys , The program takes a part CPU Time to delete these expired keys ( It can be understood as : Deleting the expired key will compete with the main task CPU Execution time of ); And to create a timer, you need to use Redis Time events in the server , The implementation of the current time event ---- Disordered list , Because its search time complexity is O(N), Therefore, it is not efficient to deal with a large number of time events
Lazy deletion
Inert deletion policy pair CPU Time is very friendly : Only when a key is used will it be judged whether the key is expired , It will be deleted after expiration ; conversely . And the target of deletion is limited to the currently processed key , It doesn't cost anything on other unrelated keys CPU Time .
But the disadvantage is : If there are a large number of expired keys in the database , But these expired keys have not been accessed , Then they may never be deleted , This can be seen as a memory leak ( Garbage data takes up most of the memory , But it cannot be deleted )
Delete periodically
- The disadvantage of scheduled deletion is : Deleting may take up too much
CPUTime , Snatch time with task execution , Affect the response time and throughput of the server - The disadvantage of lazy deletion is : Because you cannot handle keys that are not accessed , Therefore, it is easy to cause memory leakage
Periodic deletion strategy is an integration and compromise between scheduled deletion and lazy deletion
- Delete periodically. Delete expired keys every once in a while , And by limiting the execution time and frequency of the deletion operation to reduce the pair of deletion operations
CPUThe effect of time . - And through this periodic deletion , To reduce memory waste caused by expired keys
The key to this strategy is : Determination of the duration and frequency of the deletion operation . If the time is too long or the execution is too frequent , That will degenerate into a scheduled deletion strategy ; If the time is too short or the frequency is too low , It is easy to cause a large number of expired keys to accumulate , Degenerate into inert deletion .
Redis The server actually uses two strategies: lazy deletion and periodic deletion , Use two strategies together , Can reasonably be in CPU Balance time and memory
边栏推荐
- RDK仿真实验
- promise 和 Observable 的区别
- “栈”的典型应用—表达式求值(C语言实现)
- How to write controller layer code gracefully?
- Esp32-c3 introductory tutorial question ⑪ - ESP tls: create_ ssl_ handle failed, tls_ io_ instance->options. trusted_ certs null
- NM01-独立于总线协议的NM模块功能概述与API定义
- 一款简约PHP个人发卡程序V4.0版本
- 链游系统开发(Unity3D链游开发详情)丨链游开发成熟技术源码
- 【西北工业大学】考研初试复试资料分享
- 微信小程序视频分享平台系统毕业设计毕设(1)开发概要
猜你喜欢

Babbitt | metauniverse daily must read: can you buy a virtual anchor for 1000 yuan? Is this the live gospel of small businesses or "cutting leeks"

Implementation shadow introduction

Wechat nucleic acid detection appointment applet system graduation design completion (4) opening report

Relax again! These fresh students can settle directly in Shanghai

Web版3D可视化工具,程序员应该知道的97件事,AI前沿论文 | 资讯日报 #2022.07.01

Wechat applet video sharing platform system graduation design completion (1) development outline

A good programmer is worth five ordinary programmers!

Wechat applet video sharing platform system graduation design (3) background function

Leetcode 面试题 17.01. 不用加号的加法

微信核酸检测预约小程序系统毕业设计毕设(1)开发概要
随机推荐
Night God simulator +fiddler packet capture test app
如何清理废弃pv和其对应的文件夹
能解决80%故障的排查思路
1.5.1版本官方docker镜像运行容器,能设置使用 mysql 8驱动吗?
Nm01 function overview and API definition of nm module independent of bus protocol
如何设置VSCode删除整行快捷键?
cJSON 使用详解
Meal card hdu2546
Leetcode interview question 16.17 Continuous sequence
Web版3D可视化工具,程序员应该知道的97件事,AI前沿论文 | 资讯日报 #2022.07.01
再放寬!這些應届生,可直接落戶上海
又一所双非改考408,会爆冷么?南昌航空大学软件学院
719. Find the distance of the number pair with the smallest K
Rte11 interrupt decoupling function
工业软件讲堂-三维CAD设计软件的核心技术解析----讲坛第二次讲座
哪个券商公司网上开户佣金低又安全又可靠
Unity learning shader notes [82] black and white processing of enhanced single channel color rendering
一款简约PHP个人发卡程序V4.0版本
RDK simulation experiment
Leetcode(154)——寻找旋转排序数组中的最小值 II