Redis阻塞整理筆記

Redis是典型的單線程架構(gòu)歉眷,所有的讀寫操作都是在一條主線程中完成的果复。當Redis用于高并發(fā)場景時缭裆,這條線程就變成了它的生命線键闺。如果出現(xiàn)阻塞,哪怕是很短時間澈驼,對于應用來說都是噩夢辛燥。

導致阻塞問題的原因:

內(nèi)在原因:不合理地使用API或數(shù)據(jù)結(jié)構(gòu)、CPU飽和缝其、持久化阻塞等

外在原因:CPU競爭挎塌、內(nèi)存交換、網(wǎng)絡(luò)問題等

一内边、發(fā)現(xiàn)阻塞

應用方加入異常監(jiān)控榴都,如日志系統(tǒng),比如Java語言中的logback或log4j

Redis監(jiān)控系統(tǒng)漠其,如CacheCloud

二嘴高、內(nèi)在原因

2.1 API或數(shù)據(jù)結(jié)構(gòu)使用不合理

通常Redis執(zhí)行命令速度非常快和屎,但是拴驮,如果對一個包含上萬個元素的hash結(jié)構(gòu)執(zhí)行hgetall操作,由于數(shù)據(jù)量比較大且命令算法復雜度是O(n)柴信,這條命令執(zhí)行速度必然很慢套啤。

對于高并發(fā)的場景應該盡量避免在大對象上執(zhí)行算法復雜度超過O(n)的命令。

(1)如何發(fā)現(xiàn)慢查詢

Redis原生提供慢查詢統(tǒng)計功能颠印,執(zhí)行slowlog get{n}命令可以獲取最近的n條慢查詢命令纲岭,默認對于執(zhí)行超過10毫秒的命令都會記錄到一個定長隊列中,線上實例建議設(shè)置為1毫秒便于及時發(fā)現(xiàn)毫秒級以上的命令线罕。

(2)發(fā)現(xiàn)慢查詢后如何調(diào)整

修改為低算法復雜度的命令

調(diào)整大對象:縮減大對象數(shù)據(jù)或把大對象拆分為多個小對象止潮,防止一次命令操作過多的數(shù)據(jù)。大對象拆分過程需要視具體的業(yè)務決定钞楼,如用戶好友集合存儲在Redis中喇闸,有些熱點用戶會關(guān)注大量好友,這時可以按時間或其他維度拆分到多個集合中。

(3)如何發(fā)現(xiàn)大對象

Redis本身提供發(fā)現(xiàn)大對象的工具燃乍。具體命令:

redis-cli?-h?{ip}??-p?{port}?--bigkeys

內(nèi)部原理采用分段進行scan操作唆樊,把歷史掃描過的最大對象統(tǒng)計出來便于分析優(yōu)化。

2.2 CPU飽和

單線程的Redis處理命令時只能使用一個CPU刻蟹。而CPU飽和是指Redis把單核CPU使用率跑到接近100%逗旁。使用top命令很容易識別出對應Redis進程的CPU使用率。CPU飽和是非常危險的舆瘪,將導致Redis無法處理更多的命令片效,嚴重影響吞吐量和應用方的穩(wěn)定性。對于這種情況英古,首先判斷當前Redis的并發(fā)量是否達到極限淀衣,建議使用統(tǒng)計命令redis-cli -h {ip} -p {port} --stat獲取當前Redis使用情況

2.3 持久化阻塞

對于開啟了持久化功能的Redis節(jié)點,需要排查是否是持久化導致的阻塞召调。

fork阻塞:fork操作發(fā)生在RDB和AOF重寫時膨桥,Redis主線程調(diào)用fork操作產(chǎn)生共享內(nèi)存的子進程,由子進程完成持久化文件重寫工作唠叛。如果fork操作本身耗時過長只嚣,必然會導致主線程的阻塞。

