成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Redis的KEYS命令引起宕機(jī)事件

ixlei / 2905人閱讀

摘要:最近的互聯(lián)網(wǎng)線上事故發(fā)生比較頻繁,年月號(hào)順豐發(fā)生了一起線上刪庫事件,在這里就不介紹了。最后的最后,線上操作的任何一條命令,再小心也不為過,因?yàn)橛捎谀愕囊粋€(gè)符號(hào)而引起的事故可能是你所承擔(dān)不起的。

摘要: 使用 Redis 的開發(fā)者必看,吸取教訓(xùn)啊!

原文:Redis 的 KEYS 命令引起 RDS 數(shù)據(jù)庫雪崩,RDS 發(fā)生兩次宕機(jī),造成幾百萬的資金損失

作者:陳浩翔

Fundebug經(jīng)授權(quán)轉(zhuǎn)載,版權(quán)歸原作者所有。

最近的互聯(lián)網(wǎng)線上事故發(fā)生比較頻繁,2018 年 9 月 19 號(hào)順豐發(fā)生了一起線上刪庫事件,在這里就不介紹了。

在這里講述一下最近發(fā)生在我公司的事故,以及如何避免,并且如何處理優(yōu)化。

間接原因還有很多,技術(shù)跟不上業(yè)務(wù)的發(fā)展,由每日百萬量到千萬級(jí)是一個(gè)大的跨進(jìn),公司對(duì)于系統(tǒng)優(yōu)化的處理優(yōu)先級(jí)不高,技術(shù)開發(fā)人手的短缺

第一次宕機(jī)

2018 年 9 月 13 號(hào)某個(gè)點(diǎn),公司某服務(wù)化項(xiàng)目的 RDS 實(shí)例連接飆升,CPU 升到 100%,拒絕了其他應(yīng)用的所有請(qǐng)求服務(wù)

整個(gè)過程如下:

監(jiān)控報(bào)警,顯示 RDS 的 CPU 使用率達(dá)到 80%以上,DBA 介入,準(zhǔn)備 KILL 慢 SQL

1 分鐘內(nèi),沒有發(fā)現(xiàn)明顯阻塞的 SQL,CPU 持續(xù)上升到 99%

5 分鐘內(nèi),大量應(yīng)用報(bào)警,并且拒絕服務(wù),RDS 的監(jiān)控顯示出現(xiàn)大量慢 SQL,聯(lián)系服務(wù)器數(shù)據(jù)庫提供商進(jìn)行協(xié)助

8 分鐘內(nèi),進(jìn)行數(shù)據(jù)庫主備切換(業(yè)務(wù)會(huì)受損,但是也沒辦法,沒有定位到問題)

9 分鐘內(nèi),部分業(yè)務(wù)恢復(fù),但是一些業(yè)務(wù)訂單的回調(diào)消息堆積超過 20w,備庫的 CPU 使用率也持續(xù)上升

15 分鐘內(nèi),備庫 CPU 使用率超過 97%,業(yè)務(wù)再次中斷,進(jìn)行切回主庫,并進(jìn)行限流

20 分鐘內(nèi),關(guān)閉一些次要應(yīng)用的流量入口

25 分鐘內(nèi),主庫 CPU 使用率恢復(fù)正常

30 分鐘內(nèi),逐步開啟關(guān)閉的限流應(yīng)用

35 分鐘內(nèi),所有應(yīng)用恢復(fù)正常

接下來就是與服務(wù)器數(shù)據(jù)庫提供商成立應(yīng)急小組緊急優(yōu)化可能出現(xiàn)的慢 SQL,雖然說可能解決了一些慢 SQL,但此次并沒有定位到具體的問題,也就為幾天后再次發(fā)生宕機(jī)事件埋下了伏筆

事故影響

某服務(wù)化項(xiàng)目服務(wù)不可用幾十分鐘,造成訂單數(shù)減少幾十萬筆,損失百萬資金。

原因分析

當(dāng)時(shí)是沒有定位到具體的原因的,但是下面的原因也是一部分可能引起宕機(jī)的情況。

某服務(wù)化項(xiàng)目的業(yè)務(wù)增速非???,在高峰期,數(shù)據(jù)庫 QPS 突破 35000,系統(tǒng)處于高負(fù)荷狀態(tài)。

