全部產品
Search
文件中心

MaxCompute:MapReduce常見問題

更新時間:Jun 19, 2024

本文為您介紹在使用MapReduce時的常見問題。

問題類別

常見問題

功能諮詢

開發MapReduce

常見報錯

MapReduce的輸入源可以是視圖嗎?

不可以,只能是表。

MapReduce的結果寫入到表或分區時,會覆蓋還是追加資料?

會覆蓋掉原有的表資料或分區資料。

MapReduce中是否可以調用Shell檔案?

不可以,受Java沙箱限制。更多Java沙箱資訊,請參見Java沙箱

reduce.setup能否讀入輸入表?

不能讀入輸入表,只能讀入緩衝表。

Mapper是否支援同一表格多分區輸入?

Mapper支援同一表格多分區輸入,同一張表的多個分區可以理解為獨立的兩張表。

Mapper可以直接從Record中讀取分區資料區段的資訊嗎?

Mapper無法從Record中擷取分區欄位資訊,但是可以使用如下代碼。PartitionSpec為分區資訊。

PartitionSpec ps = context.getInputTableInfo().getPartitionSpec();
String area = ps.get(“area”);        

Label和分區是什麼關係?

Label是給不同的輸出處打上的一個標籤,當輸出的時候可以識別是從哪裡輸出的。

MapReduce中是否可以只有Map?

可以,MapReduce支援Map-Only。如果是Map-Only作業,需要顯式指定Reducer數量為0,即job.setNumReduceTasks(0)

Mapper中輸入表中的每條Record資料,是否可以按列名讀取?

可以。輸入表中的每條Record資料不僅可以按序號record.get(i)讀取,還可以按照列名來擷取Record,例如record.get("size")

write(Record key, Record value)write(Record record)的區別是什嗎?

  • write(Record key, Record value):輸出中間結果,例如key.set(“id”, v1),value.set(“size”, v2)。Map產出的中間結果,需要網路傳輸給Reduce,沒有關聯表進行類型推斷,所以必須聲明欄位類型用於序列化。輸出的欄位類型是MaxCompute的欄位類型。

    job.setMapOutputKeySchema(SchemaUtils.fromString(“id:string”));  
    job.setMapOutputValueSchema(SchemaUtils.fromString(“size:bigint”));               
  • write(Record record):輸出結果到最終表,有表進行類型推斷,沒必要聲明欄位類型。

MaxCompute MapReduce中,為什麼要指定兩個JAR,Libjars和Classpath?

本地用戶端會執行一些作業配置等操作,涉及遠程執行。因此本地有一個執行器,遠程有一個執行器。

遠程執行器執行載入遠端Classpath,即-libjars mapreduce-examples.jar。本地執行器載入本地Classpath,所以也要指定-classpath lib/mapreduce-examples.jar

Hadoop MapReduce的源碼,能否直接應用於MaxCompute MapReduce?

不能。MaxCompute MapReduce與Hadoop MapReduce API有一定差別,但整體風格一致。您需要修改Hadoop的源碼,並在MaxCompute MapReduce SDK下編譯通過後,才能在MaxCompute上運行。

MapReduce如何?排序?

排序代碼如下。

//設定排序的欄位(這雷根據i1,i2兩個欄位進行排序)。
job.setOutputKeySortColumns(new String[] { "i1", "i2" });
//設定欄位的排序次序(這裡設定i1為正序排序,i2為逆序排序)。
job.setOutputKeySortOrder(new SortOrder[] { SortOrder.ASC, SortOrder.DESC });        

setOutputKeySortOrder方法的用法,如下所示。

public void setOutputKeySortOrder(JobConf.SortOrder[] order)
功能:設定Key排序列的順序。
參數: Order表示排序列的順序。可選值為ASC(升序)、DESC(降序)。       

MapReduce中的Backups是什嗎?

Backups就是一種加速調優。MaxCompute會查看您的任務,如果存在一些任務的工作量特別大,便為其開啟備份任務,兩個任務執行一樣的資料,結果用最先執行結束的任務,因此存在Backups。但是如果任務非常大,Backups也無法起作用,因為原本的任務和Backups都沒有執行完成。

開發MapReduce時,如何在命令列傳入多個資源?

用逗號(,)分隔字元進行分隔,例如輸入命令jar -resource resource1,resource2,..即可。

在Main方法中如何判斷一個表為空白表?

您可以使用如下方式判斷一個表是否為空白表。

Odps odps=SessionState.get().getOdps();
Table table=odps.tables().get('tableName');
RecordReader recordReader=table.read(1);
if(recordReader.read()==null){
//TO DO      

在MaxCompute MapReduce中,如何設定Java代碼,才能列印出日誌?

推薦如下方法:

  • 可以在代碼中用System.out.println列印日誌,對應日誌輸出位置是在Logview的stdout中。

  • 使用出現異常時,用戶端會返回異常資訊,不需要列印日誌資訊。

  • 使用common logging,日誌輸出到stderr中,可以在Logview的stderr看到。

結果表中會保留兩個MapReduce計算之後的重複資料嗎?

會。查詢資料時,會得到兩條一樣的資料。

Hadoop中可以選擇多個Node進行分布處理(一個Node表示一台機器),那麼MaxCompute MapReduce進行分布處理時,該如何設定Node?

您不需要自行搭建分配Node,這正是MaxCompute的優點之一。

當運行MapReduce時,MaxCompute底層會根據演算法決定使用的資料分區。

不使用Combiner時輸出正常,使用Combiner後Reduce沒有輸入,是什麼原因?

Reduce輸出的單個Record和Map輸出的Key-Value對不一致,導致產生上述情況。

在MapOnly中,為什麼程式沒有指定輸出Table的Schema格式?

輸出表的Schema是需要預先建立好的,在create table的時候指定。MapOnly程式內部不用指定Schema,可以直接輸出。

如何在本地調用MaxCompute伺服器運行MapReduce任務?

正常情況下,MaxCompute的JAR包需要在命令列工具上執行jar命令來執行,具體文法請參見MapReduce作業提交

您也可以通過類比的方式整合到自己的工程中,方法如下:

  1. 設定包依賴。

    除了基本的SDK,還需要其他的幾個依賴包,您可在用戶端工具的lib檔案夾中找到。lib檔案夾中也包含了SDK的JAR包,建議您在匯入包的時候把最新的用戶端工具lib檔案夾中的JAR包全部導進來。

  2. 上傳JAR包。

    將在本地測試通過的MapReduce程式,打成JAR包並上傳,假設此JAR包的名稱是mr.jar。更多上傳資源操作,請參見資源操作

  3. 設定運行方式。

    配置Jobconf,配置樣本如下。

    //配置MaxCompute串連資訊。
    Account account = new AliyunAccount(accessid, accesskey);
    Odps odps = new Odps(account);
    odps.setEndpoint(endpoint);
    odps.setDefaultProject(project);
    //擷取session。
    SessionState ss = SessionState.get();
    ss.setOdps(odps);
    ss.setLocalRun(false);  //設定false,表示在伺服器上跑。如果要在本地調試,直接設定為true。
    //正常的設定jobconf等代碼。
    Job job = new Job();
    String resource = “mr.jar”;
    job.setResources(resource); //這一步類似Jar命令的jar -resources mr.jar。
    //後面的代碼為正常的MapReduce代碼規則。
    job.setMapperClass(XXXMapper.class);
    job.setReducerClass(XXXReducer.class);                            

    配置完成之後,您可以直接運行MapReduce任務。

執行MaxCompute MapReduce時,報錯BufferOverflowException,如何解決?

  • 問題現象

    執行MaxCompute MapReduce時,返回如下報錯。

    FAILED: ODPS-0123131:User defined function exception - Traceback:
         java.nio.BufferOverflowException
         at java.nio.DirectByteBuffer.put(Unknown Source)
         at com.aliyun.odps.udf.impl.batch.TextBinary.put(TextBinary.java:35)   
  • 產生原因

    一次寫入的資料太大,導致Buffer溢出。

  • 解決措施

    MaxCompute的單個欄位可以寫入的資料類型限制如下。

    String      8MB
    Bigint      -9223372036854775807 ~ 9223372036854775807
    Boolean     True/False
    Double      -1.0 10308 ~ 1.0 10308
    Date        0001-01-01 00:00:00 ~ 9999-12-31 23:59:59                  

執行MaxCompute MapReduce時,報錯Resource not found,如何解決?

提交作業時,要用-resources指定需要的資源,多個資源用逗號(,)分隔。

執行MaxCompute MapReduce時,報錯Class Not Found,如何解決?

執行MapReduce時,以下兩種情況會報此錯誤:

  • classpath參數的類名寫錯,要寫上完整的包名。

  • 打包JAR的時候出錯,注意打包時要把SRC中的源碼都選上。

執行MaxCompute MapReduce時,報錯ODPS-0010000,如何解決?

  • 問題現象:

    執行MaxCompute MapReduce時,返回如下報錯。

    ODPS-0010000: System internal error - get input pangu dir meta fail.
  • 產生原因

    出現上述報錯,是因為您還未建立分區,或是因為分區資料未到位,您就開始使用此分區。

  • 解決措施

    先建立分區,然後再運行MapReduce任務。

執行MaxCompute MapReduce時,報錯Table not found,如何解決?

  • 問題現象:

    執行MaxCompute MapReduce時,返回報錯如下。

    Exception in thread "main" com.aliyun.odps.OdpsException: Table not found: project_name.table_name.
  • 產生原因

    目標專案不正確或目標表不存在。

  • 解決措施

    MapReduce介面的Table Info Builder是ProjectName和TableName,兩個介面分別設定為Project名稱和Table名稱。

執行MaxCompute MapReduce時,報錯ODPS-0123144,如何解決?

  • 問題現象:

    執行MaxCompute MapReduce時,返回報錯如下。

    FAILED: ODPS-0123144: Fuxi job failed - WorkerRestar
  • 產生原因:

    出現上述報錯,是因為叢集的備節點在計算的過程中出現逾時的情況,導致主節點認為備節點故障,所以報錯。逾時10分鐘,即會報錯,暫時不支援使用者自行配置。

  • 解決措施

    這個報錯比較常見的原因是Reduce裡做了大迴圈,例如存在長尾資料或者笛卡爾積。您需要盡量減少這種大迴圈的情況。

執行MaxCompute MapReduce時,報錯java.security.AccessControlException,如何解決?

  • 問題現象

    執行MaxCompute MapReduce時,返回報錯如下。

    FAILED: ODPS-0123131:User defined function exception - Traceback:
    java.lang.ExceptionInInitializerError
     ...
    Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getProtectionDomain")
      at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)       
  • 產生原因

    出現上述報錯,是因為您的代碼違反了沙箱限制,詳情請參見Java沙箱

  • 解決措施

    您需要訪問外部的資源解決此報錯。但MaxCompute目前不支援訪問外部資源,請將外部的處理邏輯和涉及的資料存放區在MaxCompute上進行訪問。您需要讀取一些設定檔,詳情請參見使用資源樣本

執行MaxCompute MapReduce時,報錯 java.io.IOException,如何解決?

  • 問題現象:

    執行MaxCompute MapReduce時,返回報錯如下。

    Exception in thread “main“ java.io.IOException: ODPS-0740001: Too many local-run maps: 101, must be <= 100(specified by local-run parameter ‘odps.mapred.local.map.max.tasks‘)     
  • 產生原因

    local-run maps預設是100,需要調整。

  • 解決措施

    您可以添加-Dodps.mapred.local.map.max.tasks=200配置。

執行MaxCompute MapReduce時,報錯Exceed maximum read times,如何解決?

  • 問題現象:

    執行MaxCompute MapReduce時,返回報錯如下。

    ODPS-0730001: Exceed maximum read times per resource       
  • 產生原因:

    資源檔讀取的次數太多。

  • 解決措施

    請檢查代碼中讀取對應資源的代碼邏輯。一般情況下,資源讀取在setup中執行一次即可,不要在Map或Reduce階段中多次讀取。

執行MaxCompute MapReduce時,Reduce還沒開始執行第一句,便報錯為記憶體溢出,如何解決?

  • 產生原因

    某些資料特別大,下載到記憶體便溢出了。

  • 解決措施

    把Combiner去掉或者在Combiner中限制Sizeset odps.mapred.map.min.split.size=512;

執行MaxCompute MapReduce時,報錯記憶體溢出,如何解決?

記憶體溢出通常是由於記憶體不足導致的,可以通過調整JVM記憶體參數(odps.stage.mapper.jvm.mem和odps.stage.reducer.jvm.mem)解決。例如set odps.stage.mapper.jvm.mem = 2048將記憶體調整為2 GB。

執行MaxCompute MapReduce時,開啟了600個Reducer載入一個設定檔,但是設定檔很小且報錯java.lang.OutOfMemoryError,如何解決?

  • 問題現象

    執行MaxCompute MapReduce時,返回報錯如下。

    java.lang.OutOfMemoryError: Java heap space
  • 產生原因

    MapReduce使用限制導致,請參見使用限制

  • 解決措施

    請參見原生SDK概述進行配置。

執行MaxCompute MapReduce時,報錯ODPS-0420095,如何解決?

  • 問題現象

    執行MaxCompute MapReduce時,返回報錯如下。

    Exception in thread "main" java.io.IOException: com.aliyun.odps.OdpsException: ODPS-0420095: Access Denied - The task is not in release range: LOT
  • 產生原因

    專案為MaxCompute開發人員版資源下的專案,僅支援MaxCompute SQL(支援使用UDF)、PyODPS作業任務,暫不支援MapReduce、Spark等其它任務。

  • 解決措施

    升級專案規格,請參見轉換計費方式

在MapReduce中使用資源時,報錯檔案太多,如何解決?

  • 問題現象

    在MapReduce中使用資源時,返回報錯如下。

     Caused by: com.aliyun.odps.OdpsException: java.io.FileNotFoundException: temp/mr_XXXXXX/resource/meta.user.group.config (Too many open files)
  • 產生原因

    單個作業引用的資源數量不能超過256個,否則報錯。Table和Archive按照一個單位計算。更多限制請參見使用限制

  • 解決措施

    調整引用的資源數量。

在MapReduce程式中使用第三方類,打了一個Assembly的JAR包,運行時報錯找不到類,如何解決?

MaxCompute MapReduce在分布式環境中運行時受到Java沙箱的限制(MapReduce作業的主程式則不受此限制),具體限制請參見Java沙箱

如果您只是需要處理Json,建議您直接使用Gson,同時無需打包帶Gson的Class。Java開源組件裡提供了很多字串轉日期的方法,例如SimpleDateFormat等。

使用開源相容MapReduce在MaxCompute上運行時,報錯顯示下標越界,如何解決?

建議您使用MaxCompute的MapReduce介面進行代碼編寫。同時,非必須情境下建議使用Spark替代MapReduce。