Map-Reduce 思想在 ABAP 编程中的一个实际应用案例
ABAP 是一門企業(yè)級(jí)應(yīng)用編程語(yǔ)言,其 740 版本于 2013 年發(fā)布,增添了許多新的語(yǔ)法和關(guān)鍵字:
其中一個(gè)亮點(diǎn)就是新引入的 REDUCE 關(guān)鍵字。這個(gè)關(guān)鍵字的作用和在大規(guī)模數(shù)據(jù)集并行計(jì)算領(lǐng)域里廣泛使用的 Map-Reduce 編程模型中的 Reduce 操作類似,可以按照字面意思理解為歸約 。
什么是 Map-Reduce 思想?
Map-Reduce 是一種編程模型和相關(guān)實(shí)現(xiàn),用于在集群上使用并行分布式算法,生成和處理大規(guī)模數(shù)據(jù)集。
一個(gè) Map-Reduce 程序由一個(gè) Map 過(guò)程和一個(gè) Reduce 方法組成。Map 過(guò)程負(fù)責(zé)執(zhí)行過(guò)濾和排序,例如將學(xué)生按名字排序到隊(duì)列中,每個(gè)名稱由一個(gè)隊(duì)列維護(hù)。
Reduce 方法負(fù)責(zé)執(zhí)行匯總操作,例如計(jì)算學(xué)生的數(shù)量。
Map-Reduce 系統(tǒng)通過(guò)編排分布式服務(wù)器,來(lái)并行運(yùn)行各種任務(wù),管理系統(tǒng)各個(gè)部分之間的所有通信和數(shù)據(jù)傳輸,以及提供數(shù)據(jù)冗余,實(shí)現(xiàn)容錯(cuò)機(jī)制。
下圖是 Map Reduce 框架的工作步驟,統(tǒng)計(jì)一個(gè)海量輸入數(shù)據(jù)集(比如大于 1TB )中的單詞出現(xiàn)次數(shù)。工作步驟包含 Splitting, Mapping, Shuffling, Reducing 以得到最后的輸出結(jié)果。
Map-Reduce 編程模型已經(jīng)廣泛運(yùn)用于大數(shù)據(jù)處理領(lǐng)域的工具和框架,比如 Hadoop 之中。
Map-Reduce 在 CRM 系統(tǒng)中的一個(gè)實(shí)際應(yīng)用
我們來(lái)看一個(gè)筆者工作中的實(shí)際任務(wù)。我需要在某個(gè) CRM 測(cè)試系統(tǒng)上做個(gè)統(tǒng)計(jì),列出在數(shù)據(jù)庫(kù)表 CRM_JSTO 里,OBTYP(Object Type) 和 STSMA(Status Schema) 這兩列擁有相同值的內(nèi)表行的個(gè)數(shù)。大家可以把 OBTYP 和 STSMA 兩列具有相同值的內(nèi)表行 這個(gè)描述,類比成上圖中重復(fù)出現(xiàn)的單詞。
下圖是系統(tǒng)中數(shù)據(jù)庫(kù)表 CRM_JSTO 的部分行:
下圖是筆者最終完成的統(tǒng)計(jì)結(jié)果:
測(cè)試系統(tǒng)上數(shù)據(jù)庫(kù)表總的行數(shù)超過(guò) 55 萬(wàn)行,其中有 90279 行,只維護(hù)了 OBTYP 為TGP,而沒有維護(hù) STSMA.
排名第二的是 COH 和 CRMLEAD 的組合,出現(xiàn)了 78722 次。
上圖這個(gè)結(jié)果是怎么統(tǒng)計(jì)出來(lái)的呢?
稍稍做過(guò)一些 ABAP 開發(fā)的朋友們,一定會(huì)立即寫出下面的代碼:
利用 SELECT COUNT 直接在數(shù)據(jù)庫(kù)層完成統(tǒng)計(jì)工作。這也是 SAP 推薦的做法,即所謂 Code pusudown 準(zhǔn)則,即能放到 HANA 數(shù)據(jù)庫(kù)層面進(jìn)行的操作,就盡量放進(jìn)去,以充分利用 HANA 強(qiáng)大的計(jì)算能力。在數(shù)據(jù)庫(kù)能夠完成計(jì)算邏輯的前提下,盡量避免把計(jì)算邏輯放到 Netweaver ABAP 應(yīng)用層去做。
不過(guò),我們也需要注意到這種方式的局限性。SAP CTO 曾經(jīng)有過(guò)一句名言:
There is no future with ABAP alone
There is no future in SAP without ABAP
未來(lái)的 ABAP 會(huì)走向開放,互聯(lián)的道路。回到這個(gè)需求本身,假設(shè)待檢索的輸入數(shù)據(jù)不是從 ABAP 數(shù)據(jù)庫(kù)表中來(lái),而是來(lái)自 HTTP 請(qǐng)求,或者第三方系統(tǒng)發(fā)過(guò)來(lái)的 IDOC,此時(shí)我們無(wú)法再使用 OPEN SQL 本身的 SELECT COUNT 操作,而只能在 ABAP 應(yīng)用層解決這個(gè)問(wèn)題。
下面介紹兩種用 ABAP 編程語(yǔ)言完成這一需求的解決方案。
第一種方式比較傳統(tǒng),實(shí)現(xiàn)在方法 get_result_traditional_way 里:
ABAP 的 LOOP AT GROUP BY 這個(gè)關(guān)鍵字組合簡(jiǎn)直就像是為這個(gè)需求量身定做一般:給 GROUP BY 指定 obtyp 和 stsma 這兩列,然后 LOOP AT 會(huì)自動(dòng)將輸入內(nèi)表的行記錄根據(jù)這兩列的值進(jìn)行分組,每組行記錄的個(gè)數(shù)通過(guò)關(guān)鍵字 GROUP SIZE 自動(dòng)計(jì)算出來(lái),每組各自的 obtyp 和 stsma 的值,以及組內(nèi)行記錄的條目數(shù),存儲(chǔ)在 REFERENCE INTO 指定的變量 group_ref 里。ABAP 開發(fā)人員需要做的事情,只是簡(jiǎn)單地把這些結(jié)果存儲(chǔ)到輸出內(nèi)表即可。
第二種辦法,就是本文標(biāo)題所述,使用 ABAP 740 新引入的 REDUCE 關(guān)鍵字:
REPORT zreduce1.DATA: lt_status TYPE TABLE OF crm_jsto.SELECT * INTO TABLE lt_status FROM crm_jsto.DATA(lo_tool) = NEW zcl_status_calc_tool( ).lo_tool = REDUCE #( INIT o = lo_toollocal_item = VALUE zcl_status_calc_tool=>ty_status_result( )FOR GROUPS <group_key> OF <wa> IN lt_statusGROUP BY ( obtyp = <wa>-obtyp stsma = <wa>-stsma )ASCENDING NEXT local_item = VALUE #( obtyp = <group_key>-obtypstsma = <group_key>-stsmacount = REDUCE i( INIT sum = 0 FOR m IN GROUP <group_key>NEXT sum = sum + 1 ) )o = o->add_result( local_item ) ).DATA(ls_result) = lo_tool->get_result( ).上面的代碼乍一看可能覺得有點(diǎn)晦澀,但仔細(xì)閱讀后發(fā)現(xiàn)這種方式本質(zhì)上也采用了和方法一 LOOP AT GROUP BY 同樣的分組策略——根據(jù) obtyp 和 stsma 分組,這些子組通過(guò)變量 group_key標(biāo)識(shí),然后通過(guò)第 10 行的 REDUCE 關(guān)鍵字,通過(guò)累加的方式,手動(dòng)計(jì)算這個(gè)組的條目數(shù)——把一個(gè)大的輸入集根據(jù) GROUP BY 指定的條件歸約成一個(gè)個(gè)規(guī)模更小的子集,然后分別針對(duì)子集進(jìn)行計(jì)算——這就是 REDUCE 關(guān)鍵字通過(guò)字面含義傳遞給 ABAP 開發(fā)人員的處理思想。
總結(jié)和比較一下這三種實(shí)現(xiàn)方式:當(dāng)待統(tǒng)計(jì)的數(shù)據(jù)源為 ABAP 數(shù)據(jù)庫(kù)表時(shí),一定優(yōu)先選用 OPEN SQL 的方式,使計(jì)算邏輯在數(shù)據(jù)庫(kù)層完成,以獲得最佳的性能。
當(dāng)數(shù)據(jù)源并非 ABAP 數(shù)據(jù)庫(kù)表,而分組統(tǒng)計(jì)的需求為簡(jiǎn)單的計(jì)數(shù)操作(COUNT)時(shí), 優(yōu)先用LOOP AT … GROUP BY … GROUP SIZE,使得計(jì)數(shù)操作通過(guò) GROUP SIZE 在ABAP kernel 完成,以獲得較好的性能。
當(dāng)數(shù)據(jù)源并非 ABAP 數(shù)據(jù)庫(kù)表,而分組統(tǒng)計(jì)的需求為自定義的邏輯時(shí),用本文介紹的第三種 REDUCE 解法,將自定義統(tǒng)計(jì)邏輯寫在第 11 行的 NEXT 關(guān)鍵字后。
三種解法的性能評(píng)測(cè)
我編寫了一個(gè)簡(jiǎn)單的報(bào)表進(jìn)行性能評(píng)測(cè):
DATA: lt_status TYPE zcl_status_calc_tool=>tt_raw_input.SELECT * INTO TABLE lt_status FROM crm_jsto.DATA(lo_tool) = NEW zcl_status_calc_tool( ).zcl_abap_benchmark_tool=>start_timer( ). DATA(lt_result1) = lo_tool->get_result_traditional_way( lt_status ). zcl_abap_benchmark_tool=>stop_timer( ).zcl_abap_benchmark_tool=>start_timer( ). lo_tool = REDUCE #( INIT o = lo_toollocal_item = VALUE zcl_status_calc_tool=>ty_status_result( )FOR GROUPS <group_key> OF <wa> IN lt_statusGROUP BY ( obtyp = <wa>-obtyp stsma = <wa>-stsma )ASCENDING NEXT local_item = VALUE #( obtyp = <group_key>-obtypstsma = <group_key>-stsmacount = REDUCE i( INIT sum = 0 FOR m IN GROUP <group_key>NEXT sum = sum + 1 ) )o = o->add_result( local_item ) ).DATA(lt_result2) = lo_tool->get_result( ). zcl_abap_benchmark_tool=>stop_timer( ).ASSERT lt_result1 = lt_result2.測(cè)試數(shù)據(jù)如下:
這三種解法的性能依次遞減,不過(guò)適用的場(chǎng)合和靈活程度依次遞增。
LOOP AT ... GROUP BY ... GROUP SIZE 這種解決方案,在筆者工作的 ABAP 測(cè)試服務(wù)器上,處理 55 萬(wàn)條記錄,用了 0.3 秒,而 REDUCE 則需花費(fèi) 0.8 秒, 兩種解法的性能處于同一數(shù)量級(jí)之內(nèi)。
總結(jié)
Map-Reduce 是一種編程模型和相關(guān)實(shí)現(xiàn),用于在集群上使用并行分布式算法,生成和處理大規(guī)模數(shù)據(jù)集。ABAP 編程語(yǔ)言從語(yǔ)言層面支持對(duì)大規(guī)模數(shù)據(jù)的 REDUCE 操作。本文分享了筆者工作中使用 Map-Reduce 思路處理大規(guī)模數(shù)據(jù)集的一個(gè)實(shí)際案例,并與傳統(tǒng)的另外兩種解決方案做了比較。在性能不遜于傳統(tǒng)解決方案的前提下,基于 Map-Reduce 的解決方案,具有更為廣泛的應(yīng)用場(chǎng)合和可擴(kuò)展性。希望本文分享的內(nèi)容對(duì)大家使用 ABAP 處理類似問(wèn)題時(shí)有所啟發(fā),感謝閱讀。
總結(jié)
以上是生活随笔為你收集整理的Map-Reduce 思想在 ABAP 编程中的一个实际应用案例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 《塞尔达传说:荒野之息》CEMU模拟器操
- 下一篇: 魔兽世界冥殇裂片怎么获得