Skip to content

Commit 303d50d

Browse files
committed
Update Java Notes
1 parent 0a99b09 commit 303d50d

4 files changed

Lines changed: 480 additions & 430 deletions

File tree

DB.md

Lines changed: 55 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3654,7 +3654,7 @@ MERGE存储引擎:
36543654

36553655
#### 基本介绍
36563656

3657-
MySQL官方对索引的定义为:索引(index)是帮助 MySQL 高效获取数据的一种数据结构,本质是排好序的快速查找数据结构。在表数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式指向数据, 这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。
3657+
MySQL 官方对索引的定义为:索引(index)是帮助 MySQL 高效获取数据的一种数据结构,本质是排好序的快速查找数据结构。在表数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式指向数据, 这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。
36583658

36593659
索引使用:一张数据表,用于保存数据;一个索引配置文件,用于保存索引;每个索引都指向了某一个数据
36603660
![](https://gitee.com/seazean/images/raw/master/DB/MySQL-索引的介绍.png)
@@ -8290,9 +8290,9 @@ Redis 所有操作都是**原子性**的,采用**单线程**机制,命令是
82908290
82918291
#### 应用
82928292
8293-
主页高频访问信息显示控制,例如新浪微博大V主页显示粉丝数与微博数量
8293+
主页高频访问信息显示控制,例如新浪微博大 V 主页显示粉丝数与微博数量
82948294
8295-
* 在 Redis 中为大V用户设定用户信息,以用户主键和属性值作为 key,后台设定定时刷新策略
8295+
* 在 Redis 中为大 V 用户设定用户信息,以用户主键和属性值作为 key,后台设定定时刷新策略
82968296
82978297
```sh
82988298
set user:id:3506728370:fans 12210947
@@ -8358,11 +8358,11 @@ struct sdshdr{
83588358
83598359
数据存储结构:一个存储空间保存多个键值对数据
83608360
8361-
hash类型:底层使用**哈希表**结构实现数据存储
8361+
hash 类型:底层使用**哈希表**结构实现数据存储
83628362
83638363
<img src="https://gitee.com/seazean/images/raw/master/DB/hash结构图.png" style="zoom: 33%;" />
83648364
8365-
类似Map结构,左边是key,右边是值,中间叫field字段,本质上**hash存了一个key-value的存储空间**
8365+
Redis 中的 hash 类似于 Java 中的 `Map<String, Map<Object,object>>`,左边是 key,右边是值,中间叫 field 字段,本质上 **hash 存了一个 key-value 的存储空间**
83668366
83678367
hash 是指的一个数据类型,并不是一个数据
83688368
@@ -8438,6 +8438,8 @@ user:id:3506728370 → {"name":"春晚","fans":12210862,"blogs":83}
84388438
84398439
<img src="https://gitee.com/seazean/images/raw/master/DB/hash应用场景结构图.png" style="zoom: 33%;" />
84408440
8441+
可以实现购物车的功能,key 对应着每个用户,存储空间存储购物车的信息
8442+
84418443
84428444
84438445
***
@@ -8452,8 +8454,8 @@ user:id:3506728370 → {"name":"春晚","fans":12210862,"blogs":83}
84528454
84538455
当存储的数据量比较小的情况下,Redis 才使用压缩列表来实现字典类型,具体需要满足两个条件:
84548456
8455-
- 当键值对个数小于 hash-max-ziplist-entries 配置(默认512个
8456-
- 所有键值都小于 hash-max-ziplist-value 配置(默认64字节
8457+
- 当键值对个数小于 hash-max-ziplist-entries 配置(默认 512 个
8458+
- 所有键值都小于 hash-max-ziplist-value 配置(默认 64 字节
84578459
84588460
ziplist 使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比 hashtable 更加优秀,当 ziplist 无法满足哈希类型时,Redis 会使用 hashtable 作为哈希的内部实现,因为此时 ziplist 的读写效率会下降,而 hashtable 的读写时间复杂度为 O(1)
84598461
@@ -8568,6 +8570,10 @@ list 类型:保存多个数据,底层使用**双向链表**存储结构实
85688570
* 使用队列模型解决多路信息汇总合并的问题
85698571
* 使用栈模型解决最新消息的问题
85708572
8573+
微信文章订阅公众号:
8574+
8575+
* 比如订阅了两个公众号,它们发布了两篇文章,文章 ID 分别为 666 和 888,可以通过执行 `LPUSH key 666 888` 命令推送给我
8576+
85718577
85728578
85738579
****
@@ -8715,13 +8721,9 @@ set 类型:与 hash 存储结构哈希表完全相同,只是仅存储键不
87158721

87168722
2. 白名单:对于安全性更高的应用访问,仅仅靠黑名单是不能解决安全问题的,此时需要设定可访问的用户群体, 依赖白名单做更为苛刻的访问验证
87178723

8724+
3. 随机操作可以实现抽奖功能
87188725

8719-
解决方案:
8720-
8721-
* 设定用户鉴别规则,周期性更新满足规则的黑名单加入 set 集合,用户行为信息达到后与黑名单进行对比
8722-
* 黑名单过滤 IP 地址:应用于开放游客访问权限的信息源
8723-
* 黑名单过滤设备信息:应用于限定访问设备的信息源
8724-
* 黑名单过滤用户:应用于基于访问权限的信息源
8726+
4. 集合的交并补可以实现微博共同关注的查看,可以根据共同关注或者共同喜欢推荐相关内容
87258727

87268728

87278729

@@ -8737,7 +8739,7 @@ set 类型:与 hash 存储结构哈希表完全相同,只是仅存储键不
87378739

87388740
* hashtable(哈希表,字典):当无法满足 intset 条件时,Redis 会使用 hashtable 作为集合的内部实现
87398741

8740-
整数集合(intset)是 Redis 用于保存整数值的集合抽象数据结构,可以保存类型为 int16_t、int32_t 或者 int64_t的整数值,并且保证集合中的元素是**有序不重复**
8742+
整数集合(intset)是 Redis 用于保存整数值的集合抽象数据结构,可以保存类型为 int16_t、int32_t 或者 int64_t 的整数值,并且保证集合中的元素是**有序不重复**
87418743

87428744

87438745

@@ -8774,7 +8776,7 @@ sorted_set类型:在 set 的存储结构基础上添加可排序字段,类
87748776
```sh
87758777
zadd key score1 member1 [score2 member2] #添加数据
87768778
zrem key member [member ...] #删除数据
8777-
zremrangebyrank key start stop #删除指定索引的数据
8779+
zremrangebyrank key start stop #删除指定索引范围的数据
87788780
zremrangebyscore key min max #删除指定分数区间内的数据
87798781
zscore key member #获取指定值的分数
87808782
zincrby key increment member #指定值的分数增加increment
@@ -8783,8 +8785,8 @@ sorted_set类型:在 set 的存储结构基础上添加可排序字段,类
87838785
* 查询操作
87848786

87858787
```sh
8786-
zrange key start stop [WITHSCORES] #获取全部数据,升序,WITHSCORES代表显示分数
8787-
zrevrange key start stop [WITHSCORES] #获取全部数据,降序
8788+
zrange key start stop [WITHSCORES] #获取指定范围的数据,升序,WITHSCORES 代表显示分数
8789+
zrevrange key start stop [WITHSCORES] #获取指定范围的数据,降序
87888790
87898791
zrangebyscore key min max [WITHSCORES] [LIMIT offset count] #按条件获取数据,从小到大
87908792
zrevrangebyscore key max min [WITHSCORES] [...] #从大到小
@@ -9768,9 +9770,15 @@ Redis 分布式锁的基本使用,悲观锁
97689770
* 对于返回设置成功的,拥有控制权,进行下一步的具体业务操作
97699771
* 对于返回设置失败的,不具有控制权,排队或等待
97709772
9771-
NX:只在键不存在时,才对键进行设置操作,`SET key value NX` 效果等同于 `SETNX key value`
9773+
`NX`:只在键不存在时,才对键进行设置操作,`SET key value NX` 效果等同于 `SETNX key value`
97729774
9773-
XX :只在键已经存在时,才对键进行设置操作
9775+
`XX` :只在键已经存在时,才对键进行设置操作
9776+
9777+
`EX`:设置键 key 的过期时间,单位时秒
9778+
9779+
`PX`:设置键 key 的过期时间,单位时毫秒
9780+
9781+
说明:由于 `SET` 命令加上选项已经可以完全取代 SETNX、SETEX、PSETEX 的功能,Redis 不推荐使用这几个命令
97749782
97759783
* 操作完毕通过 del 操作释放锁
97769784
@@ -9864,7 +9872,7 @@ TTL 返回的值有三种情况:正数,-1,-2
98649872
创建一个定时器,当 key 设置有过期时间,且过期时间到达时,由定时器任务立即执行对键的删除操作
98659873

98669874
- 优点:节约内存,到时就删除,快速释放掉不必要的内存占用
9867-
- 缺点:无论 CPU 此时负载量多高,均占用 CPU,会影响 redis 服务器响应时间和指令吞吐量
9875+
- 缺点:无论 CPU 此时负载量多高,均占用 CPU,会影响 Redis 服务器响应时间和指令吞吐量
98689876
- 总结:用处理器性能换取存储空间(拿时间换空间)
98699877

98709878

@@ -9875,7 +9883,7 @@ TTL 返回的值有三种情况:正数,-1,-2
98759883

98769884
#### 惰性删除
98779885

9878-
数据到达过期时间,不做处理,等下次访问该数据时,我们需要判断
9886+
数据到达过期时间,不做处理,等下次访问该数据时,需要判断
98799887

98809888
* 如果未过期,返回数据
98819889
* 如果已过期,删除,返回不存在
@@ -9884,7 +9892,7 @@ TTL 返回的值有三种情况:正数,-1,-2
98849892

98859893
特点:
98869894

9887-
* 优点:节约CPU性能,发现必须删除的时候才删除
9895+
* 优点:节约 CPU 性能,发现必须删除的时候才删除
98889896
* 缺点:内存压力很大,出现长期占用内存的数据
98899897
* 总结:用存储空间换取处理器性能(拿空间换时间)
98909898

@@ -9898,11 +9906,11 @@ TTL 返回的值有三种情况:正数,-1,-2
98989906

98999907
定时删除和惰性删除这两种方案都是走的极端,定期删除就是折中方案
99009908

9901-
定期删除是周期性轮询 redis 库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度
9909+
定期删除是周期性轮询 Redis 库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度
99029910

99039911
定期删除方案:
99049912

9905-
- Redis启动服务器初始化时,读取配置 server.hz 的值,默认为10。执行指令可以查看:info server
9913+
- Redis 启动服务器初始化时,读取配置 server.hz 的值,默认为 10,执行指令 info server 可以查看
99069914

99079915
- 每秒钟执行 server.hz 次 serverCron() → databasesCron() → activeExpireCycle()
99089916

@@ -9954,9 +9962,9 @@ TTL 返回的值有三种情况:正数,-1,-2
99549962

99559963
数据淘汰策略:当新数据进入 redis 时,在执行每一个命令前,会调用 **freeMemoryIfNeeded()** 检测内存是否充足。如果内存不满足新加入数据的最低存储要求,redis 要临时删除一些数据为当前指令清理存储空间,清理数据的策略称为**逐出算法**
99569964

9957-
注意:逐出数据的过程不是 100% 能够清理出足够的可使用的内存空间,如果不成功则反复执行,当对所有数据尝试完毕,如不能达到内存清理的要求,将出现错误信息如下
9965+
逐出数据的过程不是 100% 能够清理出足够的可使用的内存空间,如果不成功则反复执行,当对所有数据尝试完毕,如不能达到内存清理的要求,**出现 Redis 内存打满异常**
99589966

9959-
```shell
9967+
```sh
99609968
(error) OOM command not allowed when used memory >'maxmemory'
99619969
```
99629970

@@ -9968,13 +9976,20 @@ TTL 返回的值有三种情况:正数,-1,-2
99689976

99699977
#### 策略配置
99709978

9971-
影响数据淘汰的相关配置如下,配置 conf 文件:
9979+
Redis 如果不设置最大内存大小或者设置最大内存大小为 0,在 64 位操作系统下不限制内存大小,在 32 位操作系统默认为 3GB 内存,一般推荐设置 Redis 内存为最大物理内存的四分之三
99729980

9973-
* 最大可使用内存,即占用物理内存的比例,默认值为 0,表示不限制。生产环境中根据需求设定,通常设置在 50% 以上
9981+
内存配置方式:
99749982

9975-
```sh
9976-
maxmemory ?mb
9977-
```
9983+
* 通过修改文件配置(永久生效):修改配置文件 maxmemory 字段,单位为字节
9984+
9985+
* 通过命令修改(重启失效):
9986+
9987+
* `config set maxmemory 104857600`:设置 Redis 最大占用内存为 100MB
9988+
* `config get maxmemory`:获取 Redis 最大占用内存
9989+
9990+
* `info` :可以查看 Redis 内存使用情况,`used_memory_human` 字段表示实际已经占用的内存,`maxmemory` 表示最大占用内存
9991+
9992+
影响数据淘汰的相关配置如下,配置 conf 文件:
99789993

99799994
* 每次选取待删除数据的个数,采用随机获取数据的方式作为待检测删除数据,防止全库扫描,导致严重的性能消耗,降低读写性能
99809995

@@ -9990,21 +10005,21 @@ TTL 返回的值有三种情况:正数,-1,-2
999010005

999110006
数据删除的策略 policy:3 类 8 种
999210007

9993-
第一类:检测易失数据(可能会过期的数据集 server.db[i].expires ):
10008+
第一类:检测易失数据(可能会过期的数据集 server.db[i].expires):
999410009

999510010
```sh
9996-
volatile-lru #挑选最近最久未使用使用的数据淘汰
9997-
volatile-lfu #挑选最近使用次数最少的数据淘汰
9998-
volatile-ttl #挑选将要过期的数据淘汰
9999-
volatile-random #任意选择数据淘汰
10011+
volatile-lru # 对设置了过期时间的 key 选择最近最久未使用使用的数据淘汰
10012+
volatile-lfu # 对设置了过期时间的 key 选择最近使用次数最少的数据淘汰
10013+
volatile-ttl # 对设置了过期时间的 key 选择将要过期的数据淘汰
10014+
volatile-random # 对设置了过期时间的 key 选择任意数据淘汰
1000010015
```
1000110016

1000210017
第二类:检测全库数据(所有数据集 server.db[i].dict ):
1000310018

1000410019
```sh
10005-
allkeys-lru #挑选最近最少使用的数据淘汰
10006-
allkeLyRs-lfu #挑选最近使用次数最少的数据淘汰
10007-
allkeys-random #任意选择数据淘汰,相当于随机
10020+
allkeys-lru # 对所有 key 选择最近最少使用的数据淘汰
10021+
allkeLyRs-lfu # 对所有 key 选择最近使用次数最少的数据淘汰
10022+
allkeys-random # 对所有 key 选择任意数据淘汰,相当于随机
1000810023
```
1000910024

1001010025
第三类:放弃数据驱逐
@@ -10013,7 +10028,7 @@ TTL 返回的值有三种情况:正数,-1,-2
1001310028
no-enviction #禁止驱逐数据(redis4.0中默认策略),会引发OOM(Out Of Memory)
1001410029
```
1001510030

10016-
数据淘汰策略配置依据:使用INFO命令输出监控信息,查询缓存 hit 和 miss 的次数,根据需求调优 Redis 配置
10031+
数据淘汰策略配置依据:使用 INFO 命令输出监控信息,查询缓存 hit 和 miss 的次数,根据需求调优 Redis 配置
1001710032

1001810033

1001910034

0 commit comments

Comments
 (0)