Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如何优化处理大数据_Go_Optimization_Goroutine - Fatal编程技术网

Go 如何优化处理大数据

Go 如何优化处理大数据,go,optimization,goroutine,Go,Optimization,Goroutine,我的后端服务的目标是在一天内处理9000万数据和至少1000万数据 我的系统配置: 内存2000 Mb CPU 2核心(s) 我现在所做的是这样的: var wg sync.WaitGroup //length of evs is 4455 for i, ev := range evs { wg.Add(1) go migrate(&wg) } wg.Wait() func migrate(wg

我的后端服务的目标是在一天内处理9000万数据和至少1000万数据

我的系统配置:

  • 内存2000 Mb
  • CPU 2核心(s)
我现在所做的是这样的:

var wg sync.WaitGroup
//length of evs is 4455
for i, ev := range evs {
                wg.Add(1)
                go migrate(&wg)
            }
wg.Wait()

func migrate(wg *sync.WaitGroup) {
defer wg.Done()
//processing 
time.Sleep(time.Second)
}

如果你不知道你需要做的工作类型的更多细节,你的方法似乎很好。需要考虑的一些事情:

  • 在处理循环中重新使用变量和/或客户机。例如,重用HTTP客户端而不是重新创建HTTP客户端

  • 取决于用例调用如何处理失败。使用
    errorgroup
    可能会很有效。它是一个方便的包装器,可以在出错时停止所有线程,这可能会为您节省大量时间

  • 在migrate函数中,请务必注意有关的注意事项


我找到了解决办法。为了实现如此巨大的处理,我所做的是
将goroutine的数量限制为50个,并将Core的数量从2个增加到5个。

资源不是问题所在。也可以增加资源如果你的方法是正确的,你只需要限制goroutine的创建速度。实际需要的goroutine数量取决于任务的性质。而且你肯定不需要在那里睡觉,一次睡完也不会有问题。如果他们花费大量时间等待资源,比如网络呼叫,那应该没问题。但是,如果它们是由两个内核绑定的CPU,那么除了5个goroutine之外,您不会获得太多好处,而4500个goroutine之间的交换可能会损害性能。与I/O类似的问题是,您的速度不能超过磁盘速度。迁移在做什么?迁移实际上是对数据进行一些处理并保存到数据库。这是有道理的。因此,如果我一次将go例程限制为5,那么我可以检查处理的基准
func main() {
    g := new(errgroup.Group)
    var urls = []string{
        "http://www.someasdfasdfstupidname.com/",
        "ftp://www.golang.org/",
        "http://www.google.com/",
    }
    for _, url := range urls {
        url := url // https://golang.org/doc/faq#closures_and_goroutines
        g.Go(func() error {
            resp, err := http.Get(url)
            if err == nil {
                resp.Body.Close()
            }
            return err
        })
    }

    fmt.Println("waiting")
    if err := g.Wait(); err == nil {
        fmt.Println("Successfully fetched all URLs.")
    } else {
        fmt.Println(err)
    }
}