Skip to content

Commit 65039ea

Browse files
committed
Update Java Notes
1 parent a6c6396 commit 65039ea

File tree

4 files changed

+332
-149
lines changed

4 files changed

+332
-149
lines changed

DB.md

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ mysqlshow -uroot -p1234 test book --count
409409

410410
- 用来定义数据库的访问权限和安全级别,及创建用户。关键字:grantrevoke
411411

412-
![](https://gitee.com/seazean/images/raw/master/DB/SQL分类.png)
412+
![](https://gitee.com/seazean/images/raw/master/Java/SQL分类.png)
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
1102211024
3. 后台刷新数据:启动定时任务,高峰期来临之前,刷新数据有效期,确保不丢失
1102311025
1102411026
4. 二级缓存:设置不同的失效时间,保障不会被同时淘汰就行
1102511027
1102611028
5. 加锁:分布式锁,防止被击穿,但是要注意也是性能瓶颈,慎重!
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
1105711059
2. 白名单策略:提前预热各种分类数据 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

Issue.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
# Base
22

3+
## Algorithm
4+
5+
排序类问题:
6+
7+
* 海量数据排序:
8+
* 外部排序:归并 + 败者树
9+
* 基数排序:https://time.geekbang.org/column/article/42038
10+
11+
12+
13+
14+
15+
16+
17+
***
18+
19+
20+
321
## Network
422

523
### 传输层

0 commit comments

Comments
 (0)