SMProxy,让你的数据库操作快三倍! - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
louislivi
V2EX    PHP

SMProxy,让你的数据库操作快三倍!

  •  
  •   louislivi 2018-12-20 13:25:46 +08:00 3379 次点击
    这是一个创建于 2502 天前的主题,其中的信息可能已经有所发展或是发生改变。

    中文 | English

    SMProxy

     /$$$$$$ /$$ /$$ /$$$$$$$ /$$__ $$| $$$ /$$$| $$__ $$ | $$ \__/| $$$$ /$$$$| $$ \ $$ /$$$$$$ /$$$$$$ /$$ /$$ /$$ /$$ | $$$$$$ | $$ $$/$$ $$| $$$$$$$//$$__ $$ /$$__ $$| $$ /$$/| $$ | $$ \____ $$| $$ $$$| $$| $$____/| $$ \__/| $$ \ $$ \ $$$$/ | $$ | $$ /$$ \ $$| $$\ $ | $$| $$ | $$ | $$ | $$ >$$ $$ | $$ | $$ | $$$$$$/| $$ \/ | $$| $$ | $$ | $$$$$$/ /$$/\ $$| $$$$$$$ \______/ |__/ |__/|__/ |__/ \______/ |__/ \__/ \____ $$ /$$ | $$ | $$$$$$/ \______/ 

    github : https://github.com/louislivi/smproxy

    喜欢请 starstars

    Swoole MySQL Proxy

    一个基于 MySQL 协议,Swoole 开发的 MySQL 数据库连接池。

    原理

    将数据库连接作为对象存储在内存中,当用户需要访问数据库时,首次会建立连接,后面并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。 使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。

    同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。 也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。超出最大连接数会采用协程挂起,等到有连接关闭再恢复协程继续操作。

    特性

    • 支持读写分离
    • 支持数据库连接池,能够有效解决 PHP 带来的数据库连接瓶颈
    • 支持 SQL92 标准
    • 采用协程调度
    • 支持多个数据库连接,多个数据库,多个用户,灵活搭配
    • 遵守 MySQL 原生协议,跨语言,跨平台的通用中间件代理
    • 支持 MySQL 事物
    • 支持 HandshakeV10 协议版本
    • 完美兼容 MySQL4.1 - 8.0
    • 兼容各大框架,无缝提升性能

    设计初衷

    PHP 没有连接池,所以高并发时数据库会出现连接打满的情况,Mycat 等数据库中间件会出现部分 SQL 无法使用,例如不支持批量添加等,而且过于臃肿。 所以就自己编写了这个仅支持连接池和读写分离的轻量级中间件,使用 Swoole 协程调度 HandshakeV10 协议转发使程序更加稳定,不用像 Mycat 一样解析所有 SQL 包体,增加复杂度。

    环境

    • Swoole 2.1+ swoole_version
    • PHP 7.0+ php_version

    安装

    (推荐)直接下载最新发行版的 PHAR 文件,解压即用:

    https://github.com/louislivi/smproxy/releases/latest

    或者使用 Git 切换任意版本:

    git clone https://github.com/louislivi/smproxy.git composer install --no-dev # 如果你想贡献你的代码,请不要使用 --no-dev 参数。 

    运行

    需要给予 bin/SMProxy 执行权限。

     SMProxy [ start | stop | restart | status | reload ] [ -c | --config <configuration_path> ] SMProxy -h | --help SMProxy -v | --version 

    Options:

    • start 运行服务
    • stop 停止服务
    • restart 重启服务
    • status 查询服务运行状态
    • reload 平滑重启
    • -h --help 帮助
    • -v --version 查看当前服务版本
    • -c --config <configuration_path> 设置配置项目录

    SMProxy 连接测试

    测试 SMProxy 与测试 MySQL 完全一致,MySQL 怎么连接,SMProxy 就怎么连接。

    推荐先采用命令行测试: (请勿使用 MYSQL8.0 客户端链接测试)

    mysql -uroot -p123456 -P3366 -h127.0.0.1 

    也可采用工具连接。

    没用框架的 PHP 7.2.6

    PHP7.2.6

    没用:0.15148401260376,用了:0.040808916091919

    未使用连接池: 0.15148401260376

    ab

    使用连接池: 0.040808916091919

    ab

    ThinkPHP 5.0

    ThinkPHP5

    未使用连接池:

    ab

    使用连接池:

    ab

    Laravel 5.7

    Laravel5.7

    未使用连接池:

    ab

    使用连接池:

    ab

    MySQL 连接数

    未使用连接池:

    MySQL

    使用连接池:

    MySQL

    请以实际压测为准,根数据量,网络环境,数据库配置有关。 测试中因超出最大连接数会采用协程挂起 等到有连接关闭再恢复协程继续操作, 所有并发量与配置文件 maxConns 设置的不合适,会导致比原链接慢,主要是为了控制连接数。

    交流

    QQ 群:722124111

    配置文件

    • 配置文件位于 smproxy/conf 目录中,其中大写 ROOT 代表当前 SMProxy 根目录。

    database.json

    { "database": { "account": { "自定义用户名": { "user": "必选,数据库账户", "password": "必选,数据库密码" }, "...":"必选 1 个,自定义用户名 与 serverInfo 中的 account 相对应" }, "serverInfo": { "自定义数据库连接信息": { "write": { "host": "必选,写库地址 多个用[]表示", "port": "必选,写库端口", "timeout": "必选,写库连接超时时间(秒)", "account": "必选,自定义用户名 与 account 中的自定义用户名相对应" }, "read": { "host": "可选,读库地址 多个用[]表示", "port": "可选,读库端口", "timeout": "可选,读库连接超时时间(秒)", "account": "可选,自定义用户名 与 account 中的自定义用户名相对应" } }, "...":"必选 1 个,自定义数据库连接信息 与 databases 中的 serverInfo 相对应,read 读库可不配置" }, "databases": { "数据库名称": { "serverInfo": "必选,自定义数据库连接信息 与 serverInfo 中的自定义数据库连接信息相对应", "maxConns": "必选,该库服务最大连接数,支持计算", "maxSpareConns": "必选,该库服务最大空闲连接数,支持计算", "startConns": "可选,该库服务默认启动连接数,支持计算", "maxSpareExp": "可选,该库服务空闲连接数最大空闲时间(秒),默认为 0,支持计算", "charset": "可选,该库编码格式" }, "...":"必选 1 个,数据库名称 多个数据库配置多个" } } } 
    • maxConns,maxSpareConns,startConns
      • 推荐设置为server.json中配置的worker_num的倍数swoole_cpu_num()*N
    • 多个读库,写库
      • 目前采取的是随机获取连接,推荐将maxConnsstartConnsstartConns至少设置为max(读库,写库)*worker_num 的 1 倍以上

    server.json

    { "server": { "user": "必选,SMProxy 服务用户", "password": "必选,SMProxy 服务密码", "charset": "可选,SMProxy 编码,默认 utf8mb4", "host": "可选,SMProxy 地址,默认 0.0.0.0", "port": "可选,SMProxy 端口,默认 3366", "mode": "可选,SMProxy 运行模式,SWOOLE_PROCESS 多进程模式(默认),SWOOLE_BASE 基本模式", "sock_type": "可选,sock 类型,SWOOLE_SOCK_TCP tcp", "logs": { "open":"必选,日志开关,true 开 false 关", "config": { "system": { "log_path": "必选,SMProxy 系统日志目录", "log_file": "必选,SMProxy 系统日志文件名", "format": "必选,SMProxy 系统日志目录日期格式" }, "mysql": { "log_path": "必选,SMProxyMySQL 日志目录", "log_file": "必选,SMProxyMySQL 日志文件名", "format": "必选,SMProxyMySQL 日志目录日期格式" } } }, "swoole": { "worker_num": "必选,SWOOLE worker 进程数,支持计算", "max_coro_num": "必选,SWOOLE 协程数,推荐不低于 3000", "pid_file": "必选,worker 进程和 manager 进程 pid 目录 ", "open_tcp_nodelay": "可选,关闭 Nagle 合并算法", "daemonize": "可选,守护进程化,true 为守护进程 false 关闭守护进程", "heartbeat_check_interval": "可选,心跳检测", "heartbeat_idle_time": "可选,心跳检测最大空闲时间", "reload_async": "可选,异步重启,true 开启异步重启 false 关闭异步重启", "log_file": "可选,SWOOLE 日志目录" }, "swoole_client_setting": { "package_max_length": "可选,SWOOLE Client 最大包长,默认 16777216MySQL 最大支持包长" }, "swoole_client_sock_setting": { "sock_type": "可选,SWOOLE Client sock 类型,默认 tcp 仅支持 tcp" } } } 
    • user,password,port,host
      • SMProxy的账户|密码|端口|地址(非 Mysql 数据库账户|密码|端口|地址)
      • 可随意设置用于SMProxy登录验证
      • 例如默认配置登录为mysql -uroot -p123456 -P 3366 -h 127.0.0.1
      • SMProxy登录成功 MySQL COMMIT 会提示Server version: 5.6.0-SMProxy
    • worker_num
      • 推荐使用swoole_cpu_num()swoole_cpu_num()*N

    MySQL8.0

    • SMProxy1.2.4及以上可直接使用
    • SMProxy1.2.4以下需要做兼容处理 MySQL-8.0默认使用了安全性更强的caching_sha2_password插件,其他版本如果是从5.x升级上来的, 可以直接使用所有MySQL功能, 如是新建的MySQL, 需要进入MySQL命令行执行以下操作来兼容:
    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'password'; flush privileges; 

    将语句中的 'root'@'%' 替换成你所使用的用户, password 替换成其密码.

    如仍无法使用, 应在 my.cnf 中设置 default_authentication_plugin = mysql_native_password

    其他学习资料

    文档

    4 条回复    2019-01-01 12:40:46 +08:00
    zzfly256
        1
    zzfly256  
       2018-12-20 13:35:44 +08:00
    最近正在做这个方面的尝试,感谢楼主啦 /good
    flashrick
        2
    flashrick  
       2018-12-20 22:56:45 +08:00
    这个轮子可以 但是没这种轮子真不敢用在生产环境 自己的项目还可以玩玩
    siroleaf
        3
    siroleaf  
       2018-12-25 11:37:23 +08:00
    pdo 支持吗?
    louislivi
        4
    louislivi  
    OP
       2019-01-01 12:40:46 +08:00
    @flashrick 有很多生产环境使用的哦,这个不用担心的。
    @siroleaf 支持的哦
    关于     帮助文档     自助推广系统     博客     API   &nsp; FAQ     Solana     1052 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 23:31 PVG 07:31 LAX 16:31 JFK 19:31
    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