我在go中编写数据移动设备。获取位于一个数据中心的数据并将其移动到另一个数据中心。考虑到惯例,想去的将是完美的。
我注意到如果我有一个运行1800个线程的程序,则传输的数据量非常低
这是平均超过30秒的dstat
打印输出
---load-avg--- ----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
1m 5m 15m |usr sys idl wai hiq siq| read writ| recv send| in out | int csw
0.70 3.58 4.42| 10 1 89 0 0 0| 0 156k|7306k 6667k| 0 0 | 11k 6287
0.61 3.28 4.29| 12 2 85 0 0 1| 0 6963B|8822k 8523k| 0 0 | 14k 7531
0.65 3.03 4.18| 12 2 86 0 0 1| 0 1775B|8660k 8514k| 0 0 | 13k 7464
0.67 2.81 4.07| 12 2 86 0 0 1| 0 1638B|8908k 8735k| 0 0 | 13k 7435
0.67 2.60 3.96| 12 2 86 0 0 1| 0 819B|8752k 8385k| 0 0 | 13k 7445
0.47 2.37 3.84| 11 2 86 0 0 1| 0 2185B|8740k 8491k| 0 0 | 13k 7548
0.61 2.22 3.74| 10 2 88 0 0 0| 0 1229B|7122k 6765k| 0 0 | 11k 6228
0.52 2.04 3.63| 3 1 97 0 0 0| 0 546B|1999k 1365k| 0 0 |3117 2033
如果我运行9个程序实例,每个程序包含200个线程,我会看到更好的性能
---load-avg--- ----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
1m 5m 15m |usr sys idl wai hiq siq| read writ| recv send| in out | int csw
8.34 9.56 8.78| 53 8 36 0 0 3| 0 410B| 38M 32M| 0 0 | 41k 26k
8.01 9.37 8.74| 74 10 12 0 0 4| 0 137B| 51M 51M| 0 0 | 59k 39k
8.36 9.31 8.74| 75 9 12 0 0 4| 0 1092B| 51M 51M| 0 0 | 59k 39k
6.93 8.89 8.62| 74 10 12 0 0 4| 0 5188B| 50M 49M| 0 0 | 59k 38k
7.09 8.73 8.58| 75 9 12 0 0 4| 0 410B| 51M 50M| 0 0 | 60k 39k
7.40 8.62 8.54| 75 9 12 0 0 4| 0 137B| 52M 49M| 0 0 | 61k 40k
7.96 8.63 8.55| 75 9 12 0 0 4| 0 956B| 51M 51M| 0 0 | 59k 39k
7.46 8.44 8.49| 75 9 12 0 0 4| 0 273B| 51M 50M| 0 0 | 58k 38k
8.08 8.51 8.51| 75 9 12 0 0 4| 0 410B| 51M 51M| 0 0 | 59k 39k
平均负载有点高,但我稍后会担心。但网络流量几乎达到了网络潜力。
我在Ubuntu 12.04上, 8 Gigs Ram, 2.3 GHz处理器(EC2:P表示)
另外,我将文件描述符从1024增加到10240
我认为go是针对这种事情而设计的,还是我期待这个应用程序的用途太多?
我缺少一些微不足道的东西吗?我是否需要配置我的系统以最大限度地发挥潜力?
修改
我想我的问题不够明确。抱歉。我不是要求魔法,我知道计算机对他们可以处理的东西有限制。 所以我会改写。为什么1800个实例有1800个例程!= 9个实例,每个有200个线程?与9个实例相比,相同数量的go例程显着降低了1个实例的性能。
答案 0 :(得分:2)
请注意,goroutines也仅限于您的本地机器,并且该通道不是本机网络启用的,即您的特定情况可能不是咬着go的巧克力网站。
另外:你对每次转移到goroutine投掷(通常)有什么期望? IO操作往往会遇到瓶子撞击金属的瓶颈,即数据物理传输到介质。可以这样想:无论有多少线程或(在这种情况下是Goroutines)尝试写入Networkcard,您仍然只有一个网卡。很可能用许多并发写入调用来打击它只会减慢速度,因为所涉及的开销会增加
如果您认为这不是问题或者想要审核代码以获得最佳性能,请使用内置的内置功能:profiling go programs (official go blog) 但实际的瓶颈可能仍然在你的go程序之外和/或与os交互的方式。
在没有代码的情况下解决您的实际问题是毫无意义的猜测。发布一些,每个人都会尽力帮助你。
答案 1 :(得分:1)
您可能需要发布源代码才能获得真正的输入,但为了确保您使用的cpus数量增加了吗?
import "runtime"
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
}