当前位置: 首页 > 科技观察

Redis五大数据类型使用场景

时间:2023-03-13 00:36:01 科技观察

Redis是一个基于键值对的NoSQL数据库,其值主要由string(字符串)、hash(散列)、list(列表)、set(集合)组成,zset(Orderedset)由五种基本数据结构组成,此外还支持一些其他的数据结构和算法。key都是由字符串组成的,那么这五种数据结构的使用场景分别是什么呢?让我们来看看!string字符串类型是Redis最基本的数据结构,string类型可以是JSON、XML甚至Binary图片等数据,但最大值不能超过512MB。1.1内部编码Redis会根据当前值的类型和长度来决定使用哪种内部编码。字符串类型的内部编码有以下三种:int:8字节长整型。embstr:小于等于39字节的字符串。raw:大于39字节的字符串。1.2使用场景1.2.1web服务中的缓存,使用MySQL作为数据库,Redis作为缓存。由于Redis具有支持高并发的特点,通常可以加快读写速度,减轻后端压力。Web端的大部分请求都是从Redis获取数据。如果Redis中没有需要的数据,则从MySQL中获取并写入redis。1.2.2计数Redis有一个字符串相关的命令incrkey。incr命令对值执行自动递增操作。返回结果分为以下三种情况:value不是整数,返回的错误值为整数,返回自增后的结果key不存在,默认key为0,它返回1,比如文章的阅读量,视频的播放量等都会被redis统计。每播放一次,相应的播放音量就会加1,这些数据会异步存储到数据库中。达到坚持的目的。1.2.3SharedSession在分布式系统中,用户的每次请求都会访问不同的服务器,这会导致会话异步的问题。如果获取用户信息的请求落在服务器A上,则将获取到的用户信息存储在session中。接下来的请求就落在了B服务器上,如果想从session中获取用户信息,是无法正常获取到的,因为用户信息的session是在A服务器上的。为了解决这个问题,使用redis来集中管理这些session并将session存储在redis中,使用时直接从redis中获取即可。1.2.4限速有些网站出于安全考虑,会对IP进行限制,限制同一IP在一定时间内的访问次数不超过n次。2哈希在Redis中,哈希类型是指键值对的存储结构。2.1内部编码hash类型的内部编码有两种:ziplist(压缩列表):当hash类型元素个数小于hash-max-ziplist-entries配置(默认512)和所有值时小于使用hash-max-ziplist值配置(默认64字节)。Ziplist使用更紧凑的结构来实现多个元素的连续存储,因此比hashtable更节省内存。hashtable(哈希表):当ziplist不能满足要求时,就会使用hashtable。2.2使用场景由于hash类型存储的是键值对,例如数据库有如下用户表结构idnameage1Java之旅18.将以上信息存储在redis中,使用display:id作为key,并user属性为值:hsetuser:1nameJavajourneyage18使用hash存储比string更方便直观。三列表列表类型用于存储多个有序字符串。一个列表最多可以存储2^32-1个元素,列表的两端都可以插入和弹出元素。3.1内部编码列表有两种内部编码:ziplist(压缩列表):当hash类型元素个数小于list-max-ziplist-entries配置(默认512)且所有值都小于比list-max-ziplist-value配置时使用(默认64字节)。Ziplist使用更紧凑的结构来实现多个元素的连续存储,因此比hashtable更节省内存。linkedlist(链表):当ziplist不能满足要求时,会使用linkedlist。3.2应用场景3.2.1消息队列链表用于存储多个有序字符串。既然是有序的,就满足了消息队列的特点。使用lpush+rpop或者rpush+lpop实现消息队列。另外redis支持阻塞操作,在弹出元素时使用阻塞命令实现阻塞队列。3.2.2栈由于列表存储的是有序的字符串,满足了队列的特性,所以也可以满足栈先进后出的特性。使用lpush+lpop或者rpush+rpop来实现栈。3.2.3文章列表因为列表的元素不仅是有序的,而且支持按照索引范围获取元素。因此,我们可以使用命令lrangekey09来获取文章列表4.Setset类型也可以存储多个字符串元素。与列表不同,集合中不允许出现重复元素,集合中的元素是无序的。一个集合最多可以存储2^32-1个元素。4.1内部编码集合类型有两种内部编码:intset(整数集合):当集合中的元素全部为整数且元素个数小于set-max-intset-entries配置时(512bydefault),redis会使用intset作为集合的内部实现,从而减少内存占用。hashtable(哈希表):当intset不能满足要求时,会使用hashtable。4.2使用场景4.2.1用户标签例如,一个用户对篮球和足球感兴趣,另一个用户对橄榄球和乒乓球感兴趣。这些兴趣点是一个标签。有了这些数据,就可以得到喜欢同一个标签的人,以及用户共同感兴趣的标签。标记用户时,需要①标记用户,②将用户添加到标签中。您需要为这两个操作添加事务。标记一个用户sadduser:1:tagstag1tag2添加一个用户到一个标签saddtag1:usersuser:1saddtag2:usersuser:1使用交集(sinter)找到两个用户的公共标签sinteruser:1:tagsuser:2:tags4.2.2有两个抽奖函数set以下命令支持获取随机数,即:随机获取count个元素,set中元素个数不变srandmemberkey[count]随机弹出count个元素,从set中弹出元素,set个数元素变化spopkey[count]用户点击抽奖按钮,参数lottery,将用户号放入集合,然后抽奖,分别抽取一等奖和二等奖,如果已经中奖的用户不能参数化二等奖,使用spop,否则使用srandmember。五个有序集合有序集合和集合一样,不能有重复的元素。但是它是可以排序的,它为每个元素设置一个分数作为排序的依据。最多可以存储2^32-1个元素。5.1内部编码有序集合类型的内部编码有两种:值小于list-max-ziplist-value配置(默认64字节)被使用。Ziplist使用更紧凑的结构来实现多个元素的连续存储,节省更多的内存。Skiplist(跳过列表):当不满足ziplist的要求时,就会使用skiplist。5.2使用场景5.2.1Leaderboard用户发布n篇文章,其他人阅读文章后点赞自己喜欢的文章。分数用于记录点赞数,排序后的收藏会根据分数进行排名。流程如下:某用户发布一篇文章,初始点赞数为0,即评分为0zadduser:article0a有人点赞文章a,增量为1zincrbyuser:article1a查询前三篇文章zrevrangebyscoreuser:article02查询最后三篇zrangebyscoreuser:article025.2.2延迟消息队列点餐系统,下单后,需要在15分钟内付款,15分钟内未付款,订单将自动取消。下单后十五分钟作为评分,将订单作为值存入redis,由消费者轮询消费。如果消费大于或等于该条记录的得分,则将该条记录从队列中移除,并取消该订单。综上所述,在开发中,string类型是使用最多的数据类型,导致我们忽略了redis的其他四种数据类型。在特定的场景下选择特定的数据类型,对于提升redis的性能非常有帮助。redis虽然支持消息队列的实现,但是不支持ack。所以redis实现的消息队列不能保证消息的可靠性,除非自己实现消息确认机制,但是这样很麻烦,所以如果是重要的消息,建议使用专门的消息队列来做吧。本文转载自微信公众号“Java之旅”,可通过以下二维码关注。转载本文请联系Java之旅公众号。