Skip to content

Commit 053c142

Browse files
committed
[docs update]添加redis后台线程+完善AOF 工作基本流程和重写
1 parent 4058335 commit 053c142

File tree

6 files changed

+152
-43
lines changed

6 files changed

+152
-43
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<mxfile host="Electron" modified="2023-03-25T08:01:22.932Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/20.3.0 Chrome/104.0.5112.114 Electron/20.1.3 Safari/537.36" etag="02156dhSlPyPTH9l8v31" version="20.3.0" type="device"><diagram id="cLKaGq3Gi8W_Nx-YzgXy" name="Page-1">7VZNj9MwEP01Pm6VxE3bPTb9ACEWkIoEe3TjSWJw4uK42+7+euxk0nxtVywITlxa+3n8bM97Mwqhq/z8RrNDdqc4SBJ4/EzomgSB73sz++eQxxqZL25rINWCY1AL7MQTIOghehQcyl6gUUoaceiDsSoKiE0PY1qrUz8sUbJ/6oGlMAJ2MZNj9IvgJqvRRTBv8bcg0qw52Z/h+3LWBONLyoxxdepAdEPoSitl6lF+XoF0yWvyUu/bXlm9XExDYX5lQ5gcow98b8TN8cf6M/d3357UDbI8MHnEBy8/bslmRm5nZDEnmymJIhKhhqV5bNKi1bHg4Jh9QqNTJgzsDix2qydrBItlJpe4nKjCoLL+zM2FlCslla64KPg8hLnFS6PVd2hWClUAbt6yXEhnoHdgIs1EUdrb3KlCNeTqqKuzM2OsL4KQLu2PzYT7cQHlJFUqlcAOopzEKq8W4rIK3SY1ux12+cMgwhMwRaANnK/m3r8oaksBVA5GW0qv2dCYAKsgmOP81HrKn4c1lnX95GEgQx+nF+5WajtAtV+hfDBSfiQyFHzpSsjOYsnKUsR9XVsTeHYGZ2G+4oob3zt8EuJsfe6ErR9xUh8JfFSDg8TaazUSv+jksQCdBIfeOL8NpkEyIx7613gu53jCJyXsBS/60kVfX0oHstXXx13dIh0QTemAKBgQGaZTMCOiygKXZ/++K+jIFRpO2lb32BxWtPdsb9t9zxNMirRwhrECgi3jyNWNsP10iQu54NxxRBpK8cT2FZ/zwsG9qXplGJFwPegb4UuFiM0fydqW2/XR9SK4WrU33iToqeH/mVmaEJUkJfwV+ab/2/m/aOfDKg1un2nnwTPtZha+upvbafuNUPuk/dKim58=</diagram></mxfile>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<mxfile host="Electron" modified="2023-03-25T06:53:36.610Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/20.3.0 Chrome/104.0.5112.114 Electron/20.1.3 Safari/537.36" etag="XVuhvrMoR4qwnl8eKIhj" version="20.3.0" type="device"><diagram id="NaMnIawQRtq_GJTarwnL" name="Page-1">7Vptc+MmEP41fIxH6F0fJce69iZpO5N27u5Th0hY1kUWroRj+359AYElLDnxxXHsyWUy48ACC2If9tlFAtZ4vv5UocXslqS4AKaRroF1DUwTQsNl/7hk00g8P2gEWZWnslMruMt/YCk0pHSZp7jWOlJCCpovdGFCyhInVJOhqiIrvduUFPqsC5ThnuAuQUVf+iVP6ayR+qbXyn/DeTZTM0NXPt89Sh6yiixLOR8wrdiN49hvmudI6ZIPWs9QSlYdkTUB1rgihDal+XqMC763atuacfGe1u26K1zSQwag4N+x/8et+c/vf3+d3qR3FN4WV7ZcG92o/cAp2x5ZJRWdkYyUqJi00kg8M+ZaDVZr+9wQsmBCyITfMaUbaWu0pISJZnReyFa24GrzVY4XlW+8MnJU9XrdbbzeyNqUlDRG87zggs+YRhXKy5ot/5aURLbfkWWV8GlnlDIEmY4Vsh+2KfyHd6hHGSFZgdEir0cJmYuGpBZd42mjnRW7+h0zkjPUtCIPW5wwE0bN/vFN22sWKarVyvbZQqEfVRmmT/Qzt+BhhxKTOWZ7xMZVuEA0f9TXgeTpyLb9WoSwggTJTwBGnvZHVCzVsywWmJ2BIRzdoHvmLTTboyLPSlZO2PbgigkecUVzdhxD2TDP07SBGa7zH+he6OPWX5CcWY8rdyLgXCt7NyCD9kXgo+APHG0dw5gUpBLboVyDAgx/arwGAw5OPnHrN7pQ2n+G+3iQ2q+MkdkoOhggUtdffMM7Xch0WjNg7iJoO+XLQQV7oAITBwQQRNdgYoMoAqENJj6IYiFxgB+C0OhBrnVMHGmrWU7x3QIJa68YeelA7ILH5fW8KDr2ShH2p8n2yKuWkpT4IpC2F0Y9z7MXGVBRsGRuy5b1VcuD0JCyWYcDbfdEzsX7YKOLYSPzQDayzslGfs9xrCp26j/I6Gxk5D1HRtAIoO52Lp2dzB7Iwj9jMPFANAaBJejIBZGgLH8MovCkvGQYvuXH75qXLPPSeCk4Ly+1VPRNY6JfkpesA3kJGsMge6mfkeD07B1wupauolmYHHWCULkfK0/rTZl8UN7ZKC94Nv+CvqeBBh5HeUqzzqOBPv50fGgNZGuMDC2ep/FCBIJYsqLvgInLU7XIPxdhTv0EJ+87kXN2fdIQYVpvSZgqs9yNmVwQMFB4MqmPXDCJOSh8gY4QgnDMCwFDkK+a+tz7mujAMHWw977RAT0WQHTxYfsD+PCcAXwYp8JHP6buE1iZhvx+n5NVgeo6T3TL6gHWLhc9H6Cd37gvj5P6xu6Y0hk46Up2JOW4ju5pHHMHIU341ot++oqCHUXGjqI9YRRDBNp0usmg5PAFO8aT6/LMI/sbWn9WaFb8ujFgn4Er/HHxcd4oEO55LdMNA6EesR15L78ZHHDCW3pnEF5nSoO3bU+kwZcFy9O+PJRvck+fFx9H/P33hwVB6YffOp/fcp70W8YImratua2rI/3WG3gqux9eTgKeePji9SELPsL4pHnFL/D60LGtkacnFo7v9BML0xy9aWrhDaQWbkHltmomd/9bEtVwVQtrsk02oLtYiz1S7ayUif/8xsIRWaotLjM8IWGJqifT1SD8jB7RJ/5Nk5r1vjpyTo+/9A6gSJFZZhxsp/rOphKfT42SUs0GGnBsR++CnNmb6kgeRmgHzlJ0uO8dOjp6HLDH03WOh3a2WL1ztiLxJ3RS5oBIKZXWD5gmM1VRX1tdxpX4K5w3c+eWx/YGsnh/IPeDP3/UWLX9MK3xyu3Xf9bkfw==</diagram></mxfile>

