openresty mysql 連接池
這兩天壓測公司的一個小項目,感覺併發能力很差,想給做一下提升。最要是優化數據庫的操作。這個小項目的架構爲 前端LVS做負載 + openresty-lua做業務處理 + mysql做數據保存及查詢等,其他組件就暫時不一一羅列了。
壓測工具
apache 自帶的ab打量工具。
安裝方法:yum -y install httpd-tools
測試平臺
linux 平臺
openresty版本
openresty/1.13.6.1
主要考慮從如下幾個點進行提升
1.數據庫連接池
2.針對數據庫的打開句柄進行全局共享
3.針對常用數據使用共享內存
4.在mysql之上,搭建一層內存數據庫
1 數據庫連接池
查看了一下openresty.org官網及https://github.com/openresty/lua-nginx-module#tcpsockconnect中針對pool的介紹,發現pool_size及backlog等特性還沒有引入到openresty現有版本中,而且查看了最新的版本,也沒有包含最新的ngx-lua模塊。
這就很犯難了,後來看到https://github.com/openresty/lua-nginx-module#tcpsocksetkeepalive 可以使用長連接的功能,在每個nginx worker中創建一個連接池,nginx配置:lua_socket_pool_size 2048; 在lua調用mysql時,每次使用完調用設置長連接的set_keepalive(db, 60000)。
1 結果
在使用ab打量併發效果有大概3倍左右的提升
2.針對數據庫的打開句柄進行全局共享
主要的思路是採用lua中的表來保存已經打開的句柄。在init_by_lua_file階段時,使用setmetatable({db = nil, valid = false}, mt)進行數據保存,此時保存的db都還是nil。
在每次使用的時候,優先判斷self.db的值是否存在,當然你可以加一點自己的判斷db有效性的邏輯,比如超時,是否可用等標誌位。如果不可用在去進行和mysql建聯,將建聯後的db保存到self.db=db。
2 結果
該全局表中不能保存句柄類的數據,因爲nginx每次請求結束後,會將該請求上的ctx全部釋放掉,及時你保存了db也不能使用。但是該方法可以用於靜態數據的保存
3.針對常用數據使用共享內存
考慮到將比較常用的數據放入到nginx的共享內存中,使用的時候優先從共享內存中獲取,如果涉及到json格式的轉換,可以考慮將方法2中的table機制在共享內存之上在加一層。
結果
考慮到如果這樣修改,對目前現有架構改動較大,人力、時間成本不好考慮,可以後期在做定製優化
4.在mysql之上,搭建一層內存數據庫
這個想法還沒有好的驗證方法,主要是不想大改現有的代碼。 各位大神有什麼好的意見麼