最近想把某個問題的答題方式從線性迴歸改用決策樹演算法,使用sp_execute_external_script呼叫revoscaler下的rxDTree演算法建模時,出現了外部指令碼錯誤 : failure to allocate requested memory訊息,相同的資料量,線性模型rxFastLinear卻可以處理,筆記偵錯之路。
錯誤訊息
觀察錯誤訊息,毫無懸念的是記憶體不足,之前還在SQL 2016 CTP階段時,曾透過修改SQL Bin目錄下的組態檔案rlauncher.config (MEMORY_LIMIT_PERCENT=20),但這次組態檔找不到這組參數可以修改,硬加上組態後反而影響Launchpad.exe運作。
執行rxDTree時,R引擎已經載入9,656,993筆資料了
呼叫rxDTree建模時出現以下錯誤訊息
SQL Server與R執行的架構圖
https://docs.microsoft.com/zh-tw/sql/advanced-analytics/r/new-components-in-sql-server-to-support-r
這次出問題的是BxlServer.exe(Microsoft R Server engine),在步驟4-6。。
其他偵錯資訊
同一個環境,改成輸入少量的100筆資料,很快就把模型建好了: rxDTree使用的參數或是語法沒問題
同一個環境,Microsoftml中的線性迴歸(rxFastLinear)也正常: 這個資料量看起來記憶體應該夠。
但訊息依舊顯示failure to allocate requested memory,除了假設水星逆行,只能先假設記憶體不足,從SQL Server端檢查記憶體開始。
檢查伺服器設定:
伺服器組態: 沒限制
Rlauncher.config也沒有限制
兩個都沒限制,難道碰巧剛剛執行時記憶體真的不夠?(傷腦筋)
觀察執行rxDTree時,Mircosoft R Server Engine吃到10GB左右就Abend
明明還有記憶體
資源管理員(Resource Governor)
得想個辦法讓Launchpad.exe可以吃好吃滿記憶體,很快很快,閱讀了stackoverflow的討論,找到要設定資源管理員(Resource Governor)的解答:
就像SQL 2016 CTP的限制,外部資源只能使用20%記憶體,只是之前設定在組態檔案,現在整合進資源管理員了。
看看SQL2014(還沒有外部資源管理)
管理 > 資源管理員 > 資源集區 > Default
右鍵屬性
再看看SQL2016,果然多了外部資源集區
管理 > 資源管理員 > 資源集區 > Default
最大記憶體限制是20%,的確剛剛看到跑到這台機器的20%記憶體量(10-12GB)左右發生Abend!
設定資源管理員(Resource Governor)-外部資源使用
USE [master]
GO
/****** Object: ExternalResourcePool [default] Script Date: 2017/11/11 下午 03:07:01 ******/
ALTER EXTERNAL RESOURCE POOL [default] WITH (
AFFINITY CPU = AUTO
, MAX_MEMORY_PERCENT = 80
)
GO
ALTER RESOURCE GOVERNOR RECONFIGURE
指令執行後:資源管理員啟用
最大記憶體設定為80%
設定完成之後來重新執行建模!
建模成功,900萬筆交易資料跑決策樹花2分鐘,神速! 讓900萬筆資料用新的演算法一起回答問題。
透過DMV查詢資源管理員對於外部資源使用的設定
修改前:
select * from sys.resource_governor_external_resource_pools
修改後:
結論:
- 除了資料量與欄位數,不同演算法也會有不同的記憶體量使用。
- 之前有案子想啟用資源管理員,想用DB登入帳號(SUSER_NAME())或是程式名稱(APP_NAME())來分工作負載群組,這次訊息也提醒自己,這事沒完待續。
參考
SQL Server 2016 R Services: sp_execute_external_script returns 0x80004005 error