hive udf 执行一次调用多次问题

sql 复制代码
SELECT AppMktApi(
      'http://xx.xx.xx.xx:8282/uph/sou',
      'POST',
      concat('{','"topicId": "', 'RZRQ', '",','"auditorId": "','ngw', '",','"channels": "', 'ol', '",','"content": "', '融资融券业务指标变动提醒","longtext":"尊敬的投资者您好!您信用账户持有的科泰电源(300153)折算率已调整,敬请关注', '",','"destIds": ', '[11500435,11500433,11304133,11000126,11000619,11504802]', ',','"destType": "', '1', '",','"priority": "', '5','",','"providerId": "','ngw', '",','"rTopic": "', 'Push_Result','",','"ack": "','1','"}'),
    -- '{"topicId":"RZRQ","auditorId":"ngw","channels":"ol","content":"融资融券业务指标变动提醒","longtext":"尊敬的投资者您好!您信用账户持有的科泰电源(300153)折算率已调整,敬请关注","destIds":[11500435,11500433,11304133,11000126,11000619,11504802],"destType":"1","priority":"5","providerId":"ngw","rTopic":"Push_Result","ack":"1"}',
      'Content-Type: application/json'
    ) AS result

执行一次调用了两次,查看执行计划

sql 复制代码
explain extended SELECT AppMktApi(
      'http://xx.xx.xx.xx:8282/uph/sou',
      'POST',
        '{\"topicId\":\"RZRQ\",\"auditorId\":\"ngw\",\"channels\":\"ol\",\"content\":\"融资融券业务指标变动提醒\",\"longtext\":\"尊敬的投资者您好!您信用账户持有的科泰电源(300153)折算率已调整,敬请关注\",\"destIds\":[11500435,11500433,11304133,11000126,11000619,11504802],\"destType\":\"1\",\"priority\":\"5\",\"providerId\":\"ngw\",\"rTopic\":\"Push_Result\",\"ack\":\"1\"}',
      'Content-Type: application/json'
    ) AS result

结果显示

sql 复制代码
STAGE DEPENDENCIES:
Stage-0 is a root stage
STAGE PLANS:
Stage: Stage-0
Fetch Operator
limit: -1
Processor Tree:
TableScan
alias: _dummy_table
Row Limit Per Split: 1
GatherStats: false
Select Operator
expressions: '{"response":"{\"errcode\":\"0\",\"msgId\":\"2025090239116000001\"}","curlCommand":"curl -X POST -H \"Content-Type: application/json\" -d '{\"topicId\":\"RZRQ\",\"auditorId\":\"ngw\",\"channels\":\"ol\",\"content\":\"融资融券业务指标变动提醒\",\"longtext\":\"尊敬的投资者您好!您信用账户持有的科泰电源(300153)折算率已调整,敬请关注\",\"destIds\":[11500435,11500433,11304133,11000126,11000619,11504802],\"destType\":\"1\",\"priority\":\"5\",\"providerId\":\"ngw\",\"rTopic\":\"Push_Result\",\"ack\":\"1\"}' http://xx.xx.xx.xx:8282/uph/sou"}' (type: string)
outputColumnNames: _col0
ListSink

执行计划里仅显示 Stage-0 (属于客户端本地阶段,无分布式计算),且扫描的是 dummy_table (Hive 虚拟表,仅用于返回固定值,无需 MapReduce 处理 )。

原因:

  1. Hive 执行计划的"预执行 + 实际执行"

Hive 在解析含 UDF(这里 AppMktApi; 可理解为自定义函数逻辑)的查询时,可能会先做语法/类型校验,执行计划中的 (type: string),触发一次接口调用;实际执行查询(扫描 _dummy_table; 后处理数据)时,再触发一次。尤其当 UDF 里有固定参数拼接(像你 SQL 里构造固定请求体),Hive 校验阶段可能会提前执行 UDF 逻辑,导致额外调用。

2 解决方案

方案 1:避免 UDF 在校验阶段执行

Hive 校验阶段会执行 UDF(因固定参数/语法验证),可通过延迟 UDF 逻辑执行规避:

方法:参数化请求体(从固定值改为表字段)

把 UDF 里固定拼接的请求体,改成从表中读取字段动态生成。这样 Hive 校验阶段无实际参数,不会触发接口调用。

示例改造:

原 SQL(固定请求体,触发校验调用):

