财务数据处理问题及解决方案分享

一、平台介绍

财务自营计费主要承接京东自营数据在整个供应链中由C端转B端的功能实现,在整个供应链中属于靠后的阶段了,系统主要功能是计费和向B端的汇总。

二、问题描述

近年来自营计费数据量大增,有百亿+的数据量,一天中汇总占据了一半的数据库资源。

1、每天从单表千万W+中定位几万数据执行汇总,即全库全表执行group by操作,32库*32表,每天要花12小时处理。

2、汇总期间,系统基本停滞,导致了消息、任务处理慢,积压多,数据无法及时计费。

3、数据库压力大,有随时崩溃的风险。

4、影响供应商体验,大促期间供应商要实时查看销售数据,出战报,系统无法及时响应。

三、原技术介绍

系统汇总核心是依靠MySQL物理机在每库每表通过group by进行,汇总是按费用类型分而治之,每种类型汇总维度不一样,每次如有新的汇总维度引入,需从前到后,写一遍新的汇总逻辑,主要是锁定新维度的数据范围,确定新的group by 字段,之前逻辑还得回归测试,很蠢是吧,我也觉得。

四、解决问题的思路和办法

根据以上的背景和问题,确定大致的解决问题思路

1、首先要脱离MySQL汇总,数据库是很脆弱的,要保护数据库,不然量级一直递增,总有天塌的一天。

2、顺带解决新需求重复开发的弊端。

五、实践过程描述

由于量大,业务上允许T+1处理,既然是离线数据处理,一般都能想到spark,spring batch,finlk等,在技术调研阶段,主要考虑成熟性,社区活跃度,主要采用spark技术。按照汇总的流程划分4个步骤。以下内容为了通俗易懂,简化了逻辑进行简单描述下。

1、数据抓取

汇总前数据,就是业务数据,type泛指业务数据中划分数据费用类型的字段,ou、dept泛指源数据的维度,可以是别的一个或者多个字段,amount就是要汇总求和的字段,此处用金额表示。

配置表,就是针对源数据衍生出来的,配置数据可以由很多个,是泛指,本系统只用到了一张。type表示费用类型用来和源数据关联使用,关联可以用一个或者多个字段关联,此处用一个字段举例,merge_key是汇总的字段,字段取值是从源数据的表结构的一个或者多个字段组成。invoice_type,代表汇总后的结果集需要填充的公共字段,此处用发票类型来泛指。可以根据填充的字段扩充,扩充的话在配置表中往后增加列即可。如下示例图以单个字段表达这个意思。

2、规则匹配

进行第一次加工,即把源数据中的每一行和配置表中的唯一一行关联,如下图,特殊说明下,源数据的每一行,在配置表中有且仅有一行配置可以关联上,即left join,无法关联上的,即无配置,过滤掉,不进行汇总。第一步骤加工操作是在内存中操作完成。

然后进行第二步骤加工,此步骤我们需要把从配置表中取出的merger_key字段进一步解析成当前left join后的行所对应字段的具体值。解析后的结果如下图,此步骤说明下,根据merger_key的字段,比如第一行ou,获取本行对应列的字段值,就是81,原理是通过Java反射实现,现在已有各种开源的工具包可以直接用,如spring的表达式等工具。以此类推,也能获取多个字段的值,多个字段可以按照一定的连接符号拼接,此图以_拼接。填充字段也同步进行添加。

3、数据汇总

规则匹配数据加工完毕后,我们只需要对加工完毕后的merger_key字段进行汇总,汇总引擎中只需要按照固定的汇总字段(此处举例是第二步骤加工完毕后的merger_key字段),汇总的逻辑就能够固化下来,只需要1个通用sql即可实现所有费用类型的汇总,最终产生的汇总结果。

4、汇总结果

汇总后的数据和通过原技术实现汇总出来的数据能保持一样的结果,同时还能填充一些公共的字段。如下图,其中绿色的2行源数据,按ou汇总在结果表中变成1行;橙色的3行源数据按dept汇总在结果表中变成2行;黄色的源数据按ou、dept字段汇总变成3行。

