You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

每日S3文件同步至Redshift时最后一个文件未加载的时区相关问题排查及修复方案咨询

每日S3文件同步至Redshift时最后一个文件未加载的时区相关问题排查及修复方案咨询

碰到这种因时区导致的文件漏加载问题确实挺头疼的,我帮你梳理下代码里的潜在问题,再给出具体的排查和修复思路:

先定位核心问题方向

从你提供的代码和描述来看,大概率是时区不统一导致文件筛选逻辑出错,或者S3文件路径前缀与代码生成的前缀不匹配,最终漏选了最后一个文件。咱们一步步拆解:

排查步骤先做起来

  1. 核对S3文件路径与代码生成的前缀
    找到那个未加载的文件,看看它在S3的存储路径是不是和代码里非backfill模式生成的prefix一致(代码里是context/folder/LA时区日期)。如果文件在另一个日期的路径下,那就是前缀生成逻辑出问题了。

  2. 检查文件的LastModified时间
    S3文件的LastModified默认是UTC时区,把这个时间转换成你业务用的America/Los_Angeles时区,看看是否属于Airflow运行日期对应的LA日期范围。比如Airflow的ds是UTC日期2024-05-21,转成LA可能是2024-05-20,那文件的LA时间是否落在2024-05-20当天?

  3. 加日志验证关键变量
    在代码里多打几个关键日志:

    • 打印cloud_redshift_sync里的airflow_run_date(原始UTC日期)和date_airflow(转换后的LA日期)
    • 在get_file_from_s3里打印每个文件的LastModified(UTC)以及转成LA时区后的时间
    • 打印最终筛选出来的文件列表,确认是否包含了那个未加载的文件

针对性修复方案

1. 统一时区处理,修复文件筛选逻辑

你代码里get_file_from_s3的非backfill分支,原本的时间范围判断被注释掉了,而且即使恢复,也存在时区不统一的问题(S3的LastModified是UTC,代码里的ds是LA时区)。修改后的代码如下:

def get_file_from_s3(s3_client, raw_bucket, folder, ds, backfill, backfill_start, backfill_end):
        print("Inside get_file_from_s3 function")
        files = []
        backfill_start = datetime.strptime(backfill_start, "%Y-%m-%d").replace(tzinfo=pytz.utc)
        backfill_end = datetime.strptime(backfill_end, "%Y-%m-%d").replace(tzinfo=pytz.utc)
        objects=get_all_s3_objects(s3_client, Bucket=raw_bucket, Prefix=folder)
        if (backfill).lower() == "true":
                print(f"Backfill mode enabled from {str(backfill_start)} to {str(backfill_end)}")
                for obj in objects:
                    print(f"Checking object {obj['Key']} with LastModified (UTC) {str(obj['LastModified'])}")
                    if obj['LastModified'] < backfill_end and obj['LastModified'] >= backfill_start:
                        print(f"Adding {obj['Key']} to files for backfill")
                        filename = obj['Key']
                        print(f"File added for backfill: {filename}")
                        files.append(filename)
                return files
        else:
            print(f"Single day mode enabled for LA date {str(ds)}")
            # 把LA时区的ds转成UTC,和S3的LastModified统一时区再比较
            ds_utc = ds.astimezone(pytz.utc)
            ds_next_utc = ds_utc + timedelta(days=1)
            print(f"UTC time range: {ds_utc} to {ds_next_utc}")
            for obj in objects:
                obj_last_modified_utc = obj['LastModified']
                # 转成LA时区方便日志排查
                obj_last_modified_la = obj_last_modified_utc.astimezone(pytz.timezone('America/Los_Angeles'))
                print(f"Checking object {obj['Key']}: LastModified (UTC) {obj_last_modified_utc}, (LA) {obj_last_modified_la}")
                if obj_last_modified_utc < ds_next_utc and obj_last_modified_utc >= ds_utc:
                    filename = obj['Key']
                    print(f"Adding {obj['Key']} to files for single day")
                    files.append(filename)
            print(f"Final selected files: {files}")
            return files

2. 确保prefix生成逻辑与S3存储规则匹配

  • 如果你的S3文件是按UTC日期路径存储的,那代码里的date_airflow不需要转LA时区,直接用原始的airflow_run_date就行:
    # 替换原date_airflow生成代码
    date_airflow = airflow_run_date
    
  • 如果S3确实是按LA日期路径存储的,那当前的prefix生成逻辑没问题,但要确保文件筛选逻辑和路径规则对应。

3. 排查Redshift加载环节的时区问题

如果文件已经被正确筛选到,但Redshift没存储数据,还要检查:

  • Redshift表的时区设置是否和数据中的时间字段一致
  • 加载脚本有没有对时间字段做错误的时区转换,导致数据被过滤或插入失败

备注:内容来源于stack exchange,提问作者devia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 03:23:17