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

    zrangebyscore zset (5 (10:返回所有5

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

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

你可能感兴趣的:(Redis数据结构及应用场景总结)