一次線上事故,導致公司損失400萬

語言: CN / TW / HK

一、 順豐高階開發工程師線上執行了 Redis 危險命令導致某公司損失 400 萬

最近安全事故瀕發啊,前幾天發生了《順豐高階運維工程師的刪庫事件》,今天又看到了 PHP 工程師線上執行了 Redis 危險命令導致某公司損失 400 萬。。

什麼樣的 Redis 命令會有如此威力,造成如此大的損失?

具體訊息如下:

據云頭條報道,某公司技術部發生 2 起本年度 PO 級特大事故,造成公司資金損失 400 萬,原因如下:

由於 PHP 工程師直接操作上線 redis,執行 keys wxdb(此處省略)cf8 這樣的命令,導致redis鎖住,導致 CPU 飆升,引起所有支付鏈路卡住,等十幾秒結束後,所有的請求流量全部擠壓到了 rds 資料庫中,使資料庫產生了雪崩效應,發生了資料庫宕機事件。

該公司表示,如再犯類似事故,將直接開除,並表示之後會逐步收回運維部各項許可權。

一個命令損失數百萬,這,需要賠償嗎?

程式碼不規範,同事兩行淚,擼碼需謹慎!

處於好奇考慮,我來測試一下,這到底是什麼問題?

二、測試一下1000萬資料的效能

1、編寫指令碼檔案

寫入1000萬資料。

java for((i=1;i<=10000000;i++)); do echo "set k$i 哪吒程式設計$i" >> /tmp/test1.txt;done;

通過/tmp/test1.txt檢視一下是否寫入成功。

2、寫入Redis1000萬資料

lua cat /tmp/test1.txt | redis-cli -a 111111 --pipe

3、通過keys * 檢視1000萬資料

4、通過配置檔案禁止keys *的使用

在redis.conf檔案中配置security:

lua rename- command keys "" rename- command flushdb "" rename- command flushall ""

三、使用scan替代keys *

Redis Scan 命令用於迭代資料庫中的資料庫鍵。

SCAN 命令是一個基於遊標的迭代器,每次被呼叫之後, 都會向用戶返回一個新的遊標, 使用者在下次迭代時需要使用這個新遊標作為 SCAN 命令的遊標引數, 以此來延續之前的迭代過程。

SCAN 返回一個包含兩個元素的陣列, 第一個元素是用於進行下一次迭代的新遊標, 而第二個元素則是一個數組, 這個陣列中包含了所有被迭代的元素。如果新遊標返回 0 表示迭代已結束。

scan語法:

lua SCAN cursor [MATCH pattern] [COUNT count]

四、拒絕bigkey

1、阿里雲Redis開發規範

阿里雲Redis開發規範中明確規定“拒絕bigkey(防止網絡卡流量、慢查詢)”。

String型別控制在10KB以內,hash、list、set、zset元素個數不要超過5000。

2、出現bigkey時如何刪除?

  1. String型別的用del刪除。
  2. 其它型別使用hscan、sscan、zscan方式漸進式刪除,同時要避免bigkey過期時間自動刪除問題,因為它會造成主執行緒阻塞。

Hash 刪除: hscan+hdel

```java public void delBigHash(String host, int port, String password, String bigHashKey) { Jedis jedis = new Jedis(host, port); if (password != null && !"".equals(password)) { jedis.auth(password); } ScanParams scanParams = new ScanParams().count(100); String cursor = "0"; do { ScanResult> scanResult = jedis.hscan(bigHashKey, cursor, scanParams); List> entryList = scanResult.getResult(); if (entryList != null && !entryList.isEmpty()) { for (Entry entry : entryList) { jedis.hdel(bigHashKey, entry.getKey()); } } cursor = scanResult.getStringCursor(); } while (!"0".equals(cursor));

//刪除 bigkey
jedis.del(bigHashKey);

} ```

3、bigkey會造成哪些問題?

  1. 記憶體不均,叢集遷移困難;
  2. 超時刪除,阻塞執行緒;
  3. 網路流量阻塞;

4、如何發現bigkey?

(1)通過redis-cli --bigkeys查詢。

(2)計算每個鍵值的位元組數,通過memory usage key查詢