AOF刷盤阻塞:當我們開啟AOF持久化功能時玻墅,文件刷盤的方式一般采用每秒一次介牙,后臺線程每秒對AOF文件做fsync操作。當硬盤壓力過大時澳厢,fsync操作需要等待环础,直到寫入完成。如果主線程發(fā)現(xiàn)距離上一次的fsync成功超過2秒剩拢,為了數(shù)據(jù)安全性它會阻塞直到后臺線程執(zhí)行fsync操作完成线得。這種阻塞行為主要是硬盤壓力引起。

HugePage寫操作阻塞:子進程在執(zhí)行重寫期間利用Linux寫時復制技術(shù)降低內(nèi)存開銷徐伐,因此只有寫操作時Redis才復制要修改的內(nèi)存頁贯钩。對于開啟Transparent HugePages的操作系統(tǒng),每次寫命令引起的復制內(nèi)存頁單位由4K變?yōu)?MB办素,放大了512倍角雷,會拖慢寫操作的執(zhí)行時間,導致大量寫操作慢查詢性穿。

三勺三、外在原因

3.1 CPU競爭

進程競爭:Redis是典型的CPU密集型應用,不建議和其他多核CPU密集型服務部署在一起需曾。當其他進程過度消耗CPU時吗坚,將嚴重影響Redis吞吐量祈远。可以通過top商源、sar等命令定位到CPU消耗的時間點和具體進程车份,這個問題比較容易發(fā)現(xiàn),需要調(diào)整服務之間部署結(jié)構(gòu)牡彻。

綁定CPU:部署Redis時為了充分利用多核CPU扫沼,通常一臺機器部署多個實例。常見的一種優(yōu)化是把Redis進程綁定到CPU上讨便,用于降低CPU頻繁上下文切換的開銷充甚。這個優(yōu)化技巧正常情況下沒有問題,但是存在例外情況霸褒,當Redis父進程創(chuàng)建子進程進行RDB/AOF重寫時,如果做了CPU綁定盈蛮,會與父進程共享使用一個CPU废菱。子進程重寫時對單核CPU使用率通常在90%以上,父進程與子進程將產(chǎn)生激烈CPU競爭抖誉,極大影響Redis穩(wěn)定性殊轴。因此對于開啟了持久化或參與復制的主節(jié)點不建議綁定CPU。

3.2 內(nèi)存交換

內(nèi)存交換(swap)對于Redis來說是非常致命的袒炉,Redis保證高性能的一個重要前提是所有的數(shù)據(jù)在內(nèi)存中旁理。如果操作系統(tǒng)把Redis使用的部分內(nèi)存換出到硬盤,由于內(nèi)存與硬盤讀寫速度差幾個數(shù)量級我磁,會導致發(fā)生交換后的Redis性能急劇下降孽文。

預防內(nèi)存交換:

保證機器充足的可用內(nèi)存。

確保所有Redis實例設(shè)置最大可用內(nèi)存(maxmemory)夺艰,防止極端情況下Redis內(nèi)存不可控的增長芋哭。

降低系統(tǒng)使用swap優(yōu)先級。

3.3 網(wǎng)絡(luò)問題

(1)連接拒絕

網(wǎng)絡(luò)閃斷(網(wǎng)絡(luò)割接或者帶寬耗盡)

Redis連接拒絕(超過客戶端最大連接數(shù))

連接溢出(進程限制或backlog隊列溢出)

(2)網(wǎng)絡(luò)延遲

網(wǎng)絡(luò)延遲取決于客戶端到Redis服務器之間的網(wǎng)絡(luò)環(huán)境郁副。主要包括它們之間的物理拓撲和帶寬占用情況减牺。常見的物理拓撲按網(wǎng)絡(luò)延遲由快到慢可分為:同物理機>同機架>跨機架>同機房>同城機房>異地機房。但它們?nèi)轂男哉孟喾创婊眩锢頇C容災性最低而異地機房容災性最高拔疚。

網(wǎng)絡(luò)延遲問題經(jīng)常出現(xiàn)在跨機房的部署結(jié)構(gòu)上,對于機房之間延遲比較嚴重的場景需要調(diào)整拓撲結(jié)構(gòu)既荚,如把客戶端和Redis部署在同機房或同城機房等稚失。

