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

Redis数据结构与性能优化详解

Redis数据结构与性能优化详解

1. Redis数据类型

1.1 字符串(String)

最基本的数据类型:

// 设置值 rdb.Set(ctx, "name", "John", 0) rdb.SetNX(ctx, "name", "John", 0) // 不存在时设置 rdb.SetEx(ctx, "name", "John", 3600) // 设置过期时间 // 获取值 val, err := rdb.Get(ctx, "name").Result() // 批量操作 rdb.MSet(ctx, "key1", "value1", "key2", "value2") rdb.MGet(ctx, "key1", "key2")

1.2 哈希(Hash)

适合存储对象:

// 设置哈希 rdb.HSet(ctx, "user:1", map[string]interface{}{ "name": "John", "age": 30, "email": "john@example.com", }) // 获取字段 name, _ := rdb.HGet(ctx, "user:1", "name").Result() // 获取所有字段 user, _ := rdb.HGetAll(ctx, "user:1").Result() // 字段自增 rdb.HIncrBy(ctx, "user:1", "age", 1)

1.3 列表(List)

有序集合,支持栈和队列操作:

// 左插入 rdb.LPush(ctx, "tasks", "task1") rdb.LPush(ctx, "tasks", "task2") // 右插入 rdb.RPush(ctx, "tasks", "task3") // 获取范围 tasks, _ := rdb.LRange(ctx, "tasks", 0, -1).Result() // 弹出 task, _ := rdb.LPop(ctx, "tasks").Result()

1.4 集合(Set)

无序不重复:

// 添加 rdb.SAdd(ctx, "tags", "go", "redis", "database") // 获取所有 tags, _ := rdb.SMembers(ctx, "tags").Result() // 判断是否存在 isMember, _ := rdb.SIsMember(ctx, "tags", "go").Result() // 交集 common, _ := rdb.SInter(ctx, "tags1", "tags2").Result()

1.5 有序集合(ZSet)

按分数排序:

// 添加 rdb.ZAdd(ctx, "leaderboard", redis.Z{ Score: 100, Member: "player1", }) rdb.ZAdd(ctx, "leaderboard", redis.Z{ Score: 90, Member: "player2", }) // 获取排名 rank, _ := rdb.ZRevRank(ctx, "leaderboard", "player1").Result() // 获取分数 score, _ := rdb.ZScore(ctx, "leaderboard", "player1").Result() // 获取topN topPlayers, _ := rdb.ZRevRangeWithScores(ctx, "leaderboard", 0, 9).Result()

2. Go语言Redis客户端

2.1 go-redis客户端

import "github.com/redis/go-redis/v9" rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", DB: 0, PoolSize: 10, }) defer rdb.Close()

2.2 连接池配置

rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", DB: 0, PoolSize: 100, // 连接池大小 MinIdleConns: 10, // 最小空闲连接 MaxRetries: 3, // 最大重试次数 DialTimeout: 5 * time.Second, ReadTimeout: 3 * time.Second, WriteTimeout: 3 * time.Second, })

3. 性能优化

3.1 管道操作

批量执行命令减少网络开销:

