当前位置: 首页 > news >正文

redis的基础数据结构-list列表

文章目录

    • 1. redis的list数据结构
      • 1.1. list结构的特性
      • 1.2. 常用命令
    • 2. 常见业务场景
      • 2.1 消息队列
        • 案例讲解
          • 背景
          • 优势
          • 解决方案
          • 代码实现
      • 2.2 排行榜
        • 案例讲解
          • 背景
          • 优势
          • 解决方案
          • 代码实现
    • 3. 注意事项:

1. redis的list数据结构

参考链接:https://mp.weixin.qq.com/s/srkd73bS2n3mjIADLVg72A
Redis 中的 List 数据结构是一个简单的字符串列表,可以在两端快速推入和弹出元素。List 的实现是双向链表,这使得它在插入和删除操作上非常高效。List 的元素可以是字符串类型,且可以重复。

1.1. list结构的特性

  • 有序:List 中的元素有顺序,元素按照插入的顺序进行排列。
  • 支持重复:同一个元素可以出现多次。
  • 双向操作:可以在两端进行插入和删除操作。

1.2. 常用命令

以下是一些常用的 Redis List 命令:

  1. LPUSH key value:在列表的左侧(头部)推入元素。
  2. RPUSH key value:在列表的右侧(尾部)推入元素。
  3. LPOP key:从列表的左侧弹出元素。
  4. RPOP key:从列表的右侧弹出元素。
  5. LRANGE key start stop:获取列表中指定范围的元素。
  6. LLEN key:获取列表的长度。
  7. LREM key count value:移除列表中指定数量的某个元素。
  8. LINSERT key BEFORE|AFTER pivot value:在列表中指定元素之前或之后插入一个新元素。
  9. LSET key index value:通过索引设置列表中的元素。
  10. LTRIM key start stop:修剪列表,只保留指定范围内的元素。
XXXXXX:6379> LPUSH user:1001:orders "order_1" #用户1001创建新订单order_1
(integer) 1
XXXXXX:6379> LPUSH user:1001:orders "order_2" #用户1001创建新订单order_2
(integer) 2
XXXXXX:6379> LPUSH user:1001:orders "order_3" #用户1001创建新订单order_3
(integer) 3
XXXXXX:6379> LRANGE user:1001:orders 0 -1 #用户1001查询所有订单
1) "order_3"
2) "order_2"
3) "order_1"
XXXXXX:6379> LLEN user:1001:orders #用户1001查询所有订单的数量
(integer) 3
XXXXXX:6379> LPOP user:1001:orders #用户1001取消最新的订单
"order_3"
XXXXXX:6379> LRANGE user:1001:orders 0 -1 #用户1001查询所有订单
1) "order_2"
2) "order_1"
XXXXXX:6379> LSET user:1001:orders 1 "order_1_completed" #订单order_1完成
OK
XXXXXX:6379> LRANGE user:1001:orders 0 -1 #用户1001查询所有订单
1) "order_2"
2) "order_1_completed"
XXXXXX:6379> LTRIM user:1001:orders 0 9 #用户修剪订单列表,只保留最近的 10 个订单
OK
XXXXXX:6379> LRANGE user:1001:orders 0 -1 #用户1001查询所有订单
1) "order_2"
2) "order_1_completed"
XXXXXX:6379> LREM user:1001:orders 1 "order_2" #用户移除订单order_2
(integer) 1
XXXXXX:6379> LRANGE user:1001:orders 0 -1 ##用户1001查询所有订单
1) "order_1_completed"
XXXXXX:6379> LINSERT user:1001:orders BEFORE "order_1_completed" "order_4" #用户在order_1前插入order_4
(integer) 2
XXXXXX:6379> LRANGE user:1001:orders 0 -1 ##用户1001查询所有订单
1) "order_4"
2) "order_1_completed"

2. 常见业务场景

2.1 消息队列

消息队列:List类型常用于实现消息队列,用于异步处理任务,如邮件发送队列、任务调度等。

案例讲解
背景

在一个电商平台中,用户下单后,系统需要执行多个异步任务,如订单处理、库存更新、发送确认邮件等
在这里插入图片描述

优势
  1. 异步处理:使用List作为消息队列,可以将任务异步化,提高用户体验和系统响应速度。
  2. 任务管理:方便地对任务进行管理和监控,如重试失败的任务、监控任务处理进度等。
  3. 系统解耦:各个任务处理模块可以独立运行,降低系统间的耦合度。
解决方案

使用Redis List类型存储和管理任务消息队列。

