2013-04-27 79 views
0

下面是我想到的hadoop框架處理文本文件。如果我在某個地方出錯,請糾正我。DBRecordReader創建多少次?

每個映射器都作用於包含某些記錄的輸入拆分。 對於每個輸入分割,將創建一個記錄閱讀器,該閱讀器開始從輸入分割中讀取記錄。 如果輸入拆分中有n條記錄,則映射器中的映射方法將被調用n次,然後使用記錄讀取器讀取一個鍵值對。

現在來到數據庫的角度 我在單個遠程節點上有一個數據庫。我想從這個數據庫的表中獲取一些數據。我將使用DBConfigure配置參數,並使用DBInputFormat提及輸入表。現在說,如果我的表共有100條記錄,並執行一個SQL查詢,它會在輸出中生成70條記錄。

我想知道:

如何在InputSplits得到在上述情況下(數據庫)創造出來的?

輸入拆分創建依賴於什麼,我的sql查詢生成的記錄數或表(數據庫)中的記錄總數?

在上述情況(數據庫)中創建多少個DBRecordReaders?

回答

2

如何在InputSplits得到在上述情況下(數據庫)創造出來的?

// Split the rows into n-number of chunks and adjust the last chunk 
// accordingly 
    for (int i = 0; i < chunks; i++) { 
    DBInputSplit split; 
    if ((i + 1) == chunks) 
     split = new DBInputSplit(i * chunkSize, count); 
    else 
     split = new DBInputSplit(i * chunkSize, (i * chunkSize) 
      + chunkSize); 
    splits.add(split); 
    } 

還有就是怎麼樣,而是要明白這取決於我們來看看CHUNKSIZE:

statement = connection.createStatement(); 
results = statement.executeQuery(getCountQuery()); 
results.next(); 

long count = results.getLong(1); 

int chunks = job.getConfiguration().getInt("mapred.map.tasks", 1); 
long chunkSize = (count/chunks); 

所以CHUNKSIZE取數= SELECT COUNT(*) FROM tableName和塊= mapred.map.tasks或1如果劃分這它沒有在配置中定義。

然後,最後,每個輸入分割將有一個RecordReader創建來處理您正在閱讀的數據庫的類型,例如:MySQLDBRecordReader MySQL數據庫。

欲瞭解更多信息請查看source

+0

那麼這是否意味着如果我的表中有100條記錄,並且映射任務的數量設置爲3,那麼在這種情況下塊的數量以及因此創建的輸入拆分的數量是3.第一個塊與33記錄,第二塊有33個記錄,第三塊有34個記錄[已調整]。因此,我們還將爲所有塊/輸入分割創建3個記錄讀取程序? – 2013-04-29 15:15:50

+0

完全正確。請注意上面第一個代碼塊中的註釋_將行分割爲n個塊並相應地調整最後一個塊_因此,如果使用chunkSize = 33和chunk = 3完成代碼,那麼您將最終得到上面描述的內容。最後的地圖(地圖編號3)將觸發(i + 1)==塊,最後的分割將是(塊大小= 33次i = 2)= 66(開始)到100(結束)記錄長 - 這是34! Yei Math! – Engineiro 2013-04-29 19:20:18

+0

我是否回答您的問題令您滿意?如果是這樣,請選擇我的答案。它激勵我們走得更遠 – Engineiro 2013-04-30 18:34:58

1

看來@Engineiro通過採取實際的Hadoop源解釋得很好。只是回答,DBRecordReader的數量等於地圖任務的數量。

爲了進一步解釋,Hadoop Map端框架爲每個Map任務創建一個DBRecordReader實例,以防子JVM不能用於其他Map任務。換句話說,在DBInputFormat的情況下,輸入拆分的數量等於map.reduce.tasks的值。因此,每個Map Task的記錄讀取器都有元信息來構造查詢以從表中獲取數據的子集。每個記錄讀取器執行與下面類似的分頁類型的SQL。

SELECT * FROM (SELECT a.*,ROWNUM dbif_rno FROM (select * from emp) a WHERE rownum <= 6 + 7) WHERE dbif_rno >= 6 

上述SQL是用於第二Map任務至6和13

之間返回行要泛指任何類型的輸入格式,記錄讀者的數目是等於地圖的任務數。

+0

有沒有辦法知道這個元數據以及你構建的示例查詢的方式?這將有很大的幫助... – 2013-04-29 15:28:08

+0

DBInputFormat的輸入分割包含開始和結束行,它與分頁鍵非常相似,例如開始和結束行。這是給MapTask的DBRecordReader的元信息,它使用這些信息並構造SQL並執行。有關信息,請參閱org.apache.hadoop.mapreduce.lib.db.DBRecordReader中的nextKeyValue()方法 – 2013-04-29 19:05:04