Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Coudy Hou
JavaGuide
提交
80a25217
J
JavaGuide
项目概览
Coudy Hou
/
JavaGuide
与 Fork 源项目一致
从无法访问的项目Fork
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
JavaGuide
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
80a25217
编写于
11月 30, 2019
作者:
S
Snailclimb
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
完善 Redis 内容
上级
8a757d23
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
46 addition
and
7 deletion
+46
-7
docs/database/Redis/Redis.md
docs/database/Redis/Redis.md
+46
-7
未找到文件。
docs/database/Redis/Redis.md
浏览文件 @
80a25217
...
...
@@ -257,11 +257,15 @@ Redis 通过 MULTI、EXEC、WATCH 等命令来实现事务(transaction)功能。
### 缓存雪崩和缓存穿透问题解决方案
**缓存雪崩**
#### **缓存雪崩**
**什么是缓存雪崩?**
简介:缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。
解决办法(中华石杉老师在他的视频中提到过,视频地址在最后一个问题中有提到):
**有哪些解决办法?**
(中华石杉老师在他的视频中提到过,视频地址在最后一个问题中有提到):
-
事前:尽量保证整个 redis 集群的高可用性,发现机器宕机尽快补上。选择合适的内存淘汰策略。
-
事中:本地ehcache缓存 + hystrix限流&降级,避免MySQL崩掉
...
...
@@ -269,16 +273,46 @@ Redis 通过 MULTI、EXEC、WATCH 等命令来实现事务(transaction)功能。
![](
http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-25/6078367.jpg
)
#### **缓存穿透**
**
缓存穿透**
**
什么是缓存穿透?**
简介:一般是黑客故意去请求缓存中不存在的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉
。
缓存穿透说简单点就是大量请求的 key 根本不存在于缓存中,导致请求直接到了数据库上,根本没有经过缓存这一层。举个例子:某个黑客故意制造我们缓存中不存在的 key 发起大量请求,导致大量请求落到数据库
。
解决办法: 有很多种方法可以有效地解决缓存穿透问题,最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法(我们采用的就是这种),如果一个查询返回的数据为空(不管是数 据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
一般MySQL 默认的最大连接数在 150 左右,这个可以通过
`show variables like '%max_connections%'; `
命令来查看。最大连接数一个还只是一个指标,cpu,内存,磁盘,网络等无力条件都是其运行指标,这些指标都会限制其并发能力!所以,一般 3000 个并发请求就能打死大部分数据库了。
**有哪些解决办法?**
最基本的就是首先做好参数校验,一些不合法的参数请求直接抛出异常信息返回给客户端。比如查询的数据库 id 不能小于 0、传入的邮箱格式不对的时候直接返回错误消息给客户端等等。
**1)缓存无效 key**
: 如果缓存和数据库都查不到某个 key 的数据就写一个到 redis 中去并设置过期时间,具体命令如下:
`SET key value EX 10086`
。这种方式可以解决请求的 key 变化不频繁的情况,如何黑客恶意攻击,每次构建的不同的请求key,会导致 redis 中缓存大量无效的 key 。很明显,这种方案并不能从根本上解决此问题。如果非要用这种方式来解决穿透问题的话,尽量将无效的 key 的过期时间设置短一点比如 1 分钟。
另外,这里多说一嘴,一般情况下我们是这样设计 key 的:
`表名:列名:主键名:主键值`
。
如果用 Java 代码展示的话,差不多是下面这样的:
```
java
public
Object
getObjectInclNullById
(
Integer
id
)
{
// 从缓存中获取数据
Object
cacheValue
=
cache
.
get
(
id
);
// 缓存为空
if
(
cacheValue
!=
null
)
{
// 从数据库中获取
Object
storageValue
=
storage
.
get
(
key
);
// 缓存空对象
cache
.
set
(
key
,
storageValue
);
// 如果存储数据为空,需要设置一个过期时间(300秒)
if
(
storageValue
==
null
)
{
// 必须设置过期时间,否则有被攻击的风险
cache
.
expire
(
key
,
60
*
5
);
}
return
storageValue
;
}
return
cacheValue
;
}
```
参考:
-
[
https://blog.csdn.net/zeb_perfect/article/details/54135506
](
https://blog.csdn.net/zeb_perfect/article/details/54135506
)
### 如何解决 Redis 的并发竞争 Key 问题
...
...
@@ -308,6 +342,11 @@ Redis 通过 MULTI、EXEC、WATCH 等命令来实现事务(transaction)功能。
**参考:**
Java工程师面试突击第1季(可能是史上最好的Java面试突击课程)-中华石杉老师!公众号后台回复关键字“1”即可获取该视频内容。
### 参考
-
《Redis开发与运维》
-
Redis 命令总结:http://redisdoc.com/string/set.html
## 公众号
如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录