億級(無限級)并發(fā)沒那么難_第1頁
億級(無限級)并發(fā)沒那么難_第2頁
億級(無限級)并發(fā)沒那么難_第3頁
億級(無限級)并發(fā)沒那么難_第4頁
億級(無限級)并發(fā)沒那么難_第5頁
已閱讀5頁,還剩56頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

億級(無限級)并發(fā),沒那么難多大并發(fā)是高并發(fā)一、什么是高并發(fā)定義:

高并發(fā)(HighConcurrency)是使用技術手段使系統(tǒng)可以并行處理很多請求。

關鍵指標:-響應時間(ResponseTime)-吞吐量(Throughput)-每秒查詢率QPS(QueryPerSecond)-每秒事務處理量TPS(TransactionPerSecond)-同時在線用戶數(shù)量

關鍵指標的維度:-平均,如:小時平均、日平均、月平均-Top百分數(shù)TP(TopPercentile),如:TP50、TP90、TP99、TP4個9-最大值-趨勢

「并發(fā)」由于在互聯(lián)網(wǎng)架構中,已經(jīng)從機器維度上升到了系統(tǒng)架構層面,所以和「并行」已經(jīng)沒有清晰的界限。「并」(同時)是其中的關鍵。由于「同時」會引發(fā)多久才叫同時的問題,將時間擴大,又根據(jù)不同業(yè)務關注點不同,引申出了引申指標。引申指標:-活躍用戶數(shù),如:日活DAU(DailyActiveUser)、月活MAU(MonthlyActiveUsers)-點擊量PV(PageView)-訪問某站點的用戶數(shù)UV(UniqueVisitor)-獨立IP數(shù)IP(InternetProtocol)-日單量

二、多大算高并發(fā)

這個問題的答案不是一個數(shù)字。來看兩個場景:場景1:

木頭同學去一家創(chuàng)業(yè)公司面試。這個公司做的產(chǎn)品還沒有上線,面試官小熊之前就職過公司的產(chǎn)品都沒有什么量。小熊:“有高并發(fā)經(jīng)驗嗎?”木頭:“我們服務單機QPS2000+,線上有4臺機器負載均衡?!边@時候小熊心里的表情大概是:

但是如果小熊就職的公司是美團之類的。那這這時候小熊心里的表情大概是:

場景2:固態(tài)硬盤SSD(SolidStateDisk)說:我讀取和寫入高達1000MB/秒mysql說:我單機TPS10000+nginx說:我單機QPS10W+靜兒說:給我一臺56核200G高配物理機,我可以創(chuàng)建一個單機QPS1000W

不在同一維度,沒有任何前提,無法比較誰更牛?!拔业南到y(tǒng)算不算高并發(fā)?”這個問題就如同一個女孩子愛問的問題:“我美不美?”

三、高并發(fā)是解決問題的方式

俗話說:「沒有對比就沒有傷害」。算不算高并發(fā),這個問題的答案需要加對比和前提。

對比包括:-業(yè)界:在業(yè)界同類產(chǎn)品中并發(fā)量處于什么位置。舉個栗子??,美團外賣的日單量是千萬級別,一個系統(tǒng)日單量在百萬,雖然差一個數(shù)量級,但是相比大多數(shù)公司已經(jīng)很不錯。-自身:在自身系統(tǒng)中,并發(fā)問題是否已經(jīng)是系統(tǒng)的瓶頸?如果是,這么這個瓶頸怎么打破?如果不是,那當初架構設計的時候是怎么保證并發(fā)不是問題的?(別告訴我:是通過系統(tǒng)沒有訪問量來保證的[擦汗])。

前提包括:-業(yè)務復雜度:舉個栗子??,訪問百度首頁的時間基本就是看自己家的網(wǎng)速,通常情況下都是點一下就看到結果了。而掃描二維碼支付,通常需要等很久,雖然這可能已經(jīng)是業(yè)界最牛的支付公司出品了。-配置:用高配物理機得出的數(shù)據(jù)和最老最低配的虛擬器上的出來的結果是無法比較的。通常的配置有:cpu、內存、磁盤、帶寬、網(wǎng)卡

高并發(fā)的本質不是「多大算高并發(fā)」的一個數(shù)字,而是從架構上、設計上、編碼上怎么來保證或者解決由并發(fā)引起的問題。當別人問你:“做過高并發(fā)嗎?”回答者完全可以描述自己系統(tǒng)的各項指標,然后開始敘述自己對系統(tǒng)中對預防、解決并發(fā)問題作出的思考和行動。這里就有一個非常重要的概念要講一下了,經(jīng)常面試官問,你們系統(tǒng)是多大并發(fā),我說單臺2000,面試官就會問2000QPS,還是PV秒懂QPS、TPS、PV、UV、IPQPS、TPS、PV、UV、GMV、IP、RPS等各種名詞,外行看起來很牛X,實際上每個程序員都是必懂知識點。下面我來一一解釋一下。QPSQueriesPerSecond,每秒查詢數(shù)。每秒能夠響應的查詢次數(shù)。QPS是對一個特定的查詢服務器在規(guī)定時間內所處理流量多少的衡量標準,在因特網(wǎng)上,作為域名系統(tǒng)服務器的機器的性能經(jīng)常用每秒查詢率來衡量。每秒的響應請求數(shù),也即是最大吞吐能力。TPSTransactionsPerSecond的縮寫,每秒處理的事務數(shù)目。一個事務是指一個客戶機向服務器發(fā)送請求然后服務器做出反應的過程。客戶機在發(fā)送請求時開始計時,收到服務器響應后結束計時,以此來計算使用的時間和完成的事務個數(shù),最終利用這些信息作出的評估分。TPS的過程包括:客戶端請求服務端、服務端內部處理、服務端返回客戶端。例如,訪問一個Index頁面會請求服務器3次,包括一次html,一次css,一次js,那么訪問這一個頁面就會產(chǎn)生一個“T”,產(chǎn)生三個“Q”。PVPV(pageview)即頁面瀏覽量,通常是衡量一個網(wǎng)絡新聞頻道或網(wǎng)站甚至一條網(wǎng)絡新聞的主要指標。PV

即pageview,頁面瀏覽量。用戶每一次對網(wǎng)站中的每個頁面訪問均被記錄1次。用戶對同一頁面的多次刷新,訪問量累計。根據(jù)這個特性,刷網(wǎng)站的PV就很好刷了。與PV相關的還有

RV,即重復訪問者數(shù)量(repeatvisitors)。UVUV

