作者|周明尧来源|Java旅途(IDJavatrip)头图|CSDN下载自东方ICRedis是一种基于键值对的NoSQL数据库它的值主要由strin 作者 | 周明尧来源 | Java旅途(IDJavatrip)头图 | CSDN 下载自东方ICRedis 是一种
字符串
字符串类型是Redis最基础的数据结构字符串类型可以是JSON、XML甚至是二进制的图片等数据但是最大值不能超过512MB。1.1 内部编码
Redis会根据当前值的类型和长度决定使用哪种内部编码来实现。字符串类型的内部编码有3种- int8个字节的长整型。
- embstr小于等于39个字节的字符串。
- raw大于39个字节的字符串。
1.2 使用场景
1.2.1 缓存
在web服务中使用MySQL作为数据库Redis作为缓存。由于Redis具有支撑高并发的特性通常能起到加速读写和降低后端压力的作用。web端的大多数请求都是从Redis中获取的数据如果Redis中没有需要的数据则会从MySQL中去获取并将获取到的数据写入redis。1.2.2 计数
Redis中有一个字符串相关的命令incr keyincr命令对值做自增操作返回结果分为以下三种情况- 值不是整数返回错误
- 值是整数返回自增后的结果
- key不存在默认键为0返回1
1.2.3 共享Session
在分布式系统中用户的每次请求会访问到不同的服务器这就会导致session不同步的问题假如一个用来获取用户信息的请求落在A服务器上获取到用户信息后存入session。下一个请求落在B服务器上想要从session中获取用户信息就不能正常获取了因为用户信息的session在服务器A上为了解决这个问题使用redis集中管理这些session将session存入redis使用的时候直接从redis中获取就可以了。1.2.4 限速
为了安全考虑有些网站会对IP进行限制限制同一IP在一定时间内访问次数不能超过n次。哈希Redis中哈希类型是指一个键值对的存储结构。2.1 内部编码
哈希类型的内部编码有两种- ziplist(压缩列表)当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个)同时所有值都小于hash-max-ziplist-value配置(默认64字节)时使用。ziplist使用更加紧凑的结构实现多个元素的连续存储所以比hashtable更加节省内存。
- hashtable(哈希表)当ziplist不能满足要求时会使用hashtable。
2.2 使用场景
由于hash类型存储的是一个键值对比如数据库有以下一个用户表结构idnameage1Java旅途18将以上信息存入redis用表明:id作为key用户属性作为值hset user:1 name Java旅途 age 18使用哈希存储会比字符串更加方便直观
列表
列表类型用来存储多个有序的字符串一个列表最多可以存储2^32-1个元素列表的两端都可以插入和弹出元素。3.1 内部编码
列表的内部编码有两种- ziplist(压缩列表)当哈希类型元素个数小于list-max-ziplist-entries配置(默认512个)同时所有值都小于list-max-ziplist-value配置(默认64字节)时使用。ziplist使用更加紧凑的结构实现多个元素的连续存储所以比hashtable更加节省内存。
- linkedlist(链表)当ziplist不能满足要求时会使用linkedlist。
3.2 使用场景
3.2.1 消息队列
列表用来存储多个有序的字符串既然是有序的那么就满足消息队列的特点。使用lpushrpop或者rpushlpop实现消息队列。除此之外redis支持阻塞操作在弹出元素的时候使用阻塞命令来实现阻塞队列。3.2.2 栈
由于列表存储的是有序字符串满足队列的特点也就能满足栈先进后出的特点使用lpushlpop或者rpushrpop实现栈。3.2.3 文章列表
因为列表的元素不但是有序的而且还支持按照索引范围获取元素。因此我们可以使用命令lrange key 0 9分页获取文章列表集合
集合类型也可以保存多个字符串元素与列表不同的是集合中不允许有重复元素并且集合中的元素是无序的。一个集合最多可以存储2^32-1个元素。4.1 内部编码
集合类型的内部编码有两种- intset(整数集合)当集合中的元素都是整数且元素个数小于set-max-intset-entries配置(默认512个)时redis会选用intset来作为集合的内部实现从而减少内存的使用。
- hashtable(哈希表)当intset不能满足要求时会使用hashtable。
4.2 使用场景
4.2.1 用户标签
例如一个用户对篮球、足球感兴趣另一个用户对橄榄球、乒乓球感兴趣这些兴趣点就是一个标签。有了这些数据就可以得到喜欢同一个标签的人以及用户的共同感兴趣的标签。给用户打标签的时候需要①给用户打标签②给标签加用户需要给这两个操作增加事务。- 给用户打标签
sadd user:1:tags tag1 tag2
- 给标签添加用户
sadd tag1:users user:1sadd tag2:users user:1使用交集(sinter)求两个user的共同标签
sinter user:1:tags user:2:tags
4.2.2 抽奖功能
集合有两个命令支持获取随机数分别是- 随机获取count个元素集合元素个数不变
srandmember key [count]
- 随机弹出count个元素元素从集合弹出集合元素个数改变
spop key [count]用户点击抽奖按钮参数抽奖将用户编号放入集合然后抽奖分别抽一等奖、二等奖如果已经抽中一等奖的用户不能参数抽二等奖则使用spop反之使用srandmember。
有序集合
有序集合和集合一样不能有重复元素。但是可以排序它给每个元素设置一个score作为排序的依据。最多可以存储2^32-1个元素。5.1 内部编码
有序集合类型的内部编码有两种- ziplist(压缩列表)当有序集合的元素个数小于list-max-ziplist-entries配置(默认128个)同时所有值都小于list-max-ziplist-value配置(默认64字节)时使用。ziplist使用更加紧凑的结构实现多个元素的连续存储更加节省内存。
- skiplist(跳跃表)当不满足ziplist的要求时会使用skiplist。
5.2 使用场景
5.2.1 排行榜
用户发布了n篇文章其他人看到文章后给喜欢的文章点赞使用score来记录点赞数有序集合会根据score排行。流程如下用户发布一篇文章初始点赞数为0即score为0zadd user:article 0 a有人给文章a点赞递增1
zincrby user:article 1 a查询点赞前三篇文章
zrevrangebyscore user:article 0 2查询点赞后三篇文章
zrangebyscore user:article 0 2
5.2.2 延迟消息队列
下单系统下单后需要在15分钟内进行支付如果15分钟未支付则自动取消订单。将下单后的十五分钟后时间作为score订单作为value存入redis消费者轮询去消费如果消费的大于等于这笔记录的score则将这笔记录移除队列取消订单。总结
在开发中字符串类型是用的最多的数据类型导致我们忽视了redis的其他四种数据类型在具体场景下选择具体的数据类型对提升redis性能有非常大的帮助。redis虽然支持消息队列的实现但是并不支持ack。所以redis实现的消息队列不能保证消息的可靠性除非自己实现消息确认机制不过这非常麻烦所以如果是重要的消息还是推荐使用专门的消息队列去做。更多精彩推荐
☞深度揭秘腾讯存储技术发展史
☞可以“作为医生”的 GPT-3究竟是炒作还是名副其实
☞Java变量声明在循环体内还是循环体外你用哪一个
☞蚂蚁上市员工人均一套大 House阿里程序员身价和这匹配吗
☞Robust.ai 获得 1500 万美元融资嘴炮 Gary Marcus 也难逃真香定律
☞图灵奖得主 John E. Hopcroft 等 300 余位 AI 学者“穿越”回宋代开国际 AI 大会这场面你见过吗
点分享点点赞点在看