Redis的Zset有多牛?請(qǐng)把耳朵遞過(guò)來(lái)
本篇文章很短,但信息量很大,是關(guān)于redis的zset。我來(lái)分享一點(diǎn)遇到過(guò)的線上數(shù)據(jù),或許對(duì)你的決策有幫助。
redis支持一個(gè)數(shù)據(jù)結(jié)構(gòu),叫做 zset,也就是有序的列表。當(dāng)然redis也不能濫用,可以看我以前的規(guī)范文章:《這可能是最中肯的Redis規(guī)范了》
忘了zset是個(gè)啥的同學(xué)可以看這張gif圖。
通過(guò)它,可以實(shí)現(xiàn)游戲排行榜一類的功能,或者實(shí)現(xiàn)Topx這樣的需求,也能精準(zhǔn)的讓用戶在海量數(shù)據(jù)中找到自己的位置。
zset的底層結(jié)構(gòu)是跳躍表,而與之類似的Java中的有序Set是TreeSet,使用紅黑樹(shù)實(shí)現(xiàn)的。
concurrent包里面,還有一個(gè)類叫做ConcurrentSkipListMap,從它的名字就可以看出來(lái),也是用跳躍表實(shí)現(xiàn)的,這個(gè)和zset最像。
好了,這是前提。廣度面試的時(shí)候我也會(huì)這么問(wèn)。
我們的問(wèn)題是:zset中能存放多少條記錄?線上有沒(méi)有有說(shuō)服力的數(shù)據(jù)?
先籠統(tǒng)的回答一下,zset理論上支持的元素最多是2^32-1個(gè),約42億,如果你的內(nèi)存夠大,放下國(guó)人綽綽有余。
使用redis-benchmark去測(cè)這個(gè)效果,不是很可信,測(cè)試用例寫起來(lái)也比較費(fèi)勁。測(cè)完了也不一定信,那就讓線上流量去沖擊吧。
為了應(yīng)付產(chǎn)品的需求,我把用戶按照省市進(jìn)行了劃分(geohash),結(jié)果,用戶分布最大的就是廣東省,非常棒。
在廣東省的zset里,存放了接近6千萬(wàn)的數(shù)據(jù),我們就要算在這6千萬(wàn)內(nèi)任何人的排行。zcard、zrank等一系列操作,easy實(shí)現(xiàn)。
運(yùn)行一段時(shí)間后,內(nèi)存直接飆升到了8G左右。這是由于跳表的特殊結(jié)構(gòu)所引起的,額外的輔助信息會(huì)占用更多的內(nèi)存。
以下是經(jīng)驗(yàn)值:
- 最高TPS寫入量1k/秒。
- 同時(shí)最高QPS查詢量5k/秒。
- 平均耗時(shí)5ms左右。
- 百分之95的請(qǐng)求都在10ms以內(nèi)返回。
- 長(zhǎng)尾請(qǐng)求超過(guò)100ms的不超過(guò)100條。
也就是說(shuō),在保持高寫入和高查詢的同時(shí),zset能夠保證較低的響應(yīng)耗時(shí)。
你要說(shuō)再多,我就不知道了,看這些數(shù)據(jù),或許還能夠再升一把。但要讓服務(wù)要盡量的穩(wěn),壓力盡量的分散,就不能太過(guò)苛刻,對(duì)這個(gè)數(shù)據(jù)我已經(jīng)很滿意了。
這只是一個(gè)省份的數(shù)據(jù)。如果綜合起來(lái),上層的業(yè)務(wù),就需要承載10w/s的請(qǐng)求。這是非常容易的,但也沒(méi)有意義,許多高并發(fā)經(jīng)驗(yàn)都是這么吹上去的,要不要去改改簡(jiǎn)歷?
復(fù)雜業(yè)務(wù)高并發(fā)才有價(jià)值,10w/s請(qǐng)求,給我兩臺(tái)redis就夠了,沒(méi)必要拿來(lái)吹。
但也是被zset的性能震驚了一把。跳表的結(jié)構(gòu),也了解一些,沒(méi)想到在高并發(fā)大數(shù)據(jù)量場(chǎng)景下,能這么快。
測(cè)試數(shù)據(jù)?沒(méi)有。本文只是分享一個(gè)經(jīng)驗(yàn)值。對(duì)了,redis幾乎不占用CPU,你只需要一臺(tái)2core16gb的服務(wù)器就可以了。
作者簡(jiǎn)介:小姐姐味道 (xjjdog),一個(gè)不允許程序員走彎路的公眾號(hào)。聚焦基礎(chǔ)架構(gòu)和Linux。十年架構(gòu),日百億流量,與你探討高并發(fā)世界,給你不一樣的味道。我的個(gè)人微信xjjdog0,歡迎添加好友,進(jìn)一步交流。