阿里巴巴開源項目 Druid 負責人溫少訪談

擋住去路的,每每不是大樹,而是小藤!html

阿里巴巴開源項目 Druid 負責人溫少訪談

本文是由轉載而來.git

 

Druid是阿里巴巴開源平臺上的一個項目,整個項目由數據庫鏈接池、插件框架和 SQL解析 器組成。該項目主要是爲了擴展JDBC的一些限制,可讓程序員實現一些特殊的需求,好比向密鑰服務請求憑證、統計SQL信息、SQL性能收集、SQL注 入檢查、SQL翻譯等,程序員能夠經過定製來實現本身須要的功能。
 程序員

該項目在阿里巴巴內部獲得了普遍的部署,在外部也有大量的用戶羣。爲了使你們更好地瞭解和使用Druid,咱們採訪了Druid項目的主要負責人——溫少(博客)。github

 

問:溫少是ITeye的名人了,爲了照顧新會員,先來個自我介紹吧! sql


溫少:我2001年畢業於深圳大學,畢業後到金蝶軟件研發中心工做9年,工做內容包括工做流引擎、多數據庫支持引擎、短信網網關等。

2010年3月加入阿里巴巴至今,主要的工做是設計和實現阿里巴巴應用監控系統Dragoon,Druid和Fastjson都是監控系統實現的副產品。數據庫

 

問:Druid是什麼?有什麼做用? apache

 

溫少:Druid首先是一個數據庫鏈接池,但它不只僅是一個數據庫鏈接池,它還包含一個ProxyDriver,一系列內置的JDBC組件庫,一個SQL Parser。json

 

問:Druid的項目背景?目前的項目團隊狀況?開源目的? 緩存


溫少:2010年開始,我負責設計一個叫作Dragoon的監控系統,須要一些 監控組件,監控應用程序的運行狀況,包括Web URI、Spring、JDBC等。爲了監控SQL執行狀況,我作了一個Filter-Chain模式的ProxyDriver,缺省提供 StatFilter。當時我還作了一個SQL Parser。老闆說,不如咱們來一個更大的計劃,把鏈接池、SQL Parser、Proxy Driver合起來作一個項目,命名爲Druid,因而Druid就誕生了。

2011年2月春節期間,我完成了鏈接池(DruidDataSource)的第一個版本,4月開始在生產環境測試,2012年第一季度開始大規模實施。

提交過代碼的開發者有5我的,主要代碼是我維護,有一人專門負責內部實施。

經過開源,但願有更多使用場景,更多的反饋,更多人蔘與其中,共同打造最好的數據庫鏈接池。服務器

 

問:Druid支持哪些數據庫?


溫少:Druid支持全部JDBC兼容的數據庫,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等等。

Druid針對Oracle和MySql作了特別優化,好比Oracle的PS Cache內存佔用優化,MySql的ping檢測優化。

 

問:Druid是如何擴展JDBC的?


溫少:Druid在DruidDataSourc和ProxyDriver上提供了Filter-Chain模式的擴展API,相似Serlvet的Filter,配置Filter攔截JDBC的方法調用。

 

問:爲何說Druid是「最好的數據庫鏈接池」?體如今哪些方面?這是如何實現的?


溫少:阿里巴巴是一個重度使用關係數據庫的公司,咱們在生產環境中大量的使用Druid,經過長期在極高負載的生產環境中實際使用、修改和完善,讓Druid逐步發展成最好的數據庫鏈接池。Druid在監控、可擴展性、穩定性和性能方面都有明顯的優點。

首先,強大的監控特性,經過Druid提供的監控功能,能夠清楚知道鏈接池和SQL的工做狀況。
 

  •  監控SQL的執行時間、ResultSet持有時間、返回行數、更新行數、錯誤次數、錯誤堆棧信息。
  •  SQL執行的耗時區間 分佈。什麼是耗時區間分佈呢?好比說,某個SQL執行了1000次,其中0~1毫秒區間50次,1~10毫秒800次,10~100毫秒100 次,100~1000毫秒30次,1~10秒15次,10秒以上5次。經過耗時區間分佈,可以很是清楚知道SQL的執行耗時狀況。
  •  監控鏈接池的物理鏈接建立和銷燬次數、邏輯鏈接的申請和關閉次數、非空等待次數、PSCache命中率等

 



