從Exchager資料交換到基於trade-off的系統設計

monkeysayhi發表於2018-10-29

可以使用JDK提供的Exchager類進行同步交換:進行資料交換的雙方將互相等待對方,直到雙方的資料都準備完畢,才進行交換。Exchager類很少用到,但理解資料交換的時機卻十分重要,這是一個基於trade-off的系統設計。下述分析方法能擴充套件到諸多系統設計的場景中,幫助我們更好的進行trade-off。

《Java併發程式設計實戰》中介紹了判定資料交換時機的兩種方案,卻不甚清晰。從“時機選擇的目的”出發,實際上存在著三種方案,各方案又有優劣,從而產生了trade-off。本文比較了這三種方案,通過對資料交換時機的分析加強trade-off的意識。

定義

資料交換:在Exchanger的兩方柵欄機制中,雙方互相等待對方的資料。

如讀執行緒在讀取發生前持有“空快取”,寫執行緒在寫入完成後持有“滿緩衝”(“滿”只表示寫入完成),那麼資料交換就是指將讀執行緒的“空緩衝”與寫執行緒的“滿緩衝”交換。

方案比較

依據“時機選擇的的目的”,存在三種方案:

方案1. 交換次數最少

交換次數最少的目的出發,交換行為應該發生在緩衝滿和緩衝空時,這兩種情況下都不得不發生交換,以滿足最低的響應需求

緩衝滿時(填充執行緒的緩衝),填充任務發現無法繼續填充緩衝區,就發起交換,以減少資料(到空)繼續填充;緩衝空時(清空執行緒的緩衝),清空任務發現無法繼續清空,就發起交換,以增加資料(到滿)繼續清空。

也可以將實際的交換任務委派給專門的交換執行緒,填充任務和清空任務都向該執行緒申請執行交換。

方案2. 交換最及時(響應最及時)

響應最及時的目的出發,交換行為應該發生在緩衝剛增加資料和緩衝剛減少資料時,以滿足“存在資料即交換”的最高的響應需求

這種方案相當於去掉了緩衝區。一方面,一旦快取不空就立刻發生交換,交換後就沒有了資料;另一方面,一旦快取空就開始交換資料,交換後快取就不空。看起來資料根本需要寫入快取就完成了交換。

也可以設定一個特別小的緩衝,比如1個位元組。但交換區的緩衝減小,只會讓交換雙方各自維護的緩衝區加大。

方案3. 適度的交換頻率和響應

很明顯:交換次數最少的話,一些資料的處理過程就將延遲;響應最及時的話,交換頻率太高,很浪費效能,甚至大型系統中耗電都會成為問題。

所以可採用折中的方案,達到適度的交換頻率和響應交換行為發生在緩衝被填充到一定程度並保持一定時間 t 後,同時一旦緩衝滿或緩衝空就立即發生交換

如果將時間 t 設定為 0,則退化為方案2;如果將時間 t 設定無窮大,則退化為方案1,從而既能相容以上兩種方案,又能根據實際響應需求靜態配置,甚至根據實時的效能分析結果進行動態調整。

如果將Exchager比作“資料交換系統”,方案3即完成了對“資料交換系統”的trade-off,也就是基於成本(如耗電等)、收益(如延遲等)對系統設計作出的權衡、妥協。

總結

通過對三種Exchager資料交換時機的分析,加強了我們在系統設計中的trade-off意識。

《Java併發程式設計實戰》中介紹了方案1和方案3。直接在書中看到方案1和方案3可能很難理解,但分析了上述trade-off過程後,就能輕鬆理解資料交換的時機了。


本文連結:從Exchager資料交換到基於trade-off的系統設計
作者:猴子007
出處:monkeysayhi.github.io
本文基於 知識共享署名-相同方式共享 4.0 國際許可協議釋出,歡迎轉載,演繹或用於商業目的,但是必須保留本文的署名及連結。

相關文章