千万级数据清洗ETL设计方案

2023-11-15


距离上次写博客已经过去好几个月了,中间其实还是有大量的时间去写博客的,但还是应为比较懒,就没写,毕竟咱也不是要成为吸粉的博主,每日更新比较基础的知识嘛,要整就整点有难度的,这才过瘾嘛。
在这里插入图片描述

现在看看之前自己的一些博客,讲的东西确实比较适合基础薄弱的同学,但是毕竟大家来CSDN,肯定还是想找到自己解决不了的问题的答案嘛,与其到处去搬运别人写好的资料,还不如自己找个时间认认真真的思考一下最近的几个月都干了什么,毕竟前有温故而知新,后有学而不思则罔嘛

项目简介

这个项目只是目前大项目中的一个需求而已,数据清洗在企业中的作用不言而喻,用户能否正确的看到网站的信息,全靠着对从各个渠道获取到的数据进行整理的需求。不同的数据量所需要的技术支持自然是不同的,对于才几十万或者上百的数据量,可能自己写一个简单的类,使用几个方法去格式化就搞定了。但是对于从不同渠道,不同格式的数据源,数据量上千万的处理需求来说,就必须使用一套能稳定输出的框架设计方案。

一、需求分析

1. 前期需求

项目刚接手的时候,要求其实还没多高,只不过是需要对于不同的数据源进行单独的处理和统一格式化,项目还处于初期设计,数据量也不是很全,所有当时只需要一个类,其中在写几个方法即可,包括但不限于,数据库获取原始数据、数据筛选、数据格式化、数据去重、数据入库
在这里插入图片描述

2. 中期需求

项目进行了一两个月后,第一版比较完整的数据从各个网站获取下来了,这里所说的完整是对于前期设计的数据库中的所有表,都已经有数据存在。这是的需求就开始提高了,虽然还是提取数据、筛选、格式化、去重数据,但是使用之前的流线型代码(后面会讲到)已经不能满足日常的功能需求了,必须要对代码进行重构,这里就需要使用工厂模式(后面会讲到)
在这里插入图片描述

3. 后期需求

到了后期项目临近上线,需要进行大量的环境测试,则需要在不同的环境下的数据清洗,都能产出一样的数据,包括但不限于,线上环境、线下环境、测试环境等。在保证数据稳定输出的前提下,也要保证不同的环境在同时进行数据清洗时获取到的数据是相同的,同时面临的数据备份,数据库表设计等优化使用的问题(后面会讲到)。
在这里插入图片描述

二、技术支持

1. MySQL

因为数据的来源和结构基本是不一样的,好一点的网站,返回的数据源就是json格式,而比较差的网站,返回的数据格式则都是HTML,这对于数据的统一保存是个大问题。
在这里插入图片描述

所以我们在设计表字段的时候,没有将所需要的字段一一列出,而是将整个完整的原始数据存入一个字段中,在数据清洗的时候从该字段中格式化出需要的字段,这样就解决了不同数据源相同格式存入数据库的需求。需要注意的是,不同的表的不同数据必须要有一个标识来判断数据的来源,对于后面的ETL数据清洗有着非常重要的作用。
在这里插入图片描述

设计数据表的时候还需要预留一两个备用字段(other_tags…),避免重复修改表结构的情况出现。

2. Redis

redis的使用涉及的东西就比较多了,目前整个清洗流程中用到的几个功能大概有:

  1. 缓存临时数据,减少数据库查询压力
  2. 不同数据的清洗结果计数
  3. 数据去重
  4. 任务结束标识
  5. 查询数据库使用的缓存下标(用于程序断开后能继续从断开处继续执行)
    在这里插入图片描述

这里在使用的过程中,还是存在着比较严重的问题的,也是因为前期的清洗设计没有设计好导致,具体问题会在下面的redis使用中讲解。

三、框架设计

1. 流线型代码

流线型代码就是最为普通的代码结构了,属于一个类中完成多个功能,所有功能耦合性高,代码串行,不易调式,不易走读,一步错步步错。这样的代码适用于比较小的项目,只要保证代码能跑起来,捕捉到异常,不会中断程序即可(这种代码不能用于生产),大家可以想想自己的代码是不是这样的,最明显的特征就是串行。
在这里插入图片描述

2. 工厂模式

工厂模式大家应该听得还是比较多的,现实的项目中用的也会比较多,无论是大的项目还是小的项目,从工厂模式基本都能套的上,主要的特征就是OOP,通过面向对象的设计,功能独立开,低耦合,易读、易维护,可扩展性强
在这里插入图片描述

