張文韜 汪 璐 程耀東
1(中國科學院高能物理研究所計算中心 北京 100049)2(中國科學院大學 北京 100049)
高能物理計算是一種數據密集型計算,存儲系統是其性能決定因素之一.未來10年內,各大物理實驗如江門中微子實驗、高海拔宇宙線實驗、北京譜儀實驗等將累積近100 PB的物理數據.大規模的數據處理給存儲系統提出了“百GBs的聚合帶寬、數萬個客戶端并發訪問、數據可靠性和可用性、跨域站點數據共享以及數據長期保存”等需求和挑戰[1].
高能物理數據處理主要包括模擬計算、重建計算以及物理分析3種類型,每種計算類型各有其特點.高能物理計算中數據是1次寫入、多次讀取.通過監控計算節點上的用戶作業,可以得到文件系統的訪問模式:大部分文件的連續讀請求大小分布在256 KB~4 MB之間,每2個連續讀請求之間都有offset,65%的offset絕對值分布在1~4 MB之間,這說明文件的讀訪問方式為大記錄塊的跳讀.
存儲系統管理員往往會根據系統的歷史情況以及系統的實時狀態,調節相應的參數值以提高系統的訪問性能[2].參數調節和系統的反饋之間是有延時的,如果采取了連續多個調節動作,很難確定究竟是哪個動作起了作用,或者每個動作對結果的影響是多少.因此,人工調節不免存在偏差,況且龐大的參數搜索空間、負載的連續性、負載和設備的多樣性等因素也決定了傳統方法是非常低效的.傳統的參數配置算法包括基于模型的控制反饋算法和無模型的參數搜索2大類.前者需要系統管理員具備豐富的先驗知識且不支持動態負載變化;后者在參數搜索空間很大時優化效率很低.
強化學習由于其優秀的決策能力在人工智能領域得到了廣泛應用.然而,早期的強化學習主要依賴于人工提取特征,難以處理復雜高維狀態空間下的問題.隨著深度學習的發展,算法可以直接從原始的高維數據中提取出特征.深度學習具有較強的感知能力,但是缺乏一定的決策能力;而強化學習具有較強的決策能力,但對感知問題束手無策.因此,將兩者結合起來,優勢互補,能夠為復雜狀態下的感知決策問題提供解決思路.
把調節引擎看作是智能體,把存儲系統看作是環境,存儲系統的參數調節問題是典型的順序決策問題.因此,我們很自然地將強化學習引入到存儲系統的參數調節中.本文基于高能物理計算的數據訪問特點,設計并實現了基于強化學習的參數調節系統,實驗表明,該系統可使Lustre文件系統的吞吐率提升30%左右.
Markov決策過程(Markov decision process, MDP)是強化學習的最基本的理論模型[3].在MDP中,Agent和環境之間的交互過程可如圖1所示:

Fig. 1 Interactive process of reinforcement learning圖1 強化學習交互過程
Agent的目標是找到1個最優策略π*,使得它在任意狀態s和任意時間步驟t下,都能夠獲得最大的長期累積獎賞,即:
(1)
強化學習的目標是尋找最優狀態值函數(optimal state value function):
(2)
基于此推導出貝爾曼方程:
Vπ(s)=Eπ[rt+1+γVπ(s′)].
(3)
強化學習的方法分為基于模型的方法和無模型的方法,而現實世界中大部分問題模型是未知的,所以解決無模型的方法是強化學習的精髓.無模型即意味著狀態轉移概率是未知的,這樣計算值函數時期望是無法計算的,如何計算期望呢?強化學習在此處引入了蒙特卡羅方法.
蒙特卡羅法,即經驗平均法.所謂經驗,是指利用該策略做很多次實驗,產生很多幕數據,這里1幕是1次實驗的意思,平均就是求均值.利用蒙特卡羅方法求狀態s處的值函數時,又可以分為第1次訪問蒙特卡羅方法和每次訪問蒙特卡羅方法.計算為

