知乎在Tornado開發中的Database Driver是什麼?

我了解到知乎是用Tornado做得開發,資料庫不確定是不是MySQL,如果是MySQL,Python目前現有的幾個MySQL Driver比如mysql-connector-python和MySQL-python,我所知得都無法和Tornado IOLoop結合工作,請問在知乎的開發中是如何解決資料庫查詢這塊的阻塞問題的?


知乎在早期時,基本沒利用到 Tornado 的非同步,大都是靠多進程來解決阻塞問題的。

實際上以知乎的訪問量,如果請求都落到 MySQL 上,它早就扛不住了,根本輪不到 web 伺服器撒嬌。

所以絕大部分的請求會落到緩存和任務隊列上,也就基本不會被 MySQL 拖慢了。

之後則是推行服務化,將對 MySQL 的訪問封裝到各個服務中。這些服務本身在執行時可以阻塞,但 Tornado 可以非同步調用服務。

不過我沒參與,所以不知道現在的進展是怎樣的。


的確如此,本來tornado的定位有點像nodejs,只用來扛並發,不處理特別複雜的業務。比線程模型好的地方在於新的socket進來總是能及時的accept掉,不會掛起失去響應,即便我業務處理慢也沒關係,連接來多少accept多少。並發就是這麼整起來的。

流行的mysql driver是沒有非同步非阻塞的,但是torndb是針對tornado的資料庫封裝的一個庫,貌似已經獨立出去了,沒怎麼關注,畢竟全非同步代碼寫起來比較麻煩。特別對於重業務的場景邏輯尤其複雜的時候。

嘛,自己寫輪子恐怕很幸苦,我有看過mysqldb的connection底層socket是用c語言寫的,貌似要納入ioloop管理體系也很麻煩,所以如果要自己來搞,可用純socket的方式,設置非阻塞,丟到ioloop裡面,然後按照mysql白皮書去解析數據流(也可能有庫可以利用解析)。能把這個輪子寫出來的人估計也是牛逼的不行。

還有另一種思路,對於阻塞io多線程是最好的並發模型,利用多線程去接管tornado的請求,讓tornado這一層只負責解析http文本協議,不處理具體的業務。

1.交給線程去處理(tornado+threadpool改造計劃GitHub - nikoloss/iceworld: tonado的multi-thread 多線程封裝)

2.直接交出去給請求隊列request queue,由隊列把請求分發給各個服務,各個服務處理完畢之後再把response彙報給消息隊列,tornado再去隊列中拿response回寫socket。這種方式適合分散式場景(GitHub - nikoloss/cellnest: 自治restful api service集群)


pymysql的作者在github上開源了一個基於torbado非同步的開源庫,符合體主 與 tornado ioloop結合工作的要求……

地址

https://github.com/PyMySQL/Tornado-MySQL

github上也有其他非同步mysql 庫可以使用

不清楚知乎用的什麼,可能是自己寫得輪子吧


推薦閱讀:

tornado 下劃線括弧是什麼意思?
tornado的AsyncHTTPClient和requests庫為什麼不關閉連接?
如何評價知乎開始將核心業務向 Go 技術棧遷移?
如何理解Tornado中的協程模塊(gen.coroutine)?
知乎為什麼要選擇用Tornado做為web開發框架,非同步非阻塞模式在此起到了作用?

TAG:知乎 | Python | Tornado | 非阻塞 |