Spark - saveAsTable + rename = 坑

一、背景

        挠头怎么写这篇博文,这问题其实挺偶然机会发现,甚至一度触及到了知识盲点(滑稽狗头),其实吧,就是为了清理平台底层关联不到元数据信息的垃圾文件,大家都懂滴,垃圾不清理,存储迟早要炸,
        然而发现某表的文件路径指向不太得劲儿,带有location 和 path两种属性,而且两个属性指向的文件路径,撇撇~~,居然两个不一样的路径,这就有好玩了,路径既然不一样,那数据是否会错乱呢?研究研究准备复现。

二、环境及测试场景

①、环境

组件版本备注
hive2.1.0已测试
spark2.3.2已测试
spark3.1.2已测试,同spark2

②、测试场景

场景测试状态备注
普通表已测试
分区表待测试估计和普通表没啥两样
删表已测试测试用例中留有疑问
create table like已测试location和path属性会被同时继承,但是hive和spark引擎情况不同

三、复现历程

问题是如何复现!!!同时带这俩属性的表是怎么创建出来的,神马神操作……
一个头两个大,脑袋要爆炸

①、场景探索

此处吐槽一番,绝逼是开发在偷懒,为了快速建表,图省事,不考虑可能会出现的大坑

方式引擎操作结果
手动创建hivecreate table ……未复现
手动创建sparkcreate table ……未复现
SparkSQLhivecreate table ……未复现
SparkSQLsparkcreate table ……未复现
SparkSQLsparkcreate table … using parquet复现
SparkCoresparkspark.sql(“create table ……”)未复现
SparkCoresparkdf.saveAsTable()复现
  • 复现code - 测试代码,仅供参考,谁用谁入坑
    在这里插入图片描述

  • 初始化表 并且 写入第一批数据
    测试任务执行时间:2022-05-20 19:26:51 ~ 2022-05-20 19:27:46
    在这里插入图片描述

  • 记录时间戳
    先记录再说,排查问题,时间戳很重要,方便比对
    表hdfs目录创建时间戳:2022-05-20 19:27:44
    在这里插入图片描述
    第一批文件名:part-00000-87fc30fc-90b1-4a1c-a7cc-adb42f8009af-c000.snappy.parquet
    第一批文件修改时间:2022-05-20 19:27:44
    在这里插入图片描述

  • 现象:
    这个时候的表和正常的表没啥两样,只是比普通的表多了path属性,和location指向相同,数据的读写都还在同一路径下,没啥影响

  • 问题:但是location和path不一致的情况怎么产生,产生后会有什么隐患?准备测试用例

②、测试用例(写数据)

经观察,历史存量的异常表都是表名称location一致,表名称path不一致
能产生这种情况的,那就是rename to操作了

1. rename表(hive引擎)

rename运行时间:2022-05-20 20:10:32

-- hive引擎
alter table xxx.temp_ngy_test rename to xxx.temp_ngy_test_rename;

在这里插入图片描述

2. 观察rename后表结构

异常的表结构出现了,表名称location一致,表名称path不一致
在这里插入图片描述

  • 问题:这个时候的表,数据是往哪个路径写,查询时候又是加载哪个路径下的数据

3. 记录下rename后的目录状态

  • 旧路径:temp_ngy_test目录已经不存在
    在这里插入图片描述

  • 新路径:temp_ngy_test_rename目录被创建
    并且继承第一批写入的旧数据文件和时间戳
    在这里插入图片描述
    在这里插入图片描述

4. jar包 insertInto写入第二批数据

  • 测试code:仅修改saveAsTableinsertInto
    测试任务执行时间:2022-05-20 20:45:10 ~ 2022-05-20 20:46:13
    在这里插入图片描述
  • 重点:旧路径temp_ngy_test重新创建出来,并且写入新数据
    在这里插入图片描述
    第二批文件名:part-00000-eed210c3-9106-4d18-8ee0-3abcdb5dae99-c000.snappy.parquet
    第二批文件修改时间:2022-05-20 20:45:58
    在这里插入图片描述

③、测试用例(读数据)

注意观察数据的时间戳,和上文两次数据生成的时间作比对

1. hive引擎读数据

  • 设想:走location
  • 实测:走location,读新路径temp_ngy_test_rename的旧数据
    在这里插入图片描述

2. spark引擎读数据

  • 设想:走path
  • 实测:走path,读旧路径temp_ngy_test的新数据
    在这里插入图片描述

④、测试用例(删表)

仅测试删表场景,此场景时间戳不重要,不用关心

drop table xxx.temp_ngy_test_rename;

1. hive引擎删表

  • 设想:走location
  • 实测:走location
    旧路径(path)temp_ngy_test目录未删除
    新路径(location)temp_ngy_test_rename目录被删除
    在这里插入图片描述

2. spark引擎删表???此处有疑问

因为上一步测试已经删表,此步骤需重新恢复现场,稍等……

  • 设想:走path
  • 实测:还是走location ???
    旧路径(path)temp_ngy_test目录未删除
    新路径(location)temp_ngy_test_rename目录被删除
    此处和设想不一致,留待深究,难道ddl和dml操作有差异
    在这里插入图片描述

⑤、测试用例(create table like)

create table xxx.temp_ngy_test_like like xxx.temp_ngy_test_rename;

1. hive引擎

  • 现象:同时保留pathlocation属性
  • 相同点:path指向路径相同,都指向rename表旧路径(temp_ngy_test)
  • 不同点:location指向不同,指向like表新路径(temp_ngy_test_like)
  • 结论:有隐患-,数据更新可能会冲突,造成异常丢数现象

2. spark引擎

  • 现象:同时保留pathlocation属性
  • 相同点:无
  • 不同点:pathlocation都指向like表新路径(temp_ngy_test_like)
  • 结论:有隐患-,不宜再做rename操作,不利于后期维护

四、隐患

这就很明显了,表如果同时存在location和path两个属性,读写数据的时候
hive引擎走location:rename之后的新路径
spark引擎走path:rename之前的旧路径

①、隐患:数据写入和查询混乱

重点:rename之后,hive引擎写新路径(location),spark引擎继续写旧路径(path),如果用户中间切换过引擎,数据将会错位,导致新路径和旧路径中都有新增加的数据,对于下游查询造成问题。

②、隐患:数据管理和治理困难

如果表在管理过程中,出现误操作、误删等动作,数据将不是很好修复,对于排查问题也将造成一定的困难

五、修正方案

①、方案:简单粗暴,不管何种状态,手动重建

②、方案:表已创建未rename

也简单,如果必须要rename,用spark引擎进行操作

③、无法执行的方案:表已创建,hive引擎也rename了

之前自以为是的想了个方案,步骤如下:

  1. 先hive引擎rename回旧表名,这样location和path路径就一致了
  2. 再spark引擎rename成新表名,这样location和path一致情况下,还不影响下游查询数据

当暗自窃喜自己很机智的时候,啪啪打脸
自求多福吧,hive引擎直接报错旧表名已存在
在这里插入图片描述
不死心,spark引擎总可以吧,然而,GG思密达,我跪了,报错旧目录已存在
在这里插入图片描述

假设性思考

方案③虽然不可行,但是请思考两个假设性问题:

  1. 假设此方案可执行,数据是否可以被最终目录继承,不丢失?
  2. 假设此方案可执行,表、目录、文件权限是否可以被继承,不丢失?

……

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值