最后把这个汇总结果回写到MySQL即可。

六、实践过程思考和效果评价

1、在测试环境验证的过程中,测试表和线上表表数量级别不一样,初上线时,读取数据超慢。由于spark读取单表速度很快,读取分库分表数据效率直线下降,此处采用多线程方式去读符合条件的未汇总数据,最后汇总一个大集合。

2、上线稳定运行一段时间后,性能对比图,主要是通过剥离了MySQL中执行group by的操作,汇总时长下降了,数据库性能提高了,进而处理消息和异步任务能力也提高了,牵一发而影响全局。

3、后续有新的汇总需求上线时,通过配置即可实现新维度汇总功能,简化了研发工作,提高了需求交付时效。弊端也是有的,目前汇总维度的字段必须要从主表里取,因为spark读取业务数据只读取了主表,未读取扩展表。后续对hive表数据质量有信心,可以改成spark直接读取hive表,或者读es,ck等库。

4、通过spark框架引入、把大库汇总从在线改成离线,缓解了数据库压力,数据库性能提升后,从而也提升了计费的实效性,同时还增加了系统的稳定性,提升了供应商体验。

作者:王石根

来源:京东云开发者社区 转载请注明来源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/371673.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】信号-下

欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 🏠个人专栏:题目解析 🌎推荐文章:【LeetCode】winter vacation training 目录 👉🏻信号递达,信号未决&#x…

软考20-上午题-串及其模式匹配

串(字符串)是一种特殊的线性表,其数据元素为字符。如:"abc"。 一、串的定义 由字符构成的有限序列,是一种线性表。 串的比较:以字符的ASCII值作为依据。比较操作从两个字符串的第一个字符开始&a…

Openresty+Lua+Redis实现高性能缓存

一、背景 当我们的程序需要提供较高的并发访问时,往往需要在程序中引入缓存技术,通常都是使用Redis作为缓存,但是要再更进一步提升性能的话,就需要尽可能的减少请求的链路长度,比如可以将访问Redis缓存从Tomcat服务器…

4. 树(二叉树、二叉查找树/二叉排序树/二叉搜索树、平衡二叉树、平衡二叉B树/红黑树)

树 1. 二叉树1.1 概述1.2 特点1.3 二叉树遍历方式1.3.1 前序遍历(先序遍历)1.3.2 中序遍历1.3.3 后序遍历1.3.4 层序遍历 2. 二叉查找树(二叉排序树、二叉搜索树)2.1 概述2.2 特点 3. 平衡二叉树3.1 概述3.2 特点3.3 旋转3.3.1 左旋3.3.2 右旋 3.4 平衡二…

Quartus IP 之mif与hex文件创建与使用

一、mif与hex概述 ROM IP的数据需要满足断电不丢失的要求,ROM IP数据的文件格式一般有三种文件格式:.mif、.hex、.coe,Xilinx与Intel Altera支持的ROM IP数据文件格式如下: Xilinx与Altera支持的ROM文件格式 Alterahex、mifAM&am…

JS第二天、原型、原型链、正则

☆☆☆☆ 什么是原型? 构造函数的prototype 就是原型 专门保存所有子对象共有属性和方法的对象一个对象的原型就是它的构造函数的prototype属性的值。prototype是哪来的?所有的函数都有一个prototype属性当函数被创建的时候,prototype属性…

项目02《游戏-08-开发》Unity3D

基于 项目02《游戏-07-开发》Unity3D , 本次任务做物品相互与详情的功能, 首先要做 点击相应, 接下来用接口实现点击相应事件,具体到代码中,我们找到需要响应鼠标事件的对象, 双击PackageCell…

食堂预约系统

