简介
本文将通过使用 Spark + Hive 实现 逐笔计算区块链上用户交易数据的盈亏 需求。
由于我们是进行离线计算,所以我们的数据源是 Hive 表数据,Sink 表也是Hive表,即 Spark 读取 Hive 表数据进行批计算之后写回到Hive 表并供后续使用。
通过本文你将会学到:
-
如何使用 Spark SQL API 读取 Hive 数据源
-
如何通过读取配置文件进行传参执行 SQL
-
如何将 Spark SQL 转换为 JavaRDD 进行处理
-
如何进行用户 keyBy 分组
-
如何基于 Spark 的 JavaRDD API 进行逐笔计算
-
如何进行用户的 Hash 分组,用于后期 Spark Hive SQL 分区计算
-
如何将计算结果 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