惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Proofpoint News Feed
J
Java Code Geeks
WordPress大学
WordPress大学
博客园 - 【当耐特】
博客园 - 叶小钗
小众软件
小众软件
博客园 - 聂微东
宝玉的分享
宝玉的分享
量子位
人人都是产品经理
人人都是产品经理
博客园_首页
罗磊的独立博客
腾讯CDC
美团技术团队
Google DeepMind News
Google DeepMind News
W
WeLiveSecurity
I
InfoQ
Engineering at Meta
Engineering at Meta
云风的 BLOG
云风的 BLOG
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Threat Research - Cisco Blogs
Google DeepMind News
Google DeepMind News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
H
Hacker News: Front Page
B
Blog RSS Feed
L
LangChain Blog
C
Check Point Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
G
GRAHAM CLULEY
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Microsoft Azure Blog
Microsoft Azure Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - Franky
S
Schneier on Security
Attack and Defense Labs
Attack and Defense Labs
Microsoft Security Blog
Microsoft Security Blog
N
Netflix TechBlog - Medium
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Tenable Blog
Simon Willison's Weblog
Simon Willison's Weblog
L
LINUX DO - 热门话题
阮一峰的网络日志
阮一峰的网络日志
Hacker News: Ask HN
Hacker News: Ask HN
A
Arctic Wolf
Schneier on Security
Schneier on Security
The Last Watchdog
The Last Watchdog
Latest news
Latest news
T
The Exploit Database - CXSecurity.com

Posts on WKLKEN THINKING

apisix 中的 lrucache apisix 中的服务发现机制 apisix 中的负载均衡 apisix etcd机制 聊聊框架 关于 k8s 的 zero downtime deployment 一些建议 apisix 遇到的一些问题 关于在除夕前一天换了一个洗衣机的故事 Django DRF 性能优化 DRF 的一些实践 Part1: Serializer DRF继承关系图 Better Code: 关于接口的灵活性 新的仓库: wklken/naming 缓存使用的一些经验 Better Code: 抽象: 可扩展性与可维护性的抉择 Better Code: 异常时, 该提示用户哪些信息? Better Code: 更好的异常日志打印 Go: some libs Go: logrus性能提升 Go: gin validation 远程办公的一点总结 Go: 开发过程中的一些bug 项目管理实践: 风险驱动开发 Go: 一种error wrap调用链处理方式 漫谈技术选型 Go: 基于 apitest 做handler层单元测试 Go: go-sql-driver interpolateparams参数优化 [分享]深度工作 你需要更多的思考时间 Django项目重构小结 工作七年小结: 学习,生活及其他 [分享]bash日常: bash-utils 极客时间推广海报 2017总结: 予时光以意义 k8s APIServer源码: api注册详细细节 k8s APIServer源码: api注册主体流程 k8s APIServer源码: 服务启动 k8s APIServer源码: go-restful框架 重构 - 读书笔记(Python示例) 写给新人的沟通建议 vim 杂谈 - 关于快速编辑 vim 杂谈 - 关于移动 读书笔记-重构: 章11 处理概括关系 读书笔记-重构: 章10 简化函数调用 读书笔记-重构: 章9 简化表达式 读书笔记-重构: 章8 重新组织数据 读书笔记-重构: 章7 在对象之间搬移特性 读书笔记-重构: 章6 重新组织函数 Python 代码规范小结 [分享]关于vim ElasticSearch集群部署文档 Logstash+ElasticSearch处理mysql慢查询日志 [分享]关于代码调试DE那些事 Logstash+ElasticSearch+Kibana- 实现相对通用的数据收集分析 ELK维护的一些点(二) [分享]Python源码剖析-数据结构 一些Centos Python生产环境的部署命令 摘录<<6个月学会任何一种外语>> ELK 维护的一些点 也许是一个新的开始 一些vim的个性化配置 读书笔记-调试九法 这段时间的一些想法 Python 源码阅读 - 垃圾回收机制 我为什么要写博客 APUE笔记-第一章 UNIX基础知识 Python源码阅读-闭包的实现 Python源码阅读-内存管理机制(二) Python源码阅读-内存管理机制(一) Python-基础-数据结构小结 '活动'设计的一些trick 一些简单的Python测试题 我的tmux配置及说明【k-tmux】 Review and Restart 工作四周年小结 vim插件: surround & repeat[成对符号编辑] vim插件: gundo[时光机] vim插件: expand-region[区域选中] vim插件: quickrun[快速执行] vim插件: trailing-whitespace[行尾空格处理] vim插件: closetag[成对标签补全] vim插件: ctrlp[文件搜索] vim插件: airline[状态栏增强] vim插件: theme[主题] vim插件: tagbar[大纲式导航] vim插件: nerdcommenter[快速注释] vim插件: rainbow_parentheses[括号高亮] vim插件: syntastic[语法检查] vim插件: delimitmate[符号自动补全] vim插件: matchit[成对标签跳转] vim插件: easy-align[快速对齐] vim插件: multiple-cursors[多光标操作] vim插件: vim-signature[快速标记跳转] vim插件: easymotion[快速跳转] vim插件: vundle[管理插件] Elasticsearch几个问题的解决 分享一份 Vim 简介PPT k-vim 更新9.0版本 关于知识管理工具的思考 Logstash+ElasticSearch+Kibana处理nginx访问日志
Go: go-redis/cache升级的坑
2021-03-05 · via Posts on WKLKEN THINKING