帶寬瓶頸通常出現(xiàn)在以下幾個方面:

機器網(wǎng)卡帶寬。

機架交換機帶寬固以。

機房之間專線帶寬墩虹。

(3)網(wǎng)卡軟中斷

網(wǎng)卡軟中斷是指由于單個網(wǎng)卡隊列只能使用一個CPU嘱巾,高并發(fā)下網(wǎng)卡數(shù)據(jù)交互都集中在同一個CPU,導致無法充分利用多核CPU的情況诫钓。網(wǎng)卡軟中斷瓶頸一般出現(xiàn)在網(wǎng)絡(luò)高流量吞吐的場景旬昭。

歡迎工作一到五年的Java工程師朋友們加入Java架構(gòu)開發(fā): 855835163

群內(nèi)提供免費的Java架構(gòu)學習資料(里面有高可用、高并發(fā)菌湃、高性能及分布式问拘、Jvm性能調(diào)優(yōu)、Spring源碼惧所,MyBatis骤坐,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構(gòu)資料)合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰下愈!趁年輕纽绍,使勁拼,給未來的自己一個交代势似!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拌夏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子履因,更是在濱河造成了極大的恐慌障簿,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栅迄,死亡現(xiàn)場離奇詭異站故,居然都是意外死亡,警方通過查閱死者的電腦和手機毅舆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門西篓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人朗兵,你說我怎么就攤上這事污淋。” “怎么了余掖?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵寸爆,是天一觀的道長。 經(jīng)常有香客問我盐欺,道長赁豆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任冗美,我火速辦了婚禮魔种,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘粉洼。我一直安慰自己节预,他們只是感情好叶摄,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著安拟,像睡著了一般蛤吓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上糠赦,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天会傲,我揣著相機與錄音,去河邊找鬼拙泽。 笑死淌山,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的顾瞻。 我是一名探鬼主播泼疑,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼朋其!你這毒婦竟也來了王浴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤梅猿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后秒裕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體袱蚓,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年几蜻,在試婚紗的時候發(fā)現(xiàn)自己被綠了喇潘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡梭稚,死狀恐怖颖低,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情弧烤,我是刑警寧澤忱屑,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站暇昂,受9級特大地震影響莺戒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜急波,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一从铲、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧澄暮,春花似錦名段、人聲如沸阱扬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽麻惶。三九已至,卻和暖如春自娩,著一層夾襖步出監(jiān)牢的瞬間用踩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工忙迁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留脐彩,地道東北人。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓姊扔,卻偏偏與公主長得像惠奸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子恰梢,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 從這篇文章開始佛南,將依次介紹Redis高可用相關(guān)的知識——持久化、復制(及讀寫分離)嵌言、哨兵嗅回、以及集群。 本文將先說明...
    不變甄心閱讀 693評論 0 4
  • 前言 在上一篇文章中摧茴,介紹了Redis內(nèi)存模型绵载,從這篇文章開始,將依次介紹Redis高可用相關(guān)的知識——持久化苛白、復...
    Java架構(gòu)閱讀 2,314評論 3 21
  • 企業(yè)級redis集群架構(gòu)的特點 海量數(shù)據(jù) 高并發(fā) 高可用 要達到高可用娃豹,持久化是不可減少的,持久化主要是做災難恢復...
    lucode閱讀 2,206評論 0 7
  • 大家好购裙,我是帥氣小伙懂版,差不多一個月沒有更文了,因為我想寫出一個網(wǎng)癮少年的內(nèi)心躏率,所以我把自己陷進了網(wǎng)絡(luò)游戲躯畴,說白了就...
    帥氣小伙閱讀 7,720評論 2 4
  • 喜歡微笑,并不表示你現(xiàn)在過得很好禾锤,而是你知道私股,只有微笑,以后才會過得比現(xiàn)在要好恩掷。 ? ????
    暖暖的多肉苔蘚世界閱讀 311評論 0 0