一个三百台服务器规模的公司,当线上出现故障需要紧急定位某台设备时,运维同学翻了三个Excel表格,又去问了两个同事,二十分钟后才确认机器的物理位置。这不是个例,而是普遍现象。资产检索难的本质,不是没有数据,而是数据没有被结构化、没有被关联、没有被索引。本文从元数据建模和搜索技术两个角度,给出一套可落地的解决方案。

一、为什么资产检索总是那么难
先分析问题的成因。大多数团队的资产数据现状可以用三个词概括:分散、滞后、口径不一。分散指的是信息存放位置五花八门,有的在Excel里,有的在工单系统的备注字段里,有的只存在于某位老员工的记忆里。滞后指的是数据更新不及时,机器下线了台账没改,IP换用了记录没动,久而久之台账和现实脱节。口径不一指的是不同团队记录同一台设备的方式不同,有人叫web-01,有人叫10.0.1.11,有人叫三楼机柜A2,没有一个唯一标识把它们串起来。
这三个问题的共同根源是缺少统一的元数据模型。所谓元数据,就是描述数据的数据,对资产而言,就是用一组规范化的字段来描述每一条资产记录:主机名、IP地址、MAC地址、负责人、所属业务、机柜位置、上架时间、保修到期日等。只有先把描述方式统一起来,后续的检索、统计、告警关联才有基础。
另外要注意,检索难还和使用方式有关。传统的Excel台账只支持精确匹配,而你实际查询时往往是模糊的、多维度的,比如查找三楼机柜上所有负责人是张三且系统是CentOS的机器。这种多条件组合查询,正是搜索引擎擅长的场景。
二、元数据建模:字段设计与标签体系
建模的第一步是确定唯一标识。建议以hostname作为主键,同时强制要求serial_number(设备序列号)字段,因为主机名可能重复或被复用,而序列号是硬件层面天然的身份证。字段设计上可以分为四组:标识类、位置类、归属类、状态类。
- 标识类:hostname、serial_number、ip、mac
- 位置类:idc、room、rack、rack_unit
- 归属类:owner、team、business_system、environment(生产或测试)
- 状态类:status、os_type、cpu、memory、warranty_end
除了固定字段,还应该设计一个标签(tags)体系来承接灵活的分类需求。比如给机器打上redis、高内存、待下线这类标签,后续按标签检索非常方便。字段类型上,标签适合用数组类型存储,配合搜索引擎的聚合能力可以快速做统计分析。
下面是一个用Python定义资产数据结构并写入示例,数据存储采用文档化的JSON格式,方便后续对接搜索引擎:
asset = {
"hostname": "web-01",
"serial_number": "SN2023XYZ001",
"ip": "10.0.1.11",
"mac": "00:1A:2B:3C:4D:5E",
"idc": "北京一号",
"room": "3F",
"rack": "A2",
"rack_unit": "18-19",
"owner": "zhangsan",
"team": "基础架构组",
"business_system": "电商交易",
"environment": "prod",
"status": "running",
"os_type": "CentOS 7.9",
"cpu": 16,
"memory": 64,
"tags": ["nginx", "高流量", "重点保障"]
}
import json
with open("assets.json", "a", encoding="utf-8") as f:
f.write(json.dumps(asset, ensure_ascii=False) + "\n")
这套模型的价值在于:任何一次检索请求,都可以被拆解为若干字段的精确过滤加上关键字模糊匹配,这正是搜索引擎的查询语法。建模完成后,数据从哪里来就成了下一个关键问题。
三、数据自动采集:让台账自己更新
手工维护台账注定会失败,因为人是有惰性的,紧急变更时没人记得先改Excel。正确做法是自动采集加定期核对。采集有几个可靠来源:一是通过SSH或Ansible批量采集主机信息,二是对接云厂商API拉取云主机清单,三是从DHCP或CMDB同步IP分配记录。
用Ansible采集是一个性价比很高的方案,写一个简单的playbook就能批量拿到所有机器的基本信息并汇总成JSON文件。示例playbook如下:
- name: 批量采集主机元数据
hosts: all
gather_facts: yes
tasks:
- name: 收集信息并输出
copy:
content: "{{ ansible_facts | to_nice_json }}"
dest: /tmp/facts.json
delegate_to: localhost
采集程序建议按天定时执行,写入前先做数据校验:必填字段缺失的记录写入异常表人工处理,正常记录直接更新。这样即使某台机器的采集失败,也能通过对比两次采集结果的差异快速发现,避免脏数据进入索引。对于云上资产,通过API定时拉取是最准确的方式,注意处理分页和限流即可。
四、搭建检索服务:三种方案对比与实现
数据结构化之后,检索层的选型有三个方向。第一种是继续用Excel,适合二十台以内规模,成本低但完全没有并发能力和变更审计。第二种是上CMDB平台,比如开源的蓝鲸CMDB,适合中大型团队,功能全面但部署和流程推行成本不低。第三种是自建轻量检索服务,用Elasticsearch做存储和查询,自己写一层简单的API,适合中小团队快速见效。
| 方案 | 适用规模 | 优点 | 缺点 |
|---|---|---|---|
| Excel台账 | 20台以内 | 零成本 | 无并发、易冲突、无审计 |
| CMDB平台 | 百台以上 | 流程完善、功能全 | 部署重、推行难 |
| 自建检索服务 | 几十到千台 | 灵活、上手快 | 需自行维护 |
自建方案的核心是把资产文档写入Elasticsearch。利用其全文检索能力,一个关键字可以同时匹配主机名、负责人、业务系统等多个字段,配合过滤器可以精确缩小范围。下面是索引映射定义和查询示例:
{
"mappings": {
"properties": {
"hostname": { "type": "keyword" },
"ip": { "type": "ip" },
"owner": { "type": "keyword" },
"business_system": { "type": "keyword" },
"rack": { "type": "keyword" },
"tags": { "type": "keyword" },
"os_type": { "type": "text" }
}
}
}
{
"query": {
"bool": {
"must": [
{ "query_string": { "query": "zhangsan" } }
],
"filter": [
{ "term": { "rack": "A2" } },
{ "term": { "tags": "nginx" } }
]
}
}
}
上面的查询含义是:在A2机柜上查找带nginx标签且与zhangsan相关的机器,query_string会自动在多个文本字段里做匹配。如果没有专门的运维人力维护Elasticsearch,也可以退一步用SQLite建表加LIKE查询,几百条数据量级下性能完全够用,关键是数据模型不要妥协。
五、落地建议与常见坑
实施这套体系时,有几个经验值得参考。第一,先治理存量再接入增量,把现有Excel台账清洗一遍,补齐序列号和负责人这两个最常缺失的字段。第二,给搜索入口做减法,提供一个简单的Web页面,输入关键字就能出结果,页面越简单越好,团队才愿意用。第三,把检索服务对接告警,故障时能通过IP反查负责人和业务,价值立刻体现。
常见的坑包括:字段设计过度理想化,一上来定义五六十个字段,结果没人填得全,建议核心字段控制在二十个以内;只写不清,资产下线后记录不删除导致搜出来的结果是过期信息,应该引入status字段标记并定期巡检;以及忽略权限控制,资产数据涉及网络拓扑,检索接口务必加上认证和访问日志。
总结一下,解决资产检索难的路径很清晰:统一元数据模型解决数据规范化,自动采集解决数据时效性,搜索引擎解决查询效率。三者缺一不可,先从把Excel换成结构化存储这一步做起,效果就会明显改善。