莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          HandlerSocket client for java——MySql as NoSQL

          Posted on 2010-11-30 13:51 dennis 閱讀(9023) 評(píng)論(4)  編輯  收藏 所屬分類: javamy open-source

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

              這個(gè)東西為什么讓我很激動(dòng)呢?首先性能是程序員的G點(diǎn),一聽高性能你不由地激動(dòng),其次,這也解決了緩存跟數(shù)據(jù)庫的一致性問題,因?yàn)榫彺婢驮跀?shù)據(jù)庫里面,第三,這個(gè)東西不僅僅是NoSQL,簡單的CRUD你可以通過HandlerSocket,但是復(fù)雜的查詢你仍然可以走M(jìn)ySql,完全符合我們應(yīng)用的場景,并且從實(shí)際測試來看,性能確實(shí)非常優(yōu)秀。但是呢,這個(gè)東西的代價(jià)也少不了,例如沒有權(quán)限檢查(未來可能添加);不能啟用MySql的查詢緩存,否則會(huì)導(dǎo)致數(shù)據(jù)的不一致;協(xié)議設(shè)計(jì)也不合理,使用\t做分隔符,使用\n做換行符,那么你插入或者更新的字段數(shù)據(jù)就不能含有這些字符,否則行為將不如預(yù)期。

             HandlerSocket有一個(gè)日本人的java客戶端實(shí)現(xiàn),我去嘗試了下,結(jié)果發(fā)現(xiàn)這玩意完全不具實(shí)用性,封裝的層次非常原始。因此我自己寫了個(gè)新的客戶端,這就是本文要介紹的HandlerSocket Client for Java,簡稱hs4j,項(xiàng)目放在了googlecode,代碼的網(wǎng)絡(luò)層復(fù)用xmemcached,重新實(shí)現(xiàn)了協(xié)議和上層接口,目前的狀態(tài)完全可用,也希望有需要的朋友參與測試。

             項(xiàng)目地址:http://code.google.com/p/hs4j/

              HS4J的使用很簡單,所有的操作都通過HSClient這個(gè)接口進(jìn)行,如我們創(chuàng)建一個(gè)客戶端對(duì)象:

          import com.google.code.hs4j.HSClient;
          import com.google.code.hs4j.impl.HSClientImpl;

             HSClient hsClient 
          = new HSClientImpl(new InetSocketAddress(9999));

             假設(shè)HandlerSocket運(yùn)行在本地的9999端口,默認(rèn)的9998是只讀的,9999才是允許讀和寫。HSClient是線程安全的。

             在執(zhí)行操作前需要先open index:
          import com.google.code.hs4j.IndexSession;

                IndexSession session 
          = hsClient.openIndexSession(db, table,
                                          
          "PRIMARY", columns);

             其中db是數(shù)據(jù)庫名,table是表名,"PRIMARY"表示使用主鍵索引,columns是一個(gè)字符串?dāng)?shù)組代表你要查詢的字段名稱。這里沒有指定indexid,默認(rèn)會(huì)產(chǎn)生一個(gè)indexid,你也可以指定indexid,返回表示一次open-index會(huì)話對(duì)象,IndexSession同樣是線程安全的。
          IndexSession session = hsClient.openIndexSession(indexid,db, table,
                                          
          "PRIMARY", columns);

             查詢操作通過find方法:
          import java.sql.ResultSet;

                          
          final String[] keys = { "dennis""killme2008@gmail.com" };
                          ResultSet rs 
          = session.find(keys);
                          
          while(rs.next()){
                             String name
          =rs.getString(1);
                             String mail
          =rs.getString(2);
                          }

             find返回的是java.sql.ResultSet,你完全可以像使用jdbc那樣去操作結(jié)果集。當(dāng)然我的簡單實(shí)現(xiàn)并不符合JDBC規(guī)范,只實(shí)現(xiàn)了最常見的一些方法,如getStrng、getLong等。find(keys)方法默認(rèn)使用的op是"="。其他重載方法可以設(shè)置其他類型的op,統(tǒng)一封裝為枚舉類型FindOperator。

             更新操作:
          import com.google.code.hs4j.FindOperator;

             
          int result=session.update(keys, new String[] { "1""dennis",
                                          
          "test@163.com""109" }, FindOperator.EQ);

             keys表示索引的字段列表對(duì)應(yīng)的值數(shù)組,通過FindOperator.EQ比較這些值和索引,第二個(gè)參數(shù)values表示要更新的字段值,這些值跟你在open-index的時(shí)候傳入的columns一一對(duì)應(yīng),最后返回作用的記錄數(shù)。

              刪除操作:
             int result= session.delete(new String[] { "dennis" },
                                          FindOperator.EQ)

              HS4J同樣支持連接池,可以在構(gòu)建客戶端的時(shí)候傳入連接池大小:
            //100-connections pool
             HSClient hsClient = new HSClientImpl(new InetSocketAddress(9999),100);

             在open index的時(shí)候,會(huì)在連接池里所有的連接上都o(jì)pen。并且在連接因?yàn)橐馔馇闆r(如網(wǎng)絡(luò)錯(cuò)誤)斷開的時(shí)候,HS4J會(huì)自動(dòng)重連,并在重連成功的情況下自動(dòng)發(fā)送已經(jīng)open的index,保證應(yīng)用的操作不受重連影響。

              因?yàn)镠S4J是我在兩天內(nèi)寫就的一個(gè)東西,可能還有不少隱藏的bug,并且HandlerSocket本身也是個(gè)新東西,如果有什么問題或者改進(jìn)建議,隨時(shí)歡迎告訴我,多謝。


            
            


          評(píng)論

          # re: HandlerSocket client for java——MySql as NoSQL  回復(fù)  更多評(píng)論   

          2011-01-04 14:48 by preandpre
          你好,我在google project上沒看到遠(yuǎn)嗎,能發(fā)我一份嗎preandpre@sina.com

          # re: HandlerSocket client for java——MySql as NoSQL  回復(fù)  更多評(píng)論   

          2011-01-12 22:53 by dennis
          @preandpre
          在svn里,請(qǐng)自己checkout

          # re: HandlerSocket client for java——MySql as NoSQL  回復(fù)  更多評(píng)論   

          2011-04-14 09:19 by guangyanhong
          嘻嘻 強(qiáng)烈建議支持JDBC 你這樣寫起代碼來太繁瑣 不實(shí)用(只是代碼層面的說,其他還沒有研究過)

          # re: HandlerSocket client for java——MySql as NoSQL  回復(fù)  更多評(píng)論   

          2012-03-07 22:07 by fangke
          作者的舉例還是太生澀,需要嘗試半天才知道是什么,而且最主要的是那些重栽方法沒有注釋,誰知道都干嘛的?開源還是要好好搞好,至少注釋和說明不需要說很完善,但是要有而且至少能簡單的理解。
          主站蜘蛛池模板: 齐齐哈尔市| 寻甸| 香港 | 股票| 南溪县| 连云港市| 彰化县| 增城市| 余庆县| 安新县| 昆山市| 得荣县| 东乡族自治县| 惠安县| 岳阳县| 安仁县| 濮阳县| 武平县| 苍南县| 芜湖县| 哈尔滨市| 无为县| 花莲县| 兴仁县| 万年县| 宣化县| 金沙县| 光泽县| 永宁县| 思南县| 同江市| 维西| 集安市| 合水县| 绥棱县| 花垣县| 三亚市| 镇远县| 紫阳县| 临朐县| 东丰县|