国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

關(guān)于同步/異步、阻塞/非阻塞IO的摘要

KavenFan / 918人閱讀

摘要:四種模型把同步阻塞同步非阻塞異步阻塞異步非阻塞的模型講得很清楚。有人對(duì)于模型有一些批判,認(rèn)為多線程模型同步阻塞模型不比事件模型差,講了提到的多線程模型的性能瓶頸在如今的內(nèi)核里已經(jīng)不存在了,而多線程模型開(kāi)發(fā)起來(lái)更簡(jiǎn)單。

四種IO模型

Boost application performance using asynchronous I/O把同步阻塞、同步非阻塞、異步阻塞、異步非阻塞的模型講得很清楚。

處理大量連接的問(wèn)題

event-driven模型派(異步模型):

Dan Kegal"s C10K problem

延伸閱讀:如何解決C10M問(wèn)題 The Secret To 10 Million Concurrent Connections -The Kernel Is The Problem, Not The Solution 這個(gè)presentation主要講了如何消除內(nèi)核network stack的瓶頸,沒(méi)有特別提到采用哪種模型。

有人對(duì)于event-driven模型有一些批判,認(rèn)為多線程模型(同步阻塞模型)不比事件模型差:

Thousands of Threads and Blocking I/O,講了C10K提到的多線程模型的性能瓶頸在如今的內(nèi)核里已經(jīng)不存在了,而多線程模型開(kāi)發(fā)起來(lái)更簡(jiǎn)單。

Why Events are a Bad Idea(for high concurrency servers) Rob von Behren,講了多線程模型的性能瓶頸基本上是因?yàn)閮?nèi)核支持的不好、多線程類庫(kù)有缺陷造成的。認(rèn)為可以通過(guò)編譯器的優(yōu)化、修復(fù)內(nèi)核、修復(fù)多線程類庫(kù)來(lái)達(dá)到和事件驅(qū)動(dòng)模型相當(dāng)?shù)慕Y(jié)果。且認(rèn)為事件驅(qū)動(dòng)模型的開(kāi)發(fā)比較復(fù)雜。

兩種模型也不是說(shuō)水火不容,SEDA提出了可以將兩種模型結(jié)合起來(lái),構(gòu)建更具彈性的系統(tǒng)。10年之后該作者寫(xiě)了篇回顧文章A Retrospective on SEDA。

SEDA提出了幾個(gè)很具有見(jiàn)地的意見(jiàn):

應(yīng)用程序的各個(gè)stage的壓力應(yīng)該是可觀測(cè)和可調(diào)節(jié)的。

應(yīng)用程序應(yīng)該是well-conditioned。

什么是Well-conditioned service?

Intuitively, a service is well-conditioned if it behaves like a simple pipeline, where the depth of the pipeline is determined by the path through the network and the processing stages within the service itself. As the offered load increases, the delivered throughput increases proportionally until the pipeline is full and the throughput saturates; additional load should not degrade throughput. Similarly, the response time exhibited by the service is roughly constant at light load, because it is dominated by the depth of the pipeline. As load approaches saturation, the queueing delay dominates. In the closed-loop scenario typical of many services, where each client waits for a response before delivering the next request, response time should increase linearly with the number of clients. 

The key property of a well-conditioned service is graceful degradation: as offered load exceeds capacity, the service maintains high throughput with a linear response-time penalty that impacts all clients equally, or at least predictably according to some service-specific policy. Note that this is not the typical Web experience; rather, as load increases, throughput decreases and response time increases dramatically, creating the impression that the service has crashed.

簡(jiǎn)單來(lái)說(shuō)當(dāng)負(fù)載超過(guò)一個(gè)應(yīng)用的容量時(shí),其性能表現(xiàn)要滿足以下兩點(diǎn):

吞吐量依然保持穩(wěn)定,可以稍有下跌但絕不會(huì)斷崖式下跌

隨著負(fù)載的增加其延遲線性增長(zhǎng),絕不會(huì)出現(xiàn)尖刺

Reactor pattern

事件驅(qū)動(dòng)模型到最后就變成了Reactor Pattern,下面是幾篇文章:

Scalable IO in Java介紹了如何使用NIO,其中很重要的一點(diǎn)是handler用來(lái)處理non-blocking的task,如果task是blocking的,那么要交給其他線程處理。這不就是簡(jiǎn)化版的SEDA嗎?