docs/database/redis/redis-common-blocking-problems-summary.md

+65-12
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ tag:
77

88
> 本文整理完善自:https://mp.weixin.qq.com/s/0Nqfq_eQrUb12QH6eBbHXA ,作者:阿Q说代码
99
10-
## O(n) 命令阻塞
10+
这篇文章会详细总结一下可能导致 Redis 阻塞的情况,这些情况也是影响 Redis 性能的关键因素,使用 Redis 的时候应该格外注意!
11+
12+
## O(n) 命令
1113

1214
使用` O(n)` 命令可能会导致阻塞,例如`keys *``hgetall``lrange``smembers``zrange``sinter``sunion` 命令。这些命令时间复杂度是 O(n),有时候也会全表扫描,随着 n 的增大耗时也会越大从而导致客户端阻塞。
1315

1416
不过, 这些命令并不是一定不能使用,但是需要明确 N 的值。有遍历的需求可以使用 `hscan``sscan``zscan` 代替。
1517

16-
## SAVE 创建 RDB 快照阻塞
18+
## SAVE 创建 RDB 快照
1719

1820
Redis 提供了两个命令来生成 RDB 快照文件:
1921

@@ -22,7 +24,9 @@ Redis 提供了两个命令来生成 RDB 快照文件:
2224