我这边的清洗项目所目前使用的就是工厂模式,拥有六个类,分别是Master类,Task类,Worker类,DataPart类,FormatData类,Update类

  1. Master类主要用于任务的分配和工人的调度,当然还是有一些附加的功能如:初始化工人、任务、数据库、redis等;
  2. Task类主要是任务的调度,判断任务是否完成以及更新任务的状态;
  3. Worker类主要是工人做工,从任务类中拿到数据包后进行加工数据;
  4. DataPaet类主要是从数据库中获取数据包,将数据包,数据包则由Task类进行分配;
  5. FormatData类主要负责将原始数据进行粗加工再细加工,最后筛选、格式化、去重,返回业务数据,由Worker类进行调用;
  6. Update类主要是进行数据的更新和同步,数据至少需要有两份,一份用于业务需求,一份备份保存。

四、调式工作

1. 线上测试

回顾整个项目的编写,除了主程序ETL的代码,加上其他的几个调用文件代码,加起来不过五千多行。但是整个项目花了大概两个月的时间才稳定下来。平均一天才写一百来行,通过这两个月的项目设计和持续优化,让我明白了什么叫花60%的时间思考,20%的时间写代码,20%的时间调式
在这里插入图片描述

从项目初期到现在,用很多地方的代码写了删,删了又写,反反复复,浪费了大量的时间,这就是典型的没有想明白就开始动手写代码。用在测试上的时间远远大于思考逻辑和写代码的时间,这是相当要命的事情,如果代码的逻辑流程,思考的完善,那么代码写起来是很快的,也不会有遗漏的地方,最怕的就是写一点,调式一下,再写一点,再调式一下,不仅容易漏掉重要的逻辑,所消耗的时间成本也是巨大的,再次引以为戒

五、问题回顾

1. Mysql使用问题

mysql在使用中遇到的问题如下:

  1. 查询数据库句法问题,查询语句虽不复杂,但是查询的量大;

    在使用sql语句时,一次性将整个数据库表的内容读到内存中是既不安全和不可靠的,一来内存使用太高影响性能,二来程序中断数据丢失不安全。

  2. DDL事务为提交,倒是出现数据库表锁;

    MYSQL未配置autocommit=1时,所有事务需要进行手动的commit,而数据清洗程序,需要进行大量的查询,更新,提交操作,则更需要注意事务的提交,当使用sql使用不当,导致查询时间较长,又未进行提交时,其他的所有表操作都得等到表锁释放,从而堵塞

  3. 数据库表设计问题,导致数据库单表压力巨大
    当数据量不是很大的时候,我们将数据存放在一张表中当然是没有问题的,但是现在的数据量达到上千万,内存将近7G,那么数据库的设计和索引设计就尤为关键

2. Reids使用问题

redis使用问题主要集中在把redis当作数据库使用,如果在单节点,将大量的数据存入redis中,则会导致数据无法继续存入,若触发redis的数据淘汰机制,则会删除最先入库的数据,从而使用失败。
在这里插入图片描述

现在则必须重新规范使用redis,大量的数据需要进行存储和处理时,建议使用链式结构,一边消耗一边存入,并给所使用的队列设置阈值,保证redis的正常使用

3. 设计思路问题

从最开始的设计,我这边就存在问题,并没有准确的判断出后面需要处理的数据量以及mysql、redis使用上的问题,导致项目至今重构了三次。虽然一次比一次更加的完善和健壮,但是消耗的时间成本也是巨大的,尽量不要再使用流线型的代码处理任何需求,认真思考需求以及后期可能遇到的问题,使用60% 的时间去思考和设计框架,编写开发文档和逻辑流程图,当这些准备工作完成之后,再写代码那还不是信手拈来。

关注收藏不迷路,持续更新

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

千万级数据清洗ETL设计方案 的相关文章

