文档章节

Go语言项目(kingshard)性能优化实例剖析

flikecn
 flikecn
发布于 2015/11/02 20:49
字数 1869
阅读 3521
收藏 80

kingshard性能优化网络篇

最近kingshard的功能开发节奏慢了许多。一方面是工作确实比较忙,另一方面是我觉得kingshard的功能已经比较完善了,下一步的开发重点应该是性能优化。毕竟作为一个MySQL proxy,如果转发SQL的性能很差,再多的功能都无济于事。所以这个周末一直宅在家里优化kingshard的转发性能。经过两天的探索发现,将kingshard的转发SQL性能提升了18%左右,在这个过程中学到了一下知识。借此机会分享一下,同时也是督促一下自己写博客的积极性。:)

1. 发现kingshard的性能瓶颈

首选,对kingshard进行性能优化,我们必须要找到kingshard的性能瓶颈在哪里。Go语言在性能优化支持方面做的非常好,借助于go语言的pprof工具,我们可以通过简单的几个步骤,就能得到kingshard在转发SQL请求时的各个函数耗时情况。

1.1 环境搭建

根据kingshard使用指南搭建一个kingshard代理环境。我是用macbook搭建的环境,硬件参数如下所示:

CPU: 2.2GHZ * 4
内存:16GB
硬盘: 256GB

1.2 性能测试步骤

具体步骤如下所述:

1.获取一个性能分析的封装库

go get github.com/davecheney/profile

2.在工程内import这个组件

3.在kingshard/cmd/kingshard/main.go的main函数开始部分添加CPU监控的启动和停止入口

func main() {
	defer profile.Start(profile.CPUProfile).Stop()
	fmt.Print(banner)
	runtime.GOMAXPROCS(runtime.NumCPU())
	flag.Parse()
	....
}

4.重新编译工程, 运行kingshard

./bin/kingshard -config=etc/ks.yaml

5.kingshard启动后会在终端输出下面一段提示:

2015/10/31 10:28:06 profile: cpu profiling enabled, /var/folders/4q/zzb55sfj377b6vdyz2brt6sc0000gn/T/profile205276958/cpu.pprof

后面的路径就是pprof性能分析文件的位置,Ctrl+C中断服务器

6.这时候用sysbench对kingshard进行压力测试,得到QPS(有关sysbench的安装和使用,请自行Google解决)。具体的代码如下所示:

sysbench --test=oltp --num-threads=16 --max-requests=160000 --oltp-test-mode=nontrx --db-driver=mysql --mysql-db=kingshard --mysql-host=127.0.0.1 --mysql-port=9696 --mysql-table-engine=innodb --oltp-table-size=10000 --mysql-user=kingshard --mysql-password=kingshard --oltp-nontrx-mode=select --db-ps-mode=disable run

得到如下结果:

