Redis数据结构及应用场景总结

redis与memcached区别?

长弓张(memcached):

1、我的系统业务以纯kv的缓存为主,数据量、并发业务量大,memcache较为合适。

2、memcache将所有数据存储在物理内存中。redis则有自己的VM机制,当数据超量时,会引发swap(交换分区),影响我的性能。

3、memcache使用多线程的模式(主线程监听,work子线程工作),而redis使用单线程,难以充分利用目前的多核cpu。

子木李(redis):

1、redis在数据持久化提供了两种方式RDB、AOF,虽然不是那么完美,但是系统发生崩溃时有这一层聊胜于无,对不对。

2、redis天然高可用,官方提供了sentinel集群管理工具,释放了大量的工作内容。

3、redis能存储的内容较memcached的1M要大多了。

4、redis青出于蓝而胜于蓝,代码质量比memcached好多了。

5、我的系统不仅仅只用了KV,我需要用到redis丰富的数据结构及相关功能函数,memcached不适合我的系统。

redis常用的数据结构

字符串键

1、结构类型如下图:

     Bits:二进制资源,可以存放文件、图片类型等

2、常见操作SET、SETNX区别:SET设置键值,SETNX设置一个不存在的键值才会生效

3、使用场景

      3.1 字符串键-分布式锁

           //设置锁字符串键,若存在则设置失败

           SETNX("order",'lock')==1 //成功获取锁

           SETNX(orderKey,'lock')==0 //有人占用资源获取锁失败

            //业务处理完毕释放分布式锁

           DEL(orderKey);

           //设置锁字符串键的失效时间,防止宕机,系统运行意外,导致无法释放锁

           PEXPIRE(orderKey,lockMilliSeconds)

     3.2 字符串键-计数器(帖子阅读量)

           // INCR  readcount::{帖子ID}  每阅读一次 + 1

           INCR key     

           // GET readcount::{帖子ID} 获取阅读量

           GET key

           说明:该操作是原子性操作,且redis是单线程操作不存在多线程时安全性问题,该设计适用于分布式系统

     3.3 字符串键-分布式全局系列

Hash键

 1、结构类型如下图


 2、Hash键意义

             1、Hash键可以将信息凝聚在一起,而不是直接分散的储存在整个Redis中,这不仅方便了数据管理,还可以尽量避免一定的误操作;

             2、避免键名冲突;

             3、最主要的意义:减少内存占用;

3、不适合Hash键的情况

             1、过期功能的使用,过期功能只能用在key上;

             2、二进制操作命令如:SETBIT、GETBIT、BITOP;

             3、需要考虑数据量分布的问题(redis的分布用预Hash巢/虚拟节点 方式实现如下图);


列表(List)键

 1、结构类型如下图


2、常见操作

      lpush key string 在 key 对应 list 头部添加字符串元素

      rpush key string 在 key 对应 list 尾部添加字符串元素

      rpop key 从 list 尾部删除元素 并返回删除的元素

      lpop key 从 list 头部删除元素 并返回删除的元素

      llen key 返回 key 对应 list 的长度 key 不存在 返回 0 如果key对应的类型不是 list 返回错误

      lrange key start end 返回指定区间内的元素 从下标 0 开始

      ltrin key start end 截取list 保留指定区间的元素

3、应用场景

    3.1 基于列表(list)键,实现阻塞消息队列


3.2 基于列表(list)键,实现新浪\推特用户消息列表

集合(SET)键

1、结构类型如下图

     结合键结构具有如下特点:1、无序,2、不可重复

2、常见操作

sadd:将指定的元素添加到集合。如果集合中存在该元素,则忽略。 如果集合不存在,会先创建一个集合然后在添加元素。

srem:移除一个或者多个元素,并返回移除的数量。

sismember:检查某个元素是否存在某个集合里面。

scard:返回集合里面元素的数量。

smembers:返回集合里面所有的元素。

