線上redis服務記憶體異常分析。

montya發表於2013-06-29

專案中,新增了一個統計功能,用來統計不同手機型號的每天訪問pv,看了下redis2.6有個setbit的功能,於是打算嚐嚐鮮把

redis從2.4更新到了2.6

因為是租了vps。伺服器的記憶體只有4g可以用,最近發現系統 負載很大。發現是redis服務引起的。

查了下redis的key db1 6w+。db1 不到2k。記憶體監控確有4.5g(這個很奇怪)。

 

這是很不正常的。想了最近在db1加了很多bit。於是把db1 flushdb。

發現記憶體佔用一下就刷刷的降下來了。

查了不少關於reids bit的資料。剛開始還堅信可能是redis的一個bug。昨天晚上找了凌晨2點多。還是沒啥頭緒。很惱火。

今天仔細看了下redis的 setbit 命令。恍然大悟。我做了件多麼傻b的事情。

setbit 命令

SETBIT key offset value

引數 offset  的說明

offset 引數必須大於或等於 0 ,小於 2^32 (bit 對映被限制在 512 MB 之內)。

對使用大的 offsetSETBIT 操作來說,記憶體分配可能造成 Redis 伺服器被阻塞。具體參考 SETRANGE 命令,warning(警告)部分。

 

然後在程式中檢視我的offset設定。

因為是需要統計某個機型每天的pv。所有為了最大限度防止誤差,offset 格式是當前時間的HHmmssss

SimpleDateFormat msdf = new SimpleDateFormat("HHmmssss");
long offset = Long.valueOf(msdf.format(new Date()));//時分秒毫秒
redisClient.setBit(hkey,offset,true);

  算了下offset的最大值是23595999 最小值是0,平均值是11798000,也就是說。在二進位制資料上在11798000位上置1

    然後又算了下

    11798000/8/1024/1024=1.4M

因為 db1 全是bit結構,差不多2k的樣子。這樣一共佔用了1.4*2k=2.8g記憶體。

這就找出問題所在了。修改offset的大小即可。

 

 

 

 

 

 

 

 

 

相關文章