pipe := rdb.Pipeline() pipe.Set(ctx, "key1", "value1", 0) pipe.Set(ctx, "key2", "value2", 0) pipe.Get(ctx, "key1") pipe.Incr(ctx, "counter") cmds, err := pipe.Exec(ctx) for _, cmd := range cmds { // 处理结果 }

3.2 事务

pipe := rdb.TxPipeline() pipe.Set(ctx, "key1", "value1", 0) pipe.Set(ctx, "key2", "value2", 0) _, err := pipe.Exec(ctx)

3.3 Lua脚本

原子执行:

script := redis.NewScript(` local current = redis.call('GET', KEYS[1]) if current == ARGV[1] then redis.call('SET', KEYS[1], ARGV[2]) return 1 else return 0 end `) result, err := script.Run(ctx, rdb, []string{"key"}, "expected", "new_value").Result()

4. 缓存策略

4.1 Cache-Aside模式

func GetUser(ctx context.Context, rdb *redis.Client, db *sql.DB, userID int) (*User, error) { // 1. 先查Redis cacheKey := fmt.Sprintf("user:%d", userID) cached, err := rdb.Get(ctx, cacheKey).Result() if err == nil { var user User json.Unmarshal([]byte(cached), &user) return &user, nil } // 2. 缓存不存在,查数据库 var user User err = db.QueryRowContext(ctx, "SELECT * FROM users WHERE id = ?", userID).Scan(&user) if err != nil { return nil, err } // 3. 写入缓存 data, _ := json.Marshal(user) rdb.Set(ctx, cacheKey, data, 30*time.Minute) return &user, nil }

4.2 缓存过期策略

// 设置过期时间 rdb.Set(ctx, "key", "value", 30*time.Minute) // 延长过期时间 rdb.Expire(ctx, "key", 1*time.Hour) // 查看剩余时间 ttl, _ := rdb.TTL(ctx, "key").Result()

5. 分布式锁

5.1 实现

func AcquireLock(ctx context.Context, rdb *redis.Client, key string, expiration time.Duration) (bool, error) { result, err := rdb.SetNX(ctx, "lock:"+key, "1", expiration).Result() return result, err } func ReleaseLock(ctx context.Context, rdb *redis.Client, key string) error { return rdb.Del(ctx, "lock:"+key).Err() }

5.1 可重入锁

type RedLock struct { rdb *redis.Client keys []string values []string } func (l *RedLock) Lock(ctx context.Context, expiration time.Duration) (bool, error) { for i, key := range l.keys { ok, err := l.rdb.SetNX(ctx, key, l.values[i], expiration).Result() if err != nil || !ok { return false, nil } } return true, nil }

6. 消息队列

6.1 发布订阅

// 发布 rdb.Publish(ctx, "channel1", "message1") // 订阅 sub := rdb.Subscribe(ctx, "channel1") defer sub.Close() for msg := range sub.Channel() { fmt.Println(msg.Channel, msg.Payload) }

6.2 Stream

// 添加消息 id, err := rdb.XAdd(ctx, &redis.XAddArgs{ Stream: "mystream", Values: map[string]interface{}{"field": "value"}, }).Result() // 读取消息 messages, err := rdb.XRead(ctx, &redis.XReadArgs{ Streams: []string{"mystream"}, Count: 10, }).Result()

7. 最佳实践

7.1 键命名规范

业务:对象:属性 user:1:profile order:2023:status session:abc123

7.2 内存优化

  • 选择合适的数据结构
  • 使用压缩存储大值
  • 定期清理过期键
  • 合理设置maxmemory

7.3 持久化配置

# RDB配置 save 900 1 save 300 10 save 60 10000 # AOF配置 appendonly yes appendfsync everysec

8. 总结

Redis作为高性能缓存和消息队列,在现代应用中发挥重要作用。通过合理使用数据结构、管道操作、Lua脚本等特性,可以构建高效的缓存系统和分布式应用。

http://www.jsqmd.com/news/792186/

相关文章:

  • 使用本地浏览器打开远程服务器生成的网页——详细教程
  • 打破语言壁垒:Translumo屏幕实时翻译工具的终极使用指南
  • 2026 年 Q1 全球互联网中断报告:断网、停电与战争
  • 20253221 2025-2026-2 《Python程序设计》实验3报告
  • Python函数中的全局变量详解
  • 量子计算机来了,你的企业网络隧道还安全吗?
  • PostgreSQL高级特性详解
  • Redis学习8 Redis数据结构(1)
  • 基于Vue.js与AI对话的智能思维导图生成器开发实践
  • 终极解决方案:如何快速批量转换GBK到UTF-8编码文件
  • 一次例行密钥轮换,让数百万德国域名集体蒸发
  • 独立开发者工具箱:2026年全栈与AI应用高效开发技术栈指南
  • MongoDB聚合与查询优化详解
  • 如何在 Docker 容器中部署企业微信机器人服务保证高可用
  • 31_AI短片实战第四弹:主观视角空间控制与分屏快速剪辑的AI生成策略(附提示词)
  • 高管求职渠道公司实测:4家机构核心能力对比评测 - 得赢
  • 两次全球宕机之后,Cloudflare 用半年时间重建了什么
  • 2026届最火的AI写作平台推荐榜单
  • Logseq AI助手插件:在知识管理笔记中集成ChatGPT智能写作与编辑
  • hls::stream<ap_uint<DW * NPPC>> src,报错原因分析
  • 32_AI短片实战第五弹:飞跃峡谷——高潮镜头的“放手”哲学与首帧脑补策略(附提示词)
  • DeepSeek V4 横向对比真实表现
  • 终极指南:如何用NPYViewer快速查看和可视化NumPy数组数据
  • YOLO11进阶技巧:数据增强策略 | 舍弃传统Mosaic,引入Copy-Paste与MixUp混合数据增强,有效缓解过拟合
  • R7000P梅林固件进阶玩法:解锁软件中心、挂载U盘与插件安装全攻略
  • 告别数据丢失焦虑:用Python手把手实现Reed-Solomon码(附完整代码)
  • 避开Verilog状态机设计里的那些‘坑’:从HDLbits的Fsm hdlc题看帧同步错误处理
  • 2026年4月优质的vi设计团队推荐,山野风餐饮设计/连锁餐饮品牌设计/连锁餐厅品牌设计,vi设计团队选哪家 - 品牌推荐师
  • 2026最权威的六大AI写作平台解析与推荐
  • LinkSwift:九大网盘直链解析工具使用指南