1. 人力家的数据架构演进背景
2018年我们刚开始搭建人力家SaaS平台时,选择了最传统的数仓架构。当时主要考虑的是技术成熟度和团队熟悉度,使用Hadoop+Hive的组合搭建了离线数仓。这套架构支撑了初期业务发展,但随着客户数量突破5000家,日增数据量达到TB级,问题开始显现:
- 凌晨的ETL任务经常跑不完,影响次日报表生成
- 新业务上线需要重新设计数仓模型,迭代周期长达2-3周
- 实时分析需求无法满足,T+1的数据时效性让运营决策滞后
2020年我们首次尝试湖仓一体架构,基于阿里云DataWorks+MaxCompute+OSS的方案。这个阶段最大的收获是实现了存储计算分离,成本降低了40%,但依然存在数据处理链路过长的问题。特别是当客户要求实时查看组织架构变动分析时,从业务系统到报表展示需要经历5-6个环节。
去年我们开始探索湖流一体架构,这也是本文要重点分享的内容。通过OpenLake的新特性,我们终于实现了:
- 原始数据入湖即可用(不再需要预先建模)
- 流批统一处理(同样SQL既能跑实时也能跑离线)
- 事务支持(终于可以放心做UPDATE操作了)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. OpenLake架构的核心设计
2.1 存储层的统一化设计
我们放弃了之前多套存储并存的方案,全面转向阿里云OSS作为统一存储层。这里有几个关键配置点:
xml复制<!-- POM中需要添加的OSS SDK依赖 -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.1</version>
</dependency>
存储格式选择上,经过对比测试我们最终确定:
- 原始数据层:保持CSV/JSON格式(便于问题排查)
- 中间层:Parquet格式(列存压缩比高)
- 服务层:Delta Lake格式(支持ACID)
特别要注意的是OSS生命周期管理配置。我们设置了自动转换规则:
- 热数据(3天内):标准存储
- 温数据(30天内):低频访问
- 冷数据(90天以上):归档存储
这套配置每月为我们节省约15万的存储成本。
2.2 计算引擎的选型考量
在计算层我们采用了Flink+Spark的双引擎策略:
java复制// 流处理作业的典型Flink配置
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.enableCheckpointing(5000); // 每5秒做一次checkpoint
env.getCheckpointConfig().setCheckpointStorage("oss://bucket/checkpoints");
为什么没有选择纯Flink方案?主要考虑到:
- 团队已有大量Spark SQL资产需要复用
- 复杂批处理场景Spark稳定性更优
- Spark 3.0的AQE(自适应查询执行)对数据倾斜处理效果显著
实际运行中,我们通过JindoFS实现计算加速,使得OSS访问延迟从平均200ms降低到50ms以内。
3. 元数据管理的实践细节
3.1 统一元数据服务搭建
我们基于OpenLake的元数据服务做了二次开发,主要扩展了:
- 业务属性标签系统(打标率影响数据发现效率)
- 数据血缘分析(关键报表的完整链路追踪)
- 敏感数据自动识别(身份证/手机号等字段的自动脱敏)
元数据采集采用了混合模式:
python复制# 元数据采集Agent的配置示例
collector = MetadataCollector(
source_types=["MySQL", "Kafka", "OSS"],
scan_interval=300, # 5分钟全量扫描一次
priority_fields=["owner", "biz_domain"]
)
3.2 遇到的挑战与解决方案
在元数据同步过程中,我们踩过两个大坑:
- 海量小文件导致的采集超时
- 解决方案:实现小文件合并策略,超过1000个文件触发合并
- 字段注释缺失问题
- 解决方案:开发注释自动生成工具,基于字段名和样本数据推测
4. 数据治理的关键改进
4.1 质量监控体系
我们构建了三层监控体系:
- 接入层校验(JSON Schema验证)
- 处理过程监控(Flink Metric报警)
- 结果数据核查(Great Expectations规则)
一个典型的质量规则配置:
yaml复制# 员工表数据质量规则
employee_data_checks:
- name: "id_card_valid"
type: "regex_match"
pattern: "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]$"
error_threshold: 0.01
4.2 成本优化实践
通过存储分层和计算资源动态调整,我们实现了:
- 存储成本下降62%
- 计算资源利用率从35%提升到78%
关键措施包括:
- 开发Spark动态资源配置插件
- 实现自动化的冷数据识别
- 建立资源使用看板(按项目/团队核算)
5. 实时能力建设
5.1 流批统一SQL实践
我们基于Flink SQL实现了经典的人力分析场景 - 组织架构变动追踪:
sql复制-- 同样的SQL既能跑批处理也能跑流处理
CREATE TABLE org_changes (
event_time TIMESTAMP(3),
company_id BIGINT,
dept_id BIGINT,
change_type STRING,
WATERMARK FOR event_time AS event_time - INTERVAL '5' SECOND
) WITH (
'connector' = 'kafka',
'topic' = 'org_change_events',
'properties.bootstrap.servers' = 'kafka:9092',
'format' = 'json'
);
-- 流式查询
SELECT
company_id,
COUNT(DISTINCT dept_id) AS changed_depts
FROM org_changes
GROUP BY
company_id,
TUMBLE(event_time, INTERVAL '1' HOUR);
5.2 实时数仓的挑战
在实施过程中,我们遇到的主要问题有:
- 迟到数据处理:配置了允许10分钟的延迟
- 状态数据膨胀:采用TTL状态自动清理
- 端到端一致性:通过阿里云消息队列的事务消息保证
6. 架构演进的关键收获
经过三年三次架构升级,我们总结出三条核心经验:
-
存储统一要彻底:初期我们保留了部分HDFS存储,导致数据流动复杂化。全部迁移到OSS后运维复杂度直降60%。
-
元数据先行原则:任何数据入湖前必须完成元数据注册,这个纪律性要求避免了后期的治理灾难。
-
SQL标准化:坚持所有数据处理都用SQL实现,使得团队技能栈统一,人力培养周期缩短50%。
当前我们正在试验OpenLake的最新特性——物化视图加速。初步测试显示,高频查询的响应时间从平均12秒降低到800毫秒。这个改进有望进一步提升我们的客户体验。
