五大数据类型(数据对象)
redisObject
Redis中的每个对象都由一个redisObject结构体表示:
typedef struct redisObject {
unsigned type: 4;
unsigned encoding: 4;
void *ptr;
//...
} robj;
type属性记录了数据类型,就是常说的5种数据类型中的一种。
对象的ptr指针指向了对象的底层实现数据结构。而指向的是哪些底层结构由encoding属性决定。 每个类型的对象都至少使用了两种不同的编码。OJECT ENCODING可以查看数据对象对应的编码(底层结构)。
字符串String
字符串对象的编码可以是int、raw(SDS)或embstr。 embstr是专门用于保存短字符串的一种优化编码方式,通过预留一定的内存空间减少内存分配次数。
字符串类型(包括其他类型)是以key-value形式存储。字符串存储最大长度为512M(一般认为超过10KB就是大Key?)。
应用场景
(一)缓存数据
Redis的一个主要用法即是作为分布式缓存,拥有高并发量、读写速度快的特点。String类型是数据缓存中常用的一种。
个人在使用Reids缓存大量字符串类型数据有一个项目经验: 在各个互联网媒体流量平台投放广告后,广告的曝光、点击等数据会实时回传,需要提供回调接口接收回传数据并存储。回传接口的访问量即数据的存储请求量qps在6万~8万。 经调研MySql数据库无法处理这个量级的qps,存储时会造成大量数据阻塞。项目采用Redis集群来存储回传的数据,所有数据设置14天过期时间。如下图所示。
(二)计数器
字符串类型中可以存储long类型整数,使用Incr方法可以使计数器自增1。个人也有使用经验,在创建广告素材时,需要给每个素材一个唯一的素材id,这个id即可用Redis的计数器生成。
(三)接口限流
Reids可以使用expire过期时间+incr记录访问次数的方式,防止恶意刷接口的行为。个人在做一个“邮件入职”功能的时候,使用Redis做过防刷功能。
(四)分布式共享session
一般公司内部较大型的系统都不会单机部署,而是部署到多态机器构成集群,使用ngxin做负载均衡。
个人在做“邮件入职”功能的时候,涉及到候选人登录人力资源系统。在登陆请求到达服务器时,会生成一个session文件,如果将session文件存储在服务器中,之后系统跳转到资料采集页面进行访问时,如果请求达到其他机器上,则需要重新登录。
使用Redis对用户session进行集中管理,用户每次访问都从Redis中获取登录信息。
列表List
列表对象的编码可以是ziplist或linkedlist。List是一个线性有序结构,可以嵌入String类型。常用命令lpush、rpush、lpop、rpop、lrange等。
应用场景
(一)展示列表
如bilibili里面的关注列表、粉丝列表,可以按照(时间)顺序(正序或倒序)获取List中的元素,展示最新列表这样。还可以分页展示。频繁更新的列表不适合用List,list类型的分页可能导致列表元素重复或漏掉??
与最新列表类似,还可以做排行榜。每个一段时间计算一次排行榜,记录在List中,lrange命令去分页查看。
(二)异步消息队列
利用先进先出的特点异步处理消息。不过要注意消息丢失的问题??
哈希Hash
哈希对象的编码可以是ziplist或hashtable。Hash是键值对的集合,相当于在Redis键值对的结构下又套了一层键值对。key:(field:value)。常用命令有hset、hget、hmset、hmget、hgetall等。
应用场景
(一)购物车
购物车中的redis存储模型。
(二)审核过滤
Hash可以用于记录审核流程(key)中某一个审核员(field)审核了哪些素材(values)。
集合Set
集合对象的编码可以是intset或hashtable。Set和List都是存储多个字符串元素的集合,不同的是Set中不允许出现重复元素,且没有顺序。常用命令sadd、smembers、srem、sinter、sdiff、sunion等。
应用场景
(一)标签
关注有相同喜好、关注相同或相似内容的人可以放在一个Set里面,给他们一个标签。或者是同一个标签下的素材可以放到一个Set里。
可以引申到共同好友功能、共同喜欢功能等。
(二)统计ip
Set可以快速实时统计访问防战的独立ip。
(三)抽奖
微信或bilibili等抽奖活动时,可以将参与抽奖的人放到一个Set里。或者微博关注的模型。
有序集合ZSet
有序集合的编码可以是ziplist或者skiplist(跳表+字典)。zip的话用紧邻的两个节点,一个存元素,一个存分数。skiplist里面同时用到跳表和字典分别用指针存储zset,比单独用要效率高一些,同时使用指针指向的话不会占用太多空间。 常用命令zadd、zrange、zrem、zcard(统计数量)等。
应用场景
(一)排行榜
有序集合经典使用场景。比如歌单、阅读排行榜、微信步数排行榜、热搜等??