随机推荐

  • 【多模态】22、UniDetector

    文章目录 一 背景 二 方法 2 1 UniDetector 框架结构 2 2 Heterogeneous Label Space Training 2 3 open world inference 三 效果 3 1 数据集 3 2 Obj
  • cmake:target属性POSITION_INDEPENDENT_CODE和INTERFACE_POSITION_INDEPENDENT_CODE的区别

    cmake定义的target有两个名字类似的属性 POSITION INDEPENDENT CODE和INTERFACE POSITION INDEPENDENT CODE 本文说明它们的含义和区别 fPIC 介绍POSITION INDE
  • linux ALSA & ASOC (3) — widget 、route

    目录 DAPM的基本单元widget widget的种类 widget之间的连接器path widget的连接关系route 上一篇文章中 我们介绍了音频驱动中对基本控制单元的封装 kcontrol 利用kcontrol 我们可以完成对音频
  • 退出旋流虚空

    在构建一些软件之前 您经常面临着各种可能性的漩涡 这可能导致 期权瘫痪 想象一个巨大的系统 建立框架的错误愿望 付出了很多努力 但没有进展或结果 作为一个明智的领袖曾经对我说 出色的软件开发人员的特点是他们能够解决一个大问题并将其分解为较小
  • word文件丢失怎么办?恢复Word文档的3个方案

    电脑里面有很多大大小小的文件数据 有时对我们可有可无 有时是很重要的 在清理电脑过程中 要是不小心误删了重要的文件 word文件丢失如何恢复 只需要下面的3个方案 就可以轻松找回Word文档 方案一 回收站恢复Word文档 要说电脑最容易误
  • Nginx快速入门

    Nginx服务快速入门 文章目录 Nginx服务快速入门 一 Nginx介绍 1 什么是Nginx 2 为什么要使用Nginx 3 什么是正向代理 4 什么是反向代理 二 Nginx在Linux下的安装 1 下载 2 安装 三 Nginx配
  • 用批处理将文件夹设为虚拟磁盘

    记录备忘 将下列文本保存成 bat subst Z d subst Z D WorkSpace
  • python 爬虫 requests模块 中的Cookies 验证 通过验证cookies模拟登陆豆瓣登陆

    在爬取某些数据时 需要进行网页的登陆 才可以进行数据的抓取工作 Cookies登陆就像很多网页中的自动登陆功能一样 可以让用户第二次登陆时不在需要验证账号和密码的情况下进行登陆 在requests模块中实现Cookies登陆时 首先需要在浏
  • 华为OD机试真题 Java 实现【异常的打卡记录】【2023Q1 100分】

    一 题目描述 考勤记录是分析和考核职工工作时间利用情况的原始依据 也是计算职工工资的原始依据 为了正确地计算职工工资和监督工资基金使用情况 公司决定对员工的收集打卡记录进行异常排查 如果出现以下两种情况 则认为打卡异常 实际设备号与注册设备
  • selenium+pytest——失败用例重试

    selenium pytest 失败用例重试 一 目的 在我们使用selenium pytest做UI自动化的时候偶尔会遇到因为特殊情况 比如浏览器加载失败 网络波动等等导致用例运行失败 可能单独运行没 问题 对于这些场景产生的用例结果不是
  • UE4 蓝图通信:接口调用

    UE4学习心得 蓝图间信息通信的几种方法 UE4的接口调用技术有点简单粗暴 而且主要体现在主蓝图对子蓝图的信息通信 在内容浏览器中添加一个蓝图接口 命名为TestInterface 双击打开接口 直接使用其创建时自带的一个接口函数 将其重命
  • 物理机安装centos7(u盘安装)——详细版

    我用的是华为的物理机 其它物理机操作几乎相同 可能不同的设置调试方法不同 如果是虚拟机安装 直接跳到centos7设置即可 物理机U盘启动 安装centos8方法相同 可能有些需要硬件配置相关 相关问题看具体报错方式 UltraISO下载地
  • 在C语言中 ¬∧∨这些符号什么意思

    b b b a a a b a a 或运算是 a b a b b b a a a 这三个都是位运算 是取非运算 交你个小窍门 没啥子好多的了 好好看看 里面有详细的解释 这就是在逻辑运算中常用到的短路判断 ls的已经说的很清楚了 b a b
  • 微信小程序之首页搭建

    小程序开发与实战 学习视频 https www bilibili com video BV1Gv411g7j6 p 9 spm id from pageDriver 实现导航栏和tabBar 实现导航栏和tabBar tabBar看下图 参
  • 电荷泵

    电荷泵 又称为电容式的开关稳压器 或开关电容DC DC变换器 无感式DC DC变换器 电荷泵采用电容作为开关和储能的元件 如图所示 S1与S3闭合 S2与S4断开 则Vin给电容充电 而后S1与S3断开 S2与S4闭合 则电容放电 此时Vo
  • Virtual Judge-4099:队列和栈

    Virtual Judge 4099 队列和栈 题目描述 队列和栈是两种重要的数据结构 它们具有push k和pop操作 push k是将数字k加入到队列或栈中 pop则是从队列和栈取一个数出来 队列和栈的区别在于取数的位置是不同的 队列是
  • PyTorch入门(六)使用Transformer模型进行中文文本分类

    在文章PyTorch入门 五 使用CNN模型进行中文文本分类中 笔者介绍了如何在PyTorch中使用CNN模型进行中文文本分类 本文将会使用Transformer模型实现中文文本分类 本文将会使用相同的数据集 文本预处理已经在文章PyTor
  • C语言程序——用星号打印图案

    文章目录 前言 一 用星号打印图案 二 程序实例 1 程序代码 2 运行结果 3 结果分析 三 拓展应用 总结 前言 用打印字符来输出星号组成的HELLO 一 用星号打印图案 用星号打印图案 一般利用星号画出具体的模拟输出形式 然后在输出时
  • 【Android】常用对话框大全(一)Android Dialog

    Android的对话框有多少种 Android好看的对话框有很多 如Android material qmui xui kongzue等系列对话框 但博主只打算讲解Android material系列对话框 讲太多没必要 实在想要做成人家那
  • 千万级数据清洗ETL设计方案

    千万级数据清洗项目分析总结 项目简介 一 需求分析 1 前期需求 2 中期需求 3 后期需求 二 技术支持 1 MySQL 2 Redis 三 框架设计 1 流线型代码 2 工厂模式 四 调式工作 1 线上测试 五 问题回顾 1 Mysql