Hide last authors
author | version | line-number | content |
---|---|---|---|
![]() |
2.1 | 1 | get命令本质是调用了lookupKeyRead这个底层方法, |
2 | lookupKeyRead方法如下: | ||
3 | |||
![]() |
1.1 | 4 | {{plantuml}} |
5 | @startuml | ||
6 | start | ||
7 | |||
8 | |||
![]() |
2.1 | 9 | : lookupKeyReadWithFlags; |
![]() |
1.1 | 10 | |
11 | |||
12 | end | ||
13 | @enduml | ||
14 | {{/plantuml}} | ||
15 | |||
![]() |
2.1 | 16 | |
17 | lookupKeyReadWithFlags方法如下: | ||
18 | |||
![]() |
1.1 | 19 | {{plantuml}} |
20 | @startuml | ||
21 | start | ||
22 | |||
![]() |
15.1 | 23 | if(调用expireIfNeeded方法判断key是否过期)then(1:代表过期) |
![]() |
8.1 | 24 | if(当前环境为主节点)then(yes) |
![]() |
9.1 | 25 | :返回null; |
![]() |
2.1 | 26 | stop |
27 | endif | ||
![]() |
1.1 | 28 | |
![]() |
8.1 | 29 | if(当前环境为从节点,并且命令为读的时候,那说明key过期是安全的)then(yes) |
![]() |
2.1 | 30 | :返回null; |
31 | stop | ||
32 | endif | ||
![]() |
10.1 | 33 | endif |
![]() |
1.1 | 34 | |
![]() |
11.1 | 35 | :调用lookupKey方法,查询value的值; |
![]() |
10.1 | 36 | if(返回值为空)then(yes) |
![]() |
7.1 | 37 | :缓存命中+1; |
38 | else(no) | ||
39 | :缓存非命中+1; | ||
40 | endif | ||
![]() |
5.1 | 41 | |
![]() |
2.1 | 42 | :返回查询的结果; |
43 | |||
![]() |
1.1 | 44 | end |
45 | @enduml | ||
46 | {{/plantuml}} | ||
![]() |
16.1 | 47 | |
48 | |||
49 | expireIfNeeded方法用来判断一个key是否过期 | ||
50 | 返回1,说明已经过期 | ||
51 | 返回0,说明数据没有过期 | ||
52 | |||
53 | {{plantuml}} | ||
54 | @startuml | ||
55 | start | ||
56 | |||
57 | |||
58 | :查询key的过期时间戳; | ||
59 | :获取当前时刻的时间戳; | ||
60 | if(过期时间<0)then(yes) | ||
61 | :说明该key不存在过期设置,返回0; | ||
62 | stop | ||
63 | endif | ||
64 | |||
65 | if(服务器正在启动中)then(yes) | ||
![]() |
17.1 | 66 | :过期时间的table可能没加载(同步)完全,这时直接返回0; |
![]() |
16.1 | 67 | stop |
68 | endif | ||
69 | |||
70 | if(当前环境是从服务器)then(yes) | ||
71 | :对于从服务器无需删除过期key, 直接计算过期时间和当前时间的关系并返回; | ||
72 | note left | ||
73 | 过期时间 <= 当前时间 : 已经过期 | ||
74 | 过期时间 > 当前时间 : 没有过期 | ||
![]() |
17.1 | 75 | endnote |
![]() |
16.1 | 76 | stop |
77 | endif | ||
78 | |||
79 | :写aof删除过期key; | ||
80 | :创建消息通知,用来回调那些监控key过期的钩子; | ||
81 | if(判断服务器是否打开惰性删除)then(yes) | ||
82 | :调用dbAsyncDelete方法异步删除; | ||
83 | else(no) | ||
84 | :调用dbSyncDelete方法同步删除; | ||
85 | endif | ||
![]() |
17.1 | 86 | :返回删除结果; |
87 | note left | ||
88 | 删除方法返回值说明 | ||
89 | 1: 说明数据被删除了 | ||
90 | 0: 说明数据删除失败了,在过期表中key还存在 | ||
91 | endnote | ||
![]() |
16.1 | 92 | |
![]() |
17.1 | 93 | end |
94 | @enduml | ||
95 | {{/plantuml}} | ||
![]() |
16.1 | 96 | |
![]() |
17.1 | 97 | |
98 | 先说明,redis中,过期时间等信息是单独放在一个table中存储的,因为不是所有key都设有过期时间,放在一起存储会额外增加存储成本。 | ||
99 | 再看同步删除dbSyncDelete的策略 | ||
100 | |||
101 | {{plantuml}} | ||
102 | @startuml | ||
103 | start | ||
104 | |||
105 | if(key过期表是否为空)then(no) | ||
106 | :删除过期表中的key; | ||
107 | endif | ||
108 | |||
109 | :执行dictDelete方法,删除dict表中具体的数据; | ||
110 | if(删除成功)then(yes) | ||
![]() |
18.1 | 111 | :在集群模式下的redis,还需要删除cluster中的key,防止路由查询key失败; |
![]() |
17.1 | 112 | :返回1; |
113 | else | ||
114 | :返回0; | ||
115 | endif | ||
116 | |||
117 | |||
![]() |
16.1 | 118 | end |
119 | @enduml | ||
120 | {{/plantuml}} |