背景
产品经理想要实时查询一些指标数据, 在新版本的 App 上线之后, 我们 App 的一些质量指标, 比如课堂连接掉线率, 课堂内崩溃率, App 崩溃率等指标, 以此来看 App 升级之后上课的体验是否有所提升, 上课质量是否有所提高, 为下一步的 App 升级做准备.
客户端埋点
1.0 版本设计
流程
按照需求打点, 如果想知道某一指标如进入教室成功率, 点击进入教室这一动作上报数据, 进入教室结果上报数据, 同时上报课程 id, 用户 id 等属性.
缺点
埋点规范全靠 Excel, 产品经理编写 Excel 埋点文档, 开发按照文档埋点, 测试按照文档测试. 出现如下几类问题,
产品经理埋点文档编写失误, 漏埋点, 埋点关键字错误, 上报字段值不明确等;
埋点开发者打错上报关键字, 如 device 打错成 devcie, 上报值使用全角输入法, 时间戳未按照规范上报成毫秒.
测试人员, 不重视测试环节, 只是粗略看下埋点是否存在, 并未进行埋点质量的测试.
大数据开发进行数据清洗落地时, 遇到未按照 JSON 格式上报的脏数据, 由于上报值不规范, 很多数据增加了清洗的难度和不确定性.
优点
整个流程跑起来了, 有些计算指标具有参考意义.
2.0 版本设计
规范埋点上报
经过调研, 我们 2.0 采用 Protobuf 数据格式上报, 并封装成统一埋点 SDK, 一方面可以定义枚举值, 解决上报值和关键字不规范的问题. 上报的信息进行归类, 简洁明了. 我们定义了三种数据结构:
基础信息
- message BaseInfo {
- // 系统上报时间戳 - 毫秒 (由银河服务端生成)
- int64 sysTime = 1;
- // 客户端上报时间戳 - 毫秒
- int64 time = 2;
- // 会话 Id, 一段会话的唯一标识 (客户端每次启动 App 到下一次启动 App 之间生成一个会话 id)
- // 生成规则: 16 位随机数 + 13 位时间戳 + 3 位 (端表示 pc:001 Android:002 iOS:003 web:004 server:005)
- string sessionId = 3;
- // 设备唯一标识
- string uuid = 4;
- // 公司标识
- Company company = 5;
- //sdk 版本
- SDKVersion sdkVersion = 6;
- // 用户 ID
- string userId = 7;
- // 用户类型
- UserType userType = 8;
- // 日志类型
- LogType type = 9;
- string eventId = 10;// 事件 ID (产品经理提供)
- NetType netType = 11;// 网络类型
- OperatorType operatorType = 12;// 网络运营商类型
- int32 requestCnt = 13;// 接口请求次数, 默认为 1
- string business = 14;// 业务类型 (产品经理提供)
- // 来源: 安卓, iOS,pc,Web,server
- Os os = 15;
- string channel = 16; // 渠道来源 (针对前端的落地页 url 编码, H5 商城的来源渠道)
- //App 版本号
- string appVersion = 17;
- //App 类型: yimi/bubugao/yuxuepai
- string appType = 18;
- // 设备型号, 标示手机品牌 + 型号
- string deviceInfo = 19;
- // 设备操作系统版本号
- string osVersion = 20;
- AppAction appAction = 21;
- // 信息, 崩溃信息
- string info = 22;
- int64 stayTime = 23; // 页面停留时间
- }
教室内信息
- message LiveInfo {
- // 课程 id
- string lessonId = 1;
- // 课程类型
- LessonType lessonType = 2;
- // 服务器 IP
- string serverIp = 3;
- // 用户 ip
- string userIp = 4;
- }
其他信息
- message ExtraInfo {
- // 额外字段 key
- string key = 1;
- // 额外字段 value
- string value = 2;
- }
埋点元数据界面
基于 1.0 的一些缺点, 我们进行了改造, 开发了一个埋点元数据录入的界面, 产品经理只需要在上面录入想要的埋点, 规范上报值. 开发者和测试者都可以在这个界面查看埋点的信息.
埋点测试流程规范
重新规划了埋点的测试流程, 粗略流程如下
后端架构设计
CarbonData
Apache CarbonData 是一种新的融合存储解决方案, 利用先进的列式存储, 索引, 压缩和编码技术提高计算效率, 从而加快查询速度. 其与 Spark 紧密结合, 而我们公司的技术栈也包含 Spark, 经过测试查询性能确实优秀, 遂决定使用此组件.
社区 BUG
在测试的过程中, 由于想使用新版的 Spark, 所以使用了 Spark2.3+CarbonData1.5 的组合, 但是在入库的时候, 发现了一个 bug,Spark Streaming 无法实时写入表, 社区对此 bug 至今也没有解决. 所以只能决定使用 Spark 2.2+CarbonData1.5.
实时入库
CarbonData 表结构设计
- CREATE TABLE IF NOT EXISTS carbon.dw_flow_disc_analyze_daily (
- pt string,
- lesson_id string,
- app_version string,
- user_type string,
- app_device_type string,
- server_ip string,
- event_type string,
- err_msg string,
- msg_type string,
- galaxy_type string,
- sys_time string,
- app_type string,
- lesson_type string,
- result string,
- crash_type string,
- crash_msg string,
- down_load_result string
- )
- STORED AS carbondata
- TBLPROPERTIES (
- 'DICTIONARY_INCLUDE'='pt,lesson_id,server_ip,app_version,app_device_type,user_type,event_type,err_msg,msg_type,galaxy_type,app_type,lesson_type,result,crash_type,down_load_result,crash_msg',
- 'BAD_RECORD_PATH'='hdfs://bd-tst/apps/carbon/badrecords',
- 'INVERTED_INDEX' = 'lesson_id',
- 'sort_columns'='pt,lesson_id',
- 'SORT_SCOPE'='GLOBAL_SORT',
- 'RANGE_COLUMN'='pt',
- 'streaming'='true');
参照 CarbonData 的官方文档和例子, 开发 Spark Streaming 程序, 消费日志数据实时入库.
OLAP
启动 Spark ThriftServer
nohup /opt/spark/spark-2.2.3/bin/spark-submit --master spark://bd-prod-master01:7077,bd-prod-master02:7077 --conf spark.sql.hive.thriftServer.singleSession=true --deploy-mode client --num-executors 4 --executor-memory 2g --executor-cores 2 --total-executor-cores 8 --class org.apache.carbondata.spark.thriftserver.CarbonThriftServer /opt/spark/spark-2.2.3/carbonlib/apache-carbondata-1.5.2-bin-spark2.2.1-hadoop2.7.2.jar hdfs://bd-prod/apps/carbon/warehouse>/dev/null 2>&1 &
JDBC 连接查询
明细数据入库之后, 使用 jdbc 连接 Spark ThriftServer, 对指标进行实时聚合.
总结
优点
实时入库, 新版本 App 上线后可以立刻看到买点数据;
SQL 灵活性高, 可进行 JOIN, 条件可随意定制;
查询速度快, 一个月之内的报表数据可在 30s 之内返回.
缺点
耗费资源比较严重, 需要创建索引, 需要的 spark 内存比较大, 资源充足可忽略;
与 Spark 强耦合, 不能使用 Flink 入库;
社区不活跃.
来源: https://www.cnblogs.com/ChouYarn/p/11316517.html