这是一个非常好的问题。在现代软件开发(尤其是 DevOps、云原生、配置管理)中,YAML 和 JSON 是两座绕不开的大山。
以下是关于 YAML 的历史、它解决的痛点,以及与 JSON 的深度对比。
一、 YAML 的历史:从“另一种标记语言”到“关注数据”
1. 起源 (2001年)
YAML 诞生于 2001 年,由 Clark Evans、Ingy döt Net 和 Oren Ben-Kiki 共同设计。那个年代,互联网数据交换的霸主是 XML。
2. 名字的演变
这是一个有趣的递归缩写故事:
-
初期:YAML 代表 "Yet Another Markup Language"(另一种标记语言)。这是设计者的一种自嘲,因为当时市面上充斥着各种标记语言。
-
后期:为了强调它的核心价值是“数据”而非“文档格式化”,名字被改为 "YAML Ain't Markup Language"(YAML 不是标记语言)。
3. 核心理念
设计者希望创造一种**“以人为本”**的数据格式。他们认为 XML 虽然机器能读,但对人类来说太繁琐(太多的尖括号 < > 和闭合标签)。他们深受 Python(缩进风格)、Perl 和 MIME 标准的影响,最终创造了 YAML。
二、 YAML 解决了什么痛点?
YAML 的出现主要为了解决当时 XML 和早期数据格式存在的三个核心痛点:
1. 痛点一:配置文件的可读性差 (XML 之痛)
在 YAML 之前,如果你要写一个服务器配置文件,可能得写 XML:
<server>
<port>8080</port>
<enable_logging>true</enable_logging>
</server>
这种格式写起来累,读起来眼花。
YAML 的解决方案:去除所有括号和标签,使用缩进表示层级(像 Python 一样)。
server:
port: 8080
enable_logging: true
一目了然。
2. 痛点二:缺乏注释 (JSON 之痛)
JSON 虽然比 XML 简洁,但 JSON 标准不支持注释。
这对于“数据交换”没问题(机器不需要看注释),但对于**“配置文件”**来说是致命的。运维人员需要写下“为什么要把端口改成 8080”的备注,JSON 做不到。
YAML 的解决方案:原生支持 # 注释。
3. 痛点三:数据冗余 (重复引用)
在复杂的配置中,某些数据可能重复出现(例如多个服务使用相同的数据库配置)。在 JSON 中,你必须复制粘贴。
YAML 的解决方案:引入了 锚点 (Anchors, &) 和 别名 (Aliases, *),允许在文件内部引用变量,实现 DRY (Don't Repeat Yourself)。
三、 YAML vs JSON:全面比较
虽然 YAML 1.2 标准是 JSON 的超集(即所有合法的 JSON 文件也是合法的 YAML),但它们在实际应用中有着截然不同的性格。
1. 语法与可读性
-
JSON:符号导向。充斥着大括号
{}、中括号[]、双引号""和逗号,。对机器解析非常友好,不容易出错,但人类书写时容易漏掉逗号或引号。 -
YAML:缩进导向。使用空格(严禁 Tab)缩进,没有括号。非常干净,像一份清单。
- 胜出者:YAML(在人类阅读方面)。
2. 注释支持
-
JSON:不支持(标准 JSON 不支持,虽然有些变体如 JSON5 支持,但通用性差)。
-
YAML:支持
#注释。- 胜出者:YAML(作为配置文件时)。
3. 数据类型与功能
-
JSON:只有基础类型(字符串、数字、布尔、数组、对象、Null)。
-
YAML:功能极其强大。
-
支持复杂类型(如日期时间
2025-12-09会自动解析为 Date 对象)。 -
支持二进制数据。
-
支持锚点与引用(复用数据)。
-
支持多文档(一个文件里可以用
---分隔多个 YAML 文档,K8s 常用此特性)。 -
胜出者:YAML(功能性)。
-
4. 解析性能与安全性
-
JSON:极快,极安全。因为语法简单,解析器不需要复杂的逻辑。所有现代编程语言都有内置的高性能 JSON 解析库。
-
YAML:慢,且有安全隐患。
-
YAML 极其复杂(规范文档有 80 多页)。解析 YAML 比解析 JSON 慢通常一个数量级。
-
安全陷阱:某些语言的 YAML 解析器(如 Python 的 PyYAML)默认允许实例化任意对象,这可能导致远程代码执行漏洞。
-
类型陷阱 (The Norway Problem):这是 YAML 最著名的梗。如果你在 YAML 里写国家代码
NO(挪威),老版本的 YAML 解析器会把它识别为 Boolean False (No = False),导致数据错误。你必须写成字符串"NO"。 -
胜出者:JSON(在机器交互方面是绝对霸主)。
-
四、 直观对比示例
假设我们要配置一个 Web 服务:
JSON 格式
{
"name": "My Service",
"version": 1.0,
"dependencies": [
"database",
"cache"
],
"server": {
"host": "localhost",
"port": 8080
}
// 无法添加注释,无法复用 host 配置
}
YAML 格式
# 服务基本信息
name: My Service
version: 1.0
# 定义一个公共的基础配置 (锚点)
base_config: &base
host: localhost
timeout: 30s
# 依赖列表
dependencies:
- database
- cache
server:
<<: *base # 引用上面的 base_config,自动合并 host 和 timeout
port: 8080 # 覆盖或新增配置
五、 总结:该选谁?
| 维度 | JSON | YAML |
| :--- | :--- | :--- |
| 核心定位 | 数据交换 (Data Interchange) | 配置管理 (Configuration) |
| 主要用户 | 机器 (API, 数据库) | 人类 (DevOps, 开发者) |
| 典型场景 | REST API, 前后端交互, 日志格式 | Kubernetes, Docker Compose, Ansible, CI/CD |
| 优点 | 解析极快,规范严格,无歧义,安全 | 易读易写,支持注释,支持数据复用 |
| 缺点 | 读写繁琐,不支持注释 | 解析慢,规范过于复杂,存在类型推断坑 |
一句话建议:
-
如果是 系统之间 传数据(例如 API 接口),绝对选 JSON。
-
如果是 人写给机器看 的文件(例如项目的配置文件、部署脚本),首选 YAML。