智能配料

我們都有多少次聽說“分批處理”會增加延遲? 作為對低延遲系統充滿熱情的人,這讓我感到驚訝。 以我的經驗,正確完成批處理不僅可以提高吞吐量,還可以減少平均延遲并保持一致。

那么,批處理如何神奇地減少延遲呢? 這取決于采用什么算法和數據結構。 在分布式環境中,我們經常不得不將消息/事件分批放入網絡數據包中以實現更大的吞吐量。 我們還采用類似的技術來緩沖對存儲的寫入,以減少IOPS的數量。 該存儲可以是塊設備支持的文件系統或關系數據庫。 大多數IO設備每秒只能處理少量的IO操作,因此最好高效地填充這些操作。 許多批處理方法都涉及等待超時發生,這本質上會增加等待時間。 批處理也可以在超時發生之前被填滿,從而使延遲更加不可預測。

圖1

上面的圖1.描繪了通過引入類似隊列的結構來暫存要發送的消息/事件,以及通過進行批量處理以寫入到設備的線程,將對IO設備的訪問以及對訪問它的爭用分離。

算法

批處理方法使用Java偽代碼中的以下算法:

public final class NetworkBatcherimplements Runnable
{private final NetworkFacade network;private final Queue<Message> queue;private final ByteBuffer buffer;public NetworkBatcher(final NetworkFacade network,final int maxPacketSize,final Queue<Message> queue){this.network = network;buffer = ByteBuffer.allocate(maxPacketSize);this.queue = queue;}public void run(){while (!Thread.currentThread().isInterrupted()){while (null == queue.peek()){employWaitStrategy(); // block, spin, yield, etc.}Message msg;while (null != (msg = queue.poll())){if (msg.size() > buffer.remaining()){sendBuffer();}buffer.put(msg.getBytes());}sendBuffer();}}private void sendBuffer(){buffer.flip();network.send(buffer);buffer.clear();}
}

基本上,等待數據可用,并立即將其發送。 在發送前一條消息或等待新消息時,可能會到達一連串的流量,所有流量都可以批量發送,直到緩沖區的大小,然后發送到基礎資源。 此方法可以使用ConcurrentLinkedQueue ,它提供低延遲并避免鎖定。 但是,如果線程的速度超過批處理程序的速度,則不會產生使生產/發布線程停頓的反壓力,因為隊列不受限制,因此隊列可能會失去控制。 我經常不得不包裝ConcurrentLinkedQueue來跟蹤其大小,從而產生背壓。 根據我的經驗,此大小跟蹤可以使使用此隊列的處理成本增加50%。

該算法遵循單一寫入器原理 ,可在寫入網絡或存儲設備時經常使用,因此避免了第三方API庫中的鎖爭用。 通過避免爭用,由于對鎖的排隊效應,我們避免了通常與資源爭用相關的J曲線延遲配置文件。 使用此算法,隨著負載的增加,延遲會保持恒定,直到底層設備的流量飽和為止,從而導致比“ J曲線”更多的“浴缸”配置文件。

讓我們舉一個處理10個消息的示例,這些消息作為流量突發而到達。 在大多數系統中,流量是突發的,很少在時間上均勻地間隔開。 一種方法將假定不進行批處理,并且線程將直接寫入設備API,如上面的圖1所示。 另一個將使用無鎖數據結構來收集消息,并按照上述算法在循環中收集消耗消息的單個線程。 對于該示例,我們假設花費100 μs的時間將單個緩沖區作為同步操作寫入網絡設備并得到確認。 當等待時間很關鍵時,緩沖區的大小最好小于網絡的MTU。 許多網絡子系統都是異步的,并且支持流水線化,但是我們將做出上述假設以闡明示例。 如果網絡操作在REST或Web服務下使用HTTP之類的協議,則此假設與基礎實現相匹配。

最佳(μs) 平均值(μs) 最差(μs) 發送的數據包
序列號 100 500 1,000 10
智能配料 100 150 200 1-2

如果從線程發起數據直接將消息發送到資源(如果資源無競爭),則將實現絕對最低的延遲。 上表顯示了發生爭用并產生排隊效應時發生的情況。采用串行方法時,將必須發送10個單獨的數據包,并且這些數據包通常需要排隊等待管理對資源的訪問的鎖,因此將按順序進行處理。 上圖假定鎖定策略在沒有可察覺開銷的情況下完美工作,而這在實際應用中是不可能的。

對于批處理解決方案,如果并發隊列有效,則很有可能在首批中拾取所有10個數據包,從而提供最佳的延遲情況。 在最壞的情況下,在第一批中僅發送一條消息,在下一批中發送其他九條消息。 因此,在最壞的情況下,一條消息的延遲為100 μs,隨后的9條消息的延遲為200 μs,因此,最壞情況的平均值為190 μs,這比串行方法要好得多。

當最簡單的解決方案由于爭用而過于簡單時,這就是一個很好的例子。 批處理解決方案有助于在突發條件下實現一致的低延遲,并且最適合吞吐量。 它在接收端的整個網絡上也具有很好的效果,因為接收器必須處理更少的數據包,因此使兩端的通信效率更高。

大多數硬件都會處理緩沖區中的數據(最大固定大小)以提高效率。 對于存儲設備,通常為4KB塊。 對于網絡,這將是MTU,對于以太網,通常為1500字節。 批處理時,最好了解底層硬件并以理想的緩沖區大小寫下批處理,以實現最佳效率。 但是請記住,某些設備需要封裝數據,例如,網絡數據包的以太網和IP標頭,因此緩沖區需要考慮到這一點。

線程切換總是會增加等待時間,并且通過數據結構進行交換的成本也會增加。 但是,使用無鎖技術可以使用許多非常好的非阻塞結構。 對于Disruptor,這種類型的交換可以在短短的50-100ns內完成,因此對于低延遲或高吞吐量的分布式系統而言,選擇智能批處理方法毫無困難。

這項技術可以用于許多問題,而不僅僅是IO。 當發布者突發事件并超過EventProcessor時,Disruptor的核心使用此技術來幫助重新平衡系統。 可以在BatchEventProcessor內部看到該算法。

注意:為了使該算法起作用,排隊結構必須比基礎資源更好地處理爭用。 許多隊列實現在管理爭用方面非常差。 在得出結論之前,請運用科學和測量。

使用干擾器批量處理

下面的代碼顯示了使用Disruptor的EventHandler機制執行的相同算法。 以我的經驗,這是一種非常有效的技術,可以有效地處理任何IO設備,并在處理負載或突發流量時保持較低的延遲。

public final class NetworkBatchHandlerimplements EventHander<Message>
{private final NetworkFacade network;private final ByteBuffer buffer;public NetworkBatchHandler(final NetworkFacade network,final int maxPacketSize){this.network = network;buffer = ByteBuffer.allocate(maxPacketSize);}public void onEvent(Message msg, long sequence, boolean endOfBatch) throws Exception{if (msg.size() > buffer.remaining()){sendBuffer();}buffer.put(msg.getBytes());if (endOfBatch){sendBuffer();}} private void sendBuffer(){buffer.flip();network.send(buffer);buffer.clear();}    
}

與上述算法中的double循環相比,endOfBatch參數大大簡化了批處理。

我簡化了示例以說明算法。 顯然,需要考慮錯誤處理和其他邊緣條件。

IO與工作處理的分離

還有另一個很好的理由將IO與執行工作處理的線程分開。 將IO移交給另一個線程意味著一個或多個工作線程可以繼續處理而不會以一種友好的緩存友好方式進行阻塞。 我發現這對于實現高性能吞吐量至關重要。

如果基礎IO設備或資源短暫飽和,則可以將消息排隊等待批處理程序線程,以允許工作處理線程繼續進行。 然后,批處理線程以最有效的方式將消息饋送到IO設備,從而允許數據結構處理突發數據,如果已完全施加必要的反壓力,則可以很好地分離工作流程中的關注點。

結論

所以你有它。 智能批處理可與適當的數據結構配合使用,以實現一致的低延遲和最大吞吐量。

參考:來自Mechanical慰問博客的JCG合作伙伴 Martin Thompson提供的智能配料 。


翻譯自: https://www.javacodegeeks.com/2012/08/smart-batching.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372314.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372314.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372314.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mysql從myisam_將MySQL從MyISAM轉換成InnoDB錯誤和解決辦法

原來自己用的是為了裝的&#xff0c; 所以在設置database usage(如下圖1)的時候按照discuz官方的建議&#xff0c;選的都是Non-Transactional Database Only(只支持MyISAM數據引擎的非事務數據庫)&#xff0c;用MyISAM數據庫&#xff0c;還沒涉及到需要InnoDB&#xff0c;因此打…

相似性度量中用到的一些距離函數

本文目錄 1. 歐氏距離 2. 曼哈頓距離 3. 切比雪夫距離 4. 閔可夫斯基距離 5. 標準化歐氏距離 6. 馬氏距離 7. 漢明距離 8. 杰卡德距離 & 杰卡德相似系數 9. 相關系數 & 相關距離 10. 信息熵 1. 歐氏距離(Euclidean Distance) 歐氏距離是最易于理解的一種距離計算方法&a…

Spring 3.1配置文件和Tomcat配置

Spring 3.1引入了非常有用的功能&#xff0c;稱為配置文件 。 因此&#xff0c;它易于構建&#xff0c;可以在所有環境&#xff08;開發&#xff0c;測試&#xff0c;生產等&#xff09;中部署的軟件包。 通過定義系統屬性spring.profiles.active&#xff0c; Spring允許我們使…

計算1~n之間所有奇數之和_所有奇數長度子數組的和

所有奇數長度子數組的和題目&#xff1a;給你一個正整數數組 arr &#xff0c;請你計算所有可能的奇數長度子數組的和。子數組 定義為原數組中的一個連續子序列。請你返回 arr 中 所有奇數長度子數組的和 。示例 1&#xff1a;輸入&#xff1a;arr [1,4,2,5,3]輸出&#xff1a…

MYSQL AND OR的聯用

MYSQL AND OR的聯用 MYSQL中”AND”和”OR”都是條件控制符。”AND”是求交集&#xff0c;而”OR”則是求并集&#xff0c;非常多情況下&#xff0c;須要聯用它們兩個。下面是兩張表,我僅僅列出實用的字段。 Table:student_score 學生成績 sid(學生ID) cid(課程ID) score(分數)…

九度oj 題目1456:勝利大逃亡

題目描述&#xff1a;Ignatius被魔王抓走了,有一天魔王出差去了,這可是Ignatius逃亡的好機會.魔王住在一個城堡里,城堡是一個A*B*C的立方體,可以被表示成A個B*C的矩陣,剛開始Ignatius被關在(0,0,0)的位置,離開城堡的門在(A-1,B-1,C-1)的位置,現在知道魔王將在T分鐘后回到城堡,I…

JMX:一些入門說明

JMX&#xff08;Java管理擴展&#xff09;是一種J2SE技術&#xff0c;可以管理和監視Java應用程序。 基本思想是實現一組管理對象&#xff0c;并將實現注冊到平臺服務器&#xff0c;在平臺服務器上&#xff0c;可以使用一組連接器或適配器從本地或遠程調用這些實現到JVM。 一個…

解釋java程序中的異常機制_Java編程中的異常機制

本文旨在以初學者的角度來學習Java異常的知識&#xff0c;盡量簡單&#xff0c;一些細枝末節的知識不會講述&#xff0c;但不影響對知識的掌握。&#xff08;比如try-catch可以嵌套&#xff0c;不太會這么用&#xff09;1.什么是異常我們先舉個例子int x 10/0;在IDE里輸入這樣…

keras做多層神經網絡

一、 背景與目的 背景&#xff1a;配置好了theano&#xff0c;弄了gpu&#xff0c; 要學dnn方法。 目的&#xff1a;本篇學習keras基本用法&#xff0c; 學習怎么用keras寫mlp&#xff0c;學keras搞文本的基本要點。 二、 準備 工具包&#xff1a; theano、numpy、keras等工具包…

配置環境變量

由于寫了一個關于生成簽名需要配置環境變量&#xff0c;所以在這里順便把配置環境變量的步驟說一下 1.右鍵點擊計算機&#xff0c;然后點擊高級系統設置 2.點擊環境變量&#xff0c;下方出現的即為系統變量&#xff0c;雙擊path就能直接修改&#xff0c; 轉載于:https://www.cn…

使用JavaFX AnimationTimer

回想一下&#xff0c;給AnimationTimer起個名字可能不是一個好主意&#xff0c;因為它不僅可以用于動畫&#xff0c;還可以用于測量&#xff1a;fps速率&#xff0c;碰撞檢測&#xff0c;模擬步驟&#xff0c;游戲主循環等實際上&#xff0c;大部分時間我都看到了AnimationTime…

python列表姓氏_python數據分析實例(六) 中國姓氏數據

bokeh聯動柱狀圖&#xff0c;Excel空間柱狀圖、空間熱力圖&#xff0c;Echarts空間柱狀圖&#xff0c;常用函數&#xff1a;df[工作地_省] df[工作地].str.split(省).str[0]df[工作地_市] df[工作地_市] df[工作地].str.split(省).str[1].str.split(市).str[0]df[工作地_市][…

JavaFX 2 GameTutorial第3部分

介紹 ?他是與一個六個部分組成的系列的第3部分的JavaFX 2游戲教程。 如果您錯過了第1部分和第2部分 &#xff0c;建議您在開始本教程之前先進行閱讀。 回顧第二部分&#xff0c;我討論了游戲循環的內部工作原理&#xff0c;其中我們使用動畫&#xff08;JavaFX Timeline &…

Selenium WebDriver + python 自動化測試框架

目標 組內任何人都可以進行自動化測試用例的編寫 完全分離測試用例和自動化測試代碼&#xff0c;就像寫手工測試用例一下&#xff0c;編寫excel格式的測試用例&#xff0c;包括步驟、檢查點&#xff0c;然后執行自動化工程&#xff0c;即可執行功能自動化測試用例&#xff0c;包…

mysql游戲減少積分活動圖_plantuml-繪制狀態圖和活動圖和部署圖?

背景狀態圖&#xff1a;對象的所有狀態&#xff0c;以及基于事件發生的狀態改變的過程&#xff1b;活動圖&#xff1a;用例的工作流程&#xff1b;部署圖&#xff1a;系統的軟硬件物理體系結構&#xff1b;狀態圖基本語法元素語法說明開始和結束狀態[*]標識開始和結束狀態箭頭-…

windows中當你的鍵盤無法使用時我們可以用另一種方法哦

1.使用WinR打開cmd窗口 2.輸入osk回車就出現了一個虛擬的小鍵盤啦&#xff0c;當你的鍵盤壞掉后非常實用哦 轉載于:https://www.cnblogs.com/qianzf/p/6780496.html

python web.py 404_找不到web.py開發服務器-favicon.ico-404

py API文檔引用了一個“web.SEE OTHER()”函數&#xff0c;該函數生成一個303 SEE OTHER響應&#xff0c;將瀏覽器重定向到另一個位置。(請參見http://webpy.org/docs/0.3/api#web.application)這是一個服務器端的解決方案&#xff0c;它不需要在html文件中更改頭&#xff1b;如…

NetBeans 7.2引入了TestNG

代碼生成的優點之一是能夠查看如何使用特定的語言功能或框架。 正如我在《 NetBeans 7.2 beta&#xff1a;更快&#xff0c;更有用》一文中所討論的那樣&#xff0c; NetBeans 7.2 beta提供了TestNG集成 。 除了對該功能的單一引用之外&#xff0c;我在該帖子中沒有進一步闡述&…

Javascript模塊化編程(三):require.js的用法

一、為什么要用require.js&#xff1f; 最早的時候&#xff0c;所有Javascript代碼都寫在一個文件里面&#xff0c;只要加載這一個文件就夠了。后來&#xff0c;代碼越來越多&#xff0c;一個文件不夠了&#xff0c;必須分成多個文件&#xff0c;依次加載。下面的網頁代碼&…

[KISSY5系列]淘寶全終端框架 KISSY 5--從零開始使用

KISSY 是淘寶一個開源的 JavaScript 庫&#xff0c;包含的組件有&#xff1a;日歷、圖片放大鏡、卡片切換、彈出窗口、輸入建議等 一、簡介 KISSY 是一款跨終端、模塊化、高性能、使用簡單的 JavaScript 框架。 除了完備的工具集合如 DOM、Event、Ajax、Anim 等它還提供了經典的…