代码实现
package mainimport ("context""encoding/json""fmt""github.com/go-redis/redis/v8""log""time"
)var ctx = context.Background()// Redis 客户端初始化
var redisClient = redis.NewClient(&redis.Options{Addr:     "localhost:6379",Password: "", // no password setDB:       0,  // use default DB
})type Order struct {ID     stringAmount float64
}func (o Order) ToString() string {orderJSON, _ := json.Marshal(o)return string(orderJSON)
}func addOrderToQueue(order Order) {// 将新订单添加到订单处理队列redisClient.LPush(ctx, "order_queue", order.ToString())
}func getNextOrder() (Order, error) {// 从订单处理队列中获取待处理的订单orderJSON, err := redisClient.RPop(ctx, "order_queue").Result()if err != nil {return Order{}, err}var order Ordererr = json.Unmarshal([]byte(orderJSON), &order)if err != nil {return Order{}, err}return order, nil
}func addInventoryUpdateToQueue(order Order) {// 将库存更新任务添加到库存更新队列redisClient.LPush(ctx, "inventory_update_queue", order.ToString())
}func getNextInventoryUpdate() (Order, error) {// 从库存更新队列中获取待处理的更新updateJSON, err := redisClient.RPop(ctx, "inventory_update_queue").Result()if err != nil {return Order{}, err}var order Ordererr = json.Unmarshal([]byte(updateJSON), &order)if err != nil {return Order{}, err}return order, nil
}func addEmailToQueue(order Order) {// 将邮件发送任务添加到邮件发送队列redisClient.LPush(ctx, "email_queue", order.ToString())
}func getNextEmail() (Order, error) {// 从邮件发送队列中获取待发送邮件的订单emailJSON, err := redisClient.RPop(ctx, "email_queue").Result()if err != nil {return Order{}, err}var order Ordererr = json.Unmarshal([]byte(emailJSON), &order)if err != nil {return Order{}, err}return order, nil
}func processOrder(order Order) {// 处理订单逻辑fmt.Printf("Processing order: %s\n", order.ID)// 添加库存更新任务addInventoryUpdateToQueue(order)// 添加邮件发送任务addEmailToQueue(order)// 模拟处理时间time.Sleep(1 * time.Second)
}func updateInventory(order Order) {// 更新库存逻辑fmt.Printf("Updating inventory for order: %s\n", order.ID)// 模拟更新库存的操作time.Sleep(1 * time.Second)
}func sendEmail(order Order) {// 发送确认邮件逻辑fmt.Printf("Sending confirmation email for order: %s\n", order.ID)// 模拟发送邮件的操作time.Sleep(1 * time.Second)
}

2.2 排行榜

排行榜:使用List类型,可以存储和管理如游戏得分、文章点赞数等排行榜数据。

案例讲解
背景

在一个社交平台中,用户发表的文章根据点赞数进行排名,需要实时更新和展示排行榜。
在这里插入图片描述

优势
  1. 实时性:能够快速响应用户的点赞行为,实时更新排行榜。
  2. 排序功能:利用LRANGE命令,可以方便地获取指定范围内的排行榜数据。
解决方案

使用Redis List类型存储用户的得分或点赞数,并根据需要对List进行排序。

代码实现
package mainimport ("context""fmt""github.com/go-redis/redis/v8""log"
)var ctx = context.Background()// Redis 客户端初始化
var redisClient = redis.NewClient(&redis.Options{Addr:     "localhost:6379",Password: "", // no password setDB:       0,  // use default DB
})type Article struct {ID    stringScore int64
}// 为文章点赞,更新排行榜
func likeArticle(articleID string) {// 假设每个文章都有一个对应的得分,使用 Sorted Set 来维护redisClient.ZIncrBy(ctx, "article_rankings", 1, articleID)
}// 获取文章排行榜
func getArticleRankings() ([]Article, error) {// 使用 ZREVRANGE 获取得分最高的文章result, err := redisClient.ZRevRangeWithScores(ctx, "article_rankings", 0, -1).Result()if err != nil {return nil, err}articles := []Article{}for _, z := range result {articles = append(articles, Article{ID:    z.Member.(string),Score: int64(z.Score),})}return articles, nil
}

3. 注意事项:

List类型在列表元素数量较大时,操作可能会变慢,需要考虑性能优化。

  • 在使用List实现队列时,要注意处理消息的顺序和丢失问题。
  • 可以使用BRPOP或BLPOP命令在多个列表上进行阻塞式读取,适用于多消费者场景。

http://www.mrgr.cn/news/23944.html

相关文章:

  • 0. 阿里大模型API获取步骤
  • LVGL 控件之线条(lv_line)
  • TwinCAT3 实时核中ADS实现C++ server、clinet数据传输
  • 【MADRL】反事实多智能体策略梯度法(COMA)算法
  • StarRocks 培训课程重磅上线!专家出品,助你升级打怪不走弯路!
  • 枚举,LeetCode 2552. 统计上升四元组
  • day-52 下一个排列
  • 向量——通俗地解释
  • 【Qt】Qt音频
  • ECOLOGY携带BearerToken后根据手机号码获取北森系统人员id
  • 数学建模笔记—— 多目标规划
  • 覆盖索引是什么意思?
  • 9.10总结
  • day10-配置文件日志多线程
  • 迟滞比较器/施密特触发器
  • Switch分支结构的细节
  • Python3中函数的用法
  • man命令学习记录
  • 大屏可视化:完美自适应的解决方案
  • 实战案例(2)防火墙+二交换机VLAN组网