在高峰期如果同時(shí)執(zhí)行幾個(gè)全表掃描的 SQL,會(huì)造成數(shù)據(jù)庫壓力急劇上升,應(yīng)用超時(shí)增多,前端應(yīng)用超時(shí),用戶重試,流量飆升,形成了雪崩效應(yīng)。

主要原因在與一些老項(xiàng)目的 SQL 查詢性能較差,并且使用的主庫,對(duì)數(shù)據(jù)庫影響較大。數(shù)據(jù)庫 QPS 太高,但是緩存方案因?yàn)槿耸衷蛞恢睕]有落地,慢 SQL 的問題處理優(yōu)先級(jí)應(yīng)該提升

改進(jìn)方案

針對(duì)每個(gè)應(yīng)用建一個(gè)數(shù)據(jù)庫賬號(hào),嚴(yán)格按照規(guī)范使用

緩存優(yōu)化方案即時(shí)落地,慢 SQL 問題優(yōu)先處理,集中處理目前已經(jīng)發(fā)現(xiàn)的慢 SQL(查詢時(shí)間超過 1S)

升級(jí)數(shù)據(jù)庫配置

遷移非核心業(yè)務(wù)到新的 RDS 實(shí)例中去

第二次宕機(jī)

由于上一次的宕機(jī)原因未找到,所以此次的宕機(jī)是可以預(yù)見的。

2018 年 9 月 19 號(hào),還是一樣的"配方",還是原來的"味道"。同一個(gè) RDS,CPU 飆升至 100%,接下來就是拒絕服務(wù),宕機(jī)。當(dāng)然,有了第一次的經(jīng)驗(yàn),直接主從切換,在幾十秒左右就恢復(fù)了所有業(yè)務(wù),但還是嚴(yán)重影響了公司的業(yè)務(wù)和形象。

原因分析

恢復(fù)業(yè)務(wù)后,公司緊急召開了緊急事故研究會(huì)議,當(dāng)然,我的級(jí)別是參與不了的。公司的高管,高層技術(shù)架構(gòu)、DBA、各個(gè)項(xiàng)目的主負(fù)責(zé)人一起進(jìn)行了會(huì)議。

在此次會(huì)議中,經(jīng)過查看各個(gè)項(xiàng)目的日志,后臺(tái)的監(jiān)控?cái)?shù)據(jù),發(fā)現(xiàn)在那臺(tái) RDS 數(shù)據(jù)庫 CPU 飆升時(shí),有一臺(tái) Redis 數(shù)據(jù)庫內(nèi)存將近 100%,然后急劇下降。聯(lián)系第一次的宕機(jī)情況,也是類似的。

接下來就是聯(lián)系服務(wù)器數(shù)據(jù)庫提供商,將那臺(tái) Redis 最近一周的命令全部調(diào)用出來,最后發(fā)現(xiàn),在那個(gè)時(shí)間點(diǎn)運(yùn)行了一條keys *...*命令。公司的一個(gè)工程師執(zhí)行 keys 模糊的匹配命令是為了清理沒用的鍵,但是沒有考慮到keys *進(jìn)行模糊匹配引發(fā) Redis 鎖,造成 Redis 鎖住,CPU 飆升,引起了所有調(diào)用鏈路的超時(shí)并且卡住,等 Redis 鎖的那幾秒結(jié)束,所有的請(qǐng)求流量全部請(qǐng)求到 RDS 數(shù)據(jù)庫中,使數(shù)據(jù)庫產(chǎn)生了雪崩,使數(shù)據(jù)庫宕機(jī)。

改進(jìn)方案

所有線上操作,全部要經(jīng)過運(yùn)維通過后方可執(zhí)行,運(yùn)維部門逐步快速收回各項(xiàng)權(quán)限

新增 Redis 實(shí)例,進(jìn)行分離

如果有使用類似 keys 正則命令需求,使用 scan 命令代替

總結(jié)

該事件中出現(xiàn)的兩次事故,完全是由于人為操作引起的,如果那位工程師,看過 Redis 的開發(fā)規(guī)范,會(huì)發(fā)現(xiàn)是建議禁用 keys 命令的。另外,有線上的命令操作,一定要經(jīng)過運(yùn)維評(píng)估后方可進(jìn)行操作,估計(jì)那個(gè)工程師是老員工吧,有權(quán)限,然后直接就進(jìn)行操作了。

