HandlerSocket client for java——MySql as NoSQL

 

轉:http://rdc.taobao.com/team/jm/archives/545

HandlerSocket是日本人 akira higuchi 寫的一個MySql的插件,通過這個插件,你可以直接跟MySql後端的存儲引擎做key-value式的交互,省去了MySql上層的SQL解釋、打開關閉表、創建查詢計劃等CPU消耗型的開銷,按照作者給出的數據可以在數據全部在內存的情況下可以達到75W的QPS查詢。具體信息可以看這篇Blog,中文介紹可以看這篇文章《HandlerSocket in action》。

這個東西爲什麼讓我很激動呢?首先性能是程序員的G點,一聽高性能你不由地激動,其次,這也解決了緩存跟數據庫的一致性問題,因爲緩存就在數據庫裏面,第三,這個東西不僅僅是NoSQL,簡單的CRUD你可以通過HandlerSocket,但是複雜的查詢你仍然可以走MySql,完全符合我們應用的場景,並且從實際測試來看,性能確實非常優秀。但是呢,這個東西的代價也少不了,例如沒有權限檢查(未來可能添加);不能啓用MySql的查詢緩存,否則會導致數據的不一致;協議設計也不合理,使用\t做分隔符,使用\n做換行符,那麼你插入或者更新的字段數據就不能含有這些字符,否則行爲將不如預期。

HandlerSocket有一個日本人的java客戶端實現,我去嘗試了下,結果發現這玩意完全不具實用性,封裝的層次非常原始。因此我自己寫了個新的客戶端,這就是本文要介紹的HandlerSocket Client for Java,簡稱hs4j,項目放在了googlecode,代碼的網絡層複用xmemcached,重新實現了協議和上層接口,目前的狀態完全可用,也希望有需要的朋友參與測試。

項目地址:http://code.google.com/p/hs4j/

HS4J的使用很簡單,所有的操作都通過HSClient這個接口進行,如我們創建一個客戶端對象:

 

Java代碼 複製代碼
  1. import com.google.code.hs4j.HSClient;   
  2. import com.google.code.hs4j.impl.HSClientImpl;   
  1.     
  2.    HSClient hsClient = new HSClientImpl(new InetSocketAddress(9999));  
import com.google.code.hs4j.HSClient;
import com.google.code.hs4j.impl.HSClientImpl;
 
   HSClient hsClient = new HSClientImpl(new InetSocketAddress(9999));

 假設HandlerSocket運行在本地的9999端口,默認的9998是隻讀的,9999纔是允許讀和寫。HSClient是線程安全的。

 

在執行操作前需要先open index:

 

Java代碼 複製代碼
  1. import com.google.code.hs4j.IndexSession;   
  2.     
  3.       IndexSession session = hsClient.openIndexSession(db, table,   
  4.                                 "PRIMARY", columns);  
import com.google.code.hs4j.IndexSession;
 
      IndexSession session = hsClient.openIndexSession(db, table,
                                "PRIMARY", columns);

 其中db是數據庫名,table是表名,”PRIMARY”表示使用主鍵索引,columns是一個字符串數組代表你要查詢的字段名稱。這裏沒有指定 indexid,默認會產生一個indexid,你也可以指定indexid,返回表示一次open-index會話對象,IndexSession同樣是線程安全的。

 

Java代碼 複製代碼
  1. IndexSession session = hsClient.openIndexSession(indexid,db, table,   
  2.                                 "PRIMARY", columns);  
IndexSession session = hsClient.openIndexSession(indexid,db, table,
                                "PRIMARY", columns);

 查詢操作通過find方法:

 

Java代碼 複製代碼
  1. import java.sql.ResultSet;   
  2.     
  3.                 final String[] keys = { "dennis""[email protected]" };   
  4.                 ResultSet rs = session.find(keys);   
  5.                 while(rs.next()){   
  6.                    String name=rs.getString(1);   
  7.                    String mail=rs.getString(2);   
  8.                 }  
import java.sql.ResultSet;
 
                final String[] keys = { "dennis", "[email protected]" };
                ResultSet rs = session.find(keys);
                while(rs.next()){
                   String name=rs.getString(1);
                   String mail=rs.getString(2);
                }

 find返回的是java.sql.ResultSet,你完全可以像使用jdbc那樣去操作結果集。當然我的簡單實現並不符合JDBC規範,只實現了最常見的一些方法,如getStrng、getLong等。find(keys)方法默認使用的op是”=”。其他重載方法可以設置其他類型的op,統一封裝爲枚舉類型FindOperator。

更新操作:

 

Java代碼 複製代碼
  1. import com.google.code.hs4j.FindOperator;   
  2.     
  3.    int result=session.update(keys, new String[] { "1""dennis",   
  1.                                 "[email protected]""109" }, FindOperator.EQ);  
import com.google.code.hs4j.FindOperator;
 
   int result=session.update(keys, new String[] { "1", "dennis",
                                "[email protected]", "109" }, FindOperator.EQ);

 keys表示索引的字段列表對應的值數組,通過FindOperator.EQ比較這些值和索引,第二個參數values表示要更新的字段值,這些值跟你在open-index的時候傳入的columns一一對應,最後返回作用的記錄數。

刪除操作:

 

Java代碼 複製代碼
  1. int result= session.delete(new String[] { "dennis" },   
  2.                              FindOperator.EQ)  
int result= session.delete(new String[] { "dennis" },
                             FindOperator.EQ)

 HS4J同樣支持連接池,可以在構建客戶端的時候傳入連接池大小:

 

Java代碼 複製代碼
  1. //100-connections pool   
  2.  HSClient hsClient = new HSClientImpl(new InetSocketAddress(9999),100);  
//100-connections pool
 HSClient hsClient = new HSClientImpl(new InetSocketAddress(9999),100);

 在open index的時候,會在連接池裏所有的連接上都open。並且在連接因爲意外情況(如網絡錯誤)斷開的時候,HS4J會自動重連,並在重連成功的情況下自動發送已經open的index,保證應用的操作不受重連影響。

發佈了46 篇原創文章 · 獲贊 4 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章