文章目录 前言​部分沟通内容技术点小程序功能部分代码段功能图 商家管理系统功能说明功能图登录页面商家管理页面 食品管理订单管理其他功能 结束语 前言​ 最近,接了个小项目——学校食堂预约取餐系统。 具体需求如下图: 部分沟通内容 技术点 系统…

C++:模板初阶

泛型编程 泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。 函数模板 函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。…

百面嵌入式专栏(面试题)网络编程面试题

沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将介绍网络编程面试题 。 1、什么是IO多路复用 I/O多路复用的本质是使用select,poll或者epoll函数,挂起进程,当一个或者多个I/O事件发生之后,将控制返回给用户进程。以服务器编程为例,传统的多进程(多线程…

antv/x6 边添加鼠标悬浮高亮和删除功能

antv/x6 边添加鼠标悬浮高亮和删除功能 效果添加悬浮效果和删除工具取消悬浮效果边删除后的回调函数 效果 添加悬浮效果和删除工具 this.graph.on(edge:mouseenter, ({ cell }) > {let cellId cell.store.data.source.celllet sourceCell _this.graph.getCellById(cellId…

绝地求生:盘点游戏内七款真人脸模,你最喜欢哪款?

从27.1版本更新后,游戏内上线了荣都地图代言人吴彦祖和李政宰的真人脸模,从此闲游盒的各位盒友灵魂搭配的资源库里又多了两位英俊脸庞,那么今天闲游盒来盘点一下游戏内上线的七款真人脸模,看看大家更喜欢哪款呢? 吴彦祖和李政宰 …

CSS-IN-JS

CSS-IN-JS 为什么会有CSS-IN-JS CSS-IN-JS是web项目中将CSS代码捆绑在JavaScript代码中的解决方案。 这种方案旨在解决CSS的局限性,例如缺乏动态功能,作用域和可移植性。 CSS-IN-JS介绍 1:CSS-IN-JS方案的优点: 让css代码拥…

【MySQL】DQL的总结和案例学习

🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​💫个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-VWRkWqFrRMi4uLRa {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

bert分类模型使用

使用 bert-bert-chinese 预训练模型去做分类任务,这里找了新闻分类数据,数据有 20w,来自https://github.com/649453932/Bert-Chinese-Text-Classification-Pytorch/tree/master/THUCNews 数据 20w ,18w 训练数据,1w 验…

挑战!贪吃蛇小游戏的实现(1)

引言 相信大家都玩过贪吃蛇这个游戏! 玩家控制一个不断移动的蛇形角色,在一个封闭空间内移动。随着时间推进,这个蛇形角色会逐渐增长,通常是通过吞食屏幕上出现的物品(如点或者其他标志)来实现。每当贪吃…

JQuery动态插入Bootstrap模态框(Modal)

这里所说的动态插入,是指用JS的append()方式追加元素内容,而不是静态写在HTML里面。 为什么会用到这种方式呢?比如登录框。有些网站在大部分页面都有登录按钮,如果是用Bootstrap的模态框调用的话,常规方式都是写在HTM…

目标检测及相关算法介绍

文章目录 目标检测介绍目标检测算法分类目标检测算法模型组成经典目标检测论文 目标检测介绍 目标检测是计算机视觉领域中的一项重要任务,旨在识别图像或视频中的特定对象的位置并将其与不同类别中的对象进行分类。与图像分类任务不同,目标检测不仅需要…

vue全家桶之状态管理Pinia

一、Pinia和Vuex的对比 1.什么是Pinia呢? Pinia(发音为/piːnjʌ/,如英语中的“peenya”)是最接近pia(西班牙语中的菠萝)的词; Pinia开始于大概2019年,最初是作为一个实验为Vue重新…

详解C++类和对象(上)

文章目录 写在前面1. 类的定义2. 类的访问限定符及封装2.1 类的访问限定符2.2 封装 3. 类的作用域4. 类的实例化5 类的对象大小的计算6. 类成员函数的this指针 写在前面 类和对象这一章节,分为上、中、下三篇文章进行拆分介绍的,本篇文章介绍了类和对象…