關於nodejs下redis/mysql需不須要鏈接池的問題

鏈接池的做用主要是較少每次臨時創建鏈接所帶來的開銷。初步一看,nodejs運行單線程上,它不能同時使用多個鏈接,乍一看是不須要鏈接池的。可是這只是咱們初步下意識的感受,下面咱們詳細分析來看看這個結論對是不對。 node

 

先從簡單的redis開始。
redis服務器也是運行在單線程上的。倆都是單線程,看起來更加堅決不須要鏈接池的結論了。
從詳細的圖像來看看nodejs 鏈接 redis用鏈接池有沒有意義。
 
上圖中,nodejs共有倆鏈接,分別發送查詢請求到redis服務器上。由於redis是單線程做業,無論兩個查詢任務是由一個鏈接發來仍是多個鏈接發來,也無論任務是串行一前一後前後發送到服務器,仍是並行的同時發送到服務器上,redis都將他們一個個按順序執行,並經過當前鏈接返回給客戶端(這裏是nodejs)。nodejs接受到redis的返回後,也管不了並行不併行,都得等他nodejs的主線程空閒的時候才能來一個個處理服務器返回的數據。
 
因此單從上面結論來看,nodejs + redis只須要公用一個鏈接就能夠了,因此是不須要用鏈接池的。
 
再來看看nodejs + mysql下的狀況
 
不一樣的是mysql不是單線程服務的,也就是它能夠並行處理多個查詢請求。
如上圖所示,mysql會爲每一個鏈接建立一個單獨的線程來查詢。不一樣於redis數據基本都在內存中,由於mysql會有大量的讀取磁盤的IO操做,因此多個線程一塊兒工做會比一個個查詢要快。
 
可是nodejs又是單線程的,它能不能同時發送多個請求到mysql服務器上呢?
這裏要理解nodejs的運做,雖然nodejs是一個主線程,可是它調用的IO指令等是經過另外的線程去作的,IO指令完成後就給主線程一個小任務片,也就是回調函數了。
這裏有個很關鍵的點就是,nodejs主線程一個,可是IO線程會有多個。
所以若是用nodejs + mysql只用單個鏈接的話那麼就利用不到mysql能同時服務多個查詢的優點了。應該使用相似下圖的運做方式,nodejs 使用多個鏈接來鏈接mysql。多鏈接是須要鏈接池的,有鏈接池就避免了每次鏈接都要去建立銷燬的消耗了。
 
因此咱們第一步的感受認爲Nodejs是單線程而不是須要鏈接池是錯誤的,使用不使用鏈接池,不光看客戶端,還要看數據庫服務器等。要全盤理解整個系統的運做模式才能下結論。瞭解服務器的運做模式,有沒有阻塞操做,是不是多線程等。我想redis設計成單線程主要緣由在於它的數據基本都在內存中,查詢數據過程總不會產生阻塞過程,cpu也不會處於空閒狀態。
 

全局鏈接斷開重連問題

到這裏還沒完。綜上面的分析,nodejs + mysql用線程池是沒什麼問題的。nodejs + redis只用單個鏈接就夠。不過也仍是有人建議須要鏈接池。爲了說明問題得從代碼着手。咱們使用node-redis這個包來作例子。
 
例如新建了一個db.js
var redis = require("redis"), client = redis.createClient(6379, "127.0.0.1"); module.exports = client;

上面的鏈接會在程序啓動載入完後就鏈接上了。使用它的時候引入它就可使用全局惟一的鏈接。 mysql

複製代碼
var db = require("db.js"); exports.add = function(req, res, next) { db.get("keyName", function() { res.send("ok");  }); }
複製代碼
這裏因而有這樣的問題存在。
但此處全局只有一個鏈接,而且這個鏈接是程序啓動的時候建立的。它不一樣於鏈接池中的鏈接那樣運行時候動態建立。若是某個時候惟一的鏈接斷掉了,程序又不會動態去建立鏈接,豈不是須要從新啓動服務器才行。
 
看是來挺可怕,但好在這個問題是不存在的。由於redis的客戶端會自動從新鏈接,因此不須要從新啓動服務器。
可是由於鏈接斷開那一小段時間,應用服務器不能正常對外服務,可是鏈接自動重連是須要必定的時間間隔的。例如一秒以後,因此這一秒以內系統是處在不能服務狀態。
 
也正是基於上面這樣的緣由,因而就有鏈接redis使用鏈接池的作法。若是使用鏈接池來管理,當鏈接不可用的時候當即手動去建立新鏈接。和自動重連相比,一個是手動當即重連,一個是等到必定間隔重連。相對來講手動重連的時間更短,也就是說系統那1秒中不能服務的狀態或許能夠縮短成0.5秒。因而就有了使用鏈接池管理redis鏈接的作法。嚴格來講這個不能算是鏈接池,而是一個鏈接管理模塊。 
 
到這裏最後的結論nodejs + mysql使用鏈接池更好, nodejs + redis可使用也能夠不用。
相關文章
相關標籤/搜索