银川网站建设联系电话,个人网页设计尺寸是多少,趣头条自媒体平台,扁平化的网站结构图List 列表
列表类型是用来存储多个有序的字符串#xff0c;
如图#xff1a; a、b、c、d、e 五个元素从左到右组成 了⼀个有序的列表#xff0c;列表中的每个字符串称为元素#xff08;element#xff09;#xff0c;⼀个列表最多可以存储个元素。在 Redis 中#xff…List 列表
列表类型是用来存储多个有序的字符串
如图 a、b、c、d、e 五个元素从左到右组成 了⼀个有序的列表列表中的每个字符串称为元素element⼀个列表最多可以存储个元素。在 Redis 中可以对列表两端插⼊push和弹出pop还可以获取指定范围的元素列表、 获取指定索引下标的元素等 列表是⼀种⽐较灵活的数据结构它可以充当栈和队列的⻆⾊在实际开发上有很多应⽤场景 Redis列表Lists类型的特点如下 有序性Redis列表是按照插入顺序来保存元素的。 可重复性Redis列表中的元素可以重复。 长度可变性Redis列表可以动态增长和缩小可以随时添加或删除元素。 支持左右两端插入和删除操作Redis列表提供了从左端或右端插入和删除元素的操作可以方便地实现队列和栈。 支持范围操作Redis列表提供了类似于数组的下标范围操作可以获取指定范围内的元素。 适合存储有序数据Redis列表适合存储有序数据如消息队列、最新消息列表、日志记录等。
总之Redis列表是一种非常灵活的数据结构可以用于各种不同的场景具有很高的实用价值。
Redis基本命令
LPUSH key value1 [value2 ...] - 在列表左边插入一个或多个元素RPUSH key value1 [value2 ...] - 在列表右边插入一个或多个元素LPOP key - 移除并返回列表最左边的元素RPOP key - 移除并返回列表最右边的元素LINDEX key index - 返回列表中指定索引位置的元素LLEN key - 返回列表的长度LRANGE key start stop - 返回列表中指定范围内的元素LREM key count value - 移除列表中指定数量的元素LTRIM key start stop - 保留列表中指定范围内的元素其它元素均被删除BLPOP key [key ...] timeout - 阻塞并等待列表最左边的元素并在超时时间内返回结果BRPOP key [key ...] timeout - 阻塞并等待列表最右边的元素并在超时时间内返回结果 从这里我们可以发现每个基本类型中基本命令开头必带有类型的首字母但是在 List 中发现首字母不仅只有 L 还有 R 原因在于 list 是一个双向链表既可以头插头删也可以尾插尾删 L 代表 Left R 代表 Right 不只是 L 和 R 这里居然还有 B 开头的。 这是我自己记的笔记百度网盘 可以查看命令比较具体的细节
BLPOP
B 代表 Block 阻塞L 表示 Left 这个命令就意味着阻塞并等待列表最左边的元素并在超时时间内返回结果
返回值为取出的元素或者 nil。
内部编码
列表类型的内部编码有两种 ziplist压缩列表当列表的元素个数⼩于 list-max-ziplist-entries 配置默认 512 个同时列表中每个元素的⻓度都⼩于 list-max-ziplist-value 配置默认 64 字节时Redis 会选⽤ziplist 来作为列表的内部编码实现来减少内存消耗 linkedlist链表当列表类型⽆法满⾜ ziplist 的条件时Redis 会使⽤ linkedlist 作为列表的内部实现。
当元素个数较少并没有大元素时内部编码为 ziplist
1 127.0.0.1:6379 rpush listkey e1 e2 e3
2 OK
3 127.0.0.1:6379 object encoding listkey
4 ziplist当元素个数超过 512 时内部编码为 linkedlist 1 127.0.0.1:6379 rpush listkey e1 e2 e3 ... 省略 e512 e513
2 OK
3 127.0.0.1:6379 object encoding listkey
4 linkedlist当某个元素的⻓度超过 64 字节时内部编码为 linkedlist 1 127.0.0.1:6379 rpush listkey one string is bigger than 64 bytes ... 省略 ...
2 OK
3 127.0.0.1:6379 object encoding listkey
4 linkedlist
这个所谓超出某个数字并非唯一的同样可以在 .conf 配置文件中修改的。
使用场景
消息队列
Redis 可以使用 lpush brpop 组合命令实现生产者-消费者模型队列生产者客户端使用 lpush 从列表左侧插入元素多个消费者客户端使用 brpop 命令阻塞式地从队列中 “争抢” 队首元素。通过多个客户端来保证消费的负载均衡和高可用。 微博 Timeline 每个⽤⼾都有属于⾃⼰的 Timeline微博列表现需要分⻚展⽰⽂章列表。此时可以考虑使⽤ 列表因为列表不但是有序的同时⽀持按照索引范围获取元素。 1每篇微博使⽤哈希结构存储例如微博中 3 个属性title、timestamp、content hmset mblog: 1 title xx timestamp 1476536196 content xxxxx ... hmset mblog:n title xx timestamp 1476536196 content xxxxx 2向⽤⼾ Timeline 添加微博user:uid:mblogs 作为微博的键 lpush user: 1 :mblogs mblog: 1 mblog: 3 ... lpush user:k:mblogs mblog: 9 3分⻚获取⽤⼾的 Timeline例如获取⽤⼾ 1 的前 10 篇微博 keylist lrange user: 1 :mblogs 0 9 for key in keylist { hgetall key } 此⽅案在实际中可能存在两个问题 1 n 问题。即如果每次分⻚获取的微博个数较多需要执⾏多次 hgetall 操作此时可以考虑使⽤pipeline流⽔线模式批量提交命令或者微博不采⽤哈希类型⽽是使⽤序列化的字符串类型使⽤ mget 获取。 分裂获取⽂章时lrange 在列表两端表现较好获取列表中间的元素表现较差此时可以考虑将列表做拆分。
注意 同侧存取lpush lpop 或者 rpush rpop为栈 异侧存取lpush rpop 或者 rpush lpop为队列 Set 类型 集合类型也是保存多个字符串类型的元素的但和列表类型不同的是 1. 集合中元素之间是⽆序的 2. 集合中元素不允许重复 如图 ⼀个集合中最多可以存储 2^32 - 1 个元素。Redis 除了⽀持 集合内的增删查改操作同时还⽀持多个集合取交集、并集、差集合理地使⽤好集合类型能在实 际开发中解决很多问题。 基本命令
SADD key member1 [member2]向集合中添加一个或多个元素SCARD key获取集合中元素数量SDIFF key1 [key2]返回第一个集合与其它集合的差集SDIFFSTORE destination key1 [key2]将第一个集合与其它集合的差集存储到一个新的集合中SINTER key1 [key2]返回第一个集合与其它集合的交集SINTERSTORE destination key1 [key2]将第一个集合与其它集合的交集存储到一个新的集合中SISMEMBER key member判断元素是否在集合中SMEMBERS key获取集合中所有元素SMOVE source destination member将一个元素从一个集合中移动到另一个集合中SPOP key [count]随机移除并返回集合中一个或多个元素SRANDMEMBER key [count]随机获取集合中一个或多个元素SREM key member1 [member2]从集合中移除一个或多个元素SUNION key1 [key2]返回多个集合的并集SUNIONSTORE destination key1 [key2]将多个集合的并集存储到一个新的集合中 这是我自己记的笔记百度网盘 可以查看命令比较具体的细节
内部编码
集合类型的内部编码同样也分两种 intset整数集合当集合中的元素都是整数并且元素的个数⼩于 set-max-intset-entries 配置 默认 512 个时Redis 会选⽤ intset 来作为集合的内部实现从⽽减少内存的使⽤。 hashtable哈希表当集合类型⽆法满⾜ intset 的条件时Redis 会使⽤ hashtable 作为集合的内部实现。 1当元素个数较少并且都为整数时内部编码为 intset 127.0.0.1:6379 sadd setkey 1 2 3 4
(integer) 4
127.0.0.1:6379 object encoding setkey
intset 2当元素个数超过 512 个内部编码为 hashtable 127.0.0.1:6379 sadd setkey 1 2 3 4
(integer) 513
127.0.0.1:6379 object encoding setkey
hashtable3当存在元素不是整数时内部编码为 hashtable 127.0.0.1:6379 sadd setkey a
(integer) 1
127.0.0.1:6379 object encoding setkey
hashtable
同样的这里所谓超出某个数字并非唯一的同样可以在 .conf 配置文件中修改的。
使用场景 集合类型⽐较典型的使⽤场景是标签tag。例如 A ⽤⼾对娱乐、体育板块⽐较感兴趣B ⽤⼾ 对历史、新闻⽐较感兴趣这些兴趣点可以被抽象为标签。有了这些数据就可以得到喜欢同⼀个标签的⼈以及⽤⼾的共同喜好的标签这些数据对于增强⽤⼾体验和⽤⼾黏度都⾮常有帮助。 例如⼀个电⼦商务⽹站会对不同标签的⽤⼾做不同的产品推荐。 ZSet 类型 有序集合相对于字符串、列表、哈希、集合来说会有⼀些陌⽣。它保留了集合不能有重复成员的 特点但与集合不同的是有序集合中的每个元素都有⼀个唯⼀的浮点类型的分数score与之关 联着使得有序集合中的元素是可以维护有序性的但这个有序不是⽤下标作为排序依据⽽是⽤这个分数。 基本命令
Redis中ZSet类型是有序集合每个元素都有一个对应的分数score。以下是ZSet类型的基本命令
ZADD key score member向有序集合添加一个或多个成员或者更新已存在成员的分数ZCARD key获取有序集合的元素数量ZCOUNT key min max获取有序集合中分数范围内的成员数量ZINCRBY key increment member对有序集合中指定成员的分数增加incrementZRANK key member获取有序集合中指定成员的排名从小到大ZREVRANK key member获取有序集合中指定成员的排名从大到小ZSCORE key member获取有序集合中指定成员的分数ZRANGE key start stop [WITHSCORES]获取有序集合中指定排名范围内的成员从小到大如果WITHSCORES选项被指定则同时返回成员的分数ZREVRANGE key start stop [WITHSCORES]获取有序集合中指定排名范围内的成员从大到小ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]获取有序集合中指定分数范围内的成员如果WITHSCORES选项被指定则同时返回成员的分数如果LIMIT选项被指定则返回指定数量的成员从小到大ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]获取有序集合中指定分数范围内的成员如果WITHSCORES选项被指定则同时返回成员的分数如果LIMIT选项被指定则返回指定数量的成员从大到小ZREM key member从有序集合中移除一个或多个成员ZREMRENGEByRANK key start stop移除有序集合中指定排名范围内的成员从小到大ZREMRENGEBySCORE key min max移除有序集合中指定分数范围内的成员ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]计算给定numkeys个有序集合的并集并将结果保存到destination如果WEIGHTS选项被指定则计算时使用指定权重如果AGGREGATE选项被指定则使用指定聚合方式 这是我自己记的笔记百度网盘 可以查看命令比较具体的细节
内部编码
有序集合类型的内部编码有两种 ziplist压缩列表当有序集合的元素个数⼩于 zset-max-ziplist-entries 配置默认 128 个同时每个元素的值都⼩于 zset-max-ziplist-value 配置默认 64 字节时Redis 会⽤ ziplist 来作为有序集合的内部实现ziplist 可以有效减少内存的使⽤。 skiplist跳表当 ziplist 条件不满⾜时有序集合会使⽤ skiplist 作为内部实现因为此时 ziplist 的操作效率会下降。 1当元素个数较少且每个元素较⼩时内部编码为 ziplist 127.0.0.1:6379 zadd zsetkey 50 e1 60 e2 30 e3
(integer) 3
127.0.0.1:6379 object encoding zsetkey
ziplist2当元素个数超过 128 个内部编码 skiplist 127.0.0.1:6379 zadd zsetkey 50 e1 60 e2 30 e3 ... 省略 ... 82 e129
(integer) 129
127.0.0.1:6379 object encoding zsetkey
skiplist3当某个元素⼤于 64 字节时内部编码 skiplist 127.0.0.1:6379 zadd zsetkey 50 one string bigger than 64 bytes ... 省略 ...
(integer) 1
127.0.0.1:6379 object encoding zsetkey
skiplist 使用场景 有序集合⽐较典型的使⽤场景就是排⾏榜系统。例如常⻅的⽹站上的热榜信息榜单的维度可能 是多⽅⾯的按照时间、按照阅读量、按照点赞量。本例中我们使⽤点赞数这个维度维护每天的热榜 1添加⽤⼾赞数 例如⽤⼾ james 发布了⼀篇⽂章并获得 3 个赞可以使⽤有序集合的 zadd 和 zincrby 功能 zadd user:ranking: 2022 - 03 - 15 3 james 之后如果再获得赞可以使⽤ zincrby zincrby user:ranking: 2022 - 03 - 15 1 james 2取消⽤⼾赞数 由于各种原因例如⽤⼾注销、⽤⼾作弊等需要将⽤⼾删除此时需要将⽤⼾从榜单中删除掉可以使⽤ zrem。例如删除成员 tom zrem user:ranking: 2022 - 03 - 15 tom 3展⽰获取赞数最多的 10 个⽤⼾ 此功能使⽤ zrevrange 命令实现 zrevrangebyrank user:ranking: 2022 - 03 - 15 0 9 渐进式遍历 Redis 使⽤ scan 命令进⾏渐进式遍历键进⽽解决直接使⽤ keys 获取键时可能出现的阻塞问 题。每次 scan 命令的时间复杂度是 O(1)但是要完整地完成所有键的遍历需要执⾏多次 scan。 我来演示一下就明白我再说啥了。 我们现在一共存在了 11 个 key那么现在我要使用 scan 渐进式遍历。 除了 scan 以外Redis ⾯向哈希类型、集合类型、有序集合类型分别提供了 hscan、sscan、zscan 命 令它们的⽤法和 scan 基本类似感兴趣的读者可以⾃⾏做扩展学习。 渐进性遍历 scan 虽然解决了阻塞的问题但如果在遍历期间键有所变化增加、修改、删 除可能导致遍历时键的重复遍历或者遗漏这点务必在实际开发中考虑。 本章节到此就结束了具体的命令还是建议去看官网当然也可以和 scan 一样有更优的解不听从我的建议。