高性能Go并发
1.管道chan吞吐极限10,000,000,单次Put,Get耗时大约100ns/op,无论是采用单Go程,还是多Go程并发(并发数:100, 10000, 100000),耗时均没有变化,Go内核这对chan进行优化。
解决之道:在系统设计时,避免使用管道chan传递主业务数据,避免将业务流程处理流程分割到对个Go程中执行,这样做减少chan传输耗时,和Go程调度耗时,性能会有很大的提升。
案例分析:nsq和nats都是实时消息队列,nsq在客户端端和服务端大量使用chan转发消息,导致性能不佳,只有100,000/s;而nats服务端在分发消息流程中,没有使用chan,只在客户端接收时使用chan,性能可达到1,000,000/s。
2.互斥锁Mutex在单Go程时Lock,Unlock耗时大约20ns/op,但是采用多Go程时,性能急剧下降,并发越大耗时越长,在Go1.5并发数达到1024耗时900ns/op,Go1.6优化到300ns/op,究其原因,是构建在CPU的原子操作之上,抢占过于频繁将导致,消耗大量CPU时钟,进而CPU多核无法并行。
解决之道:采用分区,将需要互斥保护的数据,分成多个固定分区(建议是2的整数倍,如256),访问时先定位分区(不互斥),这样就可降低多个Go程竞争1个数据分区的概率。
案例分析:Golang的Go程调度模块,在管理大量的Go程,使用的就是数据分区。
3.select异步操作在单管道时耗时120ns/op,但是随着管道数增加,性能线性下降,每增加1个管道增加100ns/op,究其原因,slelect时当chan数超过1后,Go内部是创建一个Go程,有它每1ms轮训的方式检查每个chan是否可用,而不是采用事件触发。
解决之道:在select中避免使用过多的管道chan分支,或者把无法用到的chan置为nil;解决select超时,避免使用单独的超时管道,应与数据返回管道共享。
案例分析:nsq和nats都是实时消息队列,由于nsq大量使用chan,这就必然导致大量使用select对多chan操作,结果是性能不高。
4.Go调度性能低下,当出现1,000,000Go程时,Go的调度器的性能急剧下降。
解决之道:避免动态创建Go程,服务端收到数据并处理的流程中,避免使用chan传递业务数据,这样会引起Go程调度。
案例分析:nsq和nats都是实时消息队列,由于nsq大量使用chan,这就必然导致在服务过程中,引起Go调度,结果是性能不高。
5.defer性能不高,每次defer耗时100ns,,在一个func内连续出现多次,性能消耗是100ns*n,累计出来浪费的cpu资源很大的。
解决之道:除了需要异常捕获时,必须使用defer;其它资源回收类defer,可以判断失败后,使用goto跳转到资源回收的代码区。
补充:defer 在 go1.8 快了一倍了。runtime: defer is slow · Issue #14939 · golang/go · GitHub
6.内存管理器性能低下,申请16字节的内存,单次消耗30ns,64字节单次消耗70ns,随着申请内存尺寸的增长,耗时会迅速增长。加上GC的性能在1.4, 1.5是都不高,直到1.6, 1.7才得到改善。
解决之道:建议使用pool,单次Put,Get的耗时大约在28ns,在并发情况下可达到18ns,比起每次创建,会节省很多的CPU时钟。
补充: 单纯看 Put, Get 耗时不高,但是 pool 取出来的是 interface{},需要类型断言成实际类型,放进去的时候,还要把实际类型转换成 interface{}(虽然是自动的),这个转换的过程对于简单类型每次需要 30ns,复杂的结构体时间会长的多,所以这个开销算上的话,用 pool 方案反而会导致性能下降。
出于性能考虑的最佳实践和建议
(1)尽可能的使用:=去初始化声明一个变量(在函数内部);
(2)尽可能的使用字符代替字符串;
(3)尽可能的使用切片代替数组;
(4)尽可能的使用数组和切片代替映射(详见参考文献15);
(5)如果只想获取切片中某项值,不需要值的索引,尽可能的使用for range去遍历切片,这比必须查询切片中的每个元素要快一些;
(6)当数组元素是稀疏的(例如有很多0值或者空值nil),使用映射会降低内存消耗;
(7)初始化映射时指定其容量;
(8)当定义一个方法时,使用指针类型作为方法的接受者;
(9)在代码中使用常量或者标志提取常量的值;
(10)尽可能在需要分配大量内存时使用缓存;
(11)使用缓存模板(参考章节15.7)。
高性能Go并发的更多相关文章
- 0930MySQL中实现高性能高并发计数器方案(例如文章点击数)
转自http://www.jb51.net/article/56656.htm 这篇文章主要介绍了MySQL中实现高性能高并发计数器方案,本文中的计数器是指如文章的点击数.喜欢数.浏览次数等,需要的朋 ...
- MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能
MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能 Clicks: Date: -- :: Power By 李轩Lane TagMysql计数器高性能 现在有很多的项目,对计数器的实现 ...
- 浅谈千万级PV/IP规模高性能高并发网站架构(转自老男孩)
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://oldboy.blog.51cto.com/2561410/736710 如果把来 ...
- 浅谈千万级PV/IP规模高性能高并发网站架构
高并发访问的核心原则其实就一句话“把所有的用户访问请求都尽量往前推”. 如果把来访用户比作来犯的"敌人",我们一定要把他们挡在800里地以外,即不能让他们的请求一下打到我们的指挥部 ...
- 高性能高并发服务器架构设计探究——以flamigo服务器代码为例
这篇文章我们将介绍服务器的开发,并从多个方面探究如何开发一款高性能高并发的服务器程序. 所谓高性能就是服务器能流畅地处理各个客户端的连接并尽量低延迟地应答客户端的请求:所谓高并发,指的是服务器可以同时 ...
- (转)浅谈千万级PV/IP规模高性能高并发网站架构
浅谈千万级PV/IP规模高性能高并发网站架构 原文:http://blog.51cto.com/oldboy/736710 文章架构简图: 高并发访问的核心原则其实就一句话“把所有的用户访问请求都 ...
- 最新IP地址数据库Dat格式-高性能高并发版(2019年3月)
最新IP地址数据库->Dat 二进制文件 高性能高并发-qqzeng-ip.dat 格式 全球IP数据库-20190301-Dat 版 国内IP数据库-20190 ...
- 设计高性能大并发WEB系统架构注意点
设计高性能大并发WEB系统架构注意点 第01:大型架构的演进之路第02(上):分布式缓存第02(下):分布式缓存第03:分布式消息队列第04:分布式数据存储第05:分布式服务框架第06:高性能系统架构 ...
- 构建高性能高并发Java系统 .
转:http://blog.csdn.net/nengyu/article/details/7591854 场景这里指的高性能高并发服务器是一个有状态的服务,可以理解成web或者socket服务器,每 ...
- Java异步NIO框架Netty实现高性能高并发
原文地址:http://blog.csdn.net/opengl_es/article/details/40979371?utm_source=tuicool&utm_medium=refer ...
随机推荐
- SDUT中大数实现的题目,持续更新(JAVA实现)
SDUT2525:A-B (模板题) import java.util.Scanner; import java.math.*; public class Main { public static v ...
- 8种主要排序算法的C#实现 (一)
简介 排序算法是我们编程中遇到的最多的算法.目前主流的算法有8种. 平均时间复杂度从高到低依次是: 冒泡排序(o(n2)),选择排序(o(n2)),插入排序(o(n2)),堆排序(o(nlogn)), ...
- 聊一聊python的单例模式
单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...
- spring boot 总结
一.什么是SpringBoot 描述:Spring Boot是Spring社区发布的一个开源项目,旨在帮助开发者快速并且更简单的构建项目.大多数SpringBoot项目只需要很少的配置文件.二.Spr ...
- ubuntu apt-get 安装 lnmp
最近在 Ubuntu 14.04 LTS 安装 LNMP 一键安装包的时候出现了问题,PHP 5 服务没有启动,只好使用 Ubuntu 官方源进行安装: Nginx (读音 “engine x”)免费 ...
- 如何建立DB2分区数据库?(转)
欢迎和大家交流技术相关问题:邮箱: jiangxinnju@163.com博客园地址: http://www.cnblogs.com/jiangxinnjuGitHub地址: https://gith ...
- RedisTemplate和StringRedisTemplate
最近在开始在学习Redis以及如何在Java当中去使用Redis,Redis是什么我这里就不说了. 我主要想说的是Redis和Java当中Spring结合起来的时候,使用到的RedisTemplate ...
- Sql调试
1 ,调试 普通sql语句, 直接 F11 2,调试存储过程 F11->F10执行到 存储过程语句 在按F11 跳转进入到Sql存储过程内
- yum安装redis phpredis扩展
转载地址:http://blog.csdn.net/musicrabbit/article/details/9729941 redis和php-redis在官方源上是没有的,需要安装其他的源,其他源的 ...
- 20145216史婧瑶《Java程序设计》第2周学习总结
20145216 <Java程序设计>第2周学习总结 教材学习内容总结 第三章 基础语法 3.1 类型.变量与运算符 •类型 •基本类型 •整数:short(占2字节).int(占4字节) ...