訪問數(shù)(UniqueVisitor)指獨立訪客訪問數(shù),統(tǒng)計1天內訪問某站點的用戶數(shù)(以cookie為依據(jù)),一臺電腦終端為一個訪客。IPIP(InternetProtocol)獨立IP數(shù),是指1天內多少個獨立的IP瀏覽了頁面,即統(tǒng)計不同的IP瀏覽用戶數(shù)量。同一IP不管訪問了幾個頁面,獨立IP數(shù)均為1;不同的IP瀏覽頁面,計數(shù)會加1。IP是基于用戶廣域網(wǎng)IP地址來區(qū)分不同的訪問者的,所以,多個用戶(多個局域網(wǎng)IP)在同一個路由器(同一個廣域網(wǎng)IP)內上網(wǎng),可能被記錄為一個獨立IP訪問者。如果用戶不斷更換IP,則有可能被多次統(tǒng)計。GMVGMV,是GrossMerchandiseVolume的簡稱。只要是訂單,不管消費者是否付款、賣家是否發(fā)貨、是否退貨,都可放進GMV。RPSRPS

代表吞吐率,即RequestsPerSecond的縮寫。吞吐率是服務器并發(fā)處理能力的量化描述,單位是reqs/s,指的是某個并發(fā)用戶數(shù)下單位時間內處理的請求數(shù)。

某個并發(fā)用戶數(shù)下單位時間內能處理的最大的請求數(shù),稱之為最大吞吐率。有人把RPS說等效于QPS。其實可以看作同一個統(tǒng)計方式,只是叫法不同而已。RPS/QPS,可以使用apcheab工具進行測量。承載高并發(fā)系統(tǒng)的本質小編剛上班的時候聽到高并發(fā)也是熱血沸騰,呼啦啦的看各個廠的架構,恨不得一下吃完,后面越看越多,發(fā)現(xiàn)怎么各家都一樣的。互聯(lián)網(wǎng)架構的三架馬車屢試不爽,提供了非常強大簡易的標準化解決方案:微服務、消息隊列、定時任務那么高并發(fā)系統(tǒng)的本質是什么呢,第一個:這么多請求來了,要在你機器里跑,是不是需要網(wǎng)絡流量,網(wǎng)絡流量太大是不是把你的程序都卡了?那么就出現(xiàn)了把占流量的圖片資源靜態(tài)資源分析,再CDN一下,你的代碼可以更安心的跑了;第二個就是:這么多請求來了,每個來的請求都是帶著一堆數(shù)據(jù)過來的,第一層要對數(shù)據(jù)做處理,處理完又要存儲,最后的處理都是把數(shù)據(jù)放到內存里,內存遞給cpu來處理,而內存數(shù)據(jù)有時又需要從硬盤拿,這就變成了內存,硬盤,cpu這三者之間的關系了,我們來看看這幾者之間的關系計算機為什么要并發(fā)?

為什么要并發(fā)?因為人類的貪婪!因為人類想要向計算機索取更多!人類想要一步,進一步的壓榨計算機。所以,為了更高效的利用計算機的計算能力,人類想出來了讓計算機并發(fā)執(zhí)行多個任務的辦法!

高速處理器與低速存儲之間的矛盾

我們都知道,計算機中的處理器決定了計算機的處理速度,現(xiàn)代處理器的計算速度是驚人的。但是,處理器并不能自己單獨工作,至少在進行運算時需要與進行內存交互,讀取數(shù)據(jù),或是寫入數(shù)據(jù)。內存這種存儲設備的速度是沒有辦法和處理器相比的,這就造成了造成了處理器計算能力的浪費。這種矛盾就猶如人民日益增長的美好生活需要和不平衡不充分的發(fā)展之間的矛盾一樣,需要聰明的程序員去解決!

調和處理器與內存的矛盾

聰明的人類想到一個辦法,他們在處理器與內存中間,增加一層高速緩存,這層緩存作為處理器與內存之間的緩沖區(qū)。將需要處理的數(shù)據(jù)放入高速緩存,處理結束后再重新放入到內存中,這樣就處理器就不需要無盡的等待與內存之間的交互。這樣一波操作看似十分的完美!但是,請往下看!

高速緩存帶來的并發(fā)問題

高速緩存看似完美的解決了高速的處理器與低速緩存之間的矛盾。但是,問題確被復雜化了。在多處理器的系統(tǒng)中,每個處理器都會有自己的高速緩存,數(shù)據(jù)都會被復制到高速緩存中處理,處理后再放回主內存。由于主內存是共享的,如果不同處理器高速緩存中的數(shù)據(jù)不同,這樣就會造成緩存不一致的問題!

解決并發(fā)問題高速緩存并發(fā)問題

高速緩存的數(shù)據(jù)不一致,這種現(xiàn)象就像鄰居家的小孩子吵架,吵到最后就需要家長出面,把矛盾化解掉。對于計算機來說,這個家長就是緩存一致性協(xié)議,在讀寫操作時按照協(xié)議來操作,避免并發(fā)問題。這樣,就完美的解決了所有的問題!處理器、高速緩存、緩存一致性協(xié)議、主內存計算機高效并發(fā)的其他操作

除了高效緩存機制外,還有一些其他的操作也可以提高效率。例如,與Java的指令重排序一樣,處理器也會根據(jù)執(zhí)行效率,將代碼進行重新排序進行執(zhí)行。有同學可能是我有多線程,我有緩存,我還有神器redis,那才是高并發(fā),沒錯,盡可能高的提高cpu的利用率,把數(shù)據(jù)都放在內存里進行,最靠近cpu的地方,所以我們的所有的互聯(lián)網(wǎng)高并發(fā)架構無非都是把數(shù)據(jù)更可能的不從磁盤里讀取和運算,更多的放入內存,同時通過多線程等方式提高cpu的利用率,哈哈,就是監(jiān)控你cpu有沒有偷懶的時候,壓榨cpu呀;cpu內存總有忙不過來的時候,這個時候怎么辦呢,就是等你不忙的時候來個定時任務或者跑到另外一臺機器的隊列來執(zhí)行。實在單機扛不過來的時候,就喊人來幫忙,于是有了集群;有的單元模塊嫌棄另外的單元模塊影響我運行,于是有了微服務。于是我們看到了大多數(shù)互聯(lián)網(wǎng)架構都是往內存里塞數(shù)據(jù),親切的稱之為緩存,通過優(yōu)化算法減少程序的執(zhí)行時間,實在不行來個磁盤順序寫,如kfaka和mysql的redolog,每次都寫數(shù)據(jù)都嫌累,就有了redispipeline,mysqlredolog組提交這樣的操作在高并發(fā)場景下,有時又需要讀的同時又在寫,怎么避免讀取到臟數(shù)據(jù)呢,這是大多數(shù)中間件要考慮的事情,而大多數(shù)中間件其實是C語言寫的,在這種情況下C一般會干什么事呢,修改數(shù)據(jù)的時原內存塊我不動你,我新在已經(jīng)分配好的內存塊里找一個地方去修改數(shù)據(jù),修改完了,再重新拷貝過去另外一塊就是網(wǎng)絡請求的處理方式,epoll,poll,select,java的nio了,