另外,公司的業(yè)務(wù)發(fā)展確實(shí)很快,技術(shù)跟不上,這是非常非常危險(xiǎn)的,極大的增加了宕機(jī)的概率。

在業(yè)務(wù)量不大的情況下,那位工程師的操作是完全沒什么問題的,畢竟并發(fā)也不大,但是現(xiàn)在,隨著公司的發(fā)展,業(yè)務(wù)量的成倍成倍增加,技術(shù)的擴(kuò)展卻沒有隨著增長那么快。

公司的技術(shù)人手不足也是一方面,絕大多數(shù)人都是邊維護(hù)老項(xiàng)目邊做新功能,但是對(duì)于項(xiàng)目的重構(gòu)優(yōu)化,人手卻少了很多,項(xiàng)目優(yōu)化的優(yōu)先級(jí)不高,這也是很大的一個(gè)原因,極有可能出現(xiàn)類似的情況,新服務(wù)化構(gòu)建迫在眉睫。

最后的最后,線上操作的任何一條命令,再小心也不為過,因?yàn)橛捎谀愕囊粋€(gè)符號(hào)而引起的事故可能是你所承擔(dān)不起的。

Redis 開發(fā)建議

最后附上 Redis 的一些開發(fā)規(guī)范和建議

1. 冷熱數(shù)據(jù)分離,不要將所有數(shù)據(jù)全部都放到 Redis 中

雖然 Redis 支持持久化,但是 Redis 的數(shù)據(jù)存儲(chǔ)全部都是在內(nèi)存中的,成本昂貴。建議根據(jù)業(yè)務(wù)只將高頻熱數(shù)據(jù)存儲(chǔ)到 Redis 中【QPS 大于 5000】,對(duì)于低頻冷數(shù)據(jù)可以使用 MySQL/ElasticSearch/MongoDB 等基于磁盤的存儲(chǔ)方式,不僅節(jié)省內(nèi)存成本,而且數(shù)據(jù)量小在操作時(shí)速度更快、效率更高!

2. 不同的業(yè)務(wù)數(shù)據(jù)要分開存儲(chǔ)

不要將不相關(guān)的業(yè)務(wù)數(shù)據(jù)都放到一個(gè) Redis 實(shí)例中,建議新業(yè)務(wù)申請(qǐng)新的多帶帶實(shí)例。因?yàn)?Redis 為單線程處理,獨(dú)立存儲(chǔ)會(huì)減少不同業(yè)務(wù)相互操作的影響,提高請(qǐng)求響應(yīng)速度;同時(shí)也避免單個(gè)實(shí)例內(nèi)存數(shù)據(jù)量膨脹過大,在出現(xiàn)異常情況時(shí)可以更快恢復(fù)服務(wù)! 在實(shí)際的使用過程中,redis 最大的瓶頸一般是 CPU,由于它是單線程作業(yè)所以很容易跑滿一個(gè)邏輯 CPU,可以使用 redis 代理或者是分布式方案來提升 redis 的 CPU 使用率。

3. 存儲(chǔ)的 Key 一定要設(shè)置超時(shí)時(shí)間

如果應(yīng)用將 Redis 定位為緩存 Cache 使用,對(duì)于存放的 Key 一定要設(shè)置超時(shí)時(shí)間!因?yàn)槿舨辉O(shè)置,這些 Key 會(huì)一直占用內(nèi)存不釋放,造成極大的浪費(fèi),而且隨著時(shí)間的推移會(huì)導(dǎo)致內(nèi)存占用越來越大,直到達(dá)到服務(wù)器內(nèi)存上限!另外 Key 的超時(shí)長短要根據(jù)業(yè)務(wù)綜合評(píng)估,而不是越長越好!

4. 對(duì)于必須要存儲(chǔ)的大文本數(shù)據(jù)一定要壓縮后存儲(chǔ)

