MixPHP 2.2 / Beego 1.12 数据库查询性能对比 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
onanying
V2EX    PHP

MixPHP 2.2 / Beego 1.12 数据库查询性能对比

  •  4
     
  •   onanying 2020-07-25 19:41:27 +08:00 3810 次点击
    这是一个创建于 1917 天前的主题,其中的信息可能已经有所发展或是发生改变。

    昨天在 V2EX 分享了一下 PHP7.3+Swoole4.4 / Go1.13 / MixPHP2.2 / Beego1.12 性能对比 被很多朋友质疑,本不想引起争端,但一时冲动和网友打赌了 10 块钱。

    质疑的点

    本主要质疑的是:

    • 测试没有数据库查询:大家觉得加上 db 查询会很不一样,但是我认为:基准测试代表天花板,还是有一些意义的,db 查询我也认为 mix 与 beego 应该是性能趋同的,我现在还没开始测试,等下看结果。
    • 测试没有序列化:本次测试,我也加上 json 序列化。
    • ab 测试不适合高并发测试:这一点我详细列举很多举例,试图说明同样的环境下,不同的压力,强弱的数值会变,但结果是不变的,这基本属于物理规则,说服不了那我就本次采用 wrk 测试吧。

    当然测试没办法做到条件绝对一致的,但结果还是可以参考的

    环境

    硬件

    • CPU: Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz
    • CPU(s): 12
    • Mem: 15G
    • Linux version 3.10.0-957.10.1.el7.x86_64

    数据库:

    • 本机

    测试命令

    wrk -d 120 -t 4 http://127.0.0.1:*/ 

    连接池

    • 最大闲置:5
    • 最大连接:50

    线程数

    • 为了最大化公平,本次两个框架都采用 1 个线程测试

    MixPHP 2.2

    代码:为了公平,我把配置里的默认中间件都移除了,之前测试没有移除。

    <?php namespace App\Web\Controllers; use App\Common\Helpers\ResponseHelper; use Mix\Http\Message\ServerRequest; use Mix\Http\Message\Response; /** * Class IndexController * @package App\Web\Controllers * @author liu,jian <[email protected]> */ class IndexController { /** * Index * @param ServerRequest $request * @param Response $response * @return Response */ public function index(ServerRequest $request, Response $response) { /** @var Database $db */ $db = context()->get('database'); $result = $db->prepare('select * from test limit 1')->queryAll(); $cOntent= json_encode($result); return ResponseHelper::html($response, $content); } } 
    • 启动方式
    /usr/local/php-7.3.12/bin/php mix/bin/mix.php web -d 
    • 进程
    [nobody@~]$ ps -ef | grep mix.php nobody 25972 1 0 18:36 ? 00:00:00 /usr/local/php-7.3.12/bin/php mix/bin/mix.php web -d 
    • 响应内容
    [nobody@~]$ curl http://127.0.0.1:9501/ [{"id":1,"name":"3"}] 
    • 测试结果:测试了很多次,在 9936.36 ~ 10080.25 左右
    [nobody@~]$ wrk -d 120 -t 4 http://127.0.0.1:9501/ Running 2m test @ http://127.0.0.1:9501/ 4 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 806.18us 501.04us 51.95ms 97.58% Req/Sec 2.53k 245.91 5.92k 79.28% 1210639 requests in 2.00m, 218.21MB read Requests/sec: 10080.25 Transfer/sec: 1.82MB 
    • CPU 状态:稳定在 99.3~99.7% 左右。
     PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 25972 nobody 20 0 1166992 12368 4064 R 99.7 0.1 2:41.11 php 

    Beego 1.12

    代码:使用 runtime.GOMAXPROCS(1) 限制了线程数。

    package main import ( "encoding/json" "github.com/astaxie/beego" "github.com/astaxie/beego/orm" _ "github.com/go-sql-driver/mysql" _ "hello/routers" "runtime" ) type Test struct { Id int `orm:"column(id)"json:"id"` Name string `orm:"column(name)"json:"name"` } func init() { orm.RegisterModel(new(Test)) orm.RegisterDriver("mysql", orm.DRMySQL) maxIdle := 5 maxConn := 50 orm.RegisterDataBase("default", "mysql", "*****@tcp(***:3306)/test?charset=utf8&loc=Asia%2FShanghai&parseTime=true", maxIdle, maxConn) } type IndexController struct { beego.Controller } func (c *IndexController) Index() { o := orm.NewOrm(); var row []*Test o.Raw("select * from test limit 1").QueryRows(&row); js, _ := json.Marshal(row) c.Ctx.Output.Body(js) } func main() { runtime.GOMAXPROCS(1) // 限制使用线程数 beego.Router("/index", &IndexController{}, "*:Index") beego.Run() } 
    • 启动方式

    为了不让日志影响到性能,屏蔽输出。

    nohup ./gobeego_linux >> /dev/null 1>&2 & 
    • 进程
    [nobody@~]$ ps -ef| grep bee nobody 27316 1 0 18:37 ? 00:00:00 ./gobeego_linux 
    • 响应内容
    [nobody@~]$ curl http://127.0.0.1:8989/index [{"id":1,"name":"3"}] 
    • 测试结果:测试了很多次,在 16306.15 ~ 16327.19 左右
    [nobody@~]$ wrk -d 120 -t 4 http://127.0.0.1:8989/index Running 2m test @ http://127.0.0.1:8989/index 4 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 521.18us 427.56us 29.46ms 92.23% Req/Sec 4.10k 260.69 4.74k 79.96% 1959389 requests in 2.00m, 310.19MB read Requests/sec: 16327.19 Transfer/sec: 2.58MB 
    • CPU 状态:稳定在 99.7~100.3% 左右。
     PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 27316 nobody 20 0 114736 10660 5008 S 100.3 0.1 0:39.87 gobeego_linux 

    总结一下

    测试结果 mix 比 beego 数据库查询+序列化的综合性能要低 62%,beego 更加优秀,不过 mix 动态脚本语言能做到这样也是蛮可以了(我只能这样安慰自己,但也是事实),显然我打赌输了,愿赌服输。

    | 框架 | 线程数 | CPU | 数值 |
    | PHP 7.3.12 + Swoole 4.4.14 + MixPHP 2.2 | 1 | 99.3~99.7% | 9936.36 ~ 10080.25 |
    | Go 1.13.4 + Beego 1.12.1 | 1 | 99.7~100.3% | 16290.73 ~ 16327.19 |

    第 1 条附言    2020-07-25 21:00:57 +08:00

    测试结果 mix 比 beego 数据库查询+序列化的综合性能要低 38.3%,上面我写错了!

    第 2 条附言    2020-07-27 11:39:25 +08:00
    • 开启 beego prod 模式

    更换模式后 beego 性能得到了显著提升,测试结果 mix 比 beego 数据库查询+序列化的综合性能要低 48.2%

    | 框架 | 线程数 | 数值 |
    | ---- | ---- | ---- |
    | PHP 7.3.12 + Swoole 4.4.14 + MixPHP 2.2 | 1 | 9835.54 |
    | Go 1.13.4 + Beego 1.12.1 | 1 | 18993.39 |

    • 移除序列化,只测试数据库

    移除序列化后测试结果变化非常小,说明序列化在这个测试中影响很小,也就是序列化相对于 db 查询来说,对整体性能影响比我们想象的要小很多。

    | 框架 | 线程数 | 数值 |
    | ---- | ---- | ---- |
    | PHP 7.3.12 + Swoole 4.4.14 + MixPHP 2.2 | 1 | 9827.51 |
    | Go 1.13.4 + Beego 1.12.1 | 1 | 19652.80 |

    第 3 条附言    2020-07-27 11:48:48 +08:00

    V2EX 没办法修改内容,完整的测试报告在这里:

    17 条回复    2020-08-14 17:43:05 +08:00
    luozic     1
    luozic  
       2020-07-25 19:46:29 +08:00 via iPhone
    同一机器玩都没达到各自的最佳,最好搞分开的 client server
    sky101001
        2
    sky101001  
       2020-07-25 21:36:40 +08:00
    赞一个楼主的实证精神
    linxl
        3
    linxl  
       2020-07-25 22:02:51 +08:00
    为啥会有这样的差距?
    wei193
        4
    wei193  
       2020-07-25 23:18:15 +08:00 via Android
    如果没有记错,beego 还有一个运行模式,好像 prod 和 dev 性能也有蛮大的差异。不知道楼主用的是啥模式
    onanying
        5
    onanying  
    OP
       2020-07-25 23:35:43 +08:00
    @luozic 分开又会有新的问题,网络吞吐量成为瓶颈,网络的其他软件占用局域网带宽,测试的结果就更加不准确了,只能现在这样了,条件不允许。
    Q4h7388nR28s95fa
        6
    Q4h7388nR28s95fa  
       2020-07-26 02:48:08 +08:00
    为楼主点赞!
    noqwerty
        7
    noqwerty  
       2020-07-26 03:44:11 +08:00 via Android
    愿赌服输,挺好的,虽然大家都说这种框架的 benchmark 没啥意义,但是每次都忍不住看一下
    loading
        8
    loading  
       2020-07-26 05:58:27 +08:00 via Android
    赞楼主精神
    mind3x
        9
    mind3x  
       2020-07-26 14:11:26 +08:00
    你这个 benchmark 看起来 cpu 主要花在 json 序列化上,php 的 json_encode 是 C 写的,按理说不应该差这么多。

    我怀疑数据库连接池的行为或者数据库驱动有什么不同,建议拿掉 json 序列化再测一下。
    ben1024
        10
    ben1024  
       2020-07-27 09:10:33 +08:00
    可以尝试下
    控制下变量,单次只测试一点
    还有应用预热
    ben1024
        11
    ben1024  
       2020-07-27 09:11:39 +08:00
    SQL 查询还需要加个随机数,避免 SQL 缓存
    onanying
        12
    onanying  
    OP
       2020-07-27 11:40:27 +08:00
    @wei193 更换模式后 beego 性能得到了显著提升,测试结果 mix 比 beego 数据库查询+序列化的综合性能要低 48.2%
    onanying
        13
    onanying  
    OP
       2020-07-27 11:41:44 +08:00
    @mind3x 移除序列化后测试结果变化非常小,说明序列化在这个测试中影响很小,也就是序列化相对于 db 查询来说,对整体性能影响比我们想象的要小很多。我在帖子后面追加了相关测试,https://zhuanlan.zhihu.com/p/163700975 也有完整的测试细节
    onanying
        14
    onanying  
    OP
       2020-07-27 11:43:40 +08:00
    @ben1024 正式使用环境也是有 sql 缓存的,这个感觉就没必要的,主要是看框架+语言直接,大概模拟一点真实业务场景,看看差异
    mind3x
        15
    mind3x  
       2020-07-27 15:24:41 +08:00
    @onanying 所以综合你之前无数据库的 benchmark 结果,总的推论是 php 的 MySQL 驱动或者连接池性能要比 go 的差不少。
    onanying
        16
    onanying  
    OP
       2020-07-27 15:35:43 +08:00
    @mind3x 推论是对的,php 驱动是 pdo,是 c 写的,应该性能不会差,可能差距在 (基于 Swoole Channel 实现的连接池,pdo 支持协程是使用的 Hook 技术)和 (php 没有 jit,代码越多总执行时间差距越大) 这两方面
    tinzing
        17
    tinzing  
       2020-08-14 17:43:05 +08:00
    其它 PHP 框架差距呢,譬如 TP,
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2199 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 00:49 PVG 08:49 LAX 17:49 JFK 20:49
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86