(4)
蒙特卡羅的方法需要等到每次實驗結束,所以學習效率不高,于是人們又提出了時間差分法(temporal difference, TD),其是蒙特卡羅法與動態規劃法的結合,不用等到實驗結束,而是在每步都更新.TD方法更新值函數的公式為
V(St)←V(St)+α[rt+1+γV(St+1)-V(St)].
(5)
根據行動策略和評估策略是否是1個策略,時間差分法又分同策略法與異策略法.時間差分法的同策略法即Sarsa方法,異策略法即Q-learning方法.
本節介紹調節系統用到的3種強化學習算法:DQN(deep q network)算法、A2C(synchronous advantage actor critic)算法、PPO(proximal policy optimization)算法.
1.2.1 DQN算法
DQN是基于Q-learning的算法,其對Q-learning的修改主要體現在3個方面[4]:
1) DQN利用深度卷積神經網絡逼近值函數.利用神經網絡逼近值函數的做法在強化學習領域早就存在了,可以追溯到20世紀90年代.當時人們發現用深度神經網絡去逼近值函數常常出現不穩定不收斂的情況,所以這個方向一直沒有突破,那DQN做了什么其他的事情呢?
2) DQN利用了經驗回放對強化學習的學習過程進行訓練.人在睡覺的時候,海馬體會把1天的記憶重放給大腦皮層.利用這個啟發機制,DQN構造了一種新的神經網絡訓練方法:經驗回放.訓練的前提是訓練數據是獨立同分布的,而通過強化學習采集到的數據之間存在著關聯性,利用這些數據進行順序訓練,神經網絡當然不穩定.經驗回放可以打破數據間的關聯,從而使網絡得以收斂.
3) DQN獨立設置了目標網絡來單獨處理時間差分算法中的TD偏差.我們稱計算TD目標時所用的網絡為TD網絡.以往的神經網絡逼近值函數時,計算TD目標的動作值函數所用的網絡參數為θ,與梯度計算中要逼近的值函數所用的網絡參數相同,這樣就容易使得數據間存在關聯性,訓練不穩定.為了解決這個問題,DQN中計算TD目標的網絡表示為θ-,計算值函數逼近的網絡表示為θ,用于動作值函數逼近的網絡每一步都更新,而用于計算TD目標的網絡每個固定的步數更新1次.因此值函數的更新變為

(6)
1.2.2 從AC(actor critic)算法到A2C算法的演化
當要解決的問題動作空間很大或者動作為連續集時,值函數方法無法有效求解.策略梯度法是將策略進行參數化,利用線性或非線性函數對策略進行表示,此時強化學習的目標回報函數可表示為

(7)
τ表示智能體的行動軌跡.我們的訓練方法則可以表示為
θt+1←θt+αθU(θ),
(8)
此時問題的關鍵是如何計算策略梯度:

(9)
利用經驗平均來估算梯度:

(10)
式(10)的意義在于,回報越高的動作越努力提高它出現的概率.但是某些情形下,每個動作的總回報rt都不為負,那么所有的梯度值都≥0,此時每個動作出現的概率都會提高,這在很大程度下減緩了學習的速度,而且也會使梯度的方差很大.因此需要對rt使用某種標準化操作來降低梯度的方差.具體地,可以讓rt減去1個基線b(baseline),b通常設為rt的1個期望估計,通過求梯度更新θ,總回報超過基線的動作的概率會提高,反之則降低,同時還可以降低梯度方差(證明略).這種方式被叫作行動者-評論家體系結構.
A3C(asynchronous advantage actor critic)算法為了提升訓練速度采用異步訓練的思想,利用多個線程[5].每個線程相當于1個智能體在隨機探索,多個智能體共同探索,并行計算策略梯度,對參數進行更新.相比DQN算法,A3C算法不需要使用經驗池來存儲歷史樣本并隨機抽取訓練來打亂數據相關性,節約了存儲空間,并且采用異步訓練,大大加倍了數據的采樣速度,也因此提升了訓練速度.與此同時,采用多個不同訓練環境采集樣本,樣本的分布更加均勻,更有利于神經網絡的訓練.
在A3C的基礎上,OpenAI又提出了A2C.如圖2所示,2個算法的不同點在于,在A3C中,每個智能體并行獨立地更新全局網絡,因此,在特定時間,智能體使用的網絡權重與其他智能體是不同的,這樣導致每個智能體使用不同的策略在探索更多的環境.而在A2C中,所有并行智能體的更新先被統一收集起來,然后去更新全局網絡,全局網絡更新完后再將權重分發到各個智能體.為了鼓勵探索,每個智能體最后執行的動作會被加入隨機噪聲.

Fig. 2 Comparison of parameter updating methodsbetween A3C and A2C圖2 A3C與A2C參數更新方式的對比
1.2.3 從TRPO算法到PPO算法的演化
對于普通的策略梯度方法,如果更新步長太大,則容易發散;如果更新步長太小,即使收斂,收斂速度也很慢,因而實際情況下訓練常處于振蕩不穩定的狀態.文獻[6]為了解決普通的策略梯度算法無法保證性能單調非遞減而提出了TRPO(trust region policy optimization)算法,TRPO的主要改進是,它可以設置較大的步長,加快學習速度,同時對目標函數進行優化時有一定的約束條件,滿足該約束條件后,優化是安全的,并能從數學上證明優化單調遞增.約束表示新舊策略差異的KL散度期望小于一定值情形下最大化下面目標表達式,通過KL散度來表示新舊策略差異,它小于一定值表示1個置信域,在這個置信域內進行優化.其目標函數:

(11)
TRPO的標準解法是將目標函數進行一階近似,約束條件利用泰勒進行二階展開,然后利用共軛梯度的方法求解最優的更新參數.然而當策略選用深層神經網絡表示時,TRPO的標準解法計算量會非常大.因為共軛梯度法需要將約束條件進行二階展開,二階矩陣的計算量非常大.PPO是TRPO的一階近似[7],把TRPO中的約束放到目標函數中,減少了計算量,可以應用到大規模的策略更新中,其目標函數為

(12)
參數調優是一個充滿挑戰的研究領域.
傳統的方法有控制反饋算法與參數搜索算法.控制反饋算法是基于模型的方法,當已知負載運行情況且該負載情況非常簡單時效果良好,但是此方法往往需要管理員設置關鍵參數的取值[8].參數搜索算法往往是針對特定系統的特定負載進行一次搜索的過程[9],當負載變化時其不適用.
文獻[10]提出了運用神經網絡來加速傳統的搜索方法.文獻[11]最先嘗試了運用深度強化學習算法來進行參數調優,但是只是針對1臺單獨的服務器.文獻[12]開發了一種系統來對更大規模的集群進行調參,但是其存在5個缺點:
1) 調節參數的范圍較小,其只調節了2個參數.
2) Reward的設置過于簡單,不能適應復雜且動態變化的負載.
3) 狀態State的設置有誤,其將每個客戶端的狀態信息作為智能體的輸入,但是智能體針對每個客戶端的決策應是相互獨立的,即智能體的輸入應是每個單獨客戶端的狀態,返回的動作信息應由接口負責將其正確分發.
4) 訓練過程未做批標準化,這樣會導致訓練不穩定,模型難以收斂.
5) 強化學習算法發展迅速,最初的DQN算法無論是在訓練速度以及模型效果上,已經與前沿算法有了顯著差距.
如圖3所示,系統由策略節點和目標集群組成.策略節點包含強化學習智能體以及信息接口,目標集群上的每個節點都包括1個用來收集節點信息的Monitor和1個用來執行參數調節動作的Actor.系統運行時,每個節點的Monitor每隔固定的時間會收集系統狀態信息,并將信息發送給接口,接口把狀態信息發送給智能體,智能體根據狀態信息返回動作信息,并將其發回給接口,由接口將該動作發送給對應的節點,該節點的Actor負責執行調節動作.然后不斷迭代執行上述過程,直至滿足終止條件.在這整個的交互過程中,強化學習智能體是在不斷訓練提升的.

Fig. 3 Framework of parameter tuning system圖3 參數調節系統框架
在實際的部署過程中,策略節點應部署在目標集群外,以盡量降低系統運行過程中對目標集群的影響.并且,策略節點應盡可能地部署在含有GPU的節點上,以加快訓練速度.
類似于人類需要對環境信息了若指掌后才能做出好的決策一樣,強化學習中的狀態信息是十分重要的,算法會分析這些信息并做出決策.傳統的機器學習方法需要大量的特征工程,近年來深度學習的飛速發展,已經證明其擁有強大的感知能力,所以深度強化學習算法只需要把狀態信息輸入深度神經網絡,神經網絡會自動抽取重要特征進行訓練.
在做狀態信息選取時,應盡可能地把跟系統性能相關的因素都包含進來.本文選取的部分狀態信息如表1所示:

Table 1 Status Information表1 狀態信息
動作決定了參數應如何調節,按離散動作空間來處理,為每個參數指定1個步長,則每個參數對應2個動作:調高和調低,調高即當前參數加步長,調低即當前參數減步長.此外,系統如果根據狀態信息判斷當前沒有需要調節的參數,那么也應可以選擇什么都不做.這樣,動作空間即為:2×參數個數+1.
從安全的角度考慮,還應為每個參數設置范圍,當調節后的值大于或小于該范圍時,相應地設置值為最大值或最小值,以保證系統的正常運行.
當性能優化目標確定時,系統應針對該優化目標進行參數選取.這需要存儲領域一定的先驗知識,即需要知道所關注的性能變化是與哪些參數相關的.如果將存儲系統的全部參數都納入進來,動作空間會很大,模型不好收斂.本文的目標性能是吞吐率,選擇的參數有7個:
1) 最大臟數據量(max dirty space, MD),對象存儲客戶端(object storage client, OSC)中可以寫入并排隊等候的臟數據量.
3) RPC最大并發處理數(max RPCs in flight, MRF),從OSC到其OST的最大可處理的并發RPC數.
4) 文件預讀的最大數據量(max read ahead space, MRA).
5) 客戶端緩存的最大非活動數據量(max cached space, MC).
6) 完整讀取文件的最大大小(max read ahead whole space, MRAW).
7) 線程預取的最大文件屬性數(statahead max, STM).
參數相關信息如表2所示:

Table 2 The Parameters Selected in This Paper andTheir Related Attributes表2 選取的參數及其相關屬性
獎勵信息的設計是強化學習最關鍵之處,因為模型的訓練是依賴獎勵信息進行的,獎勵信息設計的好壞往往決定了1個強化學習算法最后能不能成功應用.
分布式存儲系統的負載是不斷變化的,如果只是簡單定義獎勵信息為當前吞吐率與上一時刻吞吐率之差,當負載劇烈變化時,獎勵信息會相應有很大變化,那么此時的獎勵信息系統無法分辨是因為負載變化導致,還是因為參數調節導致模型無法收斂.
如果不只是考慮當前時間點的吞吐率跟上時間點的吞吐率差,而是考慮動作執行后某一時間段內的吞吐率變化情況作為獎勵信息,比如最近一定步數N的吞吐率差,此處用e表示,即:
(13)
這樣當步數選取合適的值時,可以克服某個時間點(或某個時間段)負載劇烈變化導致獎勵信息受影響的問題.γ值的選取代表了是更關心當下的獎勵還是長期獎勵.
可能會出現這個時間窗口內,負載都一直在不斷加大,從而導致獎勵信息因為負載的原因一直在變大,這樣的情況可以接受的,并且獎勵信息也理應給高,因為這代表系統利用率高(除了吞吐率外也考慮系統的利用率).
接口模塊介于強化學習算法模塊與目標集群之間,負責2個模塊之間的消息通信,使得2個模塊可以獨立開發而互相不影響,踐行了強內聚、松耦合的設計模式.
本文的消息通信模塊選用了ZeroMQ,它是一種基于消息隊列的多線程網絡庫,其對套接字類型、連接處理、幀、甚至路由的底層細節進行抽象,提供跨越多種傳輸協議的套接字,可并行運行,分散在分布式系統間.ZeroMQ將消息通信分成4種模型,分別是1對1結對模型、請求回應模型、發布訂閱模型、推拉模型.基于系統的架構,本文采用了請求回應模型.
1個前饋神經網絡如果具有線性輸出層和至少一層具有任何一種“擠壓”性質的激活函數(例如logistic sigmoid激活函數)的隱藏層,只要給予網絡足夠數量的隱藏單元,它可以以任意的精度來近似任何從1個有限維空間到另一個有限維空間的Borel可測函數,此即萬能近似定理[13].萬能近似定理意味著無論我們試圖學習什么函數,我們知道1個大的多層感知器一定能夠表示這個函數.具有單層的前饋網絡足以表示任何函數,但是網絡層可能大得不可實現,并且可能無法正確地學習和泛化.在很多情況下,使用更深的模型能夠減少表示期望函數所需單元的數量,并且可以減少泛化誤差.
深度學習與強化學習的結合,即用深度神經網絡去逼近強化學習的值函數或策略函數.本文我們采用Pytorch 0.4實現了含3個隱藏層的全連接神經網絡,每個隱藏層的單元數量是狀態空間的2倍,激活函數為ReLU函數,優化算法為Adam算法.
整個存儲系統有2個服務器節點和2個客戶端節點.2個服務器節點中1個為元數據服務器(meta data server, MDS)節點,1個為對象存儲服務器(object storage server, OSS)節點,對象存儲服務器管理著22個對象存儲目標(object storage target, OST).這些服務器節點在測試期間均為閑置節點,以避免其他負載對測試結果的影響.2個客戶端節點采用相同的配置:8個Intel?Xeon?CPU E5620@2.40 GHz,32 GB RAM,網絡帶寬為10 GBs.
策略節點配置有24個Intel?Xeon?CPU E5-2650 v4 @ 2.20 GHz,64 GB RAM,以及2個NVIDIA Tesla K80 GPU.
本文的分布式文件系統選用了Lustre(2.5.3).強化學習算法使用了Pytorch(0.4)實現.
本文選用了Iozone(3.479)來進行測試.Iozone是1個文件系統的 Benchmark 工具,可以測試不同的操作系統中文件系統的讀寫性能.
本文選取7個測試項及其定義為:
1) Write.測試向1個新文件寫入的性能.
2) Re -Write.測試向1個已存在的文件寫入的性能.
3) Read.測試讀1個已存在的文件的性能.
4) Re-Read.測試讀1個最近讀過的文件的性能.
5) Strided Read.測試跳躍讀1個文件的性能.
6) Random Read.測試讀1個文件中的隨機偏移量的性能.
7) Random Write.測試寫1個文件中的隨機偏移量的性能.
測試以吞吐量模式運行,指定每個客戶端節點啟動16個進程來并行讀寫.測試文件大小8 GB,文件塊大小1 MB,跳讀跨度為2 MB.測試時會在測試目錄里生成各個節點的數據包,測試完成后在日志文件里會看到各個節點的讀寫速度、最大速度、最小速度、平均速度、總的吞吐量.
1) 采用Lustre默認參數配置測試3次,取其測試結果均值作為 baseline.
2) 啟動Iozone測試,獨立地對每個算法訓練一定的時間,將訓練好的模型儲存以備調用.
3) 將系統參數重置為默認值.
4) 啟動Iozone測試,同時啟動調節系統,每個算法測試3次后,取其測試結果均值得到最終結果.
搭建好測試環境后,我們對各強化學習算法進行了測試.測試前,對每個算法模型預先訓練24 h,后對每個算法測3次(每次測試花費時長約10 h),取其均值作為測試結果,如表3所示,測試數據為32個并發讀寫進程的平均吞吐率.為了更加直觀地體現測試結果,我們采用柱狀圖對測試數據進行可視化,但由于各測試項數據差異較大,致使數據值較小的測試項展示效果不太明顯,故又對測試數據進行了標準化(范圍100~200),如圖4所示.
Table 3 Performance Test Data表3 各算法性能測試數據 KBs

