关于redis中的zset(sorted set)
zset相关的问题,算是面试中的高频问题了。那么zset到底是什么?底层的实现原理是什么?相关的使用场景有哪些?1. zset是什么?
在redis官网( https://redis.io/ )上,我们可以看到set, sorted set。其实zset就是sorted set。为了避免sorted set简写sset导致命令冲突,所以改为zset。同理例如class-->clazz
sorted set从字面意思上,很容易就可以理解,是个有序且不可重复的数据集合。类似set和hash的混合体,但是相比于set,zset内部由score进行排序.
2. zset中的score排序规则
升序排列,分值越大越靠后
分值相同,则按照value的字典顺序排序
3. zset的用法
zset的命令可在这里( http://www.redis.cn/commands.html#sorted_set )看到,有兴趣的同学可以直接去看。
ZADD key score1 value1 score2 value2........
即表示增加是的score和value 组,可同时增加多个
4. zset实现
在redis.conf中,有如下两个参数:
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
这两个条件均不满足,使用ziplist压缩表来实现sorted set
满足这两个条件之一,sorted set的内部实现会由ziplist转换为zset
zset-max-ziplist-entries 128,即sorted set中的元素对超过128时(存储的是score和value的元素对,所以数据项是256),内部实现会由ziplist转换为zset。
zset-max-ziplist-value 64,即任意一个value的长度超过了64字节,内部实现会由ziplist转换为zset.
zset由dict、skiplist实现。
5. ziplist,即压缩列表
压缩列表是由连续性内存组成的顺序性数据结构,一个压缩列表可以包含任意多的entry,每个entry可以保存一个字节数组或者一个整数。
压缩列表在表头有三个字段:zlbytes,zltail,zllen分别表示列表长度(整个列表占用的字节数),列表尾的偏移量(尾节点距离起始地址的字节数)和列表中entry的个数。
列表表尾还有一个zlend,表示列表结束了。
6.skiplist
由上图压缩列表可知,如果我们查找第一个元素或者最后一个元素,直接通过表头三个字段的长度可定位。复杂度是O(1),而如果查找其他元素,只能顺序查找,复杂度是O(n)。 为了解决这个问题,可以使用跳表。
在新增节点之前,也会先经过查询,确定插入位置,再完成插入操作,同时也实现了Sorted Set的排序。
跳表中新增加节点不会影响其他节点的索引位置。因此插入操作只需要修改插入节点前后的指针,不需要修改所有节点,降低了插入的复杂度,所以跳表在插入性能上明显优于平衡树。
7. zset的使用场景
需要排序的场景,比如top10的热点文章,或者排行榜
消息的延迟发送,用score存储发送时间戳,定时任务扫描sorted set,判断时间进行发送。
绛旓細鍦redis瀹樼綉锛 https://redis.io/ 锛変笂锛屾垜浠彲浠ョ湅鍒皊et, sorted set銆傚叾瀹zset灏辨槸sorted set銆備负浜嗛伩鍏峴orted set绠鍐sset瀵艰嚧鍛戒护鍐茬獊锛屾墍浠ユ敼涓簔set銆傚悓鐞嗕緥濡俢lass-->clazz sorted set浠庡瓧闈㈡剰鎬濅笂锛屽緢瀹规槗灏卞彲浠ョ悊瑙o紝鏄釜鏈夊簭涓斾笉鍙噸...
绛旓細1. zadd锛氶瓟娉曟坊鍔爖add鍛戒护璁╀綘杞绘澗娣诲姞鍏冪礌鍙婂叾瀵瑰簲鍒嗘暟锛屽锛歾add ranking 1 "鑺辫姳" 2 "涔斾箶"锛岃繖閲岀殑"鑺辫姳"寰楀垎涓1鍒嗭紝"涔斾箶"涓2鍒嗐2. zcard锛氬厓绱犺鏁板櫒zcard鐢ㄤ簬缁熻闆嗗悎涓厓绱犵殑鏁伴噺锛屽zcard ranking锛岃兘蹇熷緱鐭ュ綋鍓嶆姇绁ㄩ」鐩殑鍙備笌浜烘暟銆3. zcount锛氬垎鏁板尯闂寸粺璁count鍛戒护鑳界粺璁℃寚瀹氬垎鏁板尯...
绛旓細鍦Redis涓锛屽zset鐨勪富瑕佹搷浣滃寘鎷坊鍔犲厓绱犮佽幏鍙栧厓绱犮佹洿鏂板垎鏁般佸垹闄ゅ厓绱犱互鍙婅幏鍙栨帓鍚嶇瓑銆備緥濡傦紝閫氳繃浣跨敤ZADD鍛戒护锛屾垜浠彲浠ュ悜zset涓坊鍔犱竴涓垨澶氫釜鍏冪礌锛屽苟涓烘瘡涓厓绱犳寚瀹氫竴涓垎鏁般傚锛歚ZADD myzset 1 "one" 2 "two" 3 "three"`锛岃繖閲屽垱寤轰簡涓涓悕涓簃yzset鐨勬湁搴忛泦鍚堬紝骞舵坊鍔犱簡涓変釜鍏冪礌鍙婂叾瀵瑰簲...
绛旓細棣栧厛锛屾槑纭洖绛斾綘鐨勯棶棰橈紝Redis涓璟Set锛鏈夊簭闆嗗悎锛夌殑甯哥敤鍛戒护鍖呮嫭锛歓ADD銆乑RANGE銆乑REVRANGE銆乑REM銆乑CARD銆乑RANK銆乑REVRANK銆乑SCORE绛夈傚叾娆★紝鎴戜滑鏉ヨ缁嗚В閲婅繖浜涘懡浠ゃ俍ADD鍛戒护鐢ㄤ簬灏嗕竴涓垨澶氫釜鎴愬憳鍏冪礌鍙婂叾鍒嗘暟鍊煎姞鍏ュ埌鏈夊簭闆嗗悎涓紝濡傛灉鎴愬憳宸茬粡鏄湁搴忛泦鍚涓殑鍏冪礌锛屽垯浼氭洿鏂板叾鍒嗘暟骞堕噸鏂版帓搴忋備緥濡傦紝`ZADD...
绛旓細1.鍒涘缓zset闆嗗悎 鍛戒护锛歾add zset(闆嗗悎鍚嶅瓧) v1 k1 v2 k3 v3 k3 2.鏌ョ湅zset闆嗗悎 鍛戒护锛歾range zset(闆嗗悎鍚嶅瓧) 0 -1 limit 2 2 7.zrevrangebyscore (鍊掑簭鎺掑簭)锛坮ev(琛ㄧずreverse[鍙嶈浆鐨勬剰鎬漖)锛 鍜寊rangebyscore鐢ㄦ硶鐩镐技 娉ㄦ剰锛歾revrangebyscore 瀹冪殑鑼冨洿鏄弽鍚戞帓搴忥紝鎵浠...
绛旓細Redis鏀寔浜旂鏁版嵁绫诲瀷锛歴tring锛堝瓧绗︿覆锛夛紝hash锛堝搱甯岋級锛宭ist锛堝垪琛級锛宻et锛堥泦鍚堬級鍙zset(sorted set锛氭湁搴忛泦鍚)銆傦紙鎺ㄨ崘瀛︿範锛歊edis瑙嗛鏁欑▼锛塖tring锛堝瓧绗︿覆锛塻tring 鏄 redis 鏈鍩烘湰鐨勭被鍨嬶紝浣犲彲浠ョ悊瑙f垚涓 Memcached 涓妯′竴鏍风殑绫诲瀷锛屼竴涓 key 瀵瑰簲涓涓 value銆俿tring 绫诲瀷鏄簩杩涘埗瀹夊叏鐨勩傛剰鎬...
绛旓細redis鏀寔鐨勬暟鎹被鍨嬫湁String銆丠ash銆丩ist銆丼et銆Zset銆1銆丼tring锛堝瓧绗︿覆绫诲瀷锛夛細鍙互鏄櫘閫氬瓧绗︿覆锛屼篃鍙互鏄暣鏁版垨娴偣鏁板笺傚彲浠ヨ缃繃鏈熸椂闂达紱鍙互瀵瑰瓧绗︿覆杩涜append銆乬et銆乻et銆乮ncr銆乨ecr绛夋搷浣溿2銆丠ash锛堝搱甯岀被鍨嬶級锛氱被浼间簬涓涓暟缁勶紝鍏朵腑姣忎釜鍏冪礌閮芥槸涓涓猣ield鍜寁alue鐨勯敭鍊煎锛屽彲浠ュ鏁翠釜鍝堝笇琛...
绛旓細浜斻亃set redis鐨剒set鍜宻et涓鏍蜂篃鏄痵tring绫诲瀷鍏冪礌鐨勯泦鍚,涓斾笉鍏佽閲嶅鐨勬垚鍛樸備笉鍚岀殑鏄瘡涓厓绱犻兘浼氬叧鑱斾竴涓猟ouble绫诲瀷鐨勫垎鏁般俽edis姝f槸閫氳繃鍒嗘暟鏉ヤ负闆嗗悎涓殑鎴愬憳杩涜浠庡皬鍒板ぇ鐨勬帓搴忋倆set鐨勬垚鍛樻槸鍞竴鐨,浣嗗垎鏁锛坰core锛夊嵈鍙互閲嶅銆Redis鏁版嵁妯″瀷鍜屾ц兘锛氫竴銆佹暟鎹ā鍨 1銆佸瓧绗︿覆鍒楄〃銆2銆佹棤搴忎笉閲嶅...
绛旓細redis鏄竴涓猭ey-value瀛樺偍绯荤粺銆傚拰Memcached绫讳技锛屽畠鏀寔瀛樺偍鐨剉alue绫诲瀷鐩稿鏇村锛屽寘鎷瑂tring(瀛楃涓)銆乴ist(閾捐〃)銆乻et(闆嗗悎)銆zset(sorted set --鏈夊簭闆嗗悎)鍜宧ash锛堝搱甯岀被鍨嬶級銆傝繖浜涙暟鎹被鍨嬮兘鏀寔push/pop銆乤dd/remove鍙婂彇浜ら泦骞堕泦鍜屽樊闆嗗強鏇翠赴瀵岀殑鎿嶄綔锛岃屼笖杩欎簺鎿嶄綔閮芥槸鍘熷瓙鎬х殑銆傚湪姝ゅ熀纭涓婏紝redi...
绛旓細Redis鏀寔浜旂鏁版嵁绫诲瀷锛歴tring锛堝瓧绗︿覆锛夛紝hash锛堝搱甯岋級锛宭ist锛堝垪琛級锛宻et锛堥泦鍚堬級鍙zset(sorted set锛氭湁搴忛泦鍚)銆傛剰鎬濇槸 redis 鐨 string 鍙互鍖呭惈浠讳綍鏁版嵁銆傛瘮濡俲pg鍥剧墖鎴栬呭簭鍒楀寲鐨勫璞★紝string 绫诲瀷鐨勫兼渶澶ц兘瀛樺偍 512MB銆俁edis hash鏄竴涓 string 绫诲瀷鐨 field 鍜 value 鐨勬槧灏勮〃锛宧ash 鐗瑰埆...