美团 Flink 实时路况计算平台全链路架构揭秘

📌 一、背景:为什么自建路况平台?

虽然我们集成了高德等地图 SDK,但它们存在以下问题:

  • ❌ 不掌握算法细节,无法精细调优
  • ❌ ETA 偏差大:地图预估 vs 实际轨迹
  • ❌ 高频区域拥堵/施工无法快速更新
  • ✅ 所以我们自研了 Flink 实时路况平台

支撑美团外卖、买菜、闪购、配送等 每日亿级路径调用请求


📌 二、系统整体架构(图示)

📦 三、核心模块详解

✅ 1. Kafka轨迹接入

轨迹数据通过 GPS SDK 统一上报,每条数据结构如下:

json 复制代码
{
  "riderId": "A1234",
  "timestamp": 1717481200,
  "lat": 23.123456,
  "lng": 113.123456,
  "speed": 11.4,
  "direction": 87,
  "orderId": "O99887"
}

✅ 2. Flink清洗作业(实时)

Flink ETL Job 示例(Scala + CEP):

scala 复制代码
val gpsStream: DataStream[GPSPoint] = source
  .keyBy(_.riderId)
  .filter(_.speed < 60) // 过滤异常速度
  .assignTimestampsAndWatermarks(...) // 乱序容忍

val validPoints = gpsStream
  .process(new FilterNoiseGPSFunction)

✅ 3. 轨迹切片 + 网格映射

  • 每 30s 为一个轨迹切片
  • 切片转为 LineSegment,进行网格匹配
  • 我们将全国划分为 30m x 30m 的小网格,每个网格状态独立维护
scala 复制代码
val gridId = s"${(lat * 1000).toInt}_${(lng * 1000).toInt}"

Flink Job 的核心逻辑伪代码:

scala 复制代码
class TrafficAggregator extends KeyedProcessFunction[String, GPSPoint, TrafficStat] {
  lazy val speedState = getRuntimeContext.getState(
    new ValueStateDescriptor[List[Double]]("speeds", classOf[List[Double]])
  )

  override def processElement(point: GPSPoint, ctx: Context, out: Collector[TrafficStat]) = {
    val speeds = speedState.value() :+ point.speed
    speedState.update(speeds.takeRight(20))

    val avg = speeds.sum / speeds.size
    val level = if (avg < 5) "拥堵" else if (avg < 15) "缓慢" else "畅通"

    out.collect(TrafficStat(point.gridId, avg, level))
  }
}

📂 四、状态管理与容错

  • 所有网格状态使用 RocksDB 存储
  • 开启增量 Checkpoint,每分钟一次,约 1.3 秒完成
  • 使用 异地备份(HDFS),支持任务挂掉后快速恢复
conf 复制代码
state.backend: rocksdb
state.checkpoints.dir: hdfs:///meituan/flink/checkpoints
state.savepoints.dir: hdfs:///meituan/flink/savepoints

🔁 五、输出服务与查询系统

接口服务设计:

http 复制代码
GET /traffic/grid?lat=23.1&lng=113.1
→ 返回 {"gridId": "23123_11312", "speed": 12.3, "level": "缓慢"}
  • 实时路况用于 ETA 模型、路径规划引擎、调度器等组件
  • 支持地铁封闭、高架施工、天气数据融合

📈 六、实战效果与性能指标

指标 数值
Flink 并发任务数 280 个 SubTask
每日轨迹数据 24 亿条+
平均处理延迟 2.4 秒
状态快照大小 6.1 GB / checkpoint
实时路况命中率提升 32.8%(对 ETA 准确性)

🔍 七、实际使用场景(美团内部)

使用组件 使用方式
ETA 模型 路况等级作为特征 + 平均速度值
派单系统 拥堵区域降低配送密度
用户端地图 动态展示配送员状态(是否拥堵)
闪购/买菜智能分仓 基于通行速度判定仓到小区效率

💡 工程挑战总结

问题 解决方案
GPS 漂移 + 地图不匹配 自研轨迹纠偏引擎 + 路网融合算法
延迟波动大 引入异步 IO sink + task chaining
网格状态过多 热区分层存储,冷热分区拆表
同一 rider 多地反复出现 状态独立分流 + session 归并逻辑

✅ 总结

"路况系统是一切智能调度的前提,Flink 给了我们实时性、状态一致性和计算弹性,让平台站上了 ETA 精度的制高点。"

相关推荐
teeeeeeemo4 分钟前
Number.toFixed() 与 Math.round() 深度对比解析
开发语言·前端·javascript·笔记
why1518 分钟前
6.15 操作系统面试题 锁 内存管理
后端·性能优化
阿珊和她的猫25 分钟前
`toRaw` 与 `markRaw`:Vue3 响应式系统的细粒度控制
前端·javascript·vue.js·typescript
网络点点滴27 分钟前
探索 Vue 替代方案
前端·javascript·vue.js
丘山子33 分钟前
如何确保 Go 系统在面临超时或客户端主动取消时,能够优雅地释放资源?
后端·面试·go
武子康36 分钟前
Java-52 深入浅出 Tomcat SSL工作原理 性能优化 参数配置 JVM优化
java·jvm·后端·servlet·性能优化·tomcat·ssl
OnlyLowG1 小时前
SpringSecurity导致redis压力大问题解决
后端
深栈解码1 小时前
OpenIM 源码深度解析系列(十四):事件增量同步机制解析
后端
想用offer打牌1 小时前
一站式了解CDN😈
后端·架构·cdn
江城开朗的豌豆1 小时前
Vue的keep-alive缓存揭秘:多出来的生命周期怎么玩?
前端·javascript·vue.js