天天看點

mymysql與go-mysql-driver性能比較首先是性能測試下面比較兩邊的profilemymysql和go-mysql-driver的測試總結

mymysql和go-mysql-driver是兩個現在都很流行的go的mysql驅動,這篇文章目的是要将這兩個驅動進行一下比較

兩個mysql驅動的下載下傳位址:

<a href="https://github.com/ziutek/mymysql">https://github.com/ziutek/mymysql</a>

<a href="http://code.google.com/p/go-mysql-driver/">http://code.google.com/p/go-mysql-driver/</a>

在mysql建表和初始化資料(db是test)

1

2

3

4

5

6

7

8

9

10

11

12

13

<code>drop table</code><code>if</code> <code>exists admin;</code>

<code>create table `admin` (</code>

<code>    </code><code>`adminid` int(10) unsigned not null auto_increment,</code>

<code>    </code><code>`username` varchar(20) not null default</code><code>''</code> <code>comment</code><code>'背景使用者名'</code><code>,</code>

<code>    </code><code>`password` char(32) not null default</code><code>''</code> <code>comment</code><code>'密碼,md5存'</code><code>,</code>

<code>    </code><code>primary key(`adminid`)</code>

<code>)</code>

<code>comment=</code><code>'背景使用者資訊表'</code>

<code>collate=</code><code>'utf8_general_ci'</code>

<code>engine=innodb;</code>

<code>insert into admin set adminid=1, username=</code><code>'admin'</code><code>, password=</code><code>'21232f297a57a5a743894a0e4a801fc3'</code><code>;</code>

mymysql與go-mysql-driver性能比較首先是性能測試下面比較兩邊的profilemymysql和go-mysql-driver的測試總結

已經将gomysqldriver和mymysql的代碼放到github上了,有興趣的去裡面看看。

<a href="https://github.com/jianfengye/myworks/tree/master/gomysqltest">https://github.com/jianfengye/myworks/tree/master/gomysqltest</a>

代碼裡面注意的幾點就是我們測試了get,insert,update三個操作,并且insert的時候不指定主鍵,讓其自增,innodb的表,這樣讓mysql處理插入操作盡可能快。

mymysql的表現:

mymysql與go-mysql-driver性能比較首先是性能測試下面比較兩邊的profilemymysql和go-mysql-driver的測試總結

go-mysql-driver的表現:

mymysql與go-mysql-driver性能比較首先是性能測試下面比較兩邊的profilemymysql和go-mysql-driver的測試總結

benchmark的測試用例名   benchtime内調用了多少次  每次調用耗時(納秒)  每次調用耗記憶體  每次調用配置設定記憶體次數

比如:

mymysql 的benchmark_getadmin在1s内一共調用了2000次,每次調用使用了974622納秒,使用記憶體大小為13444byte,配置設定記憶體的alloc調用了220次

可以看出,go-mysql-driver的每個指令運作的時間是比mymysql多,但是記憶體是使用的情況卻比mymysql少。

猜測原因由于go-mysql-driver是使用預設的database/sql和database/sql/driver接口,由于接口是官方提供的,估計耗時多在方法比對上,調用記憶體方面由于是官方的database/sql來進行連接配接等配置設定,寫的會比mymysql寫的好一些。

go test -bench=".*" -c

go test -bench=".*" -cpuprofile="cpu.prof" -memprofile="mem.prof" -blockprofile="block.prof" -memprofilerate=1 -blockprofilerate=1

go tool pprof mymysql.test cpu.prof

我這裡已經将它們都生成好了并命名為諸如mymysql_cpu.svg放在github上,你也可以直接去下載下傳看

先要明白幾個名詞

sample就是“取樣”。pprof是基于取樣調查的,比如我每納秒取樣一次,收集這個時候程式的運作函數棧,知道現在是運作在那個函數中,然後把這些資訊放在pprof檔案中提供分析。

node就是函數調用資訊,哪個函數中被調用了,調用了多少次

mymysql與go-mysql-driver性能比較首先是性能測試下面比較兩邊的profilemymysql和go-mysql-driver的測試總結

本方法占用sample次數(占所有sample的總數)

本方法的下行方法調用次數(占所有sample的比例)

“本方法占用sample的次數”就是除了調用下行的方法之外的其他代碼占用的方法數,當然是越小越好,越小說明了除了下行的方法之外的代碼幾乎不占用cpu時間。node的大小和這個值是正相關的

“下行方法調用次數”就是下行方法的調用中占用了多少個sample。

如果上面兩個值相等,那麼“下行方法調用次數”就會被被忽略。這個一般隻出現在edges中。

比如sweepspan就是下行方法占用37個sample,本身隻占用了1個sample。

edges就是終結點

mymysql與go-mysql-driver性能比較首先是性能測試下面比較兩邊的profilemymysql和go-mysql-driver的測試總結

runtime.mcmp就是自身是終結點,沒有下行方法,是以下行和本方法占用的sample相等。

mymysql與go-mysql-driver性能比較首先是性能測試下面比較兩邊的profilemymysql和go-mysql-driver的測試總結

mymysql.test是可執行檔案名

total samples:總的統計sample(打點數)

focusing on:關注的sample。為什麼有關注sample這麼一說呢,并不是說所有的node和edges都是有用的資訊,有的不重要的node和edges是會被忽略的。focusing on samples就是除了這些不重要的node和edges之外的sample。

dropped nodes:參考focusing on。被忽略的node。

dropped edges: 參考focusing on。被忽略的edges。

ps: 這裡預設的total sample是等于focusing sample的。你在pprof的時候可以使用--ignore參數來忽略掉那些不重要的node或者edges

明白了這些就知道了,看圖應該從最大的node往小的方向看,分析下占用資源多的函數在那裡,是否可以優化這個函數或者方法。

比如可以看一下

gomysqldriver_cpu.svg這個例子

它有個比較占用sample的分支是

mymysql與go-mysql-driver性能比較首先是性能測試下面比較兩邊的profilemymysql和go-mysql-driver的測試總結

它的源頭在parsedsn

看到代碼裡面去,會發現是解析dsn這步的時候使用了正則,導緻運作open的時候運作速度下降了。

是以說如果parsedsn這個函數的參數不是dsn string,而是使用map直接指定username,password等,這裡的速度就會上去了。當然這其實也是不可以的,因為database/sql/driver的open方法定義的參數就是一個string。

pprof圖将代碼流程完完全全地展現在我們面前。是以說呢我們可以做這麼幾件事情:

1 根據pprof優化代碼

2 根據pprof學習一個完全陌生的開源軟體

3 根據pprof學習go的一個程式是怎麼運作的

4 項目上線前的性能測試和壓力測試(在ab之外的有一個好的選擇了)

根據以上的比較,我還是傾向于使用go-mysql-driver。原因有幾個:

1 go-mysql-driver是實作了golang标準庫database/sql的産物。底層實作比較有保證

2 go-mysql-driver雖然每個指令的運作時間比mymysql長,但是記憶體使用少得非常明顯,這點兩方算打平。

3 go-mysql-driver實作了database/sql,如果資料庫換成其他的話,不需要更改應用邏輯的代碼。

4 go-mysql-driver實作了database/sql,這個接口的設計也是非常好的,基本和php中的pdo一樣,上手和學習成本低。