成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一個bug,差點損失幾萬

數據庫 Redis
最近遇到一個線上事故,差點損失好幾萬,故事是下面這樣的,我們一起來看!

你好,我是猿java

最近遇到一個線上事故,差點損失好幾萬,故事是這樣的...

背景

在之前的文章里我們分析了 Redis中運行 Lua腳本是如何保證原子性的。實際上,在我們的電商業務中也是使用 Redis + Lua來保證庫存的原子性操作,Redis是 Cluster集群部署,Lua腳本大致如下(本文的數據都經過脫敏處理):

-- type都是java代碼中傳入的String值,sku為Long型
local function availableRealSaleCal(type,sku)
    local key = formatKey(type, sku)
    -- 銷售庫存 =(if 可售賣量 then 銷售庫存 = min(可售庫存,可售賣量)
    -- else 銷售庫存 = 可售庫存 end)
    local availableRealSale = 0;
    local availableSale = redis.call('INCRBY', key..":AVAILABLE_SALE", 0);
    local saleLimit = redis.call('HGET', key, 'sale_limit');
    redis.call('SET', stocksKey .. ":AVAILABLE_REAL_SALE", availableRealSale);
    return availableRealSale
end

-- 拼接庫存 key,比如:stock:sale:{13523551512}, 注意這里有一個 {sku}
local function formatKey(type, sku)
    return "stock:"..type..":"..":{"..sku.."}"
end;

在上面的 Lua腳本中,有 {sku}語法的使用,{}是在 Redis cluster 模式下特有的 Hash Tag,Redis 的哈希標簽是一種特殊的語法,用于在執行命令時將多個 key 分組在一起。Hash Tag 由一對大括號 {} 包圍,可以將其中的內容視為一個整體來處理。

{}的主要用途包括:

  • 強制將多個 key 分組:在執行命令時,Redis 將哈希標簽中的內容視為一個整體,這樣就可以將多個 key 分組在一起,使它們被視為同一個分片。這對于在分片集群中對多個相關 key 執行原子操作非常有用。
  • 提高數據在集群中的分布均衡性:當使用哈希標簽時,Redis 將根據標簽中的內容計算哈希槽(Hash Slot),而不是整個 key。這樣可以確保具有相同標簽的 key 被映射到相同的哈希槽,從而提高了數據在集群中的分布均衡性。

例如,假設有兩個 key:{sku}:saleStock 和 {sku}:avalibleStock。如果不使用哈希標簽,即sku:saleStock 和 sku:avalibleStock,這兩個 key 將被視為不同的 key,可能被映射到不同的哈希槽。這樣,同一個 sku的不同庫存可能被 hash到不同的 slot,但是,如果使用哈希標簽 {sku},這樣,不管 {sku}拼接什么內容,都會被視為同一個分片,從而確保它們被映射到相同的哈希槽,以保證原子性操作的一致性。

更多{}使用,可以參考redis的官方文檔。

發現問題

監控報警,于是研發查排線上日志,如下:

Caused by: redis.clients.jedis.exceptions.JedisDataException: 
ERR Error running script (call to f_1fbde7f097d74a7d77c854c93b308d36d164dbf9): @user_script:371: @user_script: 371: 
Lua script attempted to access a non local key in a cluster node at redis.clients.jedis.Protocol.processError(Protocol.java:115)

看到這個錯誤,一臉懵,代碼上線半年沒有出現過問題,怎么會突然出問題呢?

搜索問題

因為第一次遇到這個問題,于是 Google了一下,找到幾個類似的問題,大致意思差不多,下面給出一個stackover上面的例子,鏈接如下:stackoverflow相同的錯誤,Lua 腳本摘要如下:

local f3=redis.call('HGET',KEYS[1],'1');
local f4=redis.call('HGET',f3,'1') ;
return f4;

對于錯誤的解釋是:在 Lua中執行多條語句,要保證key hash的 slot是同一個,否則就會出現上面的錯誤,比如:KEYS[1]和 f3 hash后不在同一個 slot就會出現上述錯誤。

定位問題