2325
默认情况下,Redis 默认配置会使用 `bgsave` 命令。如果手动使用 `save` 命令生成 RDB 快照文件的话,就会阻塞主线程。
2426

25-
## AOF 日志记录阻塞
27+
## AOF
28+
29+
### AOF 日志记录阻塞
2630

2731
Redis AOF 持久化机制是在执行完命令之后再记录日志,这和关系型数据库(如 MySQL)通常都是执行命令之前记录日志(方便故障恢复)不同。
2832

@@ -38,21 +42,21 @@ Redis AOF 持久化机制是在执行完命令之后再记录日志,这和关
3842
- 如果刚执行完命令 Redis 就宕机会导致对应的修改丢失;
3943
- **可能会阻塞后续其他命令的执行(AOF 记录日志是在 Redis 主线程中进行的)**
4044

41-
## AOF 刷盘阻塞
45+
### AOF 刷盘阻塞
4246

4347
开启 AOF 持久化后每执行一条会更改 Redis 中的数据的命令,Redis 就会将该命令写入到 AOF 缓冲区 `server.aof_buf` 中,然后再根据 `appendfsync` 配置来决定何时将其同步到硬盘中的 AOF 文件。
4448

4549
在 Redis 的配置文件中存在三种不同的 AOF 持久化方式( `fsync`策略),它们分别是:
4650

47-
```bash
48-
appendfsync always #每次有数据修改发生时都会调用fsync函数同步AOF文件,fsync完成后线程返回,这样会严重降低Redis的速度
49-
appendfsync everysec #每秒钟调用fsync函数同步一次AOF文件
50-
appendfsync no #让操作系统决定何时进行同步,一般为30秒一次
51-
```
51+
1. `appendfsync always`:主线程调用 `write` 执行写操作后,后台线程( `aof_fsync` 线程)立即会调用 `fsync` 函数同步 AOF 文件(刷盘),`fsync` 完成后线程返回,这样会严重降低 Redis 的性能(`write` + `fsync`)。
52+
2. `appendfsync everysec` :主线程调用 `write` 执行写操作后立即返回,由后台线程( `aof_fsync` 线程)每秒钟调用 `fsync` 函数(系统调用)同步一次 AOF 文件(`write`+`fsync``fsync`间隔为 1 秒)
53+
3. `appendfsync no` :主线程调用 `write` 执行写操作后立即返回,让操作系统决定何时进行同步,Linux 下一般为 30 秒一次(`write`但不`fsync``fsync` 的时机由操作系统决定)。
5254

53-
当调用 fsync 函数同步 AOF 文件时,需要等待,直到写入完成。当磁盘压力太大的时候,主线程可能会被阻塞
55+
当后台线程( `aof_fsync` 线程)调用 `fsync` 函数同步 AOF 文件时,需要等待,直到写入完成。当磁盘压力太大的时候,会导致 `fsync` 操作发生阻塞,主线程调用 `write` 函数时也会被阻塞。`fsync` 完成后,主线程执行 `write` 才能成功返回
5456

55-
## AOF 重写阻塞
57+
关于 AOF 工作流程的详细介绍可以查看:[Redis持久化机制详解](./redis-persistence.md),有助于理解 AOF 刷盘阻塞。
58+
59+
### AOF 重写阻塞
5660

