Skip to main content

Command Palette

Search for a command to run...

数据库中的重型字段迁移优化(golang)

Published
1 min read

最近在数据迁移中的一些优化点,在这里分享一些,当然也不一定是最优的,欢迎讨论。

首先,在某些数据表中的字段,存着非常大的json数据。

并且有几十万行数据,需要更改json中的某个数组字段,追加一些元素。

常规方式

  • 读取所有的行
  • json反序列化
  • 修改数据
  • json序列号并保持到数据库

有几个问题

  • 内存占用非常大,每行大概至少有8KB的数据,各种对象,内存申请,这个迁移程序可能会吃到数G的内存。
  • 性能也不好,在读取数据库期间,其实是浪费了的

第二次优化

按每个团队划分,分别查询,内存降低了一点,因为golang中,使用过的对象并不会立即GC掉。

由于频繁的make对象,所以内存不会立即gc,内存还是比较高的。

第三次优化

使用golang中的Pool功能来复用对象:

var issueTypePool = sync.Pool{ New: func() interface{} { return make([]*IssueType, 0) }, }

数据库查询

issueTypes := issueTypePool.Get().([]*IssueType) _, err := tx.Select(&issueTypes, sql, teamUUID) if err != nil { return nil, err }

恢复对象到对象池:

defer issueTypePool.Put(issueTypes[:0])

这样已经不错了,对象能复用,内存占用取决于最大的团队的内存占用。。

第四次优化

使用golang中的游标方式。

下面的代码中有第二个参数就是channel缓冲区,并且在rows中边读边丢入channel

func AllObjects(tx sq.DB, issueTypeChan chan<- IssueType) error { // 。。。。 for rows.Next() { it := new(IssueType) err = rows.Scan(&it.UUID, &it.TeamUUID, &it.DefaultConfigs) if err != nil { return err } issueTypeChan <- it } return nil }

启动goroutine,并在持续从chan缓冲区读取数据,同时对数据修改迁移,并写入数据库。

issueTypeChan := make(chan IssueType, 1000) doneChan := make(chan bool) timer := time.NewTimer(5 time.Second) defer timer.Stop()

go func() { for { select { case <-timer.C: close(doneChan) fmt.Println("done...") return case it := <-issueTypeChan: timer.Reset(5 * time.Second) // TODO .... } } }()

这样就比较满意了,但是这种方式还没有经过测试,理论上读写分离之后,性能是更优的。

90 views

More from this blog

会有越来的多的side projects出现

什么是side project 可以理解为工作之余开发的产品,通常是收费的服务,可作为工作之外额外收入的产品。 在目前经济下行、公司开源节流(裁员)、失业率上升的大环境下,每一个程序员都应该拥有自己的side projects来对冲未来的不可靠风险。 所以side project 不仅仅是多一种「被动收入」,他也是你未来的「筹码」——工作累了,不想干了、有小孩了、买房了、家人生病了等等这些事情发生的时候,你可以「任性」一下。 而不是一些不可靠的风险出现的时候,再来提高自己的「抗风险」能力。 上面...

Jul 28, 20231 min read61

Xbox Cloud Gaming 游戏加速尝试

Xbox Cloud Gaming 游戏加速 之前有个很老的xbox游戏机,因为性能有点差劲了,所以卖了。 偶尔还是想玩玩游戏,但是老婆不让给买xbox的物理机(怀恋单身),所以含泪玩xbox cloud gaming(以下简称 xcg),xpg会员游戏还是很丰富的。 于是买了uu加速器,坦白说uu加速器不算便宜的,但是xcg在晚上高峰期,一样卡得怀疑人生,那种被马赛克糊满脸的感受,上一次这种体验还是看小姐姐的电影。 其实用uu加速器玩是ok的,就是国内的网络情况大家都知道,dddd(懂得都懂)...

Sep 5, 20221 min read258

github codespaces 在ipad上的最佳浏览器

Github Codespaces github codespaces 是github在被微软收购后,提供的一款在线web IDE,基本与vscode一致,只是运行在浏览器上而已。 而且非常土豪的提供了4核8G内存,微软就是壕。 so,通过ipad来使用codespaces就是一件比较顺其自然的事。 可是其实也没那么简单。。 IPad使用codespaces的快捷键问题 其实最大的问题就是快捷键的问题,不管你是用saferi,还是chrome,他们提供的快捷键或多或少会与你的vscode的快捷键...

Oct 8, 20211 min read59

基于binlog检查数据错误

起因 某个表的 status 「莫名其妙」变成 0 了 其实可以判断出是 status 没有被赋值,通常是结构体的 status 默认是 0 才会被插入数据库。 于是问题看起来就很简单了:只要检查相关的更新操作中的 status 字段有没有被赋值即可。 但是 这个表是用户表。 因为历史原因,源码中的更新函数很多 调用更新函数的地方也很多 无法复现该问题,测试人员也不知道做了什么操作状态变成 0 的 所以同事关注这个问题挺久了,也没看到问题原因(当然我也没看到……) 但是恰好我在做导出 bin...

Aug 5, 20212 min read61
M

Moli'blog

64 posts

曾经的少年还在吗?