srandmember:从集合里面随机返回一个或者多个元素。

spop:随机移除一个元素,返回随机移除的元素。

smove:smove source-key dest-key item 如果集合source-key包含元素item,那么从集合source-key里面移除元素item,并添加到集合dest-key里面,如果移除成功移除,那么命令返回1,否则返回0。

sdiff:sdiff key-name [key-name …] 返回那些存在于第一个集合,但不存在其他集合当中的元素(相当于差集运算)。

sdiffstore:sdiffstore store-key key1 [key… ] 将存在于第一个集合,但不存在其他集合当中的元素(相当于差集运算)找出来,并且存到dest-key里面,区别于上一步就是多了一个保存。

sinter:交集运算。

sinterstore:交集运算并存储。

sunion:并集运算。

sunionstore:并集运算并存储。

3、应用场景

     3.1 集合键-直播刷礼物、转发微博等抽奖活动

      //刷礼物、转发微博加入到集合中

      SADD key{userID}

      //获取所有用户,大轮盘转起来

      SMEMBERS key

      //抽取count名中奖者

      SPOP key[count] / SRANDMEMBER key[count]

      3.2 集合键-点赞、签到、like等功能

点赞--> SADD like::8001 1001

取消点赞--> SREM  like::8001 1001

检查用户是否点过赞-->  SISMEMBER like::8001 1001

获取点赞的用户列表-->  SISMEMBER like::8001

获取点赞用户数--> SCARD like::8001

3.3 集合键-集合运算

   SDIFF:计算差集时以第一个为主

查看共同关注的人模型

seven关注的人: sevenSubKey -->{'qing','mic','james'}

qing关注的人:qingSubKey-->{'seven','jack','mic','james'}

mic关注的人:micSubKey-->{'seven','james','qing','jack','tom'}

我和qing共同关注的人:SINTER sevenSubKey  qingSubKey -->{'mic','james'}

我关注的人也关注他:SISMEMBER micSubKey qing 、SISMEMBER micSubKey qing

我可能认识的人:SDIFFSTORE sevenMayKnow qingSubKey sevenSubKey -->{'seven','jack'}

3.4 集合键-集合运算-电商商品删选

每个商品入库时建立他的静态标签列表如:品牌、尺寸、处理器、内存...

录入:

SADD brand::lenovo 拯救者y7000P-001 ThinkPad-T480

SADD screenSize::15.6  拯救者y7000P-001 机械革命Z2AIR

SADD processor::i7  拯救者y7000P-001 机械革命X8TIPlus

SADD memory::8G 拯救者y7000P-001 ThinkPad-T480 机械革命Z2AIR 机械革命X8TIPlus

查找:

SINTER brand::lenovo screenSize::15.6  processor::i7  memory::8G --> 拯救者y7000P-001

3.5  集合键-集合运算-支付系统对账

通过两个交集计算出有问题的订单

有序集合(Zset)键

1、结构类型如下图

2、常见操作

2.1 设定/修改命令

zadd key score member [[score member] [score member] ...]

    将一个或多个member元素及其score值加入到key当中

    score值可以是整数值或双精度浮点数

    如果某个member已经是有序集合的成员,那么更新这个member的score值

    如果key不存在,创建一个空的有序集并执行zadd操作

    返回被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员

zincrby key increment member

    为key的成员member的score值加上增量increment(可以为负数)

    key不存在时创建一个空的有序集并执行zincrby操作

    member成员不存在时,创建该成员并设置其score值为0并执行zincrby操作

    返回member成员的新score值(字符串形式)

2.2 移除命令

zrem key member [member ...]:移除key中一个或多个成员,不存在的成员将被忽略。返回被成功移除的成员数量(不包括被忽略的成员)

zremrangebyrank key start stop:移除key中指定下标区间内(包含start和stop)的所有成员。返回移除成员的数量