sql 复制代码
SELECT AppMktApi(
      'http://xx.xx.xx.xx:8282/uph/sou',
      'POST',
      concat('{','"topicId": "', 'RZRQ', '",','"auditorId": "','ngw', '",','"channels": "', 'ol', '",','"content": "', '融资融券业务指标变动提醒","longtext":"尊敬的投资者您好!您信用账户持有的科泰电源(300153)折算率已调整,敬请关注', '",','"destIds": ', '[11500435,11500433,11304133,11000126,11000619,11504802]', ',','"destType": "', '1', '",','"priority": "', '5','",','"providerId": "','ngw', '",','"rTopic": "', 'Push_Result','",','"ack": "','1','"}'),
    -- '{"topicId":"RZRQ","auditorId":"ngw","channels":"ol","content":"融资融券业务指标变动提醒","longtext":"尊敬的投资者您好!您信用账户持有的科泰电源(300153)折算率已调整,敬请关注","destIds":[11500435,11500433,11304133,11000126,11000619,11504802],"destType":"1","priority":"5","providerId":"ngw","rTopic":"Push_Result","ack":"1"}',
      'Content-Type: application/json'
    ) AS result

改造后(请求体存表,动态读取):

  1. 建辅助表存请求体(一次插入,复用):
sql 复制代码
create table tmp.request_body(
name string
)

insert into table tmp.request_body 
select '{"topicId": "RZRQ","auditorId": "ngw","channels": "ol","content": "融资融券业务指标变动提醒","longtext":"尊敬的投资者您好!您信用账户持有的科泰电源(300153)折算率已调整,敬请关注","destIds": [11500435,11500433,11304133,11000126,11000619,11504802],"destType": "1","priority": "5","providerId": "ngw","rTopic": "Push_Result","ack": "1"}
' as name;
  1. 关联查询动态传参(Hive 校验阶段仅解析逻辑,不执行 UDF):
sql 复制代码
SELECT AppMktApi(
      'http://xx.xx.xx.xx:8282/uph/sou',
      'POST',
    --   concat('{','"topicId": "', 'RZRQ', '",','"auditorId": "','ngw', '",','"channels": "', 'ol', '",','"content": "', '融资融券业务指标变动提醒","longtext":"尊敬的投资者您好!您信用账户持有的科泰电源(300153)折算率已调整,敬请关注', '",','"destIds": ', '[11500435,11500433,11304133,11000126,11000619,11504802]', ',','"destType": "', '1', '",','"priority": "', '5','",','"providerId": "','ngw', '",','"rTopic": "', 'Push_Result','",','"ack": "','1','"}'),
    -- '{"topicId":"RZRQ","auditorId":"ngw","channels":"ol","content":"融资融券业务指标变动提醒","longtext":"尊敬的投资者您好!您信用账户持有的科泰电源(300153)折算率已调整,敬请关注","destIds":[11500435,11500433,11304133,11000126,11000619,11504802],"destType":"1","priority":"5","providerId":"ngw","rTopic":"Push_Result","ack":"1"}',
    name,
      'Content-Type: application/json'
    ) AS resul from tmp.request_body 

原理:Hive 校验阶段仅检查表字段引用,不会实际执行 AppMktApi ,仅实际执行阶段(扫描表时)触发 1 次调用。

相关推荐
陈年老古董8 小时前
Hive 函数学习笔记(下):窗口函数与经典案例
hive·笔记·学习
爱吃火鸡面呀8 小时前
DataX 实战:使用 HDFS Reader 读取 Hive ORC 表并输出到 Stream
hive·hadoop·hdfs
yumgpkpm9 小时前
CDP 7.3.1(Cloudera Runtime 7.3.1)VS Acceldata ODP 3.3.6.4 核心引擎详细版本对比
大数据·hive·hadoop·postgresql·zookeeper·spark·hbase
计算机毕业编程指导师10 小时前
【计算机大数据毕业设计选题】基于Hadoop+Spark的人工智能社交媒体情绪数据分析系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·人工智能·hadoop·计算机·毕业设计·课程设计·社交媒体
yumgpkpm10 小时前
(CDH 7)CDP Private Cloud Base 7.3.1 → Acceldata ODP 3.3.6.4 引擎迁移风险评估表
服务器·人工智能·hadoop·python·华为·zookeeper·hbase
计算机毕业编程指导师10 小时前
【计算机毕设】基于Hadoop的人口统计特征与肥胖风险关联分析的数据分析系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·hadoop·python·计算机·数据分析·课程设计·肥胖风险
计算机毕业编程指导师10 小时前
【计算机毕业设计选题】基于Hadoop+Spark的乳腺癌数据分析与可视化系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
hadoop·python·spark·毕业设计·课程设计·乳腺癌·计算机毕设
yumgpkpm16 小时前
Acceldata ODP 3.3.6.4 vs CDP Private Cloud Base 7.3.2 对比
大数据·运维·服务器·hadoop·华为·zookeeper·hbase
yumgpkpm2 天前
Acceldata ODP(Open Data Platform)3.3.6.4(RHEL9)保姆级完整安装手册
大数据·人工智能·hive·hadoop·kafka·hbase·cloudera
sunxunyong2 天前
hs2偶发连接失败问题处理
hadoop