① 通過Redis消息隊列實現大文件處理
一、故事背景
1、讀取離線文件數據,再通過【離線數據】作為條件,查詢第三方介面,返回最終的結果,再入庫。
2、 業務邏輯是很簡單, 讀取文件、查詢介面、返回數據集、入庫 四步。
3、業務特性:第三方介面調用400毫秒(ms) 。
如果用普通單線程去跑算500毫秒一個請求,一天也就跑8W多數據量,20多億的數據不知道跑到猴年馬月了。
二、處理方案
A) 初步方案採用ganymed-ssh2(文件都存儲在Linux伺服器上) 來讀文件,Redis來存儲消息、多線程來提升處理能力。
B) 流程圖:
三、呈現問題
四、優化問題
最終流程圖:
1、 通過Redis做一個計數器 每讀取一行記錄數值,即使服務終止後,先從Redis讀取這個數值
再通過cat指定行數開始讀數據即可。
2、 通過取模拆Key 分片到不同小Key存儲 ,降低單個節點存儲壓力,也充分利用了存儲資源。
3、Redis Push 提供了批量方式(leftPushAll) ,可以指定讀取行數再批量入庫,而pop並沒有提供批量 只能一個一個pop。
4、消費者通過多線程pop、再分發到線程去處理。
五、總結問題
② 常用的消息隊列
一、redis消息隊列和kafka消息隊列的比較
1、Redis作為消息隊列
Redis的pub-sub模式非常像西式快餐一樣,快產快消,全都是因為Redis是使用內存來做存取,所有你生產的消息立馬會被消費者一次性全部處理掉,並且沒有留下任何痕跡, 同時因為內存總是寶貴的,所以內存上會有限制,當生產者以及消費者上來的時候也會對redis的效率,還有Redis在處理發布和消費big size(10K+的文件)的數據的時候會表現出無法忍受的緩慢
如果有以下場景可以考慮使用Redis作為消息隊列:
a、如果你的需求是快產快消的即時消費場景,並且生產的消息立即被消費者消費掉
b、如果速度是你十分看重的,比如慢了一秒好幾千萬這種
c、如果允許出現消息丟失的場景
d、如果你不需要系統保存你發送過的消息,做到來無影去無蹤
e、需要處理的數據量並不是那麼巨大
2、KafKa作為消息隊列
KafKa的設計精妙,支持分布式,高可用的部署,並且對一個大的隊列採用分成多個Partition(分區),來提高消息入隊的吞吐量,分而治之的思想. 並且消費的時候支持group的概念,能夠支持多個客戶端消費同個隊列,並且一個group中可以增加consumer的數量來擴展消費的處理量.
KafKa不熟生產者數量的影響,因為吞吐量足夠支撐,即使在廉價的單機伺服器上也可以有10萬每秒的消息傳輸量,並且消費者是想什麼時候消費都可以,消息它就在那裡,十分靈活,不用擔心來無影去無蹤的恐慌.能把消息持久化,並以一定的策略(例如一定時間內刪除,或者到達多大容量的時候清空)
當有一下場景的時候你可以考慮使用KafKa作為消息隊列:
a、如果你想要穩定的消息隊列
b、如果你想要你發送過的消息可以保留一定的時間,並不是無跡可尋的時候
c、如果你無法忍受數據的丟失
d、如果速度不需要那麼的快
e、如果需要處理數據量巨大的時候
③ 高並發用消息隊列會延遲,還有什麼好方法解決
首先你要知道隊列的應用場景在於哪裡。一般在需要後台大量邏輯處理或計算資源的情況下採取隊列,同時也可以提高前端的用戶體驗。
舉個例子:微博-關注/粉絲,假如你有1000個粉絲,你發了一條微博,這時候1000個粉絲都會收到你的動態,消息隊列便適合在這樣的場景下用。原因:
1 推送1000個動態數據是耗時操作,而發送微博頁面需要盡快響應,因此可將該任務放置到隊列;
2 你發送了微博之後是即時生效的,但粉絲收到微博允許有些許的延遲,通過隊列的方式實現也契合該需求;
3 針對隊列的處理可以採取高性能的集群架構實現,架構上實現了關注點分離,系統在擴展方面更加靈活
④ 消息隊列(mq)是什麼
是生產者先將消息投遞一個叫隊列的容器中,然後再從這個容器中取出消息,最後再轉發給消費者。
消息隊列是 Microsoft 的消息處理技術,它在任何安裝 Microsoft Windows 的計算機組合中,為任何應用程序提供消息處理和消息隊列功能,無論這些計算機是否在同一個網路上或者是否同時聯機。
消息隊列網路是能夠相互間來回發送消息的任何一組計算機。網路中的不同計算機在確保消息順利處理的過程中扮演不同的角色。它們中有些提供路由信息以確定如何發送消息,有些保存整個網路的重要信息,而有些只是發送和接收消息。
消息隊列的類型介紹:
消息隊列目前主要有兩種類型:POSIX消息隊列以及系統V消息隊列,系統V消息隊列目前被大量使用。每個消息隊列都有一個隊列頭,用結構struct msg_queue來描述。隊列頭中包含了該消息隊列的大量信息。包括消息隊列鍵值、用戶ID、組ID、消息隊列中消息數目等等。
消息隊列就是一個消息的鏈表,可以把消息看作一個記錄,具有特定的格式以及特定的優先順序。對消息隊列有寫許可權的進程可以向消息隊列中按照一定的規則添加新消息;對消息隊列有讀許可權的進程則可以從消息隊列中讀走消息。消息隊列是隨內核持續的。
⑤ activemq消息隊列怎樣解決高並發
Queue模式獲取之後,消息隊列中消息就應該會被刪除: Topic模式 在持久化之後,才可能被拿走之後,依然存在
⑥ java高並發文件上傳下載設計問題
說實話 從軟體或代碼角度 沒轍 都是長連接 逃不掉的
只能從系統設計上去考慮,大致上會有以下這兩種思路(基本上是都用的):
1、對於所有的上傳的文件,根據隨機生成的名稱或code取hash用策略取模,分伺服器存/取文件,保證不觸及io瓶頸,內部文件同步策略自己考慮
2、對所有請求,分pop點分發,根據用戶的物理地址選擇相應較近的pop點處理請求(當前pop請求已滿則順延至下一pop點,依次類推)
⑦ 分布式緩存主要用在高並發環境下的作用
分布式緩存主要用在高並發環境下,減輕資料庫的壓力,提高系統的響應速度和並發吞吐。當大量的讀、寫請求湧向資料庫時,磁碟的處理速度與內存顯然不在一個量級,因此,在資料庫之前加一層緩存,能夠顯著提高系統的響應速度,並降低資料庫的壓力。作為傳統的關系型資料庫,MySQL提供完整的ACID操作,支持豐富的數據類型、強大的關聯查詢、where語句等,能夠非常客易地建立查詢索引,執行復雜的內連接、外連接、求和、排序、分組等操作,並且支持存儲過程、函數等功能,產品成熟度高,功能強大。但是,對於需要應對高並發訪問並且存儲海量數據的場景來說,出於對性能的考慮,不得不放棄很多傳統關系型資料庫原本強大的功能,犧牲了系統的易用性,並且使得系統的設計和管理變得更為復雜。這也使得在過去幾年中,流行著另一種新的存儲解決方案——NoSQL,它與傳統的關系型資料庫最大的差別在於,它不使用SQL作為查詢語言來查找數據,而採用key-value形式進行查找,提供了更高的查詢效率及吞吐,並且能夠更加方便地進行擴展,存儲海量數據,在數千個節點上進行分區,自動進行數據的復制和備份。在分布式系統中,消息作為應用間通信的一種方式,得到了十分廣泛的應用。消息可以被保存在隊列中,直到被接收者取出,由於消息發送者不需要同步等待消息接收者的響應,消息的非同步接收降低了系統集成的耦合度,提升了分布式系統協作的效率,使得系統能夠更快地響應用戶,提供更高的吞吐。
當系統處於峰值壓力時,分布式消息隊列還能夠作為緩沖,削峰填谷,緩解集群的壓力,避免整個系統被壓垮。垂直化的搜索引擎在分布式系統中是一個非常重要的角色,它既能夠滿足用戶對於全文檢索、模糊匹配的需求,解決資料庫like查詢效率低下的問題,又能夠解決分布式環境下,由於採用分庫分表,或者使用NoSQL資料庫,導致無法進行多表關聯或者進行復雜查詢的問題。
⑧ Java操作高效並發操作讀寫文件,消息持久化到本地讀取
樓主,如果寫,先判斷要寫多大的文件、然後分段寫,各線程寫自己的段
如果讀,也是先得到文件大小、再分段,然後各線程讀自己的段
⑨ 消息隊列的使用場景是怎樣的
個人認為消息隊列的主要特點是非同步處理,主要目的是減少請求響應時間和解耦。所以主要的使用場景就是將比較耗時而且不需要即時(同步)返回結果的操作作為消息放入消息隊列。同時由於使用了消息隊列,只要保證消息格式不變,消息的發送方和接收方並不需要彼此聯系,也不需要受對方的影響,即解耦和。
使用場景的話,舉個例子:
假設用戶在你的軟體中注冊,服務端收到用戶的注冊請求後,它會做這些操作:
校驗用戶名等信息,如果沒問題會在資料庫中添加一個用戶記錄
如果是用郵箱注冊會給你發送一封注冊成功的郵件,手機注冊則會發送一條簡訊
分析用戶的個人信息,以便將來向他推薦一些志同道合的人,或向那些人推薦他
發送給用戶一個包含操作指南的系統通知
等等……
但是對於用戶來說,注冊功能實際只需要第一步,只要服務端將他的賬戶信息存到資料庫中他便可以登錄上去做他想做的事情了。至於其他的事情,非要在這一次請求中全部完成么?值得用戶浪費時間等你處理這些對他來說無關緊要的事情么?所以實際當第一步做完後,服務端就可以把其他的操作放入對應的消息隊列中然後馬上返回用戶結果,由消息隊列非同步的進行這些操作。
或者還有一種情況,同時有大量用戶注冊你的軟體,再高並發情況下注冊請求開始出現一些問題,例如郵件介面承受不住,或是分析信息時的大量計算使cpu滿載,這將會出現雖然用戶數據記錄很快的添加到資料庫中了,但是卻卡在發郵件或分析信息時的情況,導致請求的響應時間大幅增長,甚至出現超時,這就有點不劃算了。面對這種情況一般也是將這些操作放入消息隊列(生產者消費者模型),消息隊列慢慢的進行處理,同時可以很快的完成注冊請求,不會影響用戶使用其他功能。
⑩ 高並發三種解決方法
處理高並發的方法不止三種。
1:系統拆分
將一個系統拆分為多個子系統,用bbo來搞。然後每個系統連一個資料庫,這樣本來就一個庫,現在多個資料庫,這樣就可以抗高並發。
2:緩存,必須得用緩存
大部分的高並發場景,都是讀多寫少,那你完全可以在資料庫和緩存里都寫一份,然後讀的時候大量走緩存不就得了。畢竟人家redis輕輕鬆鬆單機幾萬的並發,沒問題的。所以可以考的慮考慮項目里,那些承載主要請求讀場景,怎麼用緩存來抗高並發。
3:MQ(消息隊列),必須得用MQ
可能還是會出現高並發寫的場景,比如說一個業務操作里要頻繁搞資料庫幾十次,增刪改增刪改,那高並發絕對搞掛系統,人家是緩存你要是用redis來承載寫那肯定不行,數據隨時就被LRU(淘汰掉最不經常使用的)了,數據格式還無比簡單,沒有事務支持。
所以該用mysql還得用mysql,用MQ,大量的寫請求灌入MQ里,排隊慢慢玩兒,後邊系統消費後慢慢寫,控制在mysql承載范圍之內。所以得考慮考慮你的項目里,那些承載復雜寫業務邏輯的場景里,如何用MQ來非同步寫,提升並發性。MQ單機抗幾萬並發也是可以的。
4:分庫分表
可能到了最後資料庫層面還是免不了抗高並發的要求,那麼就將一個資料庫拆分為多個庫,多個庫來抗更高的並發;然後將一個表拆分為多個表,每個表的數據量保持少一點,提高sql跑的性能。
5:讀寫分離
這個就是說大部分時候資料庫可能也是讀多寫少,沒必要所有請求都集中在一個庫上,可以搞個主從架構,主庫寫入,從庫讀取,搞一個讀寫分離。讀流量太多的時候,還可以加更多的從庫。