摘要:給我們帶來便利的同時(shí),使用過程中會(huì)存在什么問題呢,本文將簡(jiǎn)單加以總結(jié)。避免使用內(nèi)存過大的實(shí)例。如果主線程距離上一次的成功超過,為了數(shù)據(jù)安全會(huì)阻塞直到后臺(tái)線程執(zhí)行完完成。
redis可以滿足很多的應(yīng)用場(chǎng)景,而且因?yàn)閷⑺袛?shù)據(jù)都放到內(nèi)存中,所以它的讀寫性能很好,很多公司都在使用redis。redis給我們帶來便利的同時(shí),使用過程中會(huì)存在什么問題呢,本文將簡(jiǎn)單加以總結(jié)。
阻塞問題
redis使用了單線程來處理請(qǐng)求,為什么單線程可以支持如此高的并發(fā)呢?主要有如下幾點(diǎn):
純內(nèi)存訪問:將所有數(shù)據(jù)都放到內(nèi)存中,內(nèi)存響應(yīng)時(shí)間為100納秒,是redis達(dá)到每秒萬(wàn)級(jí)別訪問的重要基礎(chǔ)
非阻塞IO:redis使用epoll作為I/O多路復(fù)用技術(shù),redis自身的事件處理模型將epoll中的連接、讀寫、關(guān)閉都轉(zhuǎn)換為事件,不在網(wǎng)絡(luò)I/O上浪費(fèi)過多時(shí)間
單線程:避免了線程切換和競(jìng)態(tài)產(chǎn)生的消耗,簡(jiǎn)化了數(shù)據(jù)結(jié)構(gòu)和算法的實(shí)現(xiàn)
因此如果某個(gè)命令執(zhí)行時(shí)間過長(zhǎng),會(huì)造成其他命令阻塞,對(duì)redis來說是致命的
產(chǎn)生阻塞的場(chǎng)景: A. API或數(shù)據(jù)結(jié)構(gòu)使用不合理 a. 避免使用某些易造成阻塞的命令如:keys sort hgetall smembers 執(zhí)行showlog get [n] 可以獲取最近n條執(zhí)行慢的記錄,對(duì)于執(zhí)行超過一定時(shí)間 (默認(rèn)10ms,線上建議設(shè)置為1ms)的命令都會(huì)記錄到一個(gè)定長(zhǎng)隊(duì)列(默認(rèn)128,可調(diào)整)中。 b. 防止一次操作獲取過多數(shù)據(jù):縮減大對(duì)象或者把大對(duì)象拆分為多個(gè)小對(duì)象 發(fā)現(xiàn)大對(duì)象的命令:redis-cli -h{ip} -p{port} bigkeys 內(nèi)部原理:采用分段進(jìn)行scan操作,把歷史掃描過的大對(duì)象統(tǒng)計(jì)出來 c. 防止大量key同時(shí)過期:如果有很多key在同一秒內(nèi)過期,超過了所有key的25%,redis主線程就會(huì)阻塞直到過期key比例下降到25%以內(nèi), 因此要避免同一時(shí)間過期大量key,過期時(shí)間可做散列處理。 redis4.0引入的lazyfree機(jī)制可以避免del、flushdb、flushall、rename等命令引起的redis-server阻塞,提高服務(wù)穩(wěn)定性。 B. CPU飽和 單線程的redis處理命令時(shí)只能使用一個(gè)CPU,CPU飽和是指redis把單核的CPU使用率跑到接近100%。 首先要確定redis的并發(fā)量是否達(dá)到極限,通過redis-cli-h{ip} -p{port}--stat 獲取redis當(dāng)前使用情況。 如果達(dá)到每秒6w+左右的qps,說明單臺(tái)已跑到極限,需要水平擴(kuò)展。 如果qps只有幾百或者幾千CPU就已經(jīng)飽和,可能使用了高算法復(fù)雜度的命令或者是對(duì)內(nèi)存的過度優(yōu)化 (如放寬了ziplist的使用條件,雖然使用的內(nèi)存會(huì)變少,但是更耗CPU)。 C. 持久化操作 持久化引起主線程的阻塞操作主要有:fork阻塞、AOF刷盤阻塞、HugePage寫操作阻塞 a. fork阻塞 發(fā)生在RDB和AOF重寫時(shí),redis主線程調(diào)用fork操作產(chǎn)生共享內(nèi)存的子線程,由子線程完成持久化文件的重寫工作,若fork操作耗時(shí)過長(zhǎng)會(huì)引起阻塞。 避免使用內(nèi)存過大的實(shí)例。 b. AOF刷盤阻塞 開啟AOF持久化功能時(shí),一般會(huì)采用1次/s的刷盤方式,后臺(tái)線程每秒對(duì)AOF文件做fsync操作,當(dāng)硬盤壓力過大時(shí)fsync操作需要等待直到寫入完成。 如果主線程距離上一次的fsync成功超過2s,為了數(shù)據(jù)安全會(huì)阻塞直到后臺(tái)線程執(zhí)行完fsync完成。這種阻塞是由于磁盤壓力引起。 盡量獨(dú)立部署 c. HugePage寫操作阻塞 子進(jìn)程在執(zhí)行重寫期間利用linux的copyonwrite機(jī)制,會(huì)拖慢寫操作的執(zhí)行時(shí)間,導(dǎo)致大量寫操作慢查詢。 優(yōu)化linux配置
緩存穿透
緩存穿透是指查詢一個(gè)根本不存在的數(shù)據(jù),緩存層和存儲(chǔ)層都不命中,且不將空結(jié)果寫到緩存中。
會(huì)導(dǎo)致后端存儲(chǔ)負(fù)載變大,造成后端存儲(chǔ)宕機(jī)等問題。可以在程序中分別統(tǒng)計(jì)總調(diào)用數(shù)、緩存命中數(shù)、存儲(chǔ)命中數(shù),若有大量存儲(chǔ)層空命中,可能是出現(xiàn)了緩存穿透。
產(chǎn)生原因:1.自身代碼或數(shù)據(jù)出現(xiàn)問題 2.惡意攻擊,爬蟲造成空命中
如何解決:
緩存空對(duì)象
存儲(chǔ)層不命中,扔將空對(duì)象保存到緩存層。
適用場(chǎng)景:數(shù)據(jù)頻繁變化、實(shí)時(shí)性高
帶來問題:
a.緩存了空值,會(huì)占用內(nèi)存空間;可以設(shè)置較短過期時(shí)間,自動(dòng)剔除。
b.數(shù)據(jù)不一致,若存儲(chǔ)層添加了此數(shù)據(jù),有短暫不一致;可主動(dòng)清除掉緩存的空對(duì)象。
布隆過濾器
在訪問緩存層和數(shù)據(jù)層之前將存在的key用布隆過濾器提前保存起來,做第一層攔截。
適用場(chǎng)景:大用戶集,實(shí)時(shí)性要求較低的場(chǎng)景,如有幾億的數(shù)據(jù)集,每隔一段時(shí)間會(huì)新增用戶進(jìn)去,在更新之前新用戶的訪問會(huì)存在緩存穿透問題。
缺點(diǎn):代碼維護(hù)復(fù)雜
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/61950.html
摘要:使用中存在的問題及如何避免一闡述了的阻塞問題及緩存穿透問題,本文將繼續(xù)總結(jié)在使用中的問題及方案。更多的節(jié)點(diǎn)不代表更高的性能,這就是無(wú)底洞問題。可使用漏桶令牌桶等方式進(jìn)行限流操作,將流量擋在應(yīng)用上層。 redis使用中存在的問題及如何避免(一)闡述了redis的阻塞問題及緩存穿透問題,本文將繼續(xù)總結(jié)redis在使用中的問題及方案。 無(wú)底洞問題 隨著數(shù)據(jù)量和訪問量的增長(zhǎng),需要增加更多...
閱讀 2430·2021-10-11 10:57
閱讀 1279·2021-10-09 09:59
閱讀 1997·2019-08-30 15:53
閱讀 3212·2019-08-30 15:53
閱讀 1008·2019-08-30 15:45
閱讀 737·2019-08-30 15:44
閱讀 3446·2019-08-30 14:24
閱讀 953·2019-08-30 14:21