順著上面 Google 例子的思路,排查 {sku} hash后的值是否出現變更,線上跑的代碼,sku都是 14位的 Long,新上線的 sku 變成了 15位的 Long,會不會是長度變更導致問題?

于是,在中間件部門同事的配合下,找到了中間件的執行log:

stockskey:stock:40-248-000008:{1.112422310001e+14}

太奇怪了,sku傳入的是 Long類型,現在變成{1.112422310001e+14},最后發現在 Redis中間件有個cjson的操作,當傳入的 Long類型位數大于 14時,會把 Long轉成科學計數法,導致{sku}改變了原有的語義。

解決問題

在 Java 端,把 sku 從 Long型轉成 String類型,再傳入Lua,這樣可以避免 Long被轉換成科學記數法。

事故定級

因為架構中有小流量集群,每次有新 sku上線,都會在小流量集群上進行灰度發布,所以受影響的面有限,最后定級 P4,保住了 Q2的績效。

總結

  • Redis中運行 Lua腳本的確能保證原子性,而且經過線上環境驗證。
  • 如果想對 Lua中的多個 key hash到同一個 slot,可以使用 Hash Tag 語法,Hash Tag 由一對大括號 {} 包圍,可以將 {} 里面的內容視為一個整體來處理。
  • 特別注意,在很多場景 Long類型會被轉成科學記數法,記得曾經和前端對接時,出現過 Long 類型被截斷的問題。
  • 灰度發布在生產環境是個很不錯的選擇,對于大的功能上線,可以局部是試錯驗證。
  • 告警系統可以幫助我們更快的感知問題,對于大廠是標配,對于中小公司,建議盡量去搭建告警系統,即便簡陋一些也無所謂。
責任編輯:趙寧寧 來源: 猿java
相關推薦

2021-10-08 07:50:57

軟件設計程序

2021-04-30 07:09:48

SQLP0事故

2021-07-19 08:41:49

藍屏用戶Bug

2020-02-28 08:00:33

企業異常損失

2020-03-04 17:04:00

業務異常人工智能

2015-04-29 06:36:43

2016-09-09 16:47:46

2020-04-23 08:27:21

運維軟件系統

2021-12-19 22:00:31

APP軟件開發開發

2021-06-07 10:20:31

2025-02-13 07:00:00

Dubbo-goJava服務端

2014-12-17 09:40:22

dockerLinuxPaaS

2009-09-14 17:08:02

WebFormView

2024-08-08 08:09:38

2018-02-10 09:02:27

DevOps持續交付模型

2011-03-03 21:04:08

bug程序員

2017-10-10 15:14:23

BUGiOS 11蘋果

2015-08-24 10:07:13

程序員bug

2019-08-01 12:59:21

Bug代碼程序

2022-06-15 08:14:40

Go線程遞歸
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产69精品久久久久777 | 97高清国语自产拍 | 婷婷免费视频 | 午夜精品一区二区三区在线视频 | 国产高清在线观看 | 拍真实国产伦偷精品 | 成人在线一区二区 | 国产综合久久久久久鬼色 | 久久久久亚洲精品 | 国产精品视频网址 | 激情小视频 | 断背山在线观看 | 中文字幕一区二区三区精彩视频 | 久久久国产一区二区三区 | a在线视频观看 | 国产一区免费视频 | 亚洲视频免费观看 | 亚洲三区在线 | 国产精品国产 | 香蕉视频1024 | 亚洲精品在线免费观看视频 | 国产精品欧美一区二区三区不卡 | 国产精品永久免费 | 国产免费一区二区 | 在线免费亚洲视频 | 国产精品美女一区二区三区 | 天堂在线网 | 91精品国产综合久久久久蜜臀 | 一区二区精品 | 亚洲一区二区三区免费观看 | 成人欧美一区二区三区1314 | 欧美精品久久久久 | 一区二区三区高清在线观看 | 一区二区三区不卡视频 | 日韩在线欧美 | 国产精品久久久久久一区二区三区 | 四虎影院一区二区 | 欧美日韩精品久久久免费观看 | 操操网站 | 午夜免费福利电影 | 午夜www |