这是在做 Golang 项目中的一些实践

在做一个项目, 使用了 go-redis/redisgo-redis/cache

某个节点, 做了所有依赖包的升级.

在做缓存依赖包的升级时, 必须十分注意, 新版本的第三方包做了哪些变更, 阅读CHANGE LOG和相关的源码;

主要风险:

  • breaking changes
  • 对象/方法/参数等协议变更
  • 存储格式(是否向前兼容)

即, 一旦做了升级, 原先正常的代码, 可能会有问题

所以需要确认:

  1. 新老版本存储格式是否一致?
  2. 代码中涉及的地方是否使用同样的操作?

1. v7升级v8

issue: Can’t upgrade from v7 to v8 directly?

package main

import (
	"context"
	"fmt"

	cv7 "github.com/go-redis/cache/v7"
	cv8 "github.com/go-redis/cache/v8"
	rdsv7 "github.com/go-redis/redis/v7"
	rdsv8 "github.com/go-redis/redis/v8"
	msgpackv4 "github.com/vmihailenco/msgpack/v4"
)

func main() {
	// TODO: 测试放入redis用另一个取
	d := map[string]interface{}{
		"hello": 1,
		"world": "ok",
	}

	// 使用两个版本的cli进行测试, v7/v8
	// 1. 使用v7, marshal 放入db
	// 2. use v8, 获取

	v7 := &cv7.Codec{
		Redis:     rdsv7.NewClient(&rdsv7.Options{}),
		Marshal:   msgpackv4.Marshal,
		Unmarshal: msgpackv4.Unmarshal,
	}

	err := v7.Set(&cv7.Item{
		Key:    "aaa",
		Object: d,
	})
	fmt.Println("set err:", err)

	v8 := cv8.New(&cv8.Options{
		Redis: rdsv8.NewClient(&rdsv8.Options{}),
	})

	var result map[string]interface{}
	err = v8.Get(context.TODO(), "aaa", &result)
	fmt.Println("get err:", err)
	fmt.Println(result)
}

执行结果:

set err: <nil>
get err: unknown compression method: 6b
map[]

原因, go-redis/cache v8引入的压缩 v8/cache.go, 没有做向前兼容的逻辑

解决方案: 在基础类中, 更换掉key的namespace, 增加版本号; 例如 project:hello 变成 project:v8:hello

2. 升级v8后的msgpack 与 pipeline的处理

由于 go-redis/cache 主要用于单个对象的 set/get

某些业务场景下, 我们使用pipeline进行批量操作

此时, pipeline拿回回来的是 raw string, 原先v7由于set算法用的msgpack.Marshal, 自定义pipeline处理结果直接用msgpack.Unmarshal没有问题.

但是, 升级到v8后, 由于compession逻辑的存在, 此时使用原生的msgpack.Unmarshal将会报错(无法识别被压缩的字符串)

解决: 需要切换为 go-redis/cache 对象的Unmarshal