對(duì)于大文本【+超過 500 字節(jié)】寫入到 Redis 時(shí),一定要壓縮后存儲(chǔ)!大文本數(shù)據(jù)存入 Redis,除了帶來極大的內(nèi)存占用外,在訪問量高時(shí),很容易就會(huì)將網(wǎng)卡流量占滿,進(jìn)而造成整個(gè)服務(wù)器上的所有服務(wù)不可用,并引發(fā)雪崩效應(yīng),造成各個(gè)系統(tǒng)癱瘓!

5. 線上 Redis 禁止使用 Keys 正則匹配操作

Redis 是單線程處理,在線上 KEY 數(shù)量較多時(shí),操作效率極低【時(shí)間復(fù)雜度為 O(N)】,該命令一旦執(zhí)行會(huì)嚴(yán)重阻塞線上其它命令的正常請(qǐng)求,而且在高 QPS 情況下會(huì)直接造成 Redis 服務(wù)崩潰!如果有類似需求,請(qǐng)使用 scan 命令代替!

6. 可靠的消息隊(duì)列服務(wù)

Redis List 經(jīng)常被用于消息隊(duì)列服務(wù)。假設(shè)消費(fèi)者程序在從隊(duì)列中取出消息后立刻崩潰,但由于該消息已經(jīng)被取出且沒有被正常處理,那么可以認(rèn)為該消息已經(jīng)丟失,由此可能會(huì)導(dǎo)致業(yè)務(wù)數(shù)據(jù)丟失,或業(yè)務(wù)狀態(tài)不一致等現(xiàn)象發(fā)生。

為了避免這種情況,Redis 提供了 RPOPLPUSH 命令,消費(fèi)者程序會(huì)原子性的從主消息隊(duì)列中取出消息并將其插入到備份隊(duì)列中,直到消費(fèi)者程序完成正常的處理邏輯后再將該消息從備份隊(duì)列中刪除。同時(shí)還可以提供一個(gè)守護(hù)進(jìn)程,當(dāng)發(fā)現(xiàn)備份隊(duì)列中的消息過期時(shí),可以重新將其再放回到主消息隊(duì)列中,以便其它的消費(fèi)者程序繼續(xù)處理。

7. 謹(jǐn)慎全量操作 Hash、Set 等集合結(jié)構(gòu)

在使用 HASH 結(jié)構(gòu)存儲(chǔ)對(duì)象屬性時(shí),開始只有有限的十幾個(gè) field,往往使用 HGETALL 獲取所有成員,效率也很高,但是隨著業(yè)務(wù)發(fā)展,會(huì)將 field 擴(kuò)張到上百個(gè)甚至幾百個(gè),此時(shí)還使用 HGETALL 會(huì)出現(xiàn)效率急劇下降、網(wǎng)卡頻繁打滿等問題【時(shí)間復(fù)雜度 O(N)】,此時(shí)建議根據(jù)業(yè)務(wù)拆分為多個(gè) Hash 結(jié)構(gòu);或者如果大部分都是獲取所有屬性的操作,可以將所有屬性序列化為一個(gè) STRING 類型存儲(chǔ)!同樣在使用 SMEMBERS 操作 SET 結(jié)構(gòu)類型時(shí)也是相同的情況!

8. 根據(jù)業(yè)務(wù)場景合理使用不同的數(shù)據(jù)結(jié)構(gòu)類型

目前 Redis 支持的數(shù)據(jù)庫結(jié)構(gòu)類型較多:字符串(String),哈希(Hash),列表(List),集合(Set),有序集合(Sorted Set), Bitmap, HyperLogLog 和地理空間索引(geospatial)等,需要根據(jù)業(yè)務(wù)場景選擇合適的類型。

常見的如:String 可以用作普通的 K-V、計(jì)數(shù)類;Hash 可以用作對(duì)象如商品、經(jīng)紀(jì)人等,包含較多屬性的信息;List 可以用作消息隊(duì)列、粉絲/關(guān)注列表等;Set 可以用于推薦;Sorted Set 可以用于排行榜等!

9. 命名規(guī)范

雖然說 Redis 支持多個(gè)數(shù)據(jù)庫(默認(rèn) 32 個(gè),可以配置更多),但是除了默認(rèn)的 0 號(hào)庫以外,其它的都需要通過一個(gè)額外請(qǐng)求才能使用。所以用前綴作為命名空間可能會(huì)更明智一點(diǎn)。