由于這塊相對比較比較重要,稍微展開一下:用戶空間以及內核空間概念我們知道現(xiàn)在操作系統(tǒng)都是采用虛擬存儲器,那么對32位操作系統(tǒng)而言,它的尋址空間(虛擬存儲空間)為4G(2的32次方)。操心系統(tǒng)的核心是內核,獨立于普通的應用程序,可以訪問受保護的內存空間,也有訪問底層硬件設備的所有權限。為了保證用戶進程不能直接操作內核,保證內核的安全,操心系統(tǒng)將虛擬空間劃分為兩部分,一部分為內核空間,一部分為用戶空間。針對linux操作系統(tǒng)而言,將最高的1G字節(jié)(從虛擬地址0xC0000000到0xFFFFFFFF),供內核使用,稱為內核空間,而將較低的3G字節(jié)(從虛擬地址0x00000000到0xBFFFFFFF),供各個進程使用,稱為用戶空間。每個進程可以通過系統(tǒng)調用進入內核,因此,Linux內核由系統(tǒng)內的所有進程共享。于是,從具體進程的角度來看,每個進程可以擁有4G字節(jié)的虛擬空間??臻g分配如下圖所示:有了用戶空間和內核空間,整個linux內部結構可以分為三部分,從最底層到最上層依次是:硬件-->內核空間-->用戶空間。如下圖所示:需要注意的細節(jié)問題,從上圖可以看出內核的組成:內核空間中存放的是內核代碼和數(shù)據(jù),而進程的用戶空間中存放的是用戶程序的代碼和數(shù)據(jù)。不管是內核空間還是用戶空間,它們都處于虛擬空間中。Linux使用兩級保護機制:0級供內核使用,3級供用戶程序使用。Linux網(wǎng)絡I/O模型我們都知道,為了OS的安全性等的考慮,進程是無法直接操作I/O設備的,其必須通過系統(tǒng)調用請求內核來協(xié)助完成I/O動作,而內核會為每個I/O設備維護一個buffer。如下圖所示:整個請求過程為:用戶進程發(fā)起請求,內核接受到請求后,從I/O設備中獲取數(shù)據(jù)到buffer中,再將buffer中的數(shù)據(jù)copy到用戶進程的地址空間,該用戶進程獲取到數(shù)據(jù)后再響應客戶端。在整個請求過程中,數(shù)據(jù)輸入至buffer需要時間,而從buffer復制數(shù)據(jù)至進程也需要時間。因此根據(jù)在這兩段時間內等待方式的不同,I/O動作可以分為以下五種模式:阻塞I/O(BlockingI/O)非阻塞I/O(Non-BlockingI/O)I/O復用(I/OMultiplexing)信號驅動的I/O(SignalDrivenI/O)異步I/O(AsynchrnousI/O)

說明:如果像了解更多可能需要linux/unix方面的知識了,可自行去學習一些網(wǎng)絡編程原理應該有詳細說明,不過對大多數(shù)java程序員來說,不需要了解底層細節(jié),知道個概念就行,知道對于系統(tǒng)而言,底層是支持的。本文最重要的參考文獻是RichardStevens的“UNIX?NetworkProgrammingVolume1,ThirdEdition:TheSocketsNetworking”,6.2節(jié)“I/OModels”,公眾號【肉眼品世界】回復:linuxsocket或者linux001