其次,方便擴展。Druid提供了Filter-Chain模式的擴展API,能夠本身編寫Filter攔截JDBC中的任何方法,能夠在上面作任何事情,好比說性能監控、SQL審計、用戶名密碼加密、日誌等等。
 

  • Druid內置提供了用於監控的StatFilter、日誌輸出的Log系列Filter、防護SQL注入攻擊的WallFilter。
  • 阿里巴巴內部實現了用於數據庫密碼加密的CirceFilter,以及和Web、Spring關聯監控的DragoonStatFilter。

 


第三,Druid集合了開源和商業數據庫鏈接池的優秀特性,並結合阿里巴巴大規模苛刻生產環境的使用經驗進行優化。
 

  • ExceptionSorter。當一個鏈接產生不可恢復的異常時,例如Oracle error_code_28 session has been killed,必須馬上從鏈接池中逐出,不然會產生大量錯誤。目前只有Druid和JBoss DataSource實現了ExceptionSorter。
  •  PSCache內存佔用優化對於支持遊標的數據庫(Oracle、 SQL Server、DB2等,不包括MySql),PSCache能夠大幅度提高SQL執行性能。一個PreparedStatement對應服務器一個遊 標,若是PreparedStatement被緩存起來重複執行,PreparedStatement沒有被關閉,服務器端的遊標就不會被關閉,性能提升 很是顯著。在相似「SELECT * FROM T WHERE ID = ?」這樣的場景,性能多是一個數量級的提高。但在Oracle JDBC Driver中,其餘的數據庫鏈接池(DBCP、JBossDataSource)會佔用內存過多,極端狀況可能大於1G。Druid調用 OracleDriver提供管理PSCache內部API。
  •  LRU是一個性能關鍵指標,特別Oracle,每一個 Connection對應數據庫端的一個進程,若是數據庫鏈接池聽從LRU,有助於數據庫服務器優化,這是重要的指標。Druid、DBCP、 Proxool、JBoss是遵照LRU的。BoneCP、C3P0則不是。BoneCP在mock環境下性能可能還好,但在真實環境中則就很差了。


問:Druid的性能如何?可否給出一些測試對比數據? 


溫少:性能不是Druid的設計目標,可是測試數據代表,Druid性能比DBCP、C3P0、Proxool、JBoss都好。

這裏有一些測試數據:http://code.alibabatech.com/wiki/pages/viewpage.action?pageId=2916539


問:談談Druid的SQL解析功能?效率如何?


溫少:Druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,這是一個手寫的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象語法樹很方便。

簡單SQL語句用時10微秒之內,複雜SQL用時30微秒。

經過Druid提供的SQL Parser能夠在JDBC層攔截SQL作相應處理,好比說分庫分表、審計等。Druid防護SQL注入攻擊的WallFilter就是經過Druid的SQL Parser分析語義實現的。


問:Druid的擴展性如何? 


溫少:Druid提供Filter-Chain模式的插件框架,經過編寫Filter配置到DruidDataSource中就能夠攔截JDBC的各類API,從而實現擴展。Druid提供了一系列內置Filter。

 

問:在SQL注入防護方面,Druid的優點是什麼?實現原理是什麼?


溫少:Druid的優點是在JDBC最低層進行攔截作判斷,不會遺漏。

Druid實現了Oracle、MySql、Postgresql、SQL-92的Parser,基於SQL語法分析實現,理解其中的SQL語義,智能、準確、誤報率低。

具體細節參考這裏:http://code.alibabatech.com/wiki/display/Druid/WallFilter


問:目前Druid的應用(部署)狀況?


溫少:Druid是阿里巴巴監控系統Dragoon的副產品,從Dragoon監控系統的數據來看,在阿里巴巴已經部署了600多個應用。在阿里巴巴外部也有不少Druid的用戶,外部用戶沒有正式統計數據,但常常有反饋。


問:我想將其中的某個模塊(好比監控模塊)用到其餘鏈接池,是否能夠?模塊的獨立性如何?


溫少:能夠經過DruidDriver把內置的Filter用在其餘鏈接池中。 在2011年上半年DruidDataSource不成熟的時候,咱們也是這麼作的。在其餘鏈接池中使用內置的Filter,須要修改jdbc-url, 使用DruidDriver做爲一個ProxyDriver。