Reactor Pattern的老祖宗論文:Reactor Pattern,TL;DR。Understanding Reactor Pattern: Thread-Based and Event-Driven幫助你快速理解什么是Reactor Pattern,文中提到如果要處理10K個(gè)長(zhǎng)連接,Tomcat是開(kāi)不了那么多線程的。對(duì)此有一個(gè)疑問(wèn),Tomcat可以采用NIO/NIO2的Connector,為啥不能算作是Reactor呢?這是因?yàn)門(mén)omcat不是事件驅(qū)動(dòng)的,所以算不上。

The reactor pattern and non-blocking IO對(duì)比了Tomcat和vert.x的性能差別,不過(guò)看下來(lái)發(fā)現(xiàn)文章的壓測(cè)方式存在偏心:

文中給Tomcat的線程少了(只給了500),只利用了40%左右的CPU,而vert.x的測(cè)試的CPU利用率為100%。我把的Tomcat的線程設(shè)到2000,測(cè)試結(jié)果就和vert.x差不多了(驗(yàn)證了多線程模型派的觀點(diǎn))。

vert.x的測(cè)試代碼和Tomcat的測(cè)試代碼不等價(jià),沒(méi)有使用Thread.sleep()。不過(guò)當(dāng)我嘗試在vert.x中使用sleep則發(fā)生了大量報(bào)錯(cuò),應(yīng)該是我的使用問(wèn)題,后面就沒(méi)有深究了。

我寫(xiě)的測(cè)試可以在這里看到。

總結(jié)

看了前面這么多文章其實(shí)總結(jié)下來(lái)就這么幾點(diǎn):

選擇事件驅(qū)動(dòng)模型還是多線程模型要根據(jù)具體情況來(lái)(不過(guò)這是一句廢話,; )

推崇、反對(duì)某個(gè)模型的文章/論文都是在當(dāng)時(shí)的歷史情況下寫(xiě)出來(lái)的,說(shuō)白了就是存在歷史局限性,因此一定要自己驗(yàn)證,當(dāng)時(shí)正確的論斷對(duì)現(xiàn)在來(lái)講未必正確,事情是會(huì)發(fā)生變化的。

看測(cè)試報(bào)告的時(shí)候一定要自己試驗(yàn),有些測(cè)試可能本身設(shè)計(jì)的就有問(wèn)題,導(dǎo)致結(jié)果存在偏見(jiàn)。對(duì)于大多數(shù)性能測(cè)試來(lái)說(shuō),我覺(jué)得只要抓住一點(diǎn)就行了,就是CPU一定要用足。

我們真正應(yīng)該關(guān)注的是不變的東西。

Jeff Darcy"s notes on high-performance server design提到了高性能服務(wù)器的幾個(gè)性能因素:

data copy,問(wèn)題依然存在,需要程序員去優(yōu)化。

context switch,這個(gè)問(wèn)題已經(jīng)沒(méi)有了(見(jiàn)多線程派的幾篇文章),現(xiàn)代操作系統(tǒng)不論有多少thread,開(kāi)銷不會(huì)有顯著增加。

memory allocation,這個(gè)要看看,不過(guò)在Java里似乎和JVM GC有關(guān)。

lock contention,這個(gè)問(wèn)題依然存在,應(yīng)該盡量使用lock-free/non-blocking的數(shù)據(jù)結(jié)構(gòu)。

另外補(bǔ)充:在C10M里提到kernel和內(nèi)核的network stack也是瓶頸。

仔細(xì)看看有些因素不就是事件驅(qū)動(dòng)模型和多線程模型都面臨的問(wèn)題嗎?而又有一些因素則是兩種模型提出的當(dāng)時(shí)所各自存在的短板嗎?而某些短板現(xiàn)在不是就已經(jīng)解決了嗎?

上面說(shuō)的有點(diǎn)虛,下面講點(diǎn)實(shí)在的。

如果你有10K個(gè)長(zhǎng)連接,每個(gè)連接大部分時(shí)間不使用CPU(處于Idle狀態(tài)或者blocking狀態(tài)),那么為每個(gè)連接創(chuàng)建一個(gè)多帶帶的線程就顯得不劃算。因?yàn)檫@樣做會(huì)占用大量?jī)?nèi)存,而CPU的利用率卻很低,因?yàn)榇蠖鄶?shù)時(shí)間線程都閑著。

事件驅(qū)動(dòng)模型解決的是C10K問(wèn)題,注意C是Connection,解決的是用更少的硬件資源處理更多的連接的問(wèn)題,它不解決讓請(qǐng)求更快速的問(wèn)題(這是程序員/算法的問(wèn)題)。

