我是靠谱客的博主 迷你小蝴蝶,这篇文章主要介绍缓存穿透,大面积key失效的解决方案,现在分享给大家,希望可以做个参考。

缓存穿透,大面积key失效的解决方案

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?php class cacheBreakdown { public $redis; public $queueName = 'queue_name'; public $error = ''; public $surviveTime = 20;//存活时间,以秒计算 //总共有两种解决方案 queryCache queryCache2 public function __construct() { $this->redis = new redis(); } /** * 请求获取数据,缓存没有数据,则合并请求,发送一个请求到后台,防止击穿mysql服务 * @param $key * @return bool|string */ public function queryCache($key) { $res = $this->redis->get($key); if (!empty($res)) { return $res; } $lock = $this->joinTheQueue($key); usleep(200000);//200毫秒 return $this->queryCache($key); } /** 第二种方案 * @param $key * @return bool|string */ public function queryCache2($key) { $res = $this->redis->get($key); if (!empty($res)) { return $res; } $lock = $this->getLock($key); if (!$lock) { usleep(200000);//200毫秒 return $this->queryCache2($key); } //去数据库查询数据,然后返回 //去数据库查询 $res = db::query('select * from order where id = '.$key); $this->setCache($key, $res); $this->unlock($lock); return $res; } /** * 上锁 * @return bool|resource */ public function getLock($key) { $file_name = 'lock.data'.$key; if (!file_exists($file_name)) { file_put_contents($file_name, 0); } $fp = fopen($file_name, 'r'); $res = flock($fp, LOCK_EX); if ($res) { return $fp; } else { return $res; } } /** * 释放锁 * @param $fp * @return bool */ public function unlock($fp) { flock($fp, LOCK_UN); return fclose($fp); } /** * 加入唯一队列 * @param $key * @return int */ public function joinTheQueue($key) { $s_res = $this->redis->sAdd($key, 1); if ($s_res) { $res = $this->redis->lPush($this->queueName, $key); $this->error = '队列没有该值,加入队列排队,结果为:'.$res; return $res; } $this->error = '队列有该值'; return 99; } /** * 消费队列,拿出数据,存入缓存 */ public function consumptionQueue() { while (true) { $key = $this->redis->rPop($this->queueName); if (empty($key)) { usleep(200000);//200毫秒 continue; } //去数据库查询 $res = db::query('select * from order where id = '.$key); return $this->setCache($key, $res); } } /** * 设置值 * @param $key * @param $value * @return bool */ public function setCache($key, $value) { $time = rand(0, 9); //防止大面积key同时失效 $time = $this->surviveTime + $time; return $this->redis->setex($key, $time, $value); } }

最后

以上就是迷你小蝴蝶最近收集整理的关于缓存穿透,大面积key失效的解决方案的全部内容,更多相关缓存穿透,大面积key失效内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(73)

评论列表共有 0 条评论

立即
投稿
返回
顶部