繁体   English   中英

Airflow Python 脚本退出 Task 退出并返回代码 -9,如何解决?

[英]Airflow Python script exiting with Task exited with return code -9, how to solve that?

我不知道这个错误是什么意思,有人说是内存错误,我不确定,因为错误不是明确的,但是我加载的表很大,100万行。

这是我的脚本中发生错误的部分:

# snapshot_profiles
  df_snapshot_profiles = load_table('snapshot_profiles', conn)

  def return_key(x, key):
    try:
      return (x[key])
    except:
      return (None)

  df_snapshot_profiles['is_manager'] = df_snapshot_profiles["payload"].apply(
      lambda x: return_key(x, 'is_manager'))
  df_snapshot_profiles_actual = df_snapshot_profiles.loc[:,
                                                         ['profile_id', 'date']]
  df_snapshot_profiles_actual.sort_values(['profile_id', 'date'], inplace=True)
  df_snapshot_profiles_actual = df_snapshot_profiles_actual.groupby(
      'profile_id').max().reset_index()
  df_snapshot_profiles.drop(
      ['id', 'payload', 'version', 'company_id', 'inserted_at', 'updated_at'],
      axis=1,
      inplace=True)
  df_snapshot_profiles_actual = df_snapshot_profiles_actual.merge(
      df_snapshot_profiles, on=['date', 'profile_id'], how='left')
  df_snapshot_profiles_actual.drop('date', axis=1, inplace=True)

  df = df.merge(df_snapshot_profiles_actual, on='profile_id', how='left')
  del df_snapshot_profiles

  # Excluir do banco empresas com menos de dois usuários (Empresas de testes)
  df_companies = df.groupby('company_name').count()
  df_companies.reset_index(inplace=True)
  df_companies = df_companies[df_companies['user_id'] > 2]
  df_companies.sort_values('user_id', ascending=False)

  companies = list(df_companies.company_name)

  df['check_company'] = df['company_name'].apply(lambda x: 'T'
                                                 if x in companies else 'F')
  df = df[df['check_company'] == 'T']
  df.drop('check_company', axis=1, inplace=True)

这是加载表并打印内存使用情况的脚本:

def usage():
  process = psutil.Process(os.getpid())
  return process.memory_info()[0] / float(2**20)


def load_table(table, conn):
    print_x(f'{usage()} Mb')
    print_x(f'loading table {table}')
    cursor = conn.cursor()
    cursor.execute(f'''select * from {ORIGIN_SCHEMA}.{table};''')
    df = cursor.fetchall()
    cursor.execute(f'''
        select column_name from information_schema.columns where table_name = '{table}';
    ''')
    labels = cursor.fetchall()
    label_list = []
    for label in labels:
        label_list.append(label[0])
    df = pd.DataFrame.from_records(df, columns=label_list)
    return (df)

有没有办法通过减少内存使用或其他方式来避免错误?

好。 应该是内存不足的问题。 您可以扩展内存或将部分工作切换到核心之外(以批处理模式加载工作)

  • 如果您有预算,请扩展内存。 100 万行 * 每列可怕的字符串长度(1000)=1M*1K = 1G 内存用于数据加载。 合并数据帧或转换数据帧时,您需要额外的内存,因此16G应该可以。

  • 如果您是专家,请尝试退出核心模式,这意味着在硬盘上工作。

    • dask 是核心模块之外的熊猫之一。 批处理模式下的计算机。 缓慢但仍然有效。
    • 使用数据库进行一些功能工作。 我发现尽管需要复杂的 SQL 代码,但大多数数据库都可以像 Pandas 一样完成类似的工作。

祝你好运。 如果您喜欢我的回答,请投票。

我通过实现服务器端游标并分块获取信息解决了这个问题,如下所示:

  serverCursor = conn.cursor("serverCursor")
  serverCursor.execute(f'''select * from {ORIGIN_SCHEMA}.{table};''')

  df = []
  while True:
    records = serverCursor.fetchmany(size=50000)
    df = df + records
    if not records:
      break
  serverCursor.close()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM