SMProxy,讓你的項目數據庫操做快三倍!

SMProxy

GITHUB:https://github.com/louislivi/...php

Swoole MySQL Proxy

一個基於 MySQL 協議,Swoole 開發的MySQL數據庫鏈接池。html

原理

將數據庫鏈接做爲對象存儲在內存中,當用戶須要訪問數據庫時,首次會創建鏈接,後面並不是創建一個新的鏈接,而是從鏈接池中取出一個已創建的空閒鏈接對象。
使用完畢後,用戶也並不是將鏈接關閉,而是將鏈接放回鏈接池中,以供下一個請求訪問使用。而鏈接的創建、斷開都由鏈接池自身來管理。node

同時,還能夠經過設置鏈接池的參數來控制鏈接池中的初始鏈接數、鏈接的上下限數以及每一個鏈接的最大使用次數、最大空閒時間等等。
也能夠經過其自身的管理機制來監視數據庫鏈接的數量、使用狀況等。超出最大鏈接數會採用協程掛起,等到有鏈接關閉再恢復協程繼續操做。mysql

特性

  • 支持讀寫分離
  • 支持數據庫鏈接池,可以有效解決 PHP 帶來的數據庫鏈接瓶頸
  • 支持 SQL92 標準
  • 採用協程調度
  • 支持多個數據庫鏈接,多個數據庫,多個用戶,靈活搭配
  • 遵照 MySQL 原生協議,跨語言,跨平臺的通用中間件代理
  • 支持 MySQL 事務
  • 支持 HandshakeV10 協議版本
  • 完美兼容 MySQL4.1 - 8.0
  • 兼容各大框架,無縫提高性能

設計初衷

PHP 沒有鏈接池,因此高併發時數據庫會出現鏈接打滿的狀況,Mycat 等數據庫中間件會出現部分 SQL 沒法使用,例如不支持批量添加等,並且過於臃腫。
因此就本身編寫了這個僅支持鏈接池和讀寫分離的輕量級中間件,使用 Swoole 協程調度 HandshakeV10 協議轉發使程序更加穩定,不用像 Mycat 同樣解析全部 SQL 包體,增長複雜度。git

環境

  • Swoole 2.1+ swoole_version
  • PHP 7.0+ php_version

安裝

(推薦)直接下載最新發行版的 PHAR 文件,解壓即用:github

https://github.com/louislivi/...算法

或者使用 Git 切換任意版本:sql

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:json

  • 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

其餘學習資料

相關文章
相關標籤/搜索