语言艺术

7/9/2023

密码:mianshi

# 业务是什么

  • 为了提高车友圈的活跃度,增加与车主的互动,提高用户体验。解析车辆数据,对行程数据进行清洗解析计算,最终展示给车主一份出行报告。
  • 报告会展示行程内的诸多统计信息【空调使用时长,温度次数,常用温度,低速行驶里程,低速行驶时间,挡位计算,急加减速,急转弯,倒车耗时,百公里电耗/油耗,途径城市,常驻城市】。

# 业务痛点

  1. 用户覆盖面小,导致车友圈存量用户较少,活跃度不高,且增量用户增长速度慢
  2. 数据不准,影响用户体验,容易遭到车主投诉【车主行程程统计问题(id重复,不全);行程指标值不准gps定位到非洲;反压,导致的数据计算不过来】

# 痛点思考

  • 使用数据时间作为水印,但因为数据质量问题,导致相当部分的数据无法正常产生水印,让任务水印无法正常增长,最终影响任务执行。
  • 同时,因为使用窗口,当它们组合使用的时候,会因为迟到时间的问题导致数据被抛弃,进而导致指标和行程计算不准,也影响到车友圈增量用户数量增长。
  • 然后,数据不准分为:行程不准,指标不准,反压导致更新不及时
    • 行程不准:一份是由于数据被抛弃导致的,另一个原因是,一个用户id对应了多辆车,然后用户发现明明只开了一辆车,但却有多辆车的形成报告,所以需要对对用户退出和切换这类场景做处理。
    • 指标不准:基本就是数据被抛弃导致的
    • 更新不及时:主要由于没有针对特定的数据场景使用恰当的连接方式,导致产生大量且高频次的外部交互【电池系数,实时获取gps对应位置信息(根据gps获取城市编码,再根据城市编码获取省市区信息)】。

# 解决思路

  • 更改为kafka时间作为水印,被抛弃窗口的使用,这样做有好几个好处:

    • 可以覆盖所有车辆数据,不会因为迟到时间的问题,导致数据被抛弃。
    • 下游使用keyProcess时,可以自定义数据时间的状态数据,结合kafka时间,让车辆数据全部进入到行程的计算逻辑中,更加灵活的应对更多场景下的行程结束【比如:数据质量好,通过kafka时间判断超时事件,但数据质量差的时候,可以依赖数据时间来判断超时事件】。
    • kafka的ttl时间是7天,可以很方便的根据kafka时间重跑数据
  • 使用keyCoProcess算子,这个算子可以实现规则数据和业务数据的关联,这样就很容易识别出用户的登录,退出和切换行为,避免一个用户对多车的问题,同时再结合首次读取全量数据库+后续读取kafka增量数据的方式,降低了访问数据库的频繁,减轻了数据库压力。

以上的方法可以解决行程不准和指标不准这类的偏功能性方面的问题,像反压更新慢的问题,需要对数据流方案和代码设计上进行优化

  • 电池系数和位置信息这类的需要外部交互的维度数据,根据数据实际使用场景,可以分为2种:
    • 日更新数据:采用了广播流的方式读取,一次加载,一直能用,后续更新只需要指定好定时器即可
    • 实时更新数据:则根据实际业务情况分别使用了3种解决方式:
      • 数学算法【射线法】,可以将原本需要访问接口的逻辑,改为内存计算,降低与外部交互频次。
      • 异步访问:采用异步方式(这种用于最后的结果数据)
      • 第三种就是刚刚说的全量+增量方式(这种用于明细数据,当数据库负载高的时候,可以考虑使用)

# PS

除了以上针对痛点的解决思路,还有其他方面的优化思路。例如:车辆信号数据采集被写死了,无法配置化,每次都需要重启任务。
我采用的解决方案是【规则表+广播的方式】,定时读取表数据,广播发送到下游,后面如果需要配置信息,直接添加表记录就可以了。
另外,在之前实际工作中,发生了gps定位到非洲的问题,因为用户的gps经纬度全是0,当时我只改了配置表中的gps阈值,就自动修复了,很方便快捷。
还有信号的一对多情况【例如速度值在不同车型车系时,会有不同的信号code值与之对应】,我也是采用这种方式来解决的。

从高德的接口获取行政区域边界经纬度 (opens new window)

Last Updated: 6/1/2024, 6:36:28 AM