简体   繁体   English

如何使用 goroutine 和 channel 批量读取 mysql 数据

[英]how to read mysql data using goroutine and channel in bulk

I'm a newbee for golang, now need to read a big amount data in mysql, so I wanna use goroutine and channel to get data in high performance, but don't know how to avoid data duplication for each goroutine and make whole process stable.我是golang的新手,现在需要读取mysql中的大量数据,所以我想使用goroutine和channel来高性能获取数据,但不知道如何避免每个goroutine的数据重复并制作整个过程稳定的。 for instance, table schema is as below, I wanna get all records which create_time is smaller than 1000000000000000000 , I wanna create 10 goroutines and read data concurrently, each goroutine do some business logic, how to design codes?例如,表模式如下,我想获取所有create_time小于1000000000000000000的记录,我想创建 10 个 goroutine 并同时读取数据,每个 goroutine 做一些业务逻辑,如何设计代码? thank u感谢你

id content last_id create_time

I would suggest you to create a goroutine that would publish the data to your channel.我建议您创建一个将数据发布到您的频道的 goroutine。 Then you can add listener go routines to handle the published data.然后您可以添加监听器 go 例程来处理发布的数据。 This can be done as following:这可以通过以下方式完成:

Main:主要的:

const GoroutineCount = 10

type SomeData []int

func main() {
    ch := make(chan SomeData, 1)

    go PublishData(ch)

    for i := 0; i < GoroutineCount; i++ {
        go ProcessData(ch)
    }
}

For assumptions, I have used a simple slice of int as data.对于假设,我使用了一个简单的 int 切片作为数据。 This can be slice of any struct as required.根据需要,这可以是任何结构的切片。

Publish data to channel:将数据发布到通道:

const ChunkSize = 1000

func PublishData(ch chan SomeData) {
    // Assume having 10000 records in result set
    // This has to come from db transaction
    res := make([]int, 10000)

    // split into chunks of 1000
    chunks := GetChunk(res)

    // write chunk data to channel
    for i := range chunks {
        ch <- chunks[i]
    }
}

func GetChunk(input SomeData) []SomeData {
    var result []SomeData

    boundary := len(input)
    index := 0
    for index = 0; boundary >= ChunkSize; index+=ChunkSize {
        boundary -= ChunkSize
        lastIndex := index+ChunkSize
        result = append(result, input[index:lastIndex])
    }
    boundary = len(input) % ChunkSize
    if boundary > 0 {
        lastIndex := index+ boundary
        result = append(result, input[index:lastIndex])
    }

    return result
}

Process individual chunks as:将单个块处理为:

func ProcessData(ch chan SomeData) {
    // Read single chunk
    res := <-ch

    // Process chunk data
    fmt.Printf("len %d\n", len(res))
}

Code on go playground: https://play.golang.org/p/X9Q991h6ru_n go 操场上的代码: https://play.golang.org/p/X9Q991h6ru_n

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从goroutine的频道连续接收数据 - How to continuously receive data from channel of goroutine 为什么数据被推入通道但从未从接收器 goroutine 中读取? - Why is data being pushed into the channel but never read from the receiver goroutine? 如何在不等待另一个 goroutine 中设置的情况下读取通道? - How to read channel without waiting setting in another goroutine? 如何从正在从该通道接收数据的goroutine向该通道添加对象? - How do I add an object to a channel from a goroutine that is receiving data from that channel? 有时 goroutine 不会从通道获取事件数据 - Sometimes goroutine NOT get event data from channel 如何使用频道通知goroutine正确退出 - How to use channel to notify a goroutine to quit properly 如果 Goroutine 完成并关闭错误通道,如何判断? - How to cacth if Goroutine finished and close error channel? 同一频道中的两个goroutine-如何执行? - Two goroutine in the same Channel - how are they executed? 为什么我在尝试从一个从不在 goroutine 中接收数据但在 main func 中接收数据的通道中读取时不会出现死锁 - Why do I not get a deadlock when trying to read from a channel that never receives data in a goroutine but do in the main func 是否保证首先挂在通道上的 goroutine 最终会先获取数据? - Is it guaranteed that the goroutine which is pending on the channel first will eventually get the data first?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM