云盘不是硬盘,所售即所得

简介: 一般来说,我们可以把排查问题的技术分成三层。底下是理论知识,上边是问题模式【注释1】,夹在理论知识和问题模式之间的是工具。而贯穿排查技术的是“用数据说话”。今天这篇文章,跟大家分享一例我与客户"用数据说话"的故事。

一般来说,我们可以把排查问题的技术分成三层。底下是理论知识,上边是问题模式【注释1】,夹在理论知识和问题模式之间的是工具。而贯穿排查技术的是“用数据说话”。今天这篇文章,跟大家分享一例我与客户"用数据说话"的故事。

“您有问题截图吗?”,“没有,但我能背出来。”

客户直接通过钉钉联系我:“有一个奇葩问题要你看了”。通过简单的沟通,我了解到,客户的业务程序使用一个200G的云盘做数据盘,晚上11点30的时候,业务程序由于不能写入数据而报错。这里关键的问题在于,客户声称当时磁盘并没有用光。

因为踩过不少坑,所以就算是熟客,我还是很专(jing)业(ti)地问了一句,“您有当时问题现场的截图吗?”。客户的回答让我哭笑不得:“没有,但是我能背出来”。接着呢,客户可能觉得口说无凭,就画了下边这张图给我。这里我想说的是,我们平时在跟客户处理问题的时候,总会听到客户各种各样的描述,但是最关键的沟通,还是数据沟通,比如一个报错,或者一个性能截图。然而,客户画一个性能数据给我做,这真的是第一次。

从这张手写的使用情况的截图来看,文件系统vdb1共有197G的可用空间,其中被用掉的空间是186G。这里让人难以理解的地方在于,空间使用率居然已经是100%了。

云盘不是硬盘

要想给客户解释这些“不合理”的数字,我们需要从磁盘的最基本单位说起。不管是云盘,还是传统的硬盘,都是以块为最小单位,进行数据存取的。这一点类似于我们平时读书:数只能一页一页的读,我们只要读到某一页,就能看到一整页的文字。我们没有办法只打开某一行,或者某一个字去读书。一般而言,磁盘块的大小是固定的512个字节。那么,客户购买的200G的云盘,到底是多少个字节呢?

之所以有这个提问,是因为传统的硬件厂商在售卖硬盘的时候,使用的换算单位是1000。也就是说,200G的硬盘应该是200,000,000,000个字节。那么我们卖给客户的200G的云盘,也是这么大吗?其实阿里云在售卖云盘的时候,使用的换算单位是并不是传统的1000,而是1024。有一个简单的办法可以验证这件事情。我们可以读/sys/block/vdb/size文件,得到vdb这个云盘的总块数。以200G云盘为例,我们读到的块数是419430400,每块512字节,那么200G的云盘,实际上是214748364800个字节。【注释2】

分区管理成本

了解了磁盘的最基本单位之后,我们眼中的磁盘,差不多就变成下边这个样子了:一块磁盘由若干个512字节的块组成。

然而,习惯上我们不会直接的,从第一块到最后一块这样去使用磁盘。我们要先对磁盘进行分区。客户的200G数据盘只有一个分区,所以分区之后大概是下边这样的。前边的黑色块是分区管理成本。这部分应该首先从可用空间中减掉。客户的数据盘中,分区管理成本是1M。

 文件系统管理成本

分区之后,我们需要在分区之上,创建文件系统。文件系统是我们可以直接使用的存取数据的方式。在分区之上创建文件系统,有点类似于我们拿到一个空白的笔记本,对笔记本的使用做一些简单的规划,其中一部分用来写日记,一部分做计算等,然后根据不同的用途,编写一个目录。这里的“目录”,是文件系统的管理成本。这部分内容,也是需要从可用空间中减掉的。对于Linux文件系统来说,这部分开销最主要是inode结构。如下图,vdb1这个文件系统一共有13107200个inode,每个inode256个字节。那么这部分成本是不能忽略的一部分成本:3.125G。【注释3】

问题重现了一半

减掉分区成本和文件系统成本,200G的云盘,可用的空间就剩下197G了。这与Size的值相匹配。但这显然不能解释,为什么只用掉186G,空间使用率就到100%了。在百思不得其解之后,我决定自己动手试试,看能不能跑出客户看到的问题。我申请了一个云服务器,挂载了一个200G的云盘,然后连续创建1G大小的空白文件。在跑了大概30分钟以后,我看到下边的结果。结果证明,客户当时应该是真的看到了他手写的那个数据。

但是,当我尝试继续往磁盘里写空白文件的时候,我并没有看到客户所说的,磁盘空间不足的报错,直到197G被全部用完为止。

工具df不生产数据

所有的秘密都藏在工具df里。工具df可以用来查看磁盘的容量以及剩余空间,但是就像Linux上很多其他工具一样,df并不会凭空的产生数据。df命令使用系统调用从内核拿到数据,然后加工并把相对可读的信息提供给用户。研究df的行为,我们可以使用strace。用strace追踪df的执行过程,我们发现与磁盘容量相关的数据均来自于系统调用statfs。

下边这条记录,是在重现环境中抓的。我们可以看到,statfs以文件系统挂载路劲为输入,输出一个包含此文件系统统计信息的结构体。

statfs("/mnt", {f_type=EXT2_SUPER_MAGIC, f_bsize=4096, f_blocks=51572986, f_bfree=2557603, f_bavail=0, f_files=13107200, f_ffree=13107176, f_fsid={3186720966, 3846989262}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0

在这个结构体中,f_bsize记录的是文件系统的块大小,这个和磁盘块大小是类似的概念。可以看到文件系统的块大小是4K,也就是说,1个文件系统块,需要使用8个磁盘块。f_blocks是文件系统总块数,df输出的文件系统的Size就是从这个值计算而来。

而跟这个“奇葩”问题相关的,是f_bfree和f_bavail这两个值。这两个值从命名来看都可以解释为可用空间,但意义却大不一样。根据定义,f_bfree是文件系统的可用块数,这个值是df输出的Size和Used的差值。而f_bavail,是“非特权”用户的可用块。Linux在创建文件系统的时候,会预留一部分磁盘空间,专门给root使用,默认情况下,这部分空间是磁盘空间的5%。f_bavail记录的是,从非特权用户视角看,磁盘的可用空间。

明白了上边几个数据项的含义之后,这个问题就变得很清楚了。之所以Used才到186G的时候,空间使用率就已经到了100%,是因为df计算使用率,用的是f_bavail,而不是f_bfree。换句话说,df使用的是非特权用户的视角。因为客户业务进程使用的并不是root账户,所以业务进程在使用到186G的时候报出磁盘空间不足的错误就不足为奇了。

大图

最后我们来看一下大图。200G的云盘,分区和文件系统,会用掉3G的管理成本。剩下197G就是df输出的Size值,也就是真正的可用磁盘空间。因为文件系统会预留5%的空间给特权用户使用,这大概是10G,所以对非特权用户来说,可用空间需要再减掉10G,所以大概就剩187G。

后记

在排查问题的过程中,我们必然会用到各种各样的数据和指标,毫不夸张地说,我们分析问题,解决问题的过程,就是收集数据,研究数据,以及使用数据和客户沟通的过程。而基础排查和进阶排查的一个最很重要的区别,就是我们能不能从数据本身出发,一层一层深入到数据产生的源头当中去,深入到加工数据的代码当中去,理解数据产生的原因。以今天这个问题为例,当我们弄清楚磁盘容量这些指标的计算方法之后,这个问题就变得非常的简单,但是,如果我们不能这样一步一步的深入去探究,那么这个问题就是显得奇葩而不可解释。

 

  • 注释1:问题模式这个概念和设计模式类似。设计模式是最佳实践,是软件开发领域,典型问题和经典解法的总结。而问题模式,也是类似的概念。当我们处理过大量问题之后,会自然而然的遇到一些典型的重复的场景,当然也会使用一些重复的处理方法。

  • 注释2:云盘和硬盘换算单位的差别,严格来说,是GiB和GB的差别。云盘使用的是GiB,而硬盘使用的是GB。但是使用中我们比较少对这两者做区分。

  • 注释3:文件系统还有其他一些管理开销,比如superblock等,因为占比很小,这里忽略掉了。

目录
相关文章
|
数据采集 机器学习/深度学习 数据挖掘
【机器学习4】构建良好的训练数据集——数据预处理(一)处理缺失值及异常值
【机器学习4】构建良好的训练数据集——数据预处理(一)处理缺失值及异常值
1373 0
|
8月前
|
存储 测试技术 调度
阿里云服务器2核8G、4核16G、8核32G怎么选实例?经济型、通用算力型和通用型对比与选购策略
2026年截止目前,阿里云的活动中2核8G、4核16G、8核32G配置主要有经济型e、通用算力型u2a、通用型g9i实例可选。2核8G配置最低701.40元1年,4核16G配置最低1291.80元1年,8核32G配置最低7551.94元1年。本文介绍经济型e、通用算力型u2a及通用型g9i实例的活动价格与实例规格差异及选购策略。
|
9月前
|
存储 弹性计算 人工智能
租用阿里云服务器一年要多少钱?阿里云ECS、轻量与 GPU 服务器最新价格总结,手动整理
租用阿里云服务器一年要多少钱?轻量应用服务器 200M 高带宽依旧最低 38 元/年起(限时秒杀),ECS 经济型实例 2 核 2G 仅 99 元/年、2 核 4G 实例 199 元/年。更高配置如 4 核 16G 仅 89 元/月、8 核 32G 仅 160 元/月。海外用户可选香港轻量,25 元/月起,新老用户均可购买,续费同价,无隐藏涨价。手动整理了阿里云ECS、轻量与 GPU 服务器最新价格,仅供参考。
|
12月前
|
SQL 人工智能 Java
30分钟轻松掌握Cursor,快速提升开发效率和体验
本文通过在WebX老项目中实践,验证了Cursor利用AI大模型可高效生成符合老旧项目规范的代码框架,显著提升开发效率与体验。
30分钟轻松掌握Cursor,快速提升开发效率和体验
|
7月前
|
人工智能 IDE Shell
Cursor1.7 发布,AI 编程的含金量还在上升!
Cursor 1.7 正式发布!新增智能体级自动补全、可编程Hooks、团队共享Rules、提示词深度链接、菜单栏Agent状态监控、图像文件上下文支持,以及Windows PowerShell终端原生适配,大幅提升AI编程的智能性、可控性与协作效率。(239字)
363 2
|
缓存 NoSQL 中间件
Redis,分布式缓存演化之路
本文介绍了基于Redis的分布式缓存演化,探讨了分布式锁和缓存一致性问题及其解决方案。首先分析了本地缓存和分布式缓存的区别与优劣,接着深入讲解了分布式远程缓存带来的并发、缓存失效(穿透、雪崩、击穿)等问题及应对策略。文章还详细描述了如何使用Redis实现分布式锁,确保高并发场景下的数据一致性和系统稳定性。最后,通过双写模式和失效模式讨论了缓存一致性问题,并提出了多种解决方案,如引入Canal中间件等。希望这些内容能为读者在设计分布式缓存系统时提供有价值的参考。感谢您的阅读!
607 6
Redis,分布式缓存演化之路
|
存储 网络协议 编译器
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
1429 14
|
人工智能 JavaScript 开发工具
Awesome Tools,程序员常用高效实用工具、软件资源精选,办公效率提升利器!
Awesome Tools,程序员常用高效实用工具、软件资源精选,办公效率提升利器!
1114 0