• spark sql createOrReplaceTempView


    今天在开发中遇到了一个问题,dolphinscheduler-data-quality-dev-SNAPSHOT.jar中spark sql查询clickhouse的时候对时间格式为2022-09-30 00:00:00类型的查询会自动转成2022-09-30 00:00:00.0然后再去clickhouse中查询,导致报错

    1. Caused by: java.lang.Throwable: Code: 53. DB::Exception: Cannot convert string 2022-09-30 00:00:00.0 to type DateTime: while executing 'FUNCTION equals(YWDATE : 6, '2022-09-30 00:00:00.0' : 11) -> equals(YWDATE, '2022-09-30 00:00:00.0') UInt8 : 17'. (TYPE_MISMATCH) (version 22.3.8.39 (official build))
    2. at ru.yandex.clickhouse.except.ClickHouseExceptionSpecifier.specify(ClickHouseExceptionSpecifier.java:53)
    3. ... 26 more

    原因为:Dataset inputDataSet = jdbcReader(env.sparkSession()).load();是懒加载的,就算是注册为了临时表,再进行复制的sql查询都不会立刻执行,只是简单地记住所有对数据集的转换操作逻辑,在最后excuse的时候才会解析成最方便快捷的去执行。

    • 在解析的时候如果查询条件中带了YWDATE = '2022-09-30 00:00:00'之类的时间查询,spark sql会将'2022-09-30 00:00:00'处理成'2022-09-30 00:00:00.0',再去clickhouse中查询就会报错。
    • 在解析的时候如果查询条件中带了YWDATE = '2022/09/30 00:00:00'之类的时间查询,spark sql会将'2022/09/30 00:00:00'处理掉,不在数据库中去执行,在内存中执行吧,具体的不清楚,反正就是加了时间,在clickhouse日志中也没看到,最后也查不出来数据。

    尽量不要让spark sql在懒加载后的excuse中自己去解析时间类型,具有不清楚,就是有问题

    通过查看clickhouse的query log可以看到

    1. SELECT
    2. *
    3. from
    4. `system`.query_log ql
    5. where
    6. query like '%ADS_FCM_ZW_KMDXFL_COMMON_DH%'
    7. order by
    8. event_time desc

    1.出现问题后的总结

    1. spark sql 执行查询条件中带了YWDATE = '2022-09-30 00:00:00'之类的时间查询,spark sql会将'2022-09-30 00:00:00'处理成'2022-09-30 00:00:00.0',再去clickhouse中查询就会报错。
    2. spark sql中分为action算子和transformation 算子,action算子会立刻执行,transformation 算子不会。
    3. 就算action算子立刻执行出了结果,如果没有加缓存,最后在执行excuse的时候,spark还是会解析之前全部的操作逻辑,最后整合后,全部再执行一遍。

    2.createOrReplaceTempView、缓存学习

    在spark程序实际开发过程中遇到需要对文件内容做join操作,使用createOrReplaceTempView 方式将读取的文件创建临时表,然后通过 spark.sql()方式利用sql语句做join操作,但是数据量稍微大点时候,就会导致join效率很慢。查询资料得知,这里有优化的空间,利用 cache() 或者 persist() 方法。

    2.1. 原理

    createOrReplaceTempView是 transformation 算子,而transformation是lazy模式的,也就是spark不会立即计算结果,而只是简单地记住所有对数据集的转换操作逻辑,需要有action算子来触发spark应用程序,最简单的action算子:show()。例如:spark.sql("select *** from XXX ").createOrReplaceTempView(“tmp_test_table”).show()。
    这样每次执行.show()算子时候,都需要先执行createOrReplaceTempView操作,导致效率很慢。肯有直接将读取出来的数据缓存起来,或者将createOrReplaceTempView之后的数据缓存到内存中。

    缓存的方式有两种,具体使用不在此做赘述
    1) cache()方法表示:使用非序列化的方式将RDD的数据全部尝试持久化到内存中,cache()只是一个transformtion,是lazy的,必须通过一个action触发,才能真正的将该RDD cache到内存中。
    2)persist()方法表示:手动选择持久化级别,并使用指定的方式进行持久化。

    dolphinscheduler问题:dolphinscheduler-data-quality-dev-SNAPSHOT.jar中对于ClickHouse中数据类型为DateTime类型的数据报错,如果是DateTime64就可以查询

    如果增加cacha,会增加查询到内存的数据量,除非一开始就增加过滤条件去查询加载到内存的数据,dolphinscheduler先是全部load数据,然后注册成临时表,再在转换中去处理,在执行的时候,spark会默认将时间类型的查询条件变成yyyy-MM-dd HH:mm:ss.SSS去查询,如果数据类型为DateTime类型yyyy-MM-dd HH:mm:ss就会报错,只有类型是DateTime64类型才行!mysql因为时间类型就只有datetime所以没问题。

  • 相关阅读:
    网络技术二十一:ACL包过滤
    华为机试 - 最长的指定瑕疵度的元音子串
    Wi-Fi还可以做什么?柯南解释IOT应用
    【配置】Gradle下打包springboot项目,分离配置文件、依赖包
    Qt学习总结之QAbstractButton类
    Ubuntu查看自身版本,系统架构
    C语言:从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,然后输出到一个磁盘文件“test“中保存,输入的字符以‘!‘结束
    Java内存模型JMM
    c++类型转换
    spdlog C++日志管理 安装和下载
  • 原文地址:https://blog.csdn.net/qq_16504067/article/details/127727688