另外,在使用前綴作為命名空間區(qū)隔不同 key 的時(shí)候,最好在程序中使用全局配置來實(shí)現(xiàn),直接在代碼里寫前綴的做法要嚴(yán)格避免,這樣可維護(hù)性實(shí)在太差了。

如:系統(tǒng)名:業(yè)務(wù)名:業(yè)務(wù)數(shù)據(jù):其他

但是注意,key 的名稱不要過長,盡量清晰明了,容易理解,需要自己衡量

10. 線上禁止使用 monitor 命令

禁止生產(chǎn)環(huán)境使用 monitor 命令,monitor 命令在高并發(fā)條件下,會(huì)存在內(nèi)存暴增和影響 Redis 性能的隱患

11. 禁止大 string

核心集群禁用 1mb 的 string 大 key(雖然 redis 支持 512MB 大小的 string),如果 1mb 的 key 每秒重復(fù)寫入 10 次,就會(huì)導(dǎo)致寫入網(wǎng)絡(luò) IO 達(dá) 10MB;

12. redis 容量

單實(shí)例的內(nèi)存大小不建議過大,建議在 10~20GB 以內(nèi)。redis 實(shí)例包含的鍵個(gè)數(shù)建議控制在 1kw 內(nèi),單實(shí)例鍵個(gè)數(shù)過大,可能導(dǎo)致過期鍵的回收不及時(shí)。

13. 可靠性

需要定時(shí)監(jiān)控 redis 的健康情況:使用各種 redis 健康監(jiān)控工具,實(shí)在不行可以定時(shí)返回 redis 的 info 信息??蛻舳诉B接盡量使用連接池(長鏈接和自動(dòng)重連)。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/17996.html

相關(guān)文章

  • RedisKEYS命令引起宕機(jī)事件

    摘要:最近的互聯(lián)網(wǎng)線上事故發(fā)生比較頻繁,年月號(hào)順豐發(fā)生了一起線上刪庫事件,在這里就不介紹了。最后的最后,線上操作的任何一條命令,再小心也不為過,因?yàn)橛捎谀愕囊粋€(gè)符號(hào)而引起的事故可能是你所承擔(dān)不起的。 摘要: 使用 Redis 的開發(fā)者必看,吸取教訓(xùn)啊! 原文:Redis 的 KEYS 命令引起 RDS 數(shù)據(jù)庫雪崩,RDS 發(fā)生兩次宕機(jī),造成幾百萬的資金損失 作者:陳浩翔 Fundebu...

    zoomdong 評(píng)論0 收藏0
  • 一個(gè)致命 Redis 命令,導(dǎo)致公司損失 400 萬??!

    摘要:最近安全事故瀕發(fā)啊,前幾天發(fā)生了順豐高級(jí)運(yùn)維工程師的刪庫事件,今天又看到了工程師在線執(zhí)行了危險(xiǎn)命令導(dǎo)致某公司損失萬。。該公司表示,如再犯類似事故,將直接開除,并表示之后會(huì)逐步收回運(yùn)維部各項(xiàng)權(quán)限。 最近安全事故瀕發(fā)啊,前幾天發(fā)生了《順豐高級(jí)運(yùn)維工程師的刪庫事件》,今天又看到了 PHP 工程師在線執(zhí)行了 Redis 危險(xiǎn)命令導(dǎo)致某公司損失 400 萬。。 什么樣的 Redis 命令會(huì)有如此...

    hedge_hog 評(píng)論0 收藏0
  • redis使用中存在問題及如何避免(一)

    摘要:給我們帶來便利的同時(shí),使用過程中會(huì)存在什么問題呢,本文將簡單加以總結(jié)。避免使用內(nèi)存過大的實(shí)例。如果主線程距離上一次的成功超過,為了數(shù)據(jù)安全會(huì)阻塞直到后臺(tái)線程執(zhí)行完完成。 redis可以滿足很多的應(yīng)用場景,而且因?yàn)閷⑺袛?shù)據(jù)都放到內(nèi)存中,所以它的讀寫性能很好,很多公司都在使用redis。redis給我們帶來便利的同時(shí),使用過程中會(huì)存在什么問題呢,本文將簡單加以總結(jié)。 阻塞問題 r...

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

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

0條評(píng)論

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