5761
1. fork 出一条子线程来将文件重写,在执行 `BGREWRITEAOF` 命令时,Redis 服务器会维护一个 AOF 重写缓冲区,该缓冲区会在子线程创建新 AOF 文件期间,记录服务器执行的所有写命令。
5862
2. 当子线程完成创建新 AOF 文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新 AOF 文件的末尾,使得新的 AOF 文件保存的数据库状态与现有的数据库状态一致。
@@ -62,7 +66,7 @@ appendfsync no #让操作系统决定何时进行同步,一般为30秒
6266

6367
相关阅读:[Redis AOF重写阻塞问题分析](https://cloud.tencent.com/developer/article/1633077)
6468

65-
## 大 Key 问题
69+
## 大 Key
6670

6771
如果一个 key 对应的 value 所占用的内存比较大,那这个 key 就可以看作是 bigkey。具体多大才算大呢?有一个不是特别精确的参考标准:string 类型的 value 超过 10 kb,复合类型的 value 包含的元素超过 5000 个(对于复合类型的 value 来说,不一定包含的元素越多,占用的内存就越多)。
6872

@@ -105,3 +109,52 @@ Redis 集群可以进行节点的动态扩容缩容,这一过程目前还处
105109

106110
执行迁移时,两端的 Redis 均会进入时长不等的阻塞状态,对于小 Key,该时间可以忽略不计,但如果一旦 Key 的内存使用过大,严重的时候会触发集群内的故障转移,造成不必要的切换。
107111

112+
## Swap(内存交换)
113+
114+
什么是 Swap?Swap 直译过来是交换的意思,Linux中的Swap常被称为内存交换或者交换分区。类似于 Windows 中的虚拟内存,就是当内存不足的时候,把一部分硬盘空间虚拟成内存使用,从而解决内存容量不足的情况。因此,Swap 分区的作用就是牺牲硬盘,增加内存,解决 VPS 内存不够用或者爆满的问题。
115+
116+
Swap 对于Redis来说是非常致命的,Redis保证高性能的一个重要前提是所有的数据在内存中。如果操作系统把Redis使用的部分内存换出硬盘,由于内存与硬盘读写的速度并几个数量级,会导致发生交换后的Redis性能急剧下降。
117+
118+
识别 Redis 发生 Swap 的检查方法如下:
119+
120+
1、查询Redis进程号
121+
122+
```bash
123+
reids-cli -p 6383 info server | grep process_id
124+
process_id: 4476
125+
```
126+
127+
2、根据进程号查询内存交换信息
128+
129+
```bash
130+
cat /proc/4476/smaps | grep Swap
131+
Swap: 0kB
132+
Swap: 0kB
133+
Swap: 4kB
134+
Swap: 0kB
135+
Swap: 0kB
136+
.....
137+
```
138+
139+
如果交换量都是0KB或者个别的是4KB,则正常。
140+
141+
预防内存交换的方法:
142+
143+
- 保证机器充足的可用内存
144+
- 确保所有Redis实例设置最大可用内存(maxmemory),防止极端情况Redis内存不可控的增长
145+
- 降低系统使用swap优先级,如`echo 10 > /proc/sys/vm/swappiness`
146+
147+
## CPU 竞争
148+
149+
Redis是典型的CPU密集型应用,不建议和其他多核CPU密集型服务部署在一起。当其他进程过度消耗CPU时,将严重影响Redis的吞吐量。
150+
151+
可以通过`reids-cli --stat`获取当前Redis使用情况。通过`top`命令获取进程对CPU的利用率等信息 通过`info commandstats`统计信息分析出命令不合理开销时间,查看是否是因为高算法复杂度或者过度的内存优化问题。
152+
153+
## 网络问题
154+
155+
连接拒绝、网络延迟,网卡软中断等网络问题也可能会导致 Redis 阻塞。
156+
157+
## 参考
158+
159+
- Redis阻塞的6大类场景分析与总结:https://mp.weixin.qq.com/s/eaZCEtTjTuEmXfUubVHjew
160+
- Redis开发与运维笔记-Redis的噩梦-阻塞:https://mp.weixin.qq.com/s/TDbpz9oLH6ifVv6ewqgSgA

0 commit comments

Comments
 (0)