MaxFrame常见问题

更新时间:
复制为 MD 格式

本文介绍MaxFrame的常见报错问题。

问题1:报错invalid type INT for function UDF definition, you need to set odps.sql.type.system.odps2=true; in order to use it

  • 报错原因:在未开启MaxCompute 2.0数据类型版本的情况下,使用MaxCompute 2.0的数据类型,导致作业执行时出现错误。

  • 解决方案:通过Flag开启MaxCompute 2.0数据类型,示例如下:

    from maxframe import config
    # 在new_session之前添加
    config.options.sql.settings = {
      "odps.sql.type.system.odps2": "true"
    }
    

问题2:报错UDF : No module named 'cloudpickle'

  • 报错原因:缺少依赖的cloudpickle包。

  • 解决方案:引用MaxCompute基础镜像,示例如下:

    from maxframe import config
    # 在new_session之前添加
    config.options.sql.settings = {
      "odps.session.image": "common",
    }
    

问题3:如何在DataFrame提交(apply)的UDF中实现资源复用

在部分UDF场景中,可能涉及到某些较多的资源创建或者销毁行为(例如初始化数据库连接、加载模型等),希望在每个UDF被加载时只会执行一次。

可以利用Python中函数参数默认值只被初始化一次的特性,实现资源复用。

例如,在下述UDF中,模型只会被加载一次。

def predict(s, _ctx={}):
  from ultralytics import YOLO
  # _ctx 的初始值是一个空 dict,在 Python 执行过程中只会被初始化一次。
  # 使用模型时,可以先判断 _ctx 中是否存在该模型,不存在则执行加载,然后存入 dict 中。
  if not _ctx.get("model", None):
    model = YOLO(os.path.join("./", "yolo11n.pt"))
    _ctx["model"] = model
  model = _ctx["model"]

  # 后续调用模型的相关接口
  

下面给出了一个需要销毁资源的UDF示例,该示例中使用了一个自定义的类MyConnector负责创建和关闭数据库连接。

class MyConnector:

  def __init__(self):
    # 在 __init__ 中创建数据库连接
    self.conn = create_connection()

  def __del__(self):
    # 在 __del__ 中关闭数据库连接
    try:
      self.conn.close()
    except:
      pass


def process(s, connector=MyConnector()):
  # 直接调用 connector 内的数据库连接,无需在 UDF 内部再次执行连接创建和关闭
  connector.conn.execute("xxxxx")
  
说明

初始化的实际执行次数取决于运行UDFWorker数量,每个Worker执行UDF时都是一个单独的Python环境。例如,某个UDF调用需要处理10万行数据,总共被分配给了10UDF Worker,每个Worker处理一万条数据,则总共会执行10次初始化,每个Worker在处理1万条数据的过程中,初始化过程只会执行一次。

问题4:如何在DataWorks资源组(独享和通用)更新MaxFrame版本?

问题5:MaxFrame自定义镜像使用实践

问题6:查询报错ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: java.lang.RuntimeException: sequence_row_id cannot be applied because of : no CMF

解决方案:查询时需要加上index_col,代码示例如下:

df2=md.read_odps_table("tablename",index_col="cloumn").to_pandas()
df2=reset_index(inplace=True)

问题7:使用apply等带自定义函数方法时报错Cannot determine dtypes by calculating with enumerate data, please specify it as arguments

  • 报错原因:MaxFrame尝试推导出UDF可能返回的DataFrame/Series类型,这些类型用于检查和构建后续计算的Dataframe/Series,但在下列情况下可能无法正常获得 dtypes。

    • 如果UDF在当前环境下无法正常执行,可能是依赖了一些自定义镜像、第三方依赖或者传入的参数有误。

    • 如果指定了output_type,可能函数实际返回的类型与指定的output_type不符。

  • 解决方案:修改代码或通过指定 `dtypes` 来告知MaxFrame当前UDF返回结果的类型,例如:

    • 返回一个包含一个 int 列的 DataFrame:df.apply(..., dtypes=pd.Series([np.int_]), output_type="dataframe")

    • 返回一个包含 A 和 B 两列的 DataFrame:df.apply(..., dtypes={"A": np.int_, "B": np.str_}, output_type="dataframe")

    • 返回一个类型为 bool 名为 flag 的 Series:df.apply(..., dtype="bool", name="flag", output_type="series")

问题8:如何按照SQL的方式添加flag?

