大数据实战:Spark + Hive 逐笔计算用户盈亏

简介

本文将通过使用 Spark + Hive 实现 逐笔计算区块链上用户交易数据的盈亏 需求。

由于我们是进行离线计算,所以我们的数据源是 Hive 表数据,Sink 表也是Hive表,即 Spark 读取 Hive 表数据进行批计算之后写回到Hive 表并供后续使用。

通过本文你将会学到:

  1. 如何使用 Spark SQL API 读取 Hive 数据源

  2. 如何通过读取配置文件进行传参执行 SQL

  3. 如何将 Spark SQL 转换为 JavaRDD 进行处理

  4. 如何进行用户 keyBy 分组

  5. 如何基于 Spark 的 JavaRDD API 进行逐笔计算

  6. 如何进行用户的 Hash 分组,用于后期 Spark Hive SQL 分区计算

  7. 如何将计算结果 Sink 到 Hive 存储

数据准备

这里我们采用已经同步清洗好在 Hive 表的交易数据表 dws_solana_dex_trade 表,表数据结构如下:

mint_group mint_address block_number block_hash out_index inner_index timestamp tx user_address trade_type amount trade_value price day second
10 Dd67**Mpump 320566862 C8S3**DyrN4V3 4 2 4iAbStzEnRRHU5vFchQ7h51X8gtRXG66rp3ttRhpv6zxsqydGC84zvUWAf5o6cZnQPHNrQgvxPdmfSvCmzhhR5zJ Gt3PvoejF8rMb1CLZ1heDXqhQb3FNR53j21C9pnNMm7C buy 2,409,264.312335 0.083291669 0.00000003 2025-02-14 2025-02-14 09:04:26
mint_group : 代表计算 token 所在的分组
mint_address : 代表计算的 token 地址
block_number : 代表交易所在的区块号
block_hash : 代表区块 hash
tx : 代表交易所在hash
user_address : 代表用户的钱包地址
trade_type : 代表交易类型 , sell 为卖出 ,buy 为买入
amount : 代表交易数量
trade_value : 代表交易额
price : 代表当前交易的价格
day : 时间,精确到天
second : 时间,精确到秒
编写程序
首先获取环境
SparkSession spark = SparkSession.builder()
                //.master("local[*]")
                .appName("PumpUserProfitLossApplication")
                .config("spark.sql.warehouse.dir", "hdfs://bigdata-node1:8020/warehouse/tablespace/managed/hive") // 指定hive仓库位置
                .enableHiveSupport()
                .getOrCreate();
        spark.sparkContext().setLogLevel("ERROR");
读取配置文件

这里采用的是 Flink 框架 的 flink-java Maven 模块中的 ParameterTool 进行读取配置文件

引入 Maven 模块
<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-java</artifactId>
    <version>${flink.version}</version>
</dependency>
application.properties 配置文件
pump-user-profit-loss.job.name = pump-user-profit-loss-application
​
# source config
pump-user-profit-loss.source.hive.database = crypto_solana
pump-user-profit-loss.source.hive.trade.table= dws_solana_dex_trade
​
# sink config
pump-user-profit-loss.sink.hive.database = crypto_solana
pump-user-profit-loss.sink.hive.table = ads_solana_user_position_profit
pump-user-profit-loss.sink.hive.start = 2024-11-10
pump-user-profit-loss.sink.hive.end = 2024-11-15
编写 ParameterToolUtils 工具类
public class ParameterToolUtils {
    private static final String defaultConfigFileName = "application.properties";
​
    public static ParameterTool createParameterTool(String[] args) throws IOException {
        return ParameterTool.fromPropertiesFile(Thread.currentThread().getContextClassLoader().getResourceAsStream(defaultConfigFileName))
                .mergeWith(ParameterTool.fromArgs(args))
                .mergeWith(ParameterTool.fromSyst