Skip to content

Commit

Permalink
[docs update]添加redis后台线程+完善AOF 工作基本流程和重写
Browse files Browse the repository at this point in the history
  • Loading branch information
Snailclimb committed Mar 25, 2023
1 parent 4058335 commit 053c142
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 43 deletions.
1 change: 1 addition & 0 deletions docs/database/redis/images/aof-rewrite.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +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>
1 change: 1 addition & 0 deletions docs/database/redis/images/aof-work-process.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +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>
77 changes: 65 additions & 12 deletions docs/database/redis/redis-common-blocking-problems-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ tag:

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

## O(n) 命令

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

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

## SAVE 创建 RDB 快照阻塞
## SAVE 创建 RDB 快照

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

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

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

## AOF 日志记录阻塞
## AOF

### AOF 日志记录阻塞

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

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

## AOF 刷盘阻塞
### AOF 刷盘阻塞

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

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

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

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

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

### AOF 重写阻塞

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

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

## 大 Key 问题
## 大 Key

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

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

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

## Swap(内存交换)

什么是 Swap?Swap 直译过来是交换的意思,Linux中的Swap常被称为内存交换或者交换分区。类似于 Windows 中的虚拟内存,就是当内存不足的时候,把一部分硬盘空间虚拟成内存使用,从而解决内存容量不足的情况。因此,Swap 分区的作用就是牺牲硬盘,增加内存,解决 VPS 内存不够用或者爆满的问题。

Swap 对于Redis来说是非常致命的,Redis保证高性能的一个重要前提是所有的数据在内存中。如果操作系统把Redis使用的部分内存换出硬盘,由于内存与硬盘读写的速度并几个数量级,会导致发生交换后的Redis性能急剧下降。

识别 Redis 发生 Swap 的检查方法如下:

1、查询Redis进程号

```bash
reids-cli -p 6383 info server | grep process_id
process_id: 4476
```

2、根据进程号查询内存交换信息

```bash
cat /proc/4476/smaps | grep Swap
Swap: 0kB
Swap: 0kB
Swap: 4kB
Swap: 0kB
Swap: 0kB
.....
```

如果交换量都是0KB或者个别的是4KB,则正常。

预防内存交换的方法:

- 保证机器充足的可用内存
- 确保所有Redis实例设置最大可用内存(maxmemory),防止极端情况Redis内存不可控的增长
- 降低系统使用swap优先级,如`echo 10 > /proc/sys/vm/swappiness`

## CPU 竞争

Redis是典型的CPU密集型应用,不建议和其他多核CPU密集型服务部署在一起。当其他进程过度消耗CPU时,将严重影响Redis的吞吐量。

可以通过`reids-cli --stat`获取当前Redis使用情况。通过`top`命令获取进程对CPU的利用率等信息 通过`info commandstats`统计信息分析出命令不合理开销时间,查看是否是因为高算法复杂度或者过度的内存优化问题。

## 网络问题

连接拒绝、网络延迟,网卡软中断等网络问题也可能会导致 Redis 阻塞。

## 参考

- Redis阻塞的6大类场景分析与总结:https://mp.weixin.qq.com/s/eaZCEtTjTuEmXfUubVHjew
- Redis开发与运维笔记-Redis的噩梦-阻塞:https://mp.weixin.qq.com/s/TDbpz9oLH6ifVv6ewqgSgA
Loading

0 comments on commit 053c142

Please sign in to comment.