OLTP test statistics:
    queries performed:
        read:                            160071
        write:                           0
        other:                           0
        total:                           160071
    transactions:                        160071 (16552.58 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 160071 (16552.58 per sec.)
    other operations:                    0      (0.00 per sec.)

Test execution summary:
    total time:                          9.6705s
    total number of events:              160071
    total time taken by event execution: 154.4474
    per-request statistics:
         min:                                  0.29ms
         avg:                                  0.96ms
         max:                                 14.17ms
         approx.  95 percentile:               1.37ms

Threads fairness:
    events (avg/stddev):           10004.4375/24.95
    execution time (avg/stddev):   9.6530/0.00

  • 按照上述步骤测试三次(16552.58,16769.72,16550.16)取平均值,得到优化前kingshard的QPS是:16624.15

  • 按照上述步骤,直连MySQL。测试直连MySQL的QPS,同样测试三次QPS(27730.90,28499.05,27119.20),得到直连MySQL的QPS是:27783.05。

  • 从上述数据可以计算出kingshard转发SQL的性能是直连MySQL的59%左右。

7.将cpu.prof拷贝到bin/kingshard所在位置

8.调用go tool工具制作CPU耗时的PDF文档

go tool pprof -pdf ./kingshard cpu.pprof > report.pdf

2. 性能测试报告分析

通过上述命令,可以生成压测期间主要函数耗时情况。从report来看,主要的耗时在TCP层数据包的收发上面。那我们应该主要考虑如何优化TCP层数据的收发方面。优化TCP传输效率,我首先想到了减少系统调用,每个数据包传输尽量多的数据。

在通过 TCP socket 进行通信时,数据都拆分成了数据块,这样它们就可以封装到给定连接的 TCP payload(指 TCP 数据包中的有效负荷)中了。TCP payload 的大小取决于几个因素(例如最大报文长度和路径),但是这些因素在连接发起时都是已知的。为了达到最好的性能,我们的目标是使用尽可能多的可用数据来填充每个报文。当没有足够的数据来填充 payload 时(也称为最大报文段长度(maximum segment size) 或 MSS),TCP 就会采用 Nagle 算法自动将一些小的缓冲区连接到一个报文段中。这样可以通过最小化所发送的报文的数量来提高应用程序的效率,并减轻整体的网络拥塞问题。

由于这种算法对数据进行合并,试图构成一个完整的 TCP 报文段,因此它会引入一些延时。但是这种算法可以最小化在线路上发送的报文的数量,因此可以最小化网络拥塞的问题。但是在需要最小化传输延时的情况中,GO语言中Sockets API 可以提供一种解决方案。就是通过:

func (c *TCPConn) SetNoDelay(noDelay bool) error

这个函数在Go中默认情况下,是设置为true,也就是未开启延迟选项。我们需要将其设置为false选项,来达到每个数据包传输尽量多的数据,减少系统调用的目的。

2.1 代码修改和性能测试

发现了性能瓶颈以后,修改proxy/server/server.go文件中的newClientConn函数和backend/backend_conn.go中的ReConnect函数,分别设置client与kingshard之间的连接和kingshard到MySQL之间的连接为最小化传输延时。具体的代码修改可以查看这个commit

修改后我们利用sysbench重新测试,测试命令和上述测试一致。得到的结果如下所示:

OLTP test statistics:
    queries performed:
        read:                            160174
        write:                           0
        other:                           0
        total:                           160174
    transactions:                        160174 (21291.68 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 160174 (21291.68 per sec.)
    other operations:                    0      (0.00 per sec.)

Test execution summary:
    total time:                          7.5228s
    total number of events:              160174
    total time taken by event execution: 119.9655
    per-request statistics:
         min:                                  0.26ms
         avg:                                  0.75ms
         max:                                 10.78ms
         approx.  95 percentile:               1.13ms

Threads fairness:
    events (avg/stddev):           10010.8750/38.65
    execution time (avg/stddev):   7.4978/0.00

测试三次得到的QPS为:21291.68,21670.85,21463.44。 相当于直连MySQL性能的77%左右,通过这个优化性能提升了18%左右

总结

通过这篇文章,介绍了通过Go语言提供的pprof对kingshard进行性能分析的详细步骤。对于其他Go语言项目也可以通过类似步骤生成性能报告文档。性能优化的关键是发现性能瓶颈,再去找优化方案。有时候简单的优化,就可以达到预想不到的效果,希望本文能给Go开发者在性能优化方面提供一个思路。最后打个广告:kingshard作为一个支持sharding的开源MySQL中间件项目,目前已经比较稳定了,且经过性能优化后,转发SQL的性能提升了不少。后续我还会在锁和内存方面对kingshard进行优化,敬请期待。

github: https://github.com/flike/kingshard

OSC: http://git.oschina.net/flikecn/kingshard

© 著作权归作者所有

flikecn

flikecn

粉丝 38
博文 4
码字总数 11019
作品 2
朝阳
高级程序员
私信 提问
加载中

评论(13)

shenjinxi
shenjinxi
👍
yoke白板
yoke白板
干活   
支持
myml
myml
支持
Eriloan
Eriloan
好文章!
独爱剑走偏锋
独爱剑走偏锋
好文 79
一位极其不愿意透漏姓名的马先生
一位极其不愿意透漏姓名的马先生
货 好文 非常棒
bhpx
bhpx
不明觉厉
logbird
logbird
干货 好文 非常棒
难易
难易
赞,最近也在学习Go的优化
hyper0x
hyper0x
不错,继续加油!79
flike/kingshard

kingshard简介 支持kingshard kingshard是一个由Go开发高性能MySQL Proxy项目,kingshard在满足基本的读写分离的功能上,致力于简化MySQL分库分表操作;能够让DBA通过kingshard轻松平滑地实现...

flike
2015/07/27
0
0
KingShard MySQL中间件快速入门

kingshard 是一个由Go开发高性能MySQL Proxy项目. 功能简介: 读写分离 分库分表 数据库扩容 具体功能查看官方文档,这次主要是自己动手搭建基于Kingshard的MySQL集群。 环境 Docker Go Cent...

艾贺521
2018/08/15
0
0
【开源访谈】Kingshard 作者陈非访谈实录

【项目简介】 Kingshard 是一个由Go开发高性能MySQL Proxy项目,kingshard在满足基本的读写分离的功能上,致力于简化MySQL分库分表操作;能够让DBA通过kingshard轻松平滑地实现MySQL数据库扩...

孔小菜
2015/08/03
9.3K
11
kingshard最佳实践(二)

上篇主要介绍了kingshard的工作流程、搭建及部分功能测试,今天来测试一下kingshard对sharding的支持 一、kingshard的sharding介绍 1.1 kingshard的sharding优势 现在开源的MySQL Proxy已经有...

IT--小哥
2018/05/07
295
0
小米开源数据库中间件Gaea实战(有彩蛋)

本文根据dbaplus社群第191期线上分享整理而成,文末还有好书送哦~ jpg="" p="" pingfang="" powered-by="xiumi.us" sans="" section="" src="https://dbaplus.cn/uploadfile/2019/0710/20190......

曹东瑜
07/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
16
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
19
0
jquery--DOM操作基础

本文转载于:专业的前端网站➭jquery--DOM操作基础 元素的访问 元素属性操作 获取:attr(name);$("#my").attr("src"); 设置:attr(name,value);$("#myImg").attr("src","images/1.jpg"); ......

前端老手
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部