zremrangebyscore key min max:

    移除key中score值在min和max之间(包括mi和max)的成员

    可以给参数min和max前增加"("括号来使结果不包含

    返回移除成员的数量

2.3 获取命令

zrange key start stop [withscores]

    返回key中指定下标(可以为负数)区间内的成员并按score值递增(从小到大)来排序的列表

    具有相同score值的成员按字典序(lexicographical order)来排列

    start大于最大下标或者start>stop,返回空列表

    stop大于最大下标将stop当作最大下标来处理

    withscores选项让成员和它的score值一并返回,返回列表以value1,score1, ..., valueN,scoreN的格式表示

zrevrange key start stop [withscores]:返回key中逆序排序(按score值从大到小)后指定下标(可以为负数)区间内的成员列表

zrangebyscore key min max [withscores] [limit offset count]

    返回key中score值介于min和max之间(包括min和max)的成员

    min和max可以是-inf(无限大)和+inf(无限小),这样可以在不知道最低和最高score的情况下使用zrangebyscore这类命令

    可选的limit参数指定返回结果的数量及区间

    withscores选项让成员和它的score值一并返回

    默认情况下,包括score值等于min和max的成员,可以给参数min和max前增加"("括号来使结果不包含,如:

    zrangebyscore zset (1 5:返回所有1<score<=5的成员

    zrangebyscore zset (5 (10:返回所有5<score<10的成员

    返回指定区间内的有序集成员的列表

zrevrangebyscore key min max [withscores] [limit offset count]:返回key中score值介于min和max之间(包括min和max)的成员并把这些成员逆序排序(按score值从大到小)

zscore key member:返回key成员member的score值(字符串形式),如果member元素不是key的成员或key不存在返回null

2.4 交集并集

zunionstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]

    计算给定的一个或多个有序集的和集(并集)并将该并集(结果集)储存到destination

    numkeys为给定key的数量

    weights选项为每个对应的key分别指定一个乘法因子,对应的key所有成员的score值在传递给聚合函数(aggregate)之前都要先乘以该因子,默认为1

    aggregat选项指定和集(并集)的结果集中score值的聚合方式

        默认为sum,将所有集合中某个相同成员的score值之和作为结果集中该成员的score值;

        min将所有集合中某个相同成员中最小的score值作为结果集中该成员的score值;

        max将所有集合中某个相同成员最大的score值作为结果集中该成员的score值

    返回保存到 destination 的结果集的基数。

zinterstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]

    计算给定的一个或多个有序集的交集并将该交集(结果集)储存到destination

    参数的用法和zunionstore相同

3、ZSet运算模型(可用于报表统计)

4、应用场景

4.1 ZSet集-自动补齐功能

用户首次进入搜索abc进行查询

 //对abc进行分词 a:key,1:sorce(说明当用户2也进行abc搜索时对应的key+1,实现热度排序),abc:member

ZINCRBY a 1 abc   

ZINCRBY ab 1 abc   

ZINCRBY abc 1 abc   

用户在输入abd进行查询

ZINCRBY a 1 abd

ZINCRBY ab 1 abd

ZINCRBY abd 1 abd

用户进行搜索时 输入 a,后台执行 ZREVRANGE a 0 -1 -->{abc,abd} 

4.1 ZSet集-单日排行榜

//点击第一条“马蓉怒斥王宝强 ”,设置为热词

ZADD hotNews::{11-11} 1  

//给对应热词+1

ZINCRBY hotNews::{11-11} 1 

//倒叙取10条

ZREVRANGE hotNews::{11-11}  0 10 WITHSCORES

4.1 ZSet集-周、月、年排行榜

//并集计算 11.19号-11.25号

ZUNIONSTORE hotNews{11.19-11.25} hotNews{11.19}  hotNews{11.19-11.20} ...hotNews{11.25} 

//取11.19-11.25倒叙的前十

ZREVRANGE hotNews{11.19-11.25} 0 10 WITHSCORES

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容