@@ -409,7 +409,7 @@ mysqlshow -uroot -p1234 test book --count
409409
410410 - 用来定义数据库的访问权限和安全级别,及创建用户。关键字:grant , revoke 等
411411
412- 
412+ 
413413
414414
415415
@@ -5467,16 +5467,18 @@ MySQL 的主从复制原理图:
54675467主从复制主要依赖的是 binlog,MySQL 默认是异步复制,需要三个线程:** master(binlog dump thread)、slave(I/ O thread 、SQL thread)**
54685468
54695469- binlog dump thread:在主库事务提交时,负责把数据变更作为事件 Events 记录在二进制日志文件 binlog 中,并通知 slave 有数据更新
5470- - I/ O thread:负责从主服务器上拉取二进制日志,并将 binlog 日志内容依次写到 relay log 文件的最末端,并将新的 binlog 文件名和 offset 记录到 master- info 文件中,以便下一次读取master 端新 binlog 日志时能告诉 master 服务器从新 binlog 日志的指定文件及位置开始读取新的 binlog 日志内容
5470+ - I/ O thread:负责从主服务器上拉取二进制日志,并将 binlog 日志内容依次写到 relay log 文件的最末端,并将新的 binlog 文件名和 offset 记录到 master- info 文件中,以便下一次读取日志时能告诉 master 服务器从指定 binlog 日志文件及位置开始读取新的 binlog 日志内容
54715471- SQL thread:监测本地 relay log中新增了日志内容,读取中继日志并重做其中的 SQL 语句
5472- - 从库在 relay- log .info 中记录当前应用中继日志的文件名和位置点以便下一次数据复制
5472+ - 从库在 relay- log .info 中记录当前应用中继日志的文件名和位置点以便下一次执行
54735473
54745474同步与异步:
54755475
54765476* 异步复制有数据丢失风险,例如数据还未同步到从库,主库就给客户端响应,然后主库挂了,此时从库晋升为主库的话数据是缺失的
54775477* 同步复制,主库需要将 binlog 复制到所有从库,等所有从库响应了之后才会给客户端响应,这样的话性能很差,一般不会选择同步复制
54785478* MySQL 5 .7 之出现了半同步复制,有参数可以选择成功同步几个从库就返回响应
54795479
5480+ 并行复制:MySQL 5 .6 版本增加了并行复制功能,为了改善复制延迟问题,在从库中有两个线程 IO Thread 和 SQL Thread,以采用多线程机制来促进执行,减少从库复制延迟
5481+
54805482
54815483
54825484****
@@ -8250,10 +8252,10 @@ hash类型:底层使用**哈希表**结构实现数据存储
82508252
82518253类似Map结构,左边是key,右边是值,中间叫field字段,本质上** hash存了一个key-value的存储空间**
82528254
8253- hash是指的一个数据类型 ,并不是一个数据
8255+ hash 是指的一个数据类型 ,并不是一个数据
82548256
8255- * 如果field数量较少 ,存储结构优化为** 压缩列表结构** (有序)
8256- * 如果field数量较多 ,存储结构使用HashMap结构(无序)
8257+ * 如果 field 数量较少 ,存储结构优化为** 压缩列表结构** (有序)
8258+ * 如果 field 数量较多 ,存储结构使用HashMap结构(无序)
82578259
82588260
82598261
@@ -8341,7 +8343,7 @@ user:id:3506728370 → {"name":"春晚","fans":12210862,"blogs":83}
83418343- 当哈希类型元素个数小于 hash-max-ziplist-entries 配置(默认512个)
83428344- 所有值都小于 hash-max-ziplist-value 配置(默认64字节)
83438345
8344- ziplist 使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比 hashtable 更加优秀,当 ziplist 无法满足哈希类型时,Redis 会使用 hashtable 作为哈希的内部实现,因为此时 ziplist 的读写效率会下降,而hashtable的读写时间复杂度为O (1)
8346+ ziplist 使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比 hashtable 更加优秀,当 ziplist 无法满足哈希类型时,Redis 会使用 hashtable 作为哈希的内部实现,因为此时 ziplist 的读写效率会下降,而hashtable 的读写时间复杂度为 O (1)
83458347
83468348
83478349
@@ -8351,7 +8353,7 @@ ziplist 使用更加紧凑的结构实现多个元素的连续存储,所以在
83518353
83528354# #### 压缩列表
83538355
8354- 压缩列表(ziplist)是列表和哈希的底层实现之一,压缩列表用来紧凑数据存储,节省内存:
8356+ 压缩列表(ziplist)是列表和哈希的底层实现之一,压缩列表用来紧凑数据存储,节省内存:
83558357
83568358< img src=" https://gitee.com/seazean/images/raw/master/DB/Redis-压缩列表数据结构.png" style=" zoom:67%;" />
83578359
@@ -8365,7 +8367,7 @@ ziplist 使用更加紧凑的结构实现多个元素的连续存储,所以在
83658367
83668368# #### 哈希表
83678369
8368- Redis 字典使用散列表为底层实现,一个散列表里面有多个散列表节点,每个散列表节点就保存了字典中的一个键值对,发生哈希冲突采用链表法解决
8370+ Redis 字典使用散列表为底层实现,一个散列表里面有多个散列表节点,每个散列表节点就保存了字典中的一个键值对,发生哈希冲突采用链表法解决,存储无序
83698371
83708372
83718373
@@ -8723,14 +8725,14 @@ sorted_set类型:在set的存储结构基础上添加可排序字段,类似
87238725
87248726# #### 跳跃表
87258727
8726- Redis 使用跳跃表作为有序集合键的底层实现之一,如果一个有序集合包含的** 元素数量比较多** ,又或者有序集合中元素的** 成员是比较长的字符串** 时,Redis就会使用跳跃表来作为有序集合健的底层实现
8728+ Redis 使用跳跃表作为有序集合键的底层实现之一,如果一个有序集合包含的** 元素数量比较多** ,又或者有序集合中元素的** 成员是比较长的字符串** 时,Redis 就会使用跳跃表来作为有序集合健的底层实现
87278729
8728- 跳跃表在链表的基础上增加了多级索引以提升查找的效率,索引是占内存的,所以是一个** 空间换时间** 的方案。原始链表中存储的有可能是很大的对象,而索引结点只需要存储关键值值和几个指针 ,并不需要存储对象,因此当节点本身比较大或者元素数量比较多的时候,其优势可以被放大,而缺点则可以忽略
8730+ 跳跃表在链表的基础上增加了多级索引以提升查找的效率,索引是占内存的,所以是一个** 空间换时间** 的方案。原始链表中存储的有可能是很大的对象,而索引结点只需要存储关键值和几个指针 ,并不需要存储对象,因此当节点本身比较大或者元素数量比较多的时候,其优势可以被放大,而缺点则可以忽略
87298731
87308732* 基于单向链表加索引的方式实现
87318733
87328734- Redis 的跳跃表实现由 zskiplist 和 zskiplistnode 两个结构组成,其中 zskiplist 用于保存跳跃表信息(比如表头节点、表尾节点、长度),而 zskiplistnode 则用于表示跳跃表节点
8733- - Redis 每个跳跃表节点的层高都是 1 至 32 之间的随机数(Redis5之后最大层数为64 )
8735+ - Redis 每个跳跃表节点的层高都是 1 至 32 之间的随机数(Redis5 之后最大层数为64 )
87348736- 在同一个跳跃表中,多个节点可以包含相同的分值,但每个节点的成员对象必须是唯一的。跳跃表中的节点按照分值大小进行排序,当分值相同时节点按照成员对象的大小进行排序
87358737
87368738! [](https://gitee.com/seazean/images/raw/master/DB/Redis-跳跃表数据结构.png)
@@ -11015,17 +11017,17 @@ Read-Through Pattern 也存在首次不命中的问题,采用缓存预热解
1101511017
1101611018解决方案:
1101711019
11018- 1. 预先设定:以电商为例,每个商家根据店铺等级,指定若干款主打商品,在购物节期间,加大此类信息key的过期时长 注意:购物节不仅仅指当天,以及后续若干天,访问峰值呈现逐渐降低的趋势
11020+ 1. 预先设定:以电商为例,每个商家根据店铺等级,指定若干款主打商品,在购物节期间,加大此类信息 key 的过期时长 注意:购物节不仅仅指当天,以及后续若干天,访问峰值呈现逐渐降低的趋势
1101911021
11020- 2. 现场调整:监控访问量,对自然流量激增的数据延长过期时间或设置为永久性key
11022+ 2. 现场调整:监控访问量,对自然流量激增的数据延长过期时间或设置为永久性 key
1102111023
11022110243. 后台刷新数据:启动定时任务,高峰期来临之前,刷新数据有效期,确保不丢失
1102311025
11024110264. 二级缓存:设置不同的失效时间,保障不会被同时淘汰就行
1102511027
11026110285. 加锁:分布式锁,防止被击穿,但是要注意也是性能瓶颈,慎重!
1102711029
11028- 总的来说:缓存击穿就是单个高热数据过期的瞬间,数据访问量较大,未命中redis后 ,发起了大量对同一数据的数据库访问,导致对数据库服务器造成压力。应对策略应该在业务数据分析与预防方面进行,配合运行监控测试与即时调整策略,毕竟单个key的过期监控难度较高 ,配合雪崩处理策略即可
11030+ 总的来说:缓存击穿就是单个高热数据过期的瞬间,数据访问量较大,未命中 redis 后 ,发起了大量对同一数据的数据库访问,导致对数据库服务器造成压力。应对策略应该在业务数据分析与预防方面进行,配合运行监控测试与即时调整策略,毕竟单个 key 的过期监控难度较高 ,配合雪崩处理策略即可
1102911031
1103011032
1103111033
@@ -11035,24 +11037,24 @@ Read-Through Pattern 也存在首次不命中的问题,采用缓存预热解
1103511037
1103611038# ### 缓存穿透
1103711039
11038- 场景:系统平稳运行过程中,应用服务器流量随时间增量较大,Redis服务器命中率随时间逐步降低,Redis内存平稳 ,内存无压力,Redis服务器CPU占用激增 ,数据库服务器压力激增,数据库崩溃
11040+ 场景:系统平稳运行过程中,应用服务器流量随时间增量较大,Redis 服务器命中率随时间逐步降低,Redis 内存平稳 ,内存无压力,Redis 服务器 CPU 占用激增 ,数据库服务器压力激增,数据库崩溃
1103911041
1104011042问题排查:
1104111043
11042- 1. Redis中大面积出现未命中
11044+ 1. Redis 中大面积出现未命中
1104311045
11044- 2. 出现非正常URL访问
11046+ 2. 出现非正常 URL 访问
1104511047
1104611048问题分析:
1104711049
1104811050- 获取的数据在数据库中也不存在,数据库查询未得到对应数据
11049- - Redis获取到null数据未进行持久化 ,直接返回
11051+ - Redis 获取到 null 数据未进行持久化 ,直接返回
1105011052- 下次此类数据到达重复上述过程
1105111053- 出现黑客攻击服务器
1105211054
1105311055解决方案:
1105411056
11055- 1. 缓存null :对查询结果为null的数据进行缓存 (长期使用,定期清理) ,设定短时限,例如30-60秒,最高5分钟
11057+ 1. 缓存 null :对查询结果为null的数据进行缓存 (长期使用,定期清理) ,设定短时限,例如30-60秒,最高5分钟
1105611058
11057110592. 白名单策略:提前预热各种分类数据 id 对应的 ** bitmaps** ,id 作为 bitmaps 的 offset,相当于设置了数据白名单。当加载正常数据时放行,加载异常数据时直接拦截(效率偏低),也可以使用布隆过滤器(有关布隆过滤器的命中问题对当前状况可以忽略)
1105811060
@@ -11063,7 +11065,7 @@ Read-Through Pattern 也存在首次不命中的问题,采用缓存预热解
1106311065
1106411066 根据倍数不同,启动不同的排查流程。然后使用黑名单进行防控(运营)
1106511067
11066- 4. key加密:临时启动防灾业务key,对key进行业务层传输加密服务 ,设定校验程序,过来的key校验 ;例如每天随机分配60个加密串,挑选2到3个,混淆到页面数据id中,发现访问key不满足规则 ,驳回数据访问
11068+ 4. key 加密:临时启动防灾业务 key,对 key 进行业务层传输加密服务 ,设定校验程序,过来的 key 校验 ;例如每天随机分配60个加密串,挑选2到3个,混淆到页面数据 id 中,发现访问 key 不满足规则 ,驳回数据访问
1106711069
1106811070总的来说:缓存击穿是指访问了不存在的数据,跳过了合法数据的 redis 数据缓存阶段,每次访问数据库,导致对数据库服务器造成压力。通常此类数据的出现量是一个较低的值,当出现此类情况以毒攻毒,并及时报警。无论是黑名单还是白名单,都是对整体系统的压力,警报解除后尽快移除
1106911071
0 commit comments