要不要采用事件驅(qū)動(dòng)模型取決于Task的CPU運(yùn)算時(shí)間與Blocking時(shí)間的比例,如果比例很低,那么用事件驅(qū)動(dòng)模型。對(duì)于長(zhǎng)連接來(lái)說(shuō),比如websocket,這個(gè)比例就很小,甚至可近似認(rèn)為是0,這個(gè)時(shí)候用事件驅(qū)動(dòng)模型比較好。如果比例比較高,用多線程模型也可以,它的編程復(fù)雜度很低。

不論是采用哪種模型,都要用足硬件資源,這個(gè)資源可以是CPU也可以是網(wǎng)絡(luò)帶寬,如果發(fā)生資源閑置那你的吞吐量就上不去。

對(duì)于多線程模型來(lái)說(shuō)開(kāi)多少線程合適呢?Thousands of Threads and Blocking I/O里講得很對(duì),當(dāng)能夠使系統(tǒng)飽和的時(shí)候就夠了。比如CPU到100%了、網(wǎng)絡(luò)帶寬滿了。如果內(nèi)存用滿了但是這兩個(gè)都沒(méi)用滿,那么一般來(lái)說(shuō)是出現(xiàn)BUG了。

對(duì)于事件驅(qū)動(dòng)模型來(lái)說(shuō)也有CPU用滿的問(wèn)題,現(xiàn)實(shí)中總會(huì)存在一些阻塞操作會(huì)造成CPU閑置,這也就是為什么SEDA和Scalable IO in Java都提到了要額外開(kāi)線程來(lái)處理這些阻塞操作。關(guān)于如何用滿CPU我之前寫(xiě)了一篇文章如何估算吞吐量以及線程池大小可以看看。

如何用滿網(wǎng)絡(luò)帶寬沒(méi)有什么經(jīng)驗(yàn),這里就不說(shuō)了。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/74082.html

相關(guān)文章

  • PHP socket初探 --- 關(guān)于IO一些枯燥理論

    摘要:原文地址要想更好了解編程,有一個(gè)不可繞過(guò)的環(huán)節(jié)就是在中,一切皆文件實(shí)際上要文件干啥不就是讀寫(xiě)么所以,這句話本質(zhì)就是才是王道用的打開(kāi)文件關(guān)閉文件讀讀寫(xiě)寫(xiě),這叫本地文件在編程中,本質(zhì)就是網(wǎng)絡(luò)所以,在開(kāi)始進(jìn)一步的編程前,我們必須先從概念上認(rèn)識(shí)好 [原文地址:https://blog.ti-node.com/blog...] 要想更好了解socket編程,有一個(gè)不可繞過(guò)的環(huán)節(jié)就是IO.在Lin...

    sf190404 評(píng)論0 收藏0
  • Node - 異步IO和事件循環(huán)

    摘要:它是在的基礎(chǔ)上改進(jìn)的一種方案,通過(guò)對(duì)文件描述符上的事件狀態(tài)進(jìn)行判斷。檢索新的事件執(zhí)行與相關(guān)的回調(diào)幾乎所有情況下,除了關(guān)閉的回調(diào)函數(shù),它們由計(jì)時(shí)器和排定的之外,其余情況將在此處阻塞。執(zhí)行事件的,例如或者。 前言 學(xué)習(xí)Node就繞不開(kāi)異步IO, 異步IO又與事件循環(huán)息息相關(guān), 而關(guān)于這一塊一直沒(méi)有仔細(xì)去了解整理過(guò), 剛好最近在做項(xiàng)目的時(shí)候, 有了一些思考就記錄了下來(lái), 希望能盡量將這一塊的...

    MyFaith 評(píng)論0 收藏0
  • Java NIO淺析

    摘要:阻塞請(qǐng)求結(jié)果返回之前,當(dāng)前線程被掛起。也就是說(shuō)在異步中,不會(huì)對(duì)用戶線程產(chǎn)生任何阻塞。當(dāng)前線程在拿到此次請(qǐng)求結(jié)果的過(guò)程中,可以做其它事情。事實(shí)上,可以只用一個(gè)線程處理所有的通道。 準(zhǔn)備知識(shí) 同步、異步、阻塞、非阻塞 同步和異步說(shuō)的是服務(wù)端消息的通知機(jī)制,阻塞和非阻塞說(shuō)的是客戶端線程的狀態(tài)。已客戶端一次網(wǎng)絡(luò)請(qǐng)求為例做簡(jiǎn)單說(shuō)明: 同步同步是指一次請(qǐng)求沒(méi)有得到結(jié)果之前就不返回。 異步請(qǐng)求不會(huì)...

    yeooo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<