Table 3 Performance Test Data表3 各算法性能測試數據 KBs
Test ItemsBaselineDQNA2CPPOInitial Write1233118611721215Re-Write1249120211711214Read38613305053698040924Re-Read41777308254124143380Stride Read3493357040513941Random Read1893156625052407Random Write560565581563

Fig. 4 Performance test results圖4 各算法性能測試結果
可以看到,在跳讀和隨機讀測試項上,A2C和PPO強化學習算法都有明顯的提升效果.而DQN算法在這種負載多變的測試環境上表現較差,這在文獻[12]中也有所體現,其測試結果指出DQN算法在測試讀寫比例為1∶1時性能幾乎沒有提升,本文的測試讀寫比例即為1∶1.因此,針對存儲系統參數調優任務來說,策略梯度方法是明顯優于值函數方法的.具體來說,雖然PPO算法對5個測試項都有性能提升,而就高能物理計算環境所關注的跳讀和隨機讀來說,A2C 算法表現更好,是最貼近實際應用的算法.
經過對測試結果的分析,我們發現使用強化學習的方法來對存儲系統的參數進行調節,確實對存儲系統性能有了較為顯著的提升,而當負載發生變化時,其可進行動態適應性的調整,并且對生產系統的影響很小.可以預見:將其部署在生產系統后,在提升系統性能的同時,可大大減少人力成本及時間成本.
本文介紹了一種基于強化學習的參數調節方法,實驗表明該方法使我們所關注的性能得到了顯著提升.事實上該方法不只是針對分布式存儲領域,通過自定義環境和獎勵,它可以泛化到更多的領域中.
總的來說,我們將強化學習應用到分布式存儲領域中只是1次初步的嘗試,有很多方面需要進一步探索:
1) 本文只是對Lustre客戶端的參數進行了調節,未來我們會增加Lustre服務器端以及其他分布式文件系統(如eos,ceph)的參數調節.
2) 狀態的表示.本文我們將當前時間點跟系統性能相關的因素作為狀態來訓練,事實這可能存在一定的局限,只了解到當前的狀態,而對系統的歷史信息以及變化趨勢沒有涉及.因此,未來的工作會對系統的狀態表示加以改進.
3) 算法.強化學習發展迅速,不斷有新的方法被提出,如逆向強化學習、分層強化學習、世界模型等,新的算法的性能往往會有較大提升,我們會在未來的工作中加深對算法的研究以及應用,并在前人的基礎上嘗試提出自己的強化學習算法.