Spark、MongoDB技术分享

Spark、MongoDB技术分享

注:本文初始写于2021年9月26日22时40分,当时用于公司内部技术分享,现整理至博客,供大家交流学习

一、目标

1、了解SparkMongoDB的基本概念

2、了解如何自定义改造源码

3、了解UUID基本概念及其进制转换

二、概述

1、Spark概念:加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。(简述:把数据放在内存中进行计算的框架)

2、MongoDB驱动包概念:MongoDB官方提供的连接器给SparkMongoDB作为连接桥梁。(简述:连接Mongo数据库的一个jar包,可以与spark协同工作)

3、UUID概念:是Universally Unique Identifier的缩写,它是在一定的范围内(从特定的名字空间到全球)唯一的机器生成的标识符,是一个128bit的数字,也可以表现为3216进制的字符,中间用”-”分割。(简述:128位的标识符,具有唯一性)

三、背景

SparkMongo处理MongoDB的数据不符合GVP(公司内部的产品简称)的业务需求。

场景一

  • BJSONArray为空时,SparkMongo会自动忽略该字段的schema,业务需求为空时,就是空。

修改代码前:

注:下列的schema中没有orderBysjoinNodes字段,通俗的讲把我们的想要的信息丢掉了

root
 |-- _id: struct (nullable = true)
 |-- columns: array (nullable = true)
 |-- groupBys: array (nullable = true)
 |-- metaData: array (nullable = true)
 |-- options: struct (nullable = true)
 |-- paging: struct (nullable = true)
 |-- pivotQuery: struct (nullable = true)
 |-- widgetId: string (nullable = true)

修改代码后:

注:新增的这两列中都是空array

root
 |-- _id: struct (nullable = true)
 |-- columns: string (nullable = true)
 |-- groupBys: string (nullable = true)
 |-- joinNodes: string (nullable = true)   #新增
 |-- metaData: string (nullable = true)
 |-- options: struct (nullable = true)
 |-- orderBys: string (nullable = true)   #新增
 |-- paging: struct (nullable = true)
 |-- pivotQuery: struct (nullable = true)
 |-- widgetId: string (nullable = true)

最终产品展示图:
在这里插入图片描述

场景二

  • BJSON中Timestamp/uuid/luuid/md5等类型为结构化类型,不符合业务需求;业务需求是产品数据为数据库中显示的值。

修改代码前:
在这里插入图片描述

修改代码后:
在这里插入图片描述

最终产品效果图:
在这里插入图片描述

四、如何修改

1、分析、定位代码

  • 时序图

在这里插入图片描述

  • 脑图
    在这里插入图片描述

MongoInferSchema:获取schema,映射数据库与代码的数据库类型,通俗的说这个文件是目标修改文件之一

MapFunctions:从数据库中得到的数据转化为代码中的数据,通俗的说这个文件也是目标修改文件之一

MongoSparkMongoInferSchemaMongoRelation的入口文件

MongoRelationMapFunctions的入口文件

2、是否一定要修改?

是否一定要修改,这个一定要慎重考虑。

  • 必须要修改
  • 可以修改但非必须

前者,再思考一个问题,如何最小改动源码?n个问题,可能只有1个必须要修改的,n-1非必须修改的。

注:因为当修改源码可以解决问题时,再遇到问题,可能还会去修改源码,思维定式,陷入一个误区。

3、建包

为什么要建包?因为有很多类以及方法,只在同包名才能使用或指定包名下使用。也可以理解最真实的去模拟源码的编码环境。

4、新建文件,copy源码

先创建需要修改的文件,然后把源代码copy下来(因为scala的object不支持继承使用,所以都是用的copy方法);从需要修改的文件到入口文件都要新建文件然后copy。scala的类也是支持继承的,具体情况具体使用。

5、修改关键代码

注意:修改代码的影响范围

6、删除多余代码,保留关键需要的代码

在copy的过程中有很多的代码是没有被用到的,从入口文件到需要修改的文件,一点点删除。删除方法:点击类中的方法查看是否被使用,没有就直接删除。

五、拓展

1、UUID在源码中的处理过程(17=0001 0001=11
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  def byte16ToString(array: Array[Byte]): StringBuffer = {
    val stringBuffer = new StringBuffer()
    array.foreach(x => {
      var hexStr = Integer.toHexString(x).replace("ffffff", "")
      //如果十进制为0~15,那么对应的十六进制是00、01、...、0f,Integer.toHexString(x)转化出来的就只有一位字符,不符合预期两位字符
      if (hexStr.length == 1) {
        hexStr = "0" + hexStr
      }
      stringBuffer.append(hexStr)
    })
    stringBuffer
  }

2、如果找不到源码包,如何找到源码?答:使用 jdgui 工具进行反编译,百度教程很全;经过测试,jdgui可以反编译java,但是不能反编译scala。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值