問:我想在項目中使用,應該注意哪些事項?可否用於商業項目? 


溫少:Druid是一個開源項目,基於Apache 2.0協議,你能夠免費自由使用。Druid只支持JDK 6以上版本,不支持JDK 1.4和JDK 5.0。

 

問:配置是否複雜?可否給出一個典型的配置實例? 


溫少:爲了方便你們遷移,Druid的配置和DBCP是基本一致的,若是你原來 是使用DBCP,遷移是十分方便的,只須要把corg.apache.commons.dbcp.BasicDataSource修改成 om.alibaba.druid.pool.DruidDataSource就行了。

如下是一個參考配置:

 

複製代碼

 1     <bean <span style="color:#FF0000;">id</span>="dataSource" <span style="color:#FF0000;">class</span>="com.alibaba.druid.pool.DruidDataSource" <span style="color:#FF0000;">init-method</span>="init" <span style="color:#FF0000;">destroy-method</span>="close">   
 2         <property <span style="color:#FF0000;">name</span>="url" <span style="color:#FF0000;">value</span>="${jdbc_url}" />  
 3         <property <span style="color:#FF0000;">name</span>="username" <span style="color:#FF0000;">value</span>="${jdbc_user}" />  
 4         <property <span style="color:#FF0000;">name</span>="password" <span style="color:#FF0000;">value</span>="${jdbc_password}" />  
 5            
 6         <property <span style="color:#FF0000;">name</span>="filters" <span style="color:#FF0000;">value</span>="stat" />  
 7        
 8         <property <span style="color:#FF0000;">name</span>="maxActive" <span style="color:#FF0000;">value</span>="20" />  
 9         <property <span style="color:#FF0000;">name</span>="initialSize" <span style="color:#FF0000;">value</span>="1" />  
10         <property <span style="color:#FF0000;">name</span>="maxWait" <span style="color:#FF0000;">value</span>="60000" />  
11         <property <span style="color:#FF0000;">name</span>="minIdle" value="1" />  
12        
13         <property <span style="color:#FF0000;">name</span>="timeBetweenEvictionRunsMillis" <span style="color:#FF0000;">value</span>="60000" />  
14         <property <span style="color:#FF0000;">name</span>="minEvictableIdleTimeMillis" <span style="color:#FF0000;">value</span>="300000" />  
15        
16         <property <span style="color:#FF0000;">name</span>="validationQuery" <span style="color:#FF0000;">value</span>="SELECT 'x'" />  
17         <property <span style="color:#FF0000;">name</span>="testWhileIdle" <span style="color:#FF0000;">value</span>="true" />  
18         <property <span style="color:#FF0000;">name</span>="testOnBorrow" <span style="color:#FF0000;">value</span>="false" />  
19         <property <span style="color:#FF0000;">name</span>="testOnReturn" <span style="color:#FF0000;">value</span>="false" />  
20            
21         <property <span style="color:#FF0000;">name</span>="poolPreparedStatements" <span style="color:#FF0000;">value</span>="true" />  
22         <property <span style="color:#FF0000;">name</span>="maxPoolPreparedStatementPerConnectionSize" <span style="color:#FF0000;">value</span>="50" />  
23     </bean>

複製代碼

 

 

在上面的配置中,一般你須要配置url、username、password,maxActive這三項。

在DruidDataSource中,你能夠不配置DriverClass,它根據url自動識別。Druid可以自動識別20多中url,常見的JDBC Driver都包括了。

問:我目前使用其餘鏈接池(DBCP/C3P0/Proxool等),如何遷移到Druid?

 

溫少:從DBCP遷移最方便,把org.apache.commons.dbcp.BasicDataSource修改成om.alibaba.druid.pool.DruidDataSource就行了。

Druid網站上提供了Druid/DBCP/C3P0/JBoss/WebLogic的參數對照表,經過這個對照表來遷移你目前的配置。

 

問:其餘開發者如何反饋問題、提交bug?

 

溫少:Druid源碼託管在github.com上,項目地址是https://github.com/AlibabaTech/druid。 你能夠在github上提交patch和issue(包括bug和新特性)。你也能夠加入咱們的QQ羣92748305,和開發者以及其餘用戶一塊兒交流。

相關文章
相關標籤/搜索