from maxframe import config
config.options.sql.settings = {
    "odps.stage.mapper.split.size": "8",
    "odps.stage.joiner.num": "20"
}

问题9:如何在MaxFrame开发中引用三方包?

参考引用第三方包及镜像

from maxframe.udf import with_resources


@with_resources("resource_name")
def process(row):
    ...
    

问题10:任务报错TypeError: Cannot accept arguments append_partitions

检查PyODPS版本,升级到0.12.0可以解决。

问题11:如何拆解大量JSON字符串字段

MaxFramev1.0.0及以上版本的SDK支持通过如下方式拆解大量JSON字符串字段:

https://maxframe.readthedocs.io/en/latest/reference/dataframe/generated/maxframe.dataframe.Series.mf.flatjson.html

问题12:ODPS-0010000: Fuxi job failed - Job failed for unknown reason, cannot get jobstatus

  • 错误原因:显示或间接使用 @with_python_requirements 等方式安装依赖时安装失败,导致作业无法继续运行。

  • 错误信息解释ODPS-0010000: Fuxi job failed - Job failed for unknown reason, cannot get jobstatus

    PythonPackLogviewstderr中应当能见到更详细的信息,例如下方所见的网络连接失败错误等。

    详细错误信息

    ...
      File "/root/.venv/lib/python3.11/site-packages/odps/models/instance.py", line 469, in _call_with_retry
        return utils.call_with_retry(func, **retry_kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/root/.venv/lib/python3.11/site-packages/odps/utils.py", line 996, in call_with_retry
        return func(*args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^
      File "/root/.venv/lib/python3.11/site-packages/odps/models/instance.py", line 556, in _get_resp
        return self._client.get(self.resource(), action="taskstatus")
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/root/.venv/lib/python3.11/site-packages/odps/rest.py", line 332, in get
        return self.request(url, "get", stream=stream, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/root/.venv/lib/python3.11/site-packages/odps/rest.py", line 213, in request
        return self._request(url, method, stream=stream, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/root/.venv/lib/python3.11/site-packages/odps/rest.py", line 310, in _request
        res = self.session.send(
              ^^^^^^^^^^^^^^^^^^
      File "/root/.venv/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
        r = adapter.send(request, **kwargs)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/root/.venv/lib/python3.11/site-packages/requests/adapters.py", line 700, in send
        raise ConnectionError(e, request=request)
    requests.exceptions.ConnectionError: HTTPConnectionPool(host='service.cn-beijing-intranet.maxcompute.aliyun-inc.com', port=80): Max retries exceeded with url: /api/projects/odps_monitor_odps_cn_beijing_i/instances/20250620142836623g059jg5q8pk?taskstatus&curr_project=odps_monitor_odps_cn_beijing_i (Caused by NameResolutionError("<urllib3.connection.HTTPConnection object at 0x7f326dca0510>: Failed to resolve 'service.cn-beijing-intranet.maxcompute.aliyun-inc.com' ([Errno -2] Name or service not known)"))
    [2025-06-20 14:28:40,903 pythonpack.taskcaller WARNING] Set pack result: Unexpected error occurred, is_succeeded=False
    
  • 解决方案

    1. PythonPack内部错误,考虑安装Pip依赖打包的节点暂时无法正常地访问依赖仓库,可以首先考虑重试,如果重试仍然无法解决,请联系MaxFrame团队。

    2. 如果是周期性作业,为了保证作业的稳定性,可以考虑在使用PythonPack时,直接缓存打包成功的结果,并在之后的每天作业中直接使用缓存的结果。对结果缓存的使用方法如下:

      from maxframe import options
      # 设置 pythonpack 的结果为 prod,这样在之后的作业中,pythonpack 结果会直接使用缓存
      options.pythonpack.task.settings = {"odps.pythonpack.production": "true"}
      

      如果要忽略缓存,需要在@with_python_requirements中添加force_rebuild=True

    3. 也可以考虑暂时不使用PythonPack来安装依赖,离线打包好对应的依赖,上传为MaxFrame Resource,并在对应的作业中引用,MaxFrame会自动将依赖添加到可调用的上下文中。

      PyODPS-Pack是一个简化这个流程的工具,PyODPS-Pack会自动装载相同环境的manylinux docker容器进行打包以避免出现兼容性问题,目前可以在 X86 Linux 机器上运行(M 系列的 ARM 芯片的苹果设备暂时不支持)。

      MaxFrame中使用MaxCompute Resource,可以使用@with_resources

问题13:ODPS-0123055:User script exception

  • 错误原因:这类错误是MaxFrame中最常见的出错类型,发生在UDF的执行中,例如 applyapply_chunkflatmapmaptransform 等算子。该错误信息代表提交的UDF函数运行中抛出了Python异常。目前这类异常主要由以下几个因素导致:

    • 代码本身存在问题,需要再次检查代码逻辑。

    • 错误处理逻辑存在问题,抛出了没有被正确处理的异常,需要再次检查try-except块是否正确的处理了所有的异常。

    • 在 UDF 中访问了网络,而在默认情况下MaxCompute UDF容器中网络是关闭的。

    • 算子中使用dtype或者dtypes声明的输出类型与UDF中实际返回的类型不匹配。

    • UDF中引用了一些运行环境中缺少的依赖,导致无法正确的反序列化客户的代码。

  • 错误信息解释

    ODPS-0123055:User script exception报错大部分为Python异常,可以查看失败的实例的stderr

    以如下测试为例,对一个非JSON字符串执行JSON loads,一定会出现错误,这在数据处理中非常常见。

    1. def simple_failure(row):
    2.    import json
    3.
    4.    text = row["json_text"]
    5.    data = json.loads(text)
    6.    return data
    7.
    8.
    9. df = md.read_pandas(pd.DataFrame({"json_text": ["123", "456", "789"]}))
    10. df.apply(
    11.     simple_failure, axis=1, dtypes={"text": np.str_}, output_type="dataframe"
    12. ).execute()
    

    对应的报错信息如下所示,报错信息中清晰地指出错误发生在 simple_failure 函数中,对应的代码行是line 5,也就是data = json.loads(text)这一行:

    ScriptError: ODPS-0123055: InstanceId: 20250622063246442gquihia95z2
    ODPS-0123055:User script exception - Traceback (most recent call last):
      File "/home/admin/mf_udf_ref_20250622062907997gvwps9irzzc_user_udf_139907101614080.py", line 130, in wrapped
        return func(self, *args, **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^
      File "/home/admin/mf_udf_ref_20250622062907997gvwps9irzzc_user_udf_139907101614080.py", line 262, in process
        for result in self.user_func(*args):
      File "/home/admin/mf_udf_ref_20250622062907997gvwps9irzzc_user_udf_139907101614080.py", line 230, in user_func_caller
        _user_function_results = _user_function(data, *_args, **_kw_args)
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/var/folders/_8/v9wr7xm54bz0rj5pl4p9dkww0000gn/T/ipykernel_18735/2599074506.py", line 5, in simple_failure
      File "/usr/ali/python3.11.7/lib/python3.11/json/__init__.py", line 346, in loads
        return _default_decoder.decode(s)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/ali/python3.11.7/lib/python3.11/json/decoder.py", line 337, in decode
        obj, end = self.raw_decode(s, idx=_w(s, 0).end())
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/ali/python3.11.7/lib/python3.11/json/decoder.py", line 355, in raw_decode
        raise JSONDecodeError("Expecting value", s, err.value) from None
    json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
     | fatalInstance: Odps/meta_dev_20250622063246442gquihia95z2_SQL_0_0_0_job_0/M1#0_0
    

    只要函数能正常序列化,通过对栈的分析,基本能获得到错误发生的位置。

    而如果引用了一些运行环境中缺少的依赖,会导致UDF无法被正常序列化,报错信息中会提示找不到依赖,错误信息中会明显提示出导致无法被序列化的对象或依赖,以如下为例。

    # 假定本地安装了 xxhash 并导入
    import xxhash
    
    
    def type_failure(row):
        # 在 udf 里引用 xxhash
        return str(xxhash.xxh64("hello maxfrmae"))
    
    
    df = md.read_pandas(pd.DataFrame(np.random.randn(3, 5), columns=list("ABCDE")))
    df.apply(
        type_failure, axis=1, dtypes={"hash_value": np.str_}, output_type="dataframe"
    ).execute()
    

    报错会出现如下所示的异常栈,即MaxFrame在运行中尝试unpickle本地的函数失败了,提示No module named 'xxhash',这也是一个非常精准的报错信息。

    File "/home/admin/mf_udf_ref_20250622070426909g26q6zdfar2_user_udf_140362144866304.py", line 209, in __init__
    
        _user_function = cloudpickle.loads(base64.b64decode(b'gAWVnwIAAAAAAACMF2Nsb3VkcGlja2xlLmNsb3VkcGlja2xllIwOX21ha2VfZnVuY3Rpb26Uk5QoaACMDV9idWlsdGluX3R5cGWUk5SMCENvZGVUeXBllIWUUpQoSwFLAEsASwFLBUsDQ1CXAHQBAAAAAAAAAAAAAHQCAAAAAAAAAAAAAKACAAAAAAAAAAAAAAAAAAAAAAAAAABkAaYBAACrAQAAAAAAAAAApgEAAKsBAAAAAAAAAABTAJROjA5oZWxsbyBtYXhmcm1hZZSGlIwDc3RylIwGeHhoYXNolIwFeHhoNjSUh5SMA3Jvd5SFlIxNL3Zhci9mb2xkZXJzL184L3Y5d3I3eG01NGJ6MHJqNXBsNHA5ZGt3dzAwMDBnbi9UL2lweWtlcm5lbF8xODczNS81NTM2OTIzNjYucHmUjAx0eXBlX2ZhaWx1cmWUaBJLBEMdgADdCw6Ndo98inzQHCzRDy3UDy3RCy7UCy7QBC6UQwCUKSl0lFKUfZQojAtfX3BhY2thZ2VfX5ROjAhfX25hbWVfX5SMCF9fbWFpbl9flHVOTk50lFKUjBxjbG91ZHBpY2tsZS5jbG91ZHBpY2tsZV9mYXN0lIwSX2Z1bmN0aW9uX3NldHN0YXRllJOUaBx9lH2UKGgZaBKMDF9fcXVhbG5hbWVfX5RoEowPX19hbm5vdGF0aW9uc19flH2UjA5fX2t3ZGVmYXVsdHNfX5ROjAxfX2RlZmF1bHRzX1+UTowKX19tb2R1bGVfX5RoGowHX19kb2NfX5ROjAtfX2Nsb3N1cmVfX5ROjBdfY2xvdWRwaWNrbGVfc3VibW9kdWxlc5RdlIwLX19nbG9iYWxzX1+UfZRoDGgAjAlzdWJpbXBvcnSUk5RoDIWUUpRzdYaUhlIwLg=='), buffers=[ ])
    
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/ali/python3.11.7/lib/python3.11/site-packages/cloudpickle/cloudpickle.py", line 649, in subimport
        __import__(name)
    ModuleNotFoundError: No module named 'xxhash'
    
  • 以下是其他几种类型错误的错误代码和错误信息

    • 错误的返回类型:

      def type_failure(row):
          text = row["A"]
          # 返回一个 float
          return text
      
      df = md.read_pandas(pd.DataFrame(np.random.randn(3, 5), columns=list("ABCDE")))
      
      # 声明返回一个 dataframe 包含一个名字为 A 的 str 列
      df.apply(type_failure, axis=1, dtypes={"A": np.str_}, output_type="dataframe").execute()
      

      会提醒期望一个unicode,也就是str,但是得到了一个 float 类型。这些信息通常由 dtypes 或者 dtype 指定,请确保声明的类型与函数里实际返回的类型一致。

      ScriptError: ODPS-0123055: InstanceId: 202506220642291g87d6xot20d
      ODPS-0123055:User script exception - Traceback (most recent call last):
        File "/home/admin/mf_udf_ref_20250622062907997gvwps9irzzc_user_udf_139905326100480.py", line 130, in wrapped
          return func(self, *args, **kw)
                 ^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/admin/mf_udf_ref_20250622062907997gvwps9irzzc_user_udf_139905326100480.py", line 263, in process
          self.forward(*result)
      TypeError: return value expected <class 'unicode'> but <class 'float'> found, value: 1.8263596267666997
       | fatalInstance: Odps/meta_dev_202506220642291g87d6xot20d_SQL_0_0_0_job_0/M1#0_0
      
      • 未开启网络访问的情况下访问

      def request_aliyun_com(row):
          import requests
      
          url = "https://github.com/aliyun/alibabacloud-odps-maxframe-client"
          response = requests.get(url)
          return response.text
      
      
      df.apply(
          request_aliyun_com, axis=1, dtypes={"content": np.str_}, output_type="dataframe"
      ).execute()
      

      对应的错误信息:

      ScriptError: ODPS-0123055: InstanceId: 20250622070516226gzo61d9idlr
      ODPS-0123055:User script exception - Traceback (most recent call last):
        File "/usr/ali/python3.11.7/lib/python3.11/site-packages/urllib3/connection.py", line 196, in _new_conn
          sock = connection.create_connection(
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/usr/ali/python3.11.7/lib/python3.11/site-packages/urllib3/util/connection.py", line 85, in create_connection
          raise err
        File "/usr/ali/python3.11.7/lib/python3.11/site-packages/urllib3/util/connection.py", line 73, in create_connection
          sock.connect(sa)
      ConnectionRefusedError: [Errno 111] Connection refused
      
  • 解决方案

    1. 对于异常报错,需要分析栈信息,找到导致报错的函数,然后尝试修复。

    2. 修复之后可以尝试在本地执行,只需要构造对应的数据在本地当作普通的Python函数调用即可。例如:

    def udf_func(row):
        import json
    
        text = row["json_text"]
        data = json.loads(text)
        return data
    
    # 构造输入传入,在本地测试函数逻辑
    udf_func(pd.Series(['{"hello": "maxfrmae"}'], index=["json_text"]))
    
    1. 对于网络访问的问题,需要开启网络访问,参考网络开通流程

    2. 对于反序列化失败,请仔细检查是否有非预期的依赖被引入,以及是否报错提示的依赖有正确的使用pythonpack安装或者使用resource携带到运行环境中。

问题14:ODPS-0123144: Fuxi job failed - kInstanceMonitorTimeout CRASH_EXIT, usually caused by bad udf performance

  • 错误原因:UDF运行超时。

  • 错误信息解释

    UDF运行中,可能会出现kInstanceMonitorTimeout或者CRASH_EXIT, usually caused by bad udf performance的错误信息。

    这通常意味着UDF运行超时了。在MaxCompute离线计算场景中,UDF通常按batch rows来监控运行时间,如果某个UDFM时间里没有运行完 N条,就会导致超时失败,配置方式如下:

    from maxframe import options
    options.sql.settings = {
        # batch 大小,默认 1024,最小 1
        "odps.sql.executionengine.batch.rowcount": "1",
        # batch 超时时间,默认 1800,最大 3600
        "odps.function.timeout": "3600",
    }
    
  • 解决方案

    根据实际情况,修改batch大小和batch超时时间。

问题15:ODPS-0123144: Fuxi job failed - fuxi job failed, Job exceed live limit

  • 错误原因:MaxCompute 的作业有最大超时时间,默认为24小时,超过24小时就会导致作业运行失败。

  • 错误信息解释

    调度系统认为作业超时,杀掉了作业,作业本身会显示 Failed 状态。如果是 DataWorks 上运行的作业,可能会有另外的超时时间,需要询问 DataWorks 团队(会呈现 Cancel 状态)。

  • 解决方案

    根据实际需要调整作业最大运行时长。

    from maxframe import options
    
    # 设置 MaxFrame Session 最长生存时间
    options.session.max_alive_seconds = 72 * 60 * 60
    # 设置 MaxFrame Session 最长空闲超时时间
    options.session.max_idle_seconds = 72 * 60 * 60
    options.sql.settings = {
        # 设置 SQL 作业最长运行时间,默认 24h,最长 72h
        "odps.sql.job.max.time.hours": 72,
    }
    

问题16:0130071:[0,0] Semantic analysis exception - physical plan generation failed: unable to retrive row count of file pangu://xxx

  • 错误原因:使用 odps.sql.split.dopFlag指定切分任务数量时,可能会出现该错误。

  • 错误信息解释

    通常表示在源表写入时未生成 meta 文件,无法直接获取到源表的元信息,因此无法对源表进行精确切分。

  • 解决方案

    1. 使用 odps.stage.mapper.split.size 进行代替,单位是 MB,默认是 256,最小为 1。

    2. 必要精确切分时,请考虑重新生成cmf,请联系MaxCompute团队

      此外,如果考虑写出表时需要确保meta文件的生成,可以考虑添加如下Flag:

      from maxframe import options
      
      options.sql.settings = {
          "odps.task.merge.enabled": "false",
          "odps.sql.reshuffle.dynamicpt": "false",
          "odps.sql.enable.dynaparts.stats.collection": "true",
          "odps.optimizer.dynamic.partition.is.first.nth.value.split.enable": "false",
          "odps.sql.stats.collection.aggressive":"true",
      }
      

      我们后续会考虑更优的方式确保精确 split 功能的稳定性。

问题17:ODPS-0130071:[x,y] Semantic analysis exception

  • 错误原因:ReadOdpsQuery场景中如果出现该错误,通常表示 SQL 本身存在语义问题。

  • 错误信息解释

    通常表示 SQL 本身存在语义问题。

  • 解决方案

    1. 检查SQL语法。

    2. 升级MaxFrame客户端,pip install --upgrade maxframe;

    3. 如果还不能解决请联系MaxFrame团队。

问题18:ODPS-0020041:StringOutOfMaxLength:String length X is larger than maximum Y

  • 错误原因:向表中写入数据时,或shuffle过程中,出现了超长的字符串,字符串长度超过了允许的最大长度。

  • 错误信息解释

    MaxCompute中为了确保计算的稳定性,在存储层面限制了最大的单个可读写的字符串长度。最大为268435456。

  • 解决方案

    1. 考虑截断或丢弃可能出错的数据,在ReadOdpsQuery中可以使用LENGTH过滤。

    2. 考虑压缩数据存入,例如 gzip 等,可能会明显缩小字符串长度和大小。

    def compress_string(input_string):
      """
        Compresses a string using gzip.
        """
      encoded_string = input_string.encode('utf-8')
      compressed_bytes = gzip.compress(encoded_string)
      return compressed_bytes
    
    1. 联系MaxCompute团队支持特定数据。

问题19:ODPS-0010000:System internal error - fuxi job failed, caused by: process exited with code 0

  • 错误原因:包含 UDF/AI Function 的作业运行失败。

  • 错误信息解释

    通常表示 UDF/AI Function 运行过程中出现了 OOM。

  • 解决方案

    1. 联系MaxCompute团队确认实际内存使用。

    2. 使用更大的内存运行UDF或者AI Function

      对于 UDF,可以使用 @with_running_options 设置内存。

      @with_running_options(memory="8GB")
      def udf_func(row):
          return row
      

      对于 AI Function,可以在函数中设置 running_options={"memory": "8GB"} 设置内存。

问题20:ODPS-0123131:User defined function exception - internal error - Fatal Error Happended

  • 错误原因:读写外表场景。

  • 错误信息解释:通常表示读写外表过程中出现了一些内部错误。

  • 解决方案:联系MaxCompute团队

问题21:ODPS-0010000:System internal error - com.aliyun.odps.metadata.common.MetastoreServerException: 0420111:Database not found

  • 错误原因:读写表时无法找到指定的 schema/project/table 等信息。

  • 错误信息解释:计算中依赖的元数据无法被找到,作业无法正常运行。

  • 解决方案

    1. 检查 SQL 中使用的 project.schema.table 等信息是否正确,修改后重试。

    2. 联系MaxCompute团队。

问题22:ODPS-0010000:System internal error - fuxi job failed, caused by: process killed by signal 7

  • 错误原因:包含 UDF 的作业运行失败。

  • 错误信息解释:UDF运行时发出异常信号。

  • 解决方案

    1. 检查是否在 UDF 中使用 signal 向进程发送了 cancel,timeout 等信号。

    2. 联系 MaxCompute 团队排查。

问题23:ODPS-0010000:System internal error - fuxi job failed, caused by: StdException:vector::_M_range_insert

  • 错误原因:UDF 相关作业。

  • 错误信息解释:UDF 中运行时无法申请到足够的内存,插入 vector 失败,需要检查业务代码、依赖库和内存设置。

  • 解决方案

    1. 检查 UDF 中是否有内存问题,native 依赖库是否存在内存问题,版本是否最新,调大 UDF 内存申请量。

    2. 联系 MaxCompute 团队排查。

问题24:ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: task:M1 instance count exceeds limit 99999

  • 错误原因:源表比较大的场景下,任何作业都有可能。如果错误地设置了 split flag,可能也会导致该问题。

  • 错误信息解释

    MaxCompute SQL 作业中,在没有任何设置的情况下,默认按 256MB 大小对源表进行分块分布式处理,但如果按 256MB 切分后,总共切分出的块数量超过 99999,就会导致该错误。

  • 解决方案

    1. 使用 odps.stage.mapper.split.size 代替,单位是 MB,默认是 256,最小为 1,可以设置到更大的参数确保切分总数小于 99999。

    2. 使用 odps.sql.split.dop 代替,最小为1,指定切分预期目标数量。

    3. 在各种条件限制下,最终切出来的数据数量可能不等于预期目标数量,因此压着上限设置切分数可能报错。如果上述两种方法多次调整后均不生效,请联系 MaxCompute 团队。

问题25:ODPS-0110061:Failed to run ddltask - ODPS-0130131:Table not found

  • 错误原因:MaxFrame 长时间运行的作业(超过一天)可能出现该错误。

  • 错误信息解释

    MaxFrame 内部 ddltask 运行失败,通常为单个 stage 的计算步骤运行时间超过 24h 的情况下,同 session 上游节点的表过期了。

    这类表通常为计算过程中产生的临时表,即 df.execute() 调用后产生的表。to_odps_table 指定的结果表通常不会有该问题出现。

  • 解决方案

    对临时表设置更大的过期时间,单位为天,默认情况下临时表的过期时间是 1 天。如果计算作业的多个算子可能跨天,通常需要设置该参数。

    options.sql.settings = {
        "session.temp_table_lifecycle": 3,
    }
    

问题26:NoTaskServerResponseError

  • 错误原因:Jupyter Notebook中,MaxFrame创建了 session并运行了部分作业后,停顿了超过 1h,再向下运行脚本时,可能会出现该错误。

  • 错误信息解释

    MaxFrame Session 已经过期,找不到对应的 Session 了。

  • 解决方案

    1. 重新创建 Session,但 cell 前的计算状态不会被保留下来。

    2. 如果有预期的可能会间隔一段时间,并希望可以继续运行,需要设置

    from maxframe import options
    
    # 设置为 24h 过期,默认 1h
    options.session.max_idle_seconds = 60 * 60 * 24
    

问题27:IntCastingNaNError: Cannot convert non-finite values (NA or inf) to integer: Error while type casting for column 'xx'

  • 错误原因:有列类型为BIGINT或者为INT,但其中包含了NULL或者INF,且print运行结果(也包括在 jyputer notebook 中的自动打印)。

  • 错误信息解释

    MaxFrame 的数据构建在 DataFrame 之上,在本地加载数据时,数据会被转换为 Pandas DataFrame。在 Pandas 中,BIGINTINT类型的数据均不能为 NULL(会被作为FLOAT)。

  • 解决方案

    MaxFrame 团队正着手解决这个问题,但类型系统较为复杂,目前还不能给出明确的时间。暂时可考虑如下方法:

    1. 打印之前使用 fillna 填充NULL

    2. 打印之前使用 astype 转换为FLOAT

    3. 非必要情况不要打印该列。

问题28:ODPS-0010000:System internal error - fuxi job failed, SQL job failed after failover for too many times

  • 错误原因

    1. 包含 Reduce/Join 的作业

    2. 且设置了较大的 split.dop 或者较小的 split.size,产生了大量的 mapper instance

    3. 且设置了较大的 reducer.num/joiner.num,产生了大量的 reducer/joiner instance

  • 错误信息解释

    Shuffle 数据过大,导致 Job Master OOM。

  • 解决方案

    1. 调小 mapper 和 reducer/joiner 的数量,最大不要超过 10000

    2. 联系 MaxCompute 团队。

问题29:ODPS-0010000:System internal error - task/common/task_resource_helper.cpp(747): OdpsException: ODPS-0020011:Invalid parameter - Total resource size must be <= 2048MB

  • 错误原因:包含 UDF 的作业,且 UDF 依赖了较大的 Resource。

  • 错误信息解释

    UDF 允许依赖的资源的总大小为 2048MB,超过的作业将无法运行。

  • 解决方案

    尝试使用 external volume 加速的方式从 oss 下载对应的资源,具备更快的下载速率和更高的限制。

问题30:ODPS-0130071:[22,132] Semantic analysis exception - column values_list in source has incompatible type ARRAY/MAP/STRUCT

  • 错误原因:处理的数据包含了数组、字典、结构体。

  • 错误信息解释

    1. 可能是类型声明问题,预期的目标列并非数组、字典、结构体。

    2. 可能是 MaxFrame 类型系统的 BUG。

  • 解决方案

    1. 升级 MaxFrame 客户端 pip install -U maxframe 后重试

    2. 联系 MaxFrame 团队进行排查

问题31:Shuffle output too large

解决方案:使用 odps.sql.sys.flag.fuxi_JobMaxInternalFolderSize flag 指定Shuffle 空间大小,单位是 MB。