,獲取該資料,建議電腦下載(比較大以及chm格式),本文中的流程圖也是截取自中。記住這兩點很重要1等待數(shù)據(jù)準備(Waitingforthedatatobeready)2將數(shù)據(jù)從內核拷貝到進程中(Copyingthedatafromthekerneltotheprocess)阻塞I/O(BlockingI/O)在linux中,默認情況下所有的socket都是blocking,一個典型的讀操作流程大概是這樣:當用戶進程調用了recvfrom這個系統(tǒng)調用,內核就開始了IO的第一個階段:等待數(shù)據(jù)準備。對于networkio來說,很多時候數(shù)據(jù)在一開始還沒有到達(比如,還沒有收到一個完整的UDP包),這個時候內核就要等待足夠的數(shù)據(jù)到來。而在用戶進程這邊,整個進程會被阻塞。當內核一直等到數(shù)據(jù)準備好了,它就會將數(shù)據(jù)從內核中拷貝到用戶內存,然后內核返回結果,用戶進程才解除block的狀態(tài),重新運行起來。所以,blockingIO的特點就是在IO執(zhí)行的兩個階段都被block了。非阻塞I/O(Non-BlockingI/O)linux下,可以通過設置socket使其變?yōu)閚on-blocking。當對一個non-blockingsocket執(zhí)行讀操作時,流程是這個樣子:當用戶進程調用recvfrom時,系統(tǒng)不會阻塞用戶進程,而是立刻返回一個ewouldblock錯誤,從用戶進程角度講,并不需要等待,而是馬上就得到了一個結果。用戶進程判斷標志是ewouldblock時,就知道數(shù)據(jù)還沒準備好,于是它就可以去做其他的事了,于是它可以再次發(fā)送recvfrom,一旦內核中的數(shù)據(jù)準備好了。并且又再次收到了用戶進程的systemcall,那么它馬上就將數(shù)據(jù)拷貝到了用戶內存,然后返回。當一個應用程序在一個循環(huán)里對一個非阻塞調用recvfrom,我們稱為輪詢。應用程序不斷輪詢內核,看看是否已經(jīng)準備好了某些操作。這通常是浪費CPU時間,但這種模式偶爾會遇到。I/O復用(I/OMultiplexing)IOmultiplexing這個詞可能有點陌生,但是如果我說select,epoll,大概就都能明白了。有些地方也稱這種IO方式為eventdrivenIO。我們都知道,select/epoll的好處就在于單個process就可以同時處理多個網(wǎng)絡連接的IO。它的基本原理就是select/epoll這個function會不斷的輪詢所負責的所有socket,當某個socket有數(shù)據(jù)到達了,就通知用戶進程。它的流程如圖:當用戶進程調用了select,那么整個進程會被block,而同時,內核會“監(jiān)視”所有select負責的socket,當任何一個socket中的數(shù)據(jù)準備好了,select就會返回。這個時候用戶進程再調用read操作,將數(shù)據(jù)從內核拷貝到用戶進程。這個圖和blockingIO的圖其實并沒有太大的不同,事實上,還更差一些。因為這里需要使用兩個systemcall(select和recvfrom),而blockingIO只調用了一個systemcall(recvfrom)。但是,用select的優(yōu)勢在于它可以同時處理多個connection。(多說一句。所以,如果處理的連接數(shù)不是很高的話,使用select/epoll的webserver不一定比使用multi-threading+blockingIO的webserver性能更好,可能延遲還更大。select/epoll的優(yōu)勢并不是對于單個連接能處理得更快,而是在于能處理更多的連接。)在IOmultiplexingModel中,實際中,對于每一個socket,一般都設置成為non-blocking,但是,如上圖所示,整個用戶的process其實是一直被block的。只不過process是被select這個函數(shù)block,而不是被socketIO給block。文件描述符fdLinux的內核將所有外部設備都可以看做一個文件來操作。那么我們對與外部設備的操作都可以看做對文件進行操作。我們對一個文件的讀寫,都通過調用內核提供的系統(tǒng)調用;內核給我們返回一個filedescriptor(fd,文件描述符)。而對一個socket的讀寫也會有相應的描述符,稱為socketfd(socket描述符)。描述符就是一個數(shù)字,指向內核中一個結構體(文件路徑,數(shù)據(jù)區(qū),等一些屬性)。那么我們的應用程序對文件的讀寫就通過對描述符的讀寫完成。select基本原理:select函數(shù)監(jiān)視的文件描述符分3類,分別是writefds、readfds、和exceptfds。調用后select函數(shù)會阻塞,直到有描述符就緒(有數(shù)據(jù)可讀、可寫、或者有except),或者超時(timeout指定等待時間,如果立即返回設為null即可),函數(shù)返回。當select函數(shù)返回后,可以通過遍歷fdset,來找到就緒的描述符。缺點:1、select最大的缺陷就是單個進程所打開的FD是有一定限制的,它由FDSETSIZE設置,32位機默認是1024個,64位機默認是2048。一般來說這個數(shù)目和系統(tǒng)內存關系很大,”具體數(shù)目可以cat/proc/sys/fs/file-max察看”。32位機默認是1024個。64位機默認是2048.2、對socket進行掃描時是線性掃描,即采用輪詢的方法,效率較低。當套接字比較多的時候,每次select()都要通過遍歷FDSETSIZE個Socket來完成調度,不管哪個Socket是活躍的,都遍歷一遍。這會浪費很多CPU時間。”如果能給套接字注冊某個回調函數(shù),當他們活躍時,自動完成相關操作,那就避免了輪詢”,這正是epoll與kqueue做的。3、需要維護一個用來存放大量fd的數(shù)據(jù)結構,這樣會使得用戶空間和內核空間在傳遞該結構時復制開銷大。poll基本原理:poll本質上和select沒有區(qū)別,它將用戶傳入的數(shù)組拷貝到內核空間,然后查詢每個fd對應的設備狀態(tài),如果設備就緒則在設備等待隊列中加入一項并繼續(xù)遍歷,如果遍歷完所有fd后沒有發(fā)現(xiàn)就緒設備,則掛起當前進程,直到設備就緒或者主動超時,被喚醒后它又要再次遍歷fd。這個過程經(jīng)歷了多次無謂的遍歷。它沒有最大連接數(shù)的限制,原因是它是基于鏈表來存儲的,但是同樣有一個缺點:1、大量的fd的數(shù)組被整體復制于用戶態(tài)和內核地址空間之間,而不管這樣的復制是不是有意義。2、poll還有一個特點是“水平觸發(fā)”,如果報告了fd后,沒有被處理,那么下次poll時會再次報告該fd。注意:從上面看,select和poll都需要在返回后,通過遍歷文件描述符來獲取已經(jīng)就緒的socket。事實上,同時連接的大量客戶端在一時刻可能只有很少的處于就緒狀態(tài),因此隨著監(jiān)視的描述符數(shù)量的增長,其效率也會線性下降。epollepoll是在2.6內核中提出的,是之前的select和poll的增強版本。相對于select和poll來說,epoll更加靈活,沒有描述符限制。epoll使用一個文件描述符管理多個描述符,將用戶關系的文件描述符的事件存放到內核的一個事件表中,這樣在用戶空間和內核空間的copy只需一次?;驹恚篹poll支持水平觸發(fā)和邊緣觸發(fā),最大的特點在于邊緣觸發(fā),它只告訴進程哪些fd剛剛變?yōu)榫途w態(tài),并且只會通知一次。還有一個特點是,epoll使用“事件”的就緒通知方式,通過epollctl注冊fd,一旦該fd就緒,內核就會采用類似callback的回調機制來激活該fd,epollwait便可以收到通知。epoll的優(yōu)點:1、沒有最大并發(fā)連接的限制,能打開的FD的上限遠大于1024(1G的內存上能監(jiān)聽約10萬個端口)。2、效率提升,不是輪詢的方式,不會隨著FD數(shù)目的增加效率下降。只有活躍可用的FD才會調用callback函數(shù);即Epoll最大的優(yōu)點就在于它只管你“活躍”的連接,而跟連接總數(shù)無關,因此在實際的網(wǎng)絡環(huán)境中,Epoll的效率就會遠遠高于select和poll。3、內存拷貝,利用mmap()文件映射內存加速與內核空間的消息傳遞;即epoll使用mmap減少復制開銷。JDK1.5_update10版本使用epoll替代了傳統(tǒng)的select/poll,極大的提升了NIO通信的性能。備注:JDKNIO的BUG,例如臭名昭著的epollbug,它會導致Selector空輪詢,最終導致CPU100%。官方聲稱在JDK1.6版本的update18修復了該問題,但是直到JDK1.7版本該問題仍舊存在,只不過該BUG發(fā)生概率降低了一些而已,它并沒有被根本解決。這個可以在后續(xù)netty系列里面進行說明下。信號驅動的I/O(SignalDrivenI/O)由于signaldrivenIO在實際中并不常用,所以簡單提下。很明顯可以看出用戶進程不是阻塞的。首先用戶進程建立SIGIO信號處理程序,并通過系統(tǒng)調用sigaction執(zhí)行一個信號處理函數(shù),這時用戶進程便可以做其他的事了,一旦數(shù)據(jù)準備好,系統(tǒng)便為該進程生成一個SIGIO信號,去通知它數(shù)據(jù)已經(jīng)準備好了,于是用戶進程便調用recvfrom把數(shù)據(jù)從內核拷貝出來,并返回結果。異步I/O一般來說,這些函數(shù)通過告訴內核啟動操作并在整個操作(包括內核的數(shù)據(jù)到緩沖區(qū)的副本)完成時通知我們。這個模型和前面的信號驅動I/O模型的主要區(qū)別是,在信號驅動的I/O中,內核告訴我們何時可以啟動I/O操作,但是異步I/O時,內核告訴我們何時I/O操作完成。當用戶進程向內核發(fā)起某個操作后,會立刻得到返回,并把所有的任務都交給內核去完成(包括將數(shù)據(jù)從內核拷貝到用戶自己的緩沖區(qū)),內核完成之后,只需返回一個信號告訴用戶進程已經(jīng)完成就可以了。5中I/O模型的對比結果表明:前四個模型之間的主要區(qū)別是第一階段,四個模型的第二階段是一樣的:過程受阻在調用recvfrom當數(shù)據(jù)從內核拷貝到用戶緩沖區(qū)。然而,異步I/O處理兩個階段,與前四個不同。從同步、異步,以及阻塞、非阻塞兩個維度來劃分來看:零拷貝CPU不執(zhí)行拷貝數(shù)據(jù)從一個存儲區(qū)域到另一個存儲區(qū)域的任務,這通常用于在網(wǎng)絡上傳輸文件時節(jié)省CPU周期和內存帶寬。緩存IO緩存IO又被稱作標準IO,大多數(shù)文件系統(tǒng)的默認IO操作都是緩存IO。在Linux的緩存IO機制中,操作系統(tǒng)會將IO的數(shù)據(jù)緩存在文件系統(tǒng)的頁緩存(pagecache)中,也就是說,數(shù)據(jù)會先被拷貝到操作系統(tǒng)內核的緩沖區(qū)中,然后才會從操作系統(tǒng)內核的緩沖區(qū)拷貝到應用程序的地址空間。緩存IO的缺點:數(shù)據(jù)在傳輸過程中需要在應用程序地址空間和內核進行多次數(shù)據(jù)拷貝操作,這些數(shù)據(jù)拷貝操作所帶來的CPU以及內存開銷是非常大的。零拷貝技術分類零拷貝技術的發(fā)展很多樣化,現(xiàn)有的零拷貝技術種類也非常多,而當前并沒有一個適合于所有場景的零拷貝技術的出現(xiàn)。對于Linux來說,現(xiàn)存的零拷貝技術也比較多,這些零拷貝技術大部分存在于不同的Linux內核版本,有些舊的技術在不同的Linux內核版本間得到了很大的發(fā)展或者已經(jīng)漸漸被新的技術所代替。本文針對這些零拷貝技術所適用的不同場景對它們進行了劃分。概括起來,Linux中的零拷貝技術主要有下面這幾種:直接I/O:對于這種數(shù)據(jù)傳輸方式來說,應用程序可以直接訪問硬件存儲,操作系統(tǒng)內核只是輔助數(shù)據(jù)傳輸:這類零拷貝技術針對的是操作系統(tǒng)內核并不需要對數(shù)據(jù)進行直接處理的情況,數(shù)據(jù)可以在應用程序地址空間的緩沖區(qū)和磁盤之間直接進行傳輸,完全不需要Linux操作系統(tǒng)內核提供的頁緩存的支持。在數(shù)據(jù)傳輸?shù)倪^程中,避免數(shù)據(jù)在操作系統(tǒng)內核地址空間的緩沖區(qū)和用戶應用程序地址空間的緩沖區(qū)之間進行拷貝。有的時候,應用程序在數(shù)據(jù)進行傳輸?shù)倪^程中不需要對數(shù)據(jù)進行訪問,那么,將數(shù)據(jù)從Linux的頁緩存拷貝到用戶進程的緩沖區(qū)中就可以完全避免,傳輸?shù)臄?shù)據(jù)在頁緩存中就可以得到處理。在某些特殊的情況下,這種零拷貝技術可以獲得較好的性能。Linux中提供類似的系統(tǒng)調用主要有mmap(),sendfile()以及splice()。對數(shù)據(jù)在Linux的頁緩存和用戶進程的緩沖區(qū)之間的傳輸過程進行優(yōu)化。該零拷貝技術側重于靈活地處理數(shù)據(jù)在用戶進程的緩沖區(qū)和操作系統(tǒng)的頁緩存之間的拷貝操作。這種方法延續(xù)了傳統(tǒng)的通信方式,但是更加靈活。在Linux中,該方法主要利用了寫時復制技術。前兩類方法的目的主要是為了避免應用程序地址空間和操作系統(tǒng)內核地址空間這兩者之間的緩沖區(qū)拷貝操作。這兩類零拷貝技術通常適用在某些特殊的情況下,比如要傳送的數(shù)據(jù)不需要經(jīng)過操作系統(tǒng)內核的處理或者不需要經(jīng)過應用程序的處理。第三類方法則繼承了傳統(tǒng)的應用程序地址空間和操作系統(tǒng)內核地址空間之間數(shù)據(jù)傳輸?shù)母拍?,進而針對數(shù)據(jù)傳輸本身進行優(yōu)化。我們知道,硬件和軟件之間的數(shù)據(jù)傳輸可以通過使用DMA來進行,DMA進行數(shù)據(jù)傳輸?shù)倪^程中幾乎不需要CPU參與,這樣就可以把CPU解放出來去做更多其他的事情,但是當數(shù)據(jù)需要在用戶地址空間的緩沖區(qū)和Linux操作系統(tǒng)內核的頁緩存之間進行傳輸?shù)臅r候,并沒有類似DMA這種工具可以使用,CPU需要全程參與到這種數(shù)據(jù)拷貝操作中,所以這第三類方法的目的是可以有效地改善數(shù)據(jù)在用戶地址空間和操作系統(tǒng)內核地址空間之間傳遞的效率。注意,對于各種零拷貝機制是否能夠實現(xiàn)都是依賴于操作系統(tǒng)底層是否提供相應的支持。當應用程序訪問某塊數(shù)據(jù)時,操作系統(tǒng)首先會檢查,是不是最近訪問過此文件,文件內容是否緩存在內核緩沖區(qū),如果是,操作系統(tǒng)則直接根據(jù)read系統(tǒng)調用提供的buf地址,將內核緩沖區(qū)的內容拷貝到buf所指定的用戶空間緩沖區(qū)中去。如果不是,操作系統(tǒng)則首先將磁盤上的數(shù)據(jù)拷貝的內核緩沖區(qū),這一步目前主要依靠DMA來傳輸,然后再把內核緩沖區(qū)上的內容拷貝到用戶緩沖區(qū)中。接下來,write系統(tǒng)調用再把用戶緩沖區(qū)的內容拷貝到網(wǎng)絡堆棧相關的內核緩沖區(qū)中,最后socket再把內核緩沖區(qū)的內容發(fā)送到網(wǎng)卡上。從上圖中可以看出,共產(chǎn)生了四次數(shù)據(jù)拷貝,即使使用了DMA來處理了與硬件的通訊,CPU仍然需要處理兩次數(shù)據(jù)拷貝,與此同時,在用戶態(tài)與內核態(tài)也發(fā)生了多次上下文切換,無疑也加重了CPU負擔。在此過程中,我們沒有對文件內容做任何修改,那么在內核空間和用戶空間來回拷貝數(shù)據(jù)無疑就是一種浪費,而零拷貝主要就是為了解決這種低效性。###讓數(shù)據(jù)傳輸不需要經(jīng)過userspace,使用mmap我們減少拷貝次數(shù)的一種方法是調用mmap()來代替read調用:buf=mmap(diskfd,len);write(sockfd,buf,len);應用程序調用mmap(),磁盤上的數(shù)據(jù)會通過DMA被拷貝的內核緩沖區(qū),接著操作系統(tǒng)會把這段內核緩沖區(qū)與應用程序共享,這樣就不需要把內核緩沖區(qū)的內容往用戶空間拷貝。應用程序再調用write(),操作系統(tǒng)直接將內核緩沖區(qū)的內容拷貝到socket緩沖區(qū)中,這一切都發(fā)生在內核態(tài),最后,socket緩沖區(qū)再把數(shù)據(jù)發(fā)到網(wǎng)卡去。同樣的,看圖很簡單:使用mmap替代read很明顯減少了一次拷貝,當拷貝數(shù)據(jù)量很大時,無疑提升了效率。但是使用mmap是有代價的。當你使用mmap時,你可能會遇到一些隱藏的陷阱。例如,當你的程序map了一個文件,但是當這個文件被另一個進程截斷(truncate)時,write系統(tǒng)調用會因為訪問非法地址而被SIGBUS信號終止。SIGBUS信號默認會殺死你的進程并產(chǎn)生一個coredump,如果你的服務器這樣被中止了,那會產(chǎn)生一筆損失。通常我們使用以下解決方案避免這種問題:為SIGBUS信號建立信號處理程序

