redis sadd 使用和優(yōu)化案例

redis 集合結(jié)構(gòu)介紹

redis集合(Set)結(jié)構(gòu)類似java中的set,可以保證元素的唯一性,而sadd命令用于向集合中添加一個(gè)或多個(gè)成員,已經(jīng)在集合中的元素將被忽略,key不存在則創(chuàng)建集合。

場景描述

要求創(chuàng)建一個(gè)用戶集合,這個(gè)集合是每天從其他數(shù)據(jù)源獲取,構(gòu)造任務(wù)處理這些數(shù)據(jù),提供給下游來判斷某個(gè)用戶是否在這個(gè)集合中。集合內(nèi)容是一些用戶標(biāo)識,32位的md5值,數(shù)據(jù)量較大,文本大概800MB,行數(shù)約2700萬,但還不算特別大的數(shù)據(jù)量,所以計(jì)劃放到redis中。

遇到的問題

首先很明顯, redis的set結(jié)構(gòu)是可以滿足需求的,開始也考慮到不能全部都放到一個(gè)key里。簡單了解到redis set 單個(gè)key可以支持2^32-1 的個(gè)數(shù),且根據(jù)md5值的特征,每一位都是16進(jìn)制,所以取最后一位生成key, 比如2020-03-17:e。這樣就可以有16個(gè)key,可以分擔(dān)key的數(shù)據(jù)量,減少壓力。同時(shí)程序中,使用MultiMap,在超過10000大小后,再開始批量寫入redis,最后給這些固定的key設(shè)置過期時(shí)間為2天,本地根據(jù)樣本數(shù)據(jù)跑通了整個(gè)流程,然后開始根據(jù)實(shí)際數(shù)據(jù)量進(jìn)行。
問題是在部署取到實(shí)際的數(shù)據(jù)后,執(zhí)行任務(wù),執(zhí)行近2小時(shí),依然沒有將數(shù)據(jù)全部導(dǎo)入到redis中,按理說800MB文本不算很大量的。 同時(shí)觀察redis集群監(jiān)控,CPU從2%-3%升高到10%左右,此時(shí)不得不中斷任務(wù)。
回顧現(xiàn)狀,總的數(shù)據(jù)量約2700萬,現(xiàn)有16個(gè)key, 每個(gè)key會(huì)有167萬左右的數(shù)據(jù),其中每個(gè)value的值是32位md5值,空間占32B,每個(gè)key占的空間大約54MB(167W*32B)。首先想到還是單個(gè)key太大了,才導(dǎo)致壓力升高,于是考慮增加key的數(shù)量,來減少set中單個(gè)key的元素?cái)?shù)量。同時(shí)也了解到,一般情況set的單個(gè)key下最好不要超過1MB,當(dāng)前肯定是大大超過的。1MB按單個(gè)值32B計(jì)算,大約可以存3.2萬個(gè)key,當(dāng)然這是非常理想的情況,還有其他一些必須的內(nèi)容也要占用空間,所以建議的單個(gè)key中元素也就在2-3萬左右。

引申

這里介紹幾個(gè)Redis相關(guān)命令,用于查詢當(dāng)前key狀態(tài)情況和排查問題:

1. scard

獲取set 某個(gè)key下的元素個(gè)數(shù),比如

10.118.xx.xx:xxx> scard users:2020-03-17:aff

2. memory usage

查看某個(gè)key所占的內(nèi)存,返回內(nèi)存大小,單位是字節(jié)。比如。

10.136.xxx.xxx:xxx> memory usage users:2020-03-18:000
(integer) 457389

3. pttl 和 ttl

pttl獲取毫秒級別的有效時(shí)間,注意是實(shí)際精度的,不是秒級別換算的值;ttl獲取秒級別的有效時(shí)間

解決方法

目標(biāo)確定是減少單個(gè)key的數(shù)據(jù)量,還是從md5本身出發(fā)。之前取最后一位作為鍵后綴,有16個(gè)key,如果再往前取就可以增加key的個(gè)數(shù),總的數(shù)據(jù)量是一定的,從而可以減少單個(gè)key的數(shù)據(jù)量。 這里改成取后三位來做key后綴,會(huì)有0x000-0xfff共4096(16*16*16)個(gè)key。而單個(gè)key中元素?cái)?shù)量驟減,變成2700W/4096,大約6500左右。(從167萬降到6500)。

后續(xù)追蹤

修改后開始用實(shí)際數(shù)據(jù)驗(yàn)證,開始任務(wù)后,監(jiān)控到redis CPU升高僅1%,從3%到4%左右,任務(wù)最終持續(xù)時(shí)間45分鐘,至此整個(gè)任務(wù)開發(fā)完成。這里有幾個(gè)點(diǎn)可以進(jìn)一步優(yōu)化,首先是沒有引入多線程寫入redis,其次可以對文件進(jìn)行拆分,來運(yùn)用并發(fā)讀取,還有redis查詢方面,可以換bitmap,當(dāng)然這樣整個(gè)邏輯是要變的,后續(xù)如果數(shù)據(jù)量更大可以再考慮。我們看到對這種數(shù)據(jù)量較大的問題的處理,前期的調(diào)研和計(jì)算還是非常重要的,很多功能組件在數(shù)據(jù)量較少和大量的情況下,表現(xiàn)可能是完全不一樣的,大數(shù)據(jù)量的處理會(huì)有更多未知的問題。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

  • Ubuntu下安裝redis 安裝redis 在 Ubuntu 系統(tǒng)安裝 Redi 可以使用以下命令: 啟動(dòng) Re...
    riverstation閱讀 1,046評論 0 0
  • Redis的內(nèi)存優(yōu)化 聲明:本文內(nèi)容來自《Redis開發(fā)與運(yùn)維》一書第八章,如轉(zhuǎn)載請聲明。 Redis所有的數(shù)據(jù)都...
    meng_philip123閱讀 19,075評論 2 29
  • redis是一個(gè)以key-value存儲的非關(guān)系型數(shù)據(jù)庫。有五種數(shù)據(jù)類型,string、hashes、list、s...
    林ze宏閱讀 1,111評論 0 0
  • 1.通用命令 1.1通用命令 keys *遍歷所有key keys [pattern]遍歷符合通配符的所有key ...
    香沙小熊閱讀 587評論 0 0
  • 關(guān)于女兒負(fù)面轉(zhuǎn)正面事件(3.7) 晚上,我正陪著女兒聽寫詞語。這時(shí),兒子拿著手機(jī),剛好跟出差在外的爸爸視頻,讓...
    麗平_f390閱讀 148評論 0 0

友情鏈接更多精彩內(nèi)容