一个普通健身爱好者每年产生约2.3GB健康数据,但99%的人从未真正用过。苹果健康、Strava、MyFitnessPal各自为政,你想知道「睡得好的时候训练表现是否更好」,得手动翻三个App做笔记。这不是技术问题,是数据工程问题。
有人把这套流程跑通了:用InfluxDB做时序数据库,Python写ETL管道,Grafana搭仪表盘,全部塞进Docker。成本?一台树莓派的电费。
第一步:承认你的数据是「孤岛」
量化自我运动搞了十五年,硬件厂商赚得盆满钵满,数据互通却像冷战时期的柏林。苹果健康导出的是XML,Strava给的是嵌套JSON,MyFitnessPal连官方API都没有,只能爬网页。
这像极了企业里的数据部门:每个业务系统都有自己的方言,BI报表永远滞后两周。个人用户的好处是船小好调头——你不需要说服六个部门开会,一台笔记本就能开工。
Docker Compose配置三行核心服务:InfluxDB占8086端口存原始数据,Grafana占3000端口做可视化,中间用Python脚本当翻译官。初始化时设好组织名、桶名、Token,后面所有数据都往这一个口子灌。
关键设计:InfluxDB选2.7版本而非1.x,因为Flux查询语言对时间窗口操作更友好。你想算「过去30天平均静息心率」,一行查询搞定,不用写嵌套SQL。
第二步:ETL是脏活,但必须有人干
Apple Health的XML导出是个噩梦。有人跑了三年数据,文件体积膨胀到4.7GB,解析时内存直接爆掉。解决方案是流式处理:用Python的xml.iterparse逐行读,而不是一次性load进内存。
Strava的API相对文明,但嵌套结构需要拍平。一次骑行记录包含GPS轨迹、分段成绩、设备信息,你通常只关心「日期、距离、爬升、平均功率」四个字段。Python的pandas.json_normalize在这里是救命工具。
MyFitnessPal最麻烦。官方2018年关了API,现在只能靠selenium模拟登录抓网页。反爬机制不算严,但你需要处理动态加载和偶尔的验证码。有人选择妥协:手动导出CSV,每月跑一次批量导入。
数据清洗的脏活还包括时区统一。苹果用本地时间,Strava存UTC,MyFitnessPal看服务器心情。ETL脚本里必须显式声明tzinfo,否则跨天统计会错八小时。
第三步:InfluxDB的「桶」哲学
时序数据库的设计跟关系型数据库完全不同。MySQL思维是「先建表定义schema」,InfluxDB是「先写数据,schema自动推断」。这对个人项目极其友好——你今天只想记体重,明天突然想加血酮值,不用alter table。
核心概念就三个:Bucket(桶,类似数据库)、Measurement(测量值,类似表)、Field(字段)和Tag(标签)。举个例子:
Measurement叫"body_metrics",Field存"weight_kg"数值,Tag存"source: withings_scale"来源标记。查询时可以用Tag过滤,但Field不能索引——所以设计时要想清楚什么常用来筛选。
个人数据湖建议:按数据源分Measurement,而不是按指标类型。这样某天的Apple Watch心率异常,你能快速定位是设备问题还是真·身体报警。
保留策略也得设。默认数据永久保存,但心率这种高频数据(每秒一个点)三年就能占几十G。InfluxDB支持按桶设置自动过期,比如「raw_hr保留90天,聚合后的日平均保留5年」。
第四步:Grafana的「任务控制中心」美学
开源社区有个不成文规矩:个人项目的仪表盘要看起来像NASA发射中心。Grafana的InfluxDB数据源配置简单到离谱:填URL、选Flux查询、贴Token,三分钟出图。
但真·价值在于关联查询。你可以把「昨晚睡眠评分」和「今早5公里配速」画在同一张图,时间轴对齐。苹果健康App做不到这个——它的关联分析只给预设好的「步数vs心率」之类组合。
进阶玩法是用Grafana的Alerting。静息心率连续三天高于基线10%?推送到Telegram。体重七天无记录?发邮件提醒。这套规则完全自定义,比任何商业健康App的「智能建议」都贴合你的实际目标。
有人甚至接了家里的智能秤:称重数据实时进InfluxDB,Grafana面板显示「距目标体重还差X公斤,按当前趋势预计Y周达成」。这比薄荷健康App的弹窗广告体验好十倍。
第五步:当数据足够多,你会发现奇怪的事
跑通这套系统三个月后,多数人会有个共同发现:某些「常识」在自己身上不成立。比如「睡够8小时表现更好」——有人数据里显示7小时睡眠日的训练功率反而更高,深入查发现那阵子他戒了睡前酒精。
这就是个人数据湖的真正价值:不是验证大众结论,是发现你自己的N=1规律。商业App不敢做这个,因为法律责任太大。但你自己跑的数据,自己承担解释责任。
技术债也存在。某个周末Strava改版,API返回字段改名,ETL脚本报错三天才发现。MyFitnessPal的网页结构每月微调,selenium选择器要跟着改。这是自托管的代价——没有SRE团队,你自己就是on-call。
但相比数据锁死在云端、导出格式乱七八糟的替代方案,这点维护成本可以接受。至少你的五年心率数据存在本地SSD,而不是某家公司的服务器上,随账号注销一起消失。
现在有个问题留给你:如果你能把过去三年的所有健康数据放进一张图,你最想验证的假设是什么?是咖啡因摄入与深度睡眠的关系,还是月经周期对训练表现的影响?答案可能让你重新考虑,哪些数据值得现在开始认真收集。
热门跟贴