當遇到

SIGBUS信號時,信號處理程序簡單地返回,

write系統(tǒng)調用在被中斷之前會返回已經(jīng)寫入的字節(jié)數(shù),并且

errno會被設置成success,但是這是一種糟糕的處理辦法,因為你并沒有解決問題的實質核心。使用文件租借鎖

通常我們使用這種方法,在文件描述符上使用租借鎖,我們?yōu)槲募騼群松暾堃粋€租借鎖,當其它進程想要截斷這個文件時,內核會向我們發(fā)送一個實時的

RT_SIGNAL_LEASE信號,告訴我們內核正在破壞你加持在文件上的讀寫鎖。這樣在程序訪問非法內存并且被

SIGBUS殺死之前,你的

write系統(tǒng)調用會被中斷。

write會返回已經(jīng)寫入的字節(jié)數(shù),并且置

errno為success。

我們應該在

mmap文件之前加鎖,并且在操作完文件后解鎖:if(fcntl(diskfd,F_SETSIG,RT_SIGNAL_LEASE)==-1){

perror("kernelleasesetsignal");

return-1;}/*l_typecanbeF_RDLCKF_WRLCK

加鎖*//*l_typecanbe

F_UNLCK解鎖*/if(fcntl(diskfd,F_SETLEASE,l_type)){

perror("kernelleasesettype");

return-1;}關于更多零拷貝的問題可以查看《如何理解Linux的零拷貝技術?》所以,我們可以看到高并發(fā)的本質是通過軟件層編碼的方法充分使用內存和cpu,這是單機,再加集群就是無限級了,當然集群的管理和監(jiān)控也是相當重要的組成部分這里面最重要的部分就是1:充分利用內存,壓榨cpu2:處理好網(wǎng)絡IO,socketfd這東西在貫穿網(wǎng)絡的主要核心,了解了socketfd就基本了解了外界于linux打交道的原理,至于怎么打交道就是poll,select,epoll的事情了3:算法,算法也是軟件編碼層的充分使用硬件相對獨立的一個分支,關于算法相關內容可以參考:《十大經(jīng)典排序算法(動圖演示,收藏好文)》《一遍記住Java面試中常用的八種排序算法與代碼實現(xiàn)!》主宰這個世界的10種算法已經(jīng)絕版的《數(shù)據(jù)結構和算法(第二版)》高清電子書!(附下載)435頁經(jīng)典書籍《算法心得:高效算法的奧秘(第2版)》【干貨】350+頁的《數(shù)據(jù)結構與算法》pdf一致性哈希算法在分布式場景中的應用今日頭條、抖音推薦算法原理全文詳解基于以上三點又構建了諸如docker,nginxserver,lvs,redis,多線程語言,數(shù)據(jù)庫,分布式存儲的一系列應用,至于其他,小編也在射射發(fā)抖的學習...如何構建高并發(fā)系統(tǒng)知道了高并發(fā)系統(tǒng)的相關實質,那么我們還得會使用前輩們造好的輪子來搭配好,平時我們所說的高并發(fā)系統(tǒng)更多的是用工具來組合形成一個穩(wěn)定高效的系統(tǒng),也就是所謂的高并發(fā)高可用,如果并發(fā)太大又需要對前輩們造的輪子做改造,而大多數(shù)組件是C語言寫的,所以做架構能會C,能了解到相關組件的源碼并在需要的情況下做修改是架構師向更高層次發(fā)展需要具備的要素,大佬們造的那些輪子也是支撐高并發(fā)系統(tǒng)的核心要素,如redis,lvs,nginx,mysql,感謝開源,站在巨人的肩膀上做架構竟然變得如何美好;高可用是伴隨高并發(fā)而產(chǎn)生的,前面說過高并發(fā),這里又有一個高可用,什么是高可用呢1、什么是高可用高可用指系統(tǒng)的可用程度。沒有100%的可用性。打個夸張的比方說,部署在全球的所有機房都同時停電了,那么系統(tǒng)就不能再提供服務。一般我們只需要做到4個9就已經(jīng)很不錯了,如下圖:2、高可用分類按照業(yè)務=邏輯+數(shù)據(jù)來分,高可用分為計算高可用和存儲高可用,邏輯即數(shù)據(jù),數(shù)據(jù)即存儲。2.1計算高可用常見的計算高可用架構分為主備、主從、對稱集群、非對稱集群。主備:主從:對稱集群:非對稱集群:2.2存儲高可用常見的存儲高可用有主備、主從、主備/主從切換,主主,集群(數(shù)據(jù)集中集群和數(shù)據(jù)分散集群),分區(qū)(洲際、國家、城市、同城分區(qū))。主備:主從:數(shù)據(jù)集中式集群:主主集群:數(shù)據(jù)分散集群:

比如HDFS的架構。在存儲界,還有一個比較有名的組件FastDFS,基本設計也是類似,關于高可用的知識圖譜,可以作為參考:往往我們開始做系統(tǒng)時,并不是一開始就設計這么復雜的架構,架構核心的內容是大道至簡,架構也是根據(jù)需要一步步演進而來的,一般目前的架構要比現(xiàn)在實際用戶量并發(fā)量至少高一個層級,創(chuàng)業(yè)公司剛上來也沒必要搞那么復雜的系統(tǒng),關于基礎的技術選型可以查看《創(chuàng)業(yè)公司技術選型與管理注意事項》,一個springboot跑起來再說,夠你玩好久了,等你量達到那種程度了;但對于技術來說,還是能夠提前做到心中有數(shù)比較好某些App怎么扛住1分鐘10億請求?架構的演進路線百萬級并發(fā):1秒100萬次請求。千萬級并發(fā):一分鐘6億次請求,差不多就是需求的極限。架構的設計和架構優(yōu)化要符合需求本身,不能無限制優(yōu)化。基本概念(1)分布式(系統(tǒng)中,多個模塊在不同服務器上部署)(2)集群(一個軟件部署在多臺服務器,并作為一個整體,提供一類服務)(3)高可用(系統(tǒng)中部分節(jié)點失效,其他節(jié)點能夠接替它繼續(xù)工作或有相應的處理預案)(4)負載均衡(把請求均勻的發(fā)到多個節(jié)點上)架構演進:1

