Map-Reduce 思想在 ABAP 编程中的一个实际应用案例
ABAP 是一門企業級應用編程語言,其 740 版本于 2013 年發布,增添了許多新的語法和關鍵字:
其中一個亮點就是新引入的 REDUCE 關鍵字。這個關鍵字的作用和在大規模數據集并行計算領域里廣泛使用的 Map-Reduce 編程模型中的 Reduce 操作類似,可以按照字面意思理解為歸約 。
什么是 Map-Reduce 思想?
Map-Reduce 是一種編程模型和相關實現,用于在集群上使用并行分布式算法,生成和處理大規模數據集。
一個 Map-Reduce 程序由一個 Map 過程和一個 Reduce 方法組成。Map 過程負責執行過濾和排序,例如將學生按名字排序到隊列中,每個名稱由一個隊列維護。
Reduce 方法負責執行匯總操作,例如計算學生的數量。
Map-Reduce 系統通過編排分布式服務器,來并行運行各種任務,管理系統各個部分之間的所有通信和數據傳輸,以及提供數據冗余,實現容錯機制。
下圖是 Map Reduce 框架的工作步驟,統計一個海量輸入數據集(比如大于 1TB )中的單詞出現次數。工作步驟包含 Splitting, Mapping, Shuffling, Reducing 以得到最后的輸出結果。
Map-Reduce 編程模型已經廣泛運用于大數據處理領域的工具和框架,比如 Hadoop 之中。
Map-Reduce 在 CRM 系統中的一個實際應用
我們來看一個筆者工作中的實際任務。我需要在某個 CRM 測試系統上做個統計,列出在數據庫表 CRM_JSTO 里,OBTYP(Object Type) 和 STSMA(Status Schema) 這兩列擁有相同值的內表行的個數。大家可以把 OBTYP 和 STSMA 兩列具有相同值的內表行 這個描述,類比成上圖中重復出現的單詞。
下圖是系統中數據庫表 CRM_JSTO 的部分行:
下圖是筆者最終完成的統計結果:
測試系統上數據庫表總的行數超過 55 萬行,其中有 90279 行,只維護了 OBTYP 為TGP,而沒有維護 STSMA.
排名第二的是 COH 和 CRMLEAD 的組合,出現了 78722 次。
上圖這個結果是怎么統計出來的呢?
稍稍做過一些 ABAP 開發的朋友們,一定會立即寫出下面的代碼:
利用 SELECT COUNT 直接在數據庫層完成統計工作。這也是 SAP 推薦的做法,即所謂 Code pusudown 準則,即能放到 HANA 數據庫層面進行的操作,就盡量放進去,以充分利用 HANA 強大的計算能力。在數據庫能夠完成計算邏輯的前提下,盡量避免把計算邏輯放到 Netweaver ABAP 應用層去做。
不過,我們也需要注意到這種方式的局限性。SAP CTO 曾經有過一句名言:
There is no future with ABAP alone
There is no future in SAP without ABAP
未來的 ABAP 會走向開放,互聯的道路?;氐竭@個需求本身,假設待檢索的輸入數據不是從 ABAP 數據庫表中來,而是來自 HTTP 請求,或者第三方系統發過來的 IDOC,此時我們無法再使用 OPEN SQL 本身的 SELECT COUNT 操作,而只能在 ABAP 應用層解決這個問題。
下面介紹兩種用 ABAP 編程語言完成這一需求的解決方案。
第一種方式比較傳統,實現在方法 get_result_traditional_way 里:
ABAP 的 LOOP AT GROUP BY 這個關鍵字組合簡直就像是為這個需求量身定做一般:給 GROUP BY 指定 obtyp 和 stsma 這兩列,然后 LOOP AT 會自動將輸入內表的行記錄根據這兩列的值進行分組,每組行記錄的個數通過關鍵字 GROUP SIZE 自動計算出來,每組各自的 obtyp 和 stsma 的值,以及組內行記錄的條目數,存儲在 REFERENCE INTO 指定的變量 group_ref 里。ABAP 開發人員需要做的事情,只是簡單地把這些結果存儲到輸出內表即可。
第二種辦法,就是本文標題所述,使用 ABAP 740 新引入的 REDUCE 關鍵字:
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( ).上面的代碼乍一看可能覺得有點晦澀,但仔細閱讀后發現這種方式本質上也采用了和方法一 LOOP AT GROUP BY 同樣的分組策略——根據 obtyp 和 stsma 分組,這些子組通過變量 group_key標識,然后通過第 10 行的 REDUCE 關鍵字,通過累加的方式,手動計算這個組的條目數——把一個大的輸入集根據 GROUP BY 指定的條件歸約成一個個規模更小的子集,然后分別針對子集進行計算——這就是 REDUCE 關鍵字通過字面含義傳遞給 ABAP 開發人員的處理思想。
總結和比較一下這三種實現方式:當待統計的數據源為 ABAP 數據庫表時,一定優先選用 OPEN SQL 的方式,使計算邏輯在數據庫層完成,以獲得最佳的性能。
當數據源并非 ABAP 數據庫表,而分組統計的需求為簡單的計數操作(COUNT)時, 優先用LOOP AT … GROUP BY … GROUP SIZE,使得計數操作通過 GROUP SIZE 在ABAP kernel 完成,以獲得較好的性能。
當數據源并非 ABAP 數據庫表,而分組統計的需求為自定義的邏輯時,用本文介紹的第三種 REDUCE 解法,將自定義統計邏輯寫在第 11 行的 NEXT 關鍵字后。
三種解法的性能評測
我編寫了一個簡單的報表進行性能評測:
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.測試數據如下:
這三種解法的性能依次遞減,不過適用的場合和靈活程度依次遞增。
LOOP AT ... GROUP BY ... GROUP SIZE 這種解決方案,在筆者工作的 ABAP 測試服務器上,處理 55 萬條記錄,用了 0.3 秒,而 REDUCE 則需花費 0.8 秒, 兩種解法的性能處于同一數量級之內。
總結
Map-Reduce 是一種編程模型和相關實現,用于在集群上使用并行分布式算法,生成和處理大規模數據集。ABAP 編程語言從語言層面支持對大規模數據的 REDUCE 操作。本文分享了筆者工作中使用 Map-Reduce 思路處理大規模數據集的一個實際案例,并與傳統的另外兩種解決方案做了比較。在性能不遜于傳統解決方案的前提下,基于 Map-Reduce 的解決方案,具有更為廣泛的應用場合和可擴展性。希望本文分享的內容對大家使用 ABAP 處理類似問題時有所啟發,感謝閱讀。
總結
以上是生活随笔為你收集整理的Map-Reduce 思想在 ABAP 编程中的一个实际应用案例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《塞尔达传说:荒野之息》CEMU模拟器操
- 下一篇: 使用 ABAP 开发的一个基于 Web