單機架構DNS服務器,做域名解析的服務器,作用是,經(jīng)過DNS將這類的域名轉換為實際IP地址,瀏覽器轉而訪問這個IP對應的tomcat。如果是單機一般用服務商自己的DNS解析即可,如果是多機DNSPOD在域名輪詢層就是不錯解決方案;java用tomcat,php用nginx,springboot這騷貨還自帶tomcat,你要嫌麻煩直接啟動springboot也是可以的瓶頸:用戶增長,java(php)代碼、靜態(tài)資源和數(shù)據(jù)庫之間競爭資源,單機性能不足以支撐業(yè)務,萬一哪臺機器內存突然出點兒狀況,你的服務也就不可用了。2

第一次演進:動靜分離、代碼與數(shù)據(jù)庫分離java(php,go)代碼和數(shù)據(jù)庫分別獨占服務器資源,顯著提高兩者各自性能,這個時候也可以把html和圖片靜態(tài)文件資源分離,目前大多數(shù)情況下是前后端分離的,創(chuàng)業(yè)公司用vue把打包過后的文件單獨部署一個域名,隨時可以通過jenkins部署到新服務器(tomcat服務器找一個內存大的,DB服務器找一個硬盤大的,帶寬更寬的)。瓶頸:用戶量增長,數(shù)據(jù)庫并發(fā)讀寫,尤其是讀,成為瓶頸。注意,不會通過數(shù)據(jù)庫集群解決3

第二次演進:引進CDN,緩存甚至分布式緩存在Tomcat服務器上(Java程序所在的地方)加入緩存,可以把絕大多數(shù)請求(尤其是查詢)在訪問數(shù)據(jù)庫前攔截掉。如果你的服務器是nginx或者有nginx代理層,nginx可以直接訪問和刷新緩存的Redis一般放在單獨的服務器上,也可以多弄幾臺Redis服務器,配置成主從同步(提升可用性可以加上哨兵)。

redis的進群解決方案一般有Codis,RedisCluster,twemproxy,redis主從,這幾種都各有優(yōu)缺點,如果你的redis集群量不大,搞個主從就可以了;提到天貓和redis,自然少不了秒殺場景,秒殺場景可以參考《解密Redis助力雙11背后電商秒殺系統(tǒng)》的一些做法當然,這個時候消息隊列也可以出現(xiàn)在系統(tǒng)里了,開始用redis也可以抗一陣兒,金融場景RocketMQ是不錯的選擇,kafka追求高吞吐量,起源的時候是用于海量日志傳輸,但是隨著版本的越來越完善,可靠性也在不斷提高,據(jù)說(沒親眼見代碼)某滴滴公司消息推送就使用kafka了瓶頸:用戶數(shù)量增長,并發(fā)壓力主要在單機的tomcat+java上,響應逐漸變慢。單機java變慢還可以優(yōu)化呀,每個api接口的時間監(jiān)控起來,mysql慢查詢監(jiān)控起來,推薦一款阿里問題定位神器《阿里問題定位神器Arthas的騷操作,定位線上BUG,超給力》4

第三次演進:引入反向代理和負載均衡使用反向代理,將大量的用戶請求,均勻分發(fā)到每個java應用程序中。關于nginx為什么能支撐這么大并發(fā)可以閱讀《只知道Nginx牛逼,卻不知道它怎么支持百萬并發(fā)?》瓶頸:應用服務器可支持的并發(fā)量大大增加,緩存能力也可以輕易擴展,并發(fā)量增長意味著更多請求穿透到數(shù)據(jù)庫,單機的數(shù)據(jù)庫最終成為瓶頸。靜態(tài)文件大幅度訪問影響5

第四次演進:數(shù)據(jù)庫讀寫分離把數(shù)據(jù)庫劃分為讀庫和寫庫,讀庫可以有多個,通過同步機制把寫庫的數(shù)據(jù)同步到讀庫,使用數(shù)據(jù)庫中間件(Mycat),通過它來組織數(shù)據(jù)庫的分離讀寫。php用mysqlnd或者在代碼里來個讀寫分離,讀寫分離如何做呢,就是在執(zhí)行sql前,匹配是delete,insert,update,replace操作就讀主庫,select等就讀從庫瓶頸:業(yè)務逐漸變多,不同業(yè)務之間的訪問量差距較大,不同業(yè)務直接競爭數(shù)據(jù)庫,相互影響性能。6

第五次演進:數(shù)據(jù)庫按業(yè)務分庫把不同的業(yè)務數(shù)據(jù)保存到不同的數(shù)據(jù)庫中,業(yè)務之間的資源競爭降低,訪問量大的業(yè)務可以部署更多的服務器。用戶中心一般是首先需要獨立出來的,對應的應用也可以獨立部署瓶頸:用戶數(shù)量增長,單機的寫庫會逐漸達到性能瓶頸。7

第六次演進:把數(shù)據(jù)庫的大表拆成小表比如針對訂單生成,可以按照月份,甚至小時創(chuàng)建表。到底是1000萬還是2000萬數(shù)據(jù)分表的時候,這個需要看你這張表字段多少,和每個字段存儲的量和你機器的配置,一般存一兩千萬沒什么問題,跑得呼呼的;分表分庫方法分幾種,可以參考《不用找了,大廠在用的分庫分表方案,都在這了!》這種做法可以稱作分布式數(shù)據(jù)庫,但邏輯上仍然是一個完整的數(shù)據(jù)庫整體,現(xiàn)在有一種架構叫MPP(大規(guī)模并行處理),針對于各種這類問題的使用場景。分表分庫倒是分好了,你查詢寫入和數(shù)據(jù)合并的時候麻煩了,常用的分表分庫中間件有如下幾種,各有優(yōu)缺點,一般大廠都是自己根據(jù)業(yè)務場景獨立開發(fā)的,百度用的Heisenberg,/brucexx/heisenberg(開源版已停止維護)支撐天貓?zhí)詫氈Ц秾毮敲创罅髁恳彩侨巳馐止し直矸謳靻??沒有,阿里大多數(shù)場景用了他們自己的oceanbase數(shù)據(jù)庫,oceanbase數(shù)據(jù)庫也是有一層自己的OBproxy代理的,只是沒有這層代理oceanbase也能跑得不錯的;可以發(fā)現(xiàn)要深入的做架構,需要對相關組件能根據(jù)業(yè)務做相應的改造,這個時候linux系統(tǒng),c語言,數(shù)據(jù)結構就變得非常重要了,而人的精力有限,樣樣都精不可能,這個時候你就需要團隊協(xié)作了,深入研究一個點兒,其他地方也會發(fā)現(xiàn)差不多。瓶頸:數(shù)據(jù)庫和tomcat都可以大規(guī)模水平擴展,最終單機的nginx會成為瓶頸。8

第七次演進:使用LVS讓多個Nginx負載均衡LVS是軟件,運行在操作系統(tǒng)內核態(tài),可以對TCP請求或高層網(wǎng)絡協(xié)議進行轉發(fā),分發(fā)的性能遠高于Nginx,大概十幾萬。F5是硬件,跟LVS做的事情類似,但性能更高,而且價格昂貴。這種方式,用戶可達千萬或上億級別。瓶頸:LVS達到瓶頸,或用戶分布在不同的地區(qū),與服務器機房的距離不同,導致訪問延遲的不同。9

第八次演進:智能DNS輪詢實現(xiàn)機房間的負載均衡別說,DNSPOD還挺好用的,不同機房ip智能解析,響應速度也不錯,當然還有收費版的,功能更多(這不是騰訊的廣告)在DNS中配置一個域名對應多個IP。每個IP地址對應到不同的機房里的虛擬IP。做到機房級別的水平擴展,已經(jīng)是從請求并發(fā)量來講,過億的處理方案,十幾億或幾十億的并發(fā),暫時沒人考慮。瓶頸:檢索,分析的需求越來越多,單靠數(shù)據(jù)庫無法解決各種各樣的需求。10

第九次演進:引入NoSQL數(shù)據(jù)庫和搜索引擎數(shù)據(jù)量多到一定規(guī)模的時候,關系型數(shù)據(jù)庫不再適用,而且數(shù)據(jù)量較大的查詢,MySQL不一定能運行出結果,對于海量數(shù)據(jù)的處理,通過分布式文件系統(tǒng)HDFS來存儲,對于key-value類型的數(shù)據(jù),通過HBase、Redis等處理,對于抓取查詢,可以通過ES等解決,對于多維分析,通過kylin、Druid等解決。阿里云上有各種時序數(shù)據(jù)庫,圖數(shù)據(jù)庫,表格數(shù)據(jù)庫,還有HybridDBforMySQL,支持OLTP和OLAP,tidb也干這活兒,是個不錯的選擇,也是近年以來發(fā)展不錯的數(shù)據(jù)庫廠商,有大廠給你當靠山,億級流量就變得比以前更容易了引入更多的組件同時必然極大的提高系統(tǒng)復雜度,不同的組件的數(shù)據(jù)還需要同步,需要考慮一致性問題。11

第十次演進:數(shù)據(jù)兩地三中心一般來說目前比較流行的災備體系是至少建設三個數(shù)據(jù)中心,其中:主中心:正常情況下全面提供業(yè)務服務。同城中心:一般使用同步復制的方式來向同城災備中心傳輸數(shù)據(jù),保證同城中心數(shù)據(jù)復本為最新,隨時可以接管業(yè)務,以保證RTO的指標。但是同城中心無法應對此類刪庫事件。異地中心:一般使用延時異步復制(延時時間一般為30分鐘左右)的方式向異地災備中心傳輸數(shù)據(jù),其中同步復制的好處是一旦主中心被人工破壞,那么不會立刻涉及異地中心以保證RPO的指標。一句話總結災備體系的最佳實踐就是兩地三中心;同城保證業(yè)務連續(xù)性,優(yōu)先負責用戶體驗;異地保證數(shù)據(jù)連續(xù)性,確保企業(yè)生存底線。而針對行為及日志等重要性等級不高的數(shù)據(jù),一般采用異地磁帶備份的方式。具體方式如下:解決方案有商用的也有開源的,商用的華為SAN3DC方案的不錯,mysql開源的可以嘗試一下阿里的canal:跨地域

MySQLbinlog增量訂閱&消費組件不過從目前情況看不少企業(yè)尤其是創(chuàng)業(yè)型企業(yè),都沒有百年老店的觀念,因此在異地中心的建設上投入還不夠,不過這樣的模式缺點也很明顯,一旦發(fā)生這種刪庫事件就影響就是致命的。12

第十一次演進:大應用拆為小應用按照業(yè)務板塊來劃分應用,使單個應用的職責更清晰,相互之間可以做到獨立升級迭代,甚至可以做到部分功能關閉。瓶頸:不同應用之間,存在公用的模塊,導致包含公共功能的部分在升級時,全部相關代碼都要跟著升級。13

第十一次演進:微服務、servicemesh“微服務架構是一種架構模式,它提倡將單一應用程序劃分成一組小的服務,服務之間相互協(xié)調、互相配合,為用戶提供最終價值。每個服務運行在其獨立的進程中,服務和服務之間采用輕量級的通信機制相互溝通(通常是基于HTTP的RestfulAPI).每個服務都圍繞著具體的業(yè)務進行構建,并且能夠被獨立的部署到生產(chǎn)環(huán)境、類生產(chǎn)環(huán)境等。(知乎華為云技術宅基地)微服務架構:類

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論