wang123

          2009年3月26日

          Hibernate Shard簡(jiǎn)介介紹

          HibernateShard
              多數(shù)據(jù)庫(kù)水平分區(qū)解決方案。

          1. 簡(jiǎn)介
               Hibernate 的一個(gè)擴(kuò)展,用于處理多數(shù)據(jù)庫(kù)水平分區(qū)架構(gòu)。
               由google工程師 2007年 捐獻(xiàn)給 Hibernate社區(qū)。 
               http://www.hibernate.org/414.html
               目前版本:   3.0.0 beta2, 未發(fā)GA版。
               條件:Hibernate Core 3.2, JDK 5.0

          2. 水平分區(qū)原理
               一個(gè)庫(kù)表如 Order 存在于多個(gè)數(shù)據(jù)庫(kù)實(shí)例上。按特定的分區(qū)邏輯,將該庫(kù)表的數(shù)據(jù)存儲(chǔ)在這些實(shí)例中,一條記錄的主鍵 PK,在所有實(shí)例中不得重復(fù)。
             
              水平分區(qū)在大型網(wǎng)站,大型企業(yè)應(yīng)用中經(jīng)常采用。 像www.sina.com.cn ,www.163.com  www.bt285.cn www.guihua.org
              目的出于海量數(shù)據(jù)分散存儲(chǔ),分散操作,分散查詢(xún)以便提高數(shù)據(jù)處理量和整體數(shù)據(jù)處理性能。
            
              使用:
                google工程師的設(shè)計(jì)還是非常好的,完全兼容 Hibernate本身的主要接口。
          Java代碼 復(fù)制代碼
          1. org.hibernate.Session   
          2. org.hibernate.SessionFactory    
          3.  org.hibernate.Criteria    
          4.  org.hibernate.Query   

               因此程序員開(kāi)發(fā)變化不大,甚至不需要關(guān)心后臺(tái)使用了分區(qū)數(shù)據(jù)庫(kù)。程序遷移問(wèn)題不大。而且配置上比較簡(jiǎn)明。

          3. 三種策略:
             1) ShardAccessStrategy, 查詢(xún)操作時(shí),到那個(gè)分區(qū)執(zhí)行。
                默認(rèn)提供兩個(gè)實(shí)現(xiàn):
                順序策略:SequentialShardAccessStrategy, 每個(gè)query按順序在所有分區(qū)上執(zhí)行。
                平行策略:ParallelShardAccessStrategy, 每個(gè)query以多線(xiàn)程方式并發(fā)平行的在所有分區(qū)上執(zhí)行。 此策略下,需要使用線(xiàn)程池機(jī)制滿(mǎn)足特定的性能需要,java.util.concurrent.ThreadPoolExecutor。

             2) ShardSelectionStrategy, 新增對(duì)象時(shí),存儲(chǔ)到哪個(gè)分區(qū)。
                   框架默認(rèn)提供了一個(gè)輪詢(xún)選擇策略 RoundRobinShardSelectionStrategy, 但一般不這樣使用。
                  通常采用“attribute-based sharding”機(jī)制,基于屬性分區(qū)。一般是用戶(hù)根據(jù)表自己實(shí)現(xiàn)一個(gè)基于屬性分區(qū)的策略類(lèi)ShardSelectionStrategy ,例如,以下WeatherReport基于continent屬性選擇分區(qū):
          Java代碼 復(fù)制代碼
          1.   public class WeatherReportShardSelectionStrategy implements ShardSelectionStrategy {   
          2. public ShardId selectShardIdForNewObject(Object obj) {   
          3.     if(obj instanceof WeatherReport) {   
          4.         return ((WeatherReport)obj).getContinent().getShardId();   
          5.     }   
          6.     throw new IllegalArgumentException();   
          7. }   

           

             3) ShardResolutionStrategy, 該策略用于查找單個(gè)對(duì)象時(shí),判斷它在哪個(gè)或哪幾個(gè)分區(qū)上。
                默認(rèn)使用 AllShardsShardResolutionStrategy ,可以自定義例如:
          Java代碼 復(fù)制代碼
          1. public class WeatherReportShardResolutionStrategy extends AllShardsShardResolutionStrategy {   
          2.     public WeatherReportShardResolutionStrategy(List<ShardId> shardIds) {   
          3.         super(shardIds);   
          4.     }   
          5.   
          6.     public List<ShardId> selectShardIdsFromShardResolutionStrategyData(   
          7.             ShardResolutionStrategyData srsd) {   
          8.         if(srsd.getEntityName().equals(WeatherReport.class.getName())) {   
          9.             return Continent.getContinentByReportId(srsd.getId()).getShardId();   
          10.         }   
          11.         return super.selectShardIdsFromShardResolutionStrategyData(srsd);   
          12.     }   
          13. }  



          4. 水平分區(qū)下的查詢(xún)

             對(duì)于簡(jiǎn)單查詢(xún) HibernateShard 可以滿(mǎn)足。

             水平分區(qū)下多庫(kù)查詢(xún)是一個(gè)挑戰(zhàn)。主要存在于以下三種操作:
             1) distinct
                   因?yàn)樾枰闅v所有shard分區(qū),并進(jìn)行合并判斷重復(fù)記錄。
             2) order by
                   類(lèi)似 1)
             3) aggregation
                   count,sim,avg等聚合操作先分散到分區(qū)執(zhí)行,再進(jìn)行匯總。
                   是不是有點(diǎn)類(lèi)似于 MapReduce ? 呵呵。
            
             目前 HibernateShard 不支持 1), 2), 對(duì) 3) 部分支持

              HibernateShard 目前通過(guò) Criteria 接口的實(shí)現(xiàn)對(duì) 聚合提供了較好的支持, 因?yàn)?Criteria 以API接口指定了 Projection 操作,邏輯相對(duì)簡(jiǎn)單。

              而HQL,原生 SQL 還不支持此類(lèi)操作。

              
          5. 再分區(qū)和虛擬分區(qū)
                當(dāng)數(shù)據(jù)庫(kù)規(guī)模增大,需要調(diào)整分區(qū)邏輯和數(shù)據(jù)存儲(chǔ)時(shí), 需要再分區(qū)。
                兩種方式: 1)數(shù)據(jù)庫(kù)數(shù)據(jù)遷移其他分區(qū); 2) 改變記錄和分區(qū)映射關(guān)系。這兩種方式都比較麻煩。尤其“改變記錄和分區(qū)映射關(guān)系”,需要調(diào)整 ShardResolutionStrategy。

               HibernateShard 提供了一種虛擬分區(qū)層。當(dāng)需要調(diào)整分區(qū)策略時(shí),只需要調(diào)整虛擬分區(qū)和物理分區(qū)映射關(guān)系即可。以下是使用虛擬分區(qū)時(shí)的配置創(chuàng)建過(guò)程:

          Java代碼 復(fù)制代碼
          1.     
          2.   Map<Integer, Integer> virtualShardMap = new HashMap<Integer, Integer>();   
          3. virtualShardMap.put(00);   
          4. virtualShardMap.put(10);   
          5. virtualShardMap.put(21);   
          6. virtualShardMap.put(31);   
          7. ShardedConfiguration shardedConfig =   
          8.     new ShardedConfiguration(   
          9.         prototypeConfiguration,   
          10.         configurations,   
          11.         strategyFactory,   
          12.         virtualShardMap);   
          13. return shardedConfig.buildShardedSessionFactory();  


          6.  局限:
              1)HibernateShard 不支持垂直分區(qū), 垂直+水平混合分區(qū)。

              2) 水平分區(qū)下 查詢(xún)功能受到一定限制,有些功能不支持。實(shí)踐中,需要在應(yīng)用層面對(duì)水平分區(qū)算法進(jìn)行更多的考慮。
              3) 不支持跨分區(qū)的 關(guān)系 操作。例如:刪除A分區(qū)上的 s 表,B分區(qū)上的關(guān)聯(lián)子表 t的記錄無(wú)法進(jìn)行參照完整性約束檢查。 (其實(shí)這個(gè)相對(duì) 跨分區(qū)查詢(xún)的挑戰(zhàn)應(yīng)該說(shuō)小的多,也許google工程師下個(gè)版本會(huì)支持,呵呵)

              4) 解析策略接口似乎和對(duì)象ID全局唯一性有些自相矛盾,
          AllShardsShardResolutionStrategy 的接口返回的是給定對(duì)象ID所在的 shard ID集合,按理應(yīng)該是明確的一個(gè) shard ID.

          參考資料:HibernateShard 參考指南。

          posted @ 2009-04-01 18:49 王| 編輯 收藏

          GPS經(jīng)緯度可以用來(lái)Java解析

          現(xiàn)在正開(kāi)發(fā)的定位模塊用到的定位設(shè)置是塞格車(chē)圣導(dǎo)航設(shè)備,發(fā)送指令返回的經(jīng)緯度需要轉(zhuǎn)換成十進(jìn)制,再到GIS系統(tǒng)獲取地理信息描述。以后需要要經(jīng)常用到這方面的知識(shí),隨筆寫(xiě)下。

           

          將經(jīng)緯度轉(zhuǎn)換成十進(jìn)制

           公式:
              Decimal Degrees = Degrees + minutes/60 + seconds/3600
            例:57°55'56.6" =57+55/60+56.6/3600=57.9323888888888
           
          如把經(jīng)緯度  (longitude,latitude) (205.395583333332,57.9323888888888)轉(zhuǎn)換據(jù)成坐標(biāo)(Degrees,minutes,seconds)(205°23'44.1",57°55'56.6")。
          步驟如下:

          1、 直接讀取"度":205

          2、(205.395583333332-205)*60=23.734999999920 得到"分":23

          3、(23.734999999920-23)*60=44.099999995200 得到"秒":44.1

           

          發(fā)送定位指令,終端返回的經(jīng)緯度信息如下:

          (ONE072457A3641.2220N11706.2569E000.000240309C0000400)

          按照協(xié)議解析

           

          獲得信息體的經(jīng)緯度是主要,其它不要管,直接用String類(lèi)的substring()方法截掉,獲取的經(jīng)緯度

          3641.2220N11706.2569E http://www.bt285.cn

          Java代碼 復(fù)制代碼
          1. package com.tdt.test;   
          2.   
          3. import com.tdt.api.gis.LocationInfo;   
          4.   
          5. /**  
          6.  * <p>Title:坐標(biāo)轉(zhuǎn)換 </p>  
          7.  *   
          8.  * <p>Description:</p>  
          9.  *   
          10.  * <p>Copyright: Copyright (c) 2009</p>  
          11.  *   
          12.  * <p>Company:</p>  
          13.  *   
          14.  * @author sunnylocus  
          15.  * @version 1.0 [2009-03-24]  
          16.  *   
          17.  */  
          18. public class LonlatConversion {   
          19.   
          20.     /**  
          21.      *   
          22.      * @param dms 坐標(biāo)  
          23.      * @param type 坐標(biāo)類(lèi)型  
          24.      * @return String 解析后的經(jīng)緯度  
          25.      */  
          26.     public static String xypase(String dms, String type) {   
          27.         if (dms == null || dms.equals("")) {   
          28.             return "0.0";   
          29.         }   
          30.         double result = 0.0D;   
          31.         String temp = "";   
          32.            
          33.         if (type.equals("E")) {//經(jīng)度   
          34.             String e1 = dms.substring(03);//截取3位數(shù)字,經(jīng)度共3位,最多180度   
          35.                                             //經(jīng)度是一倫敦為點(diǎn)作南北兩極的線(xiàn)為0度,所有往西和往東各180度    
          36.             String e2 = dms.substring(3, dms.length());//需要運(yùn)算的小數(shù)   
          37.   
          38.             result = Double.parseDouble(e1);   
          39.             result += (Double.parseDouble(e2) / 60.0D);   
          40.             temp = String.valueOf(result);   
          41.             if (temp.length() > 9) {   
          42.                 temp = e1 + temp.substring(temp.indexOf("."), 9);   
          43.             }   
          44.         } else if (type.equals("N")) {      //緯度,緯度是以赤道為基準(zhǔn),相當(dāng)于把地球分兩半,兩個(gè)半球面上的點(diǎn)和平面夾角0~90度   
          45.             String n1 = dms.substring(02);//截取2位,緯度共2位,最多90度   
          46.             String n2 = dms.substring(2, dms.length());   
          47.   
          48.             result = Double.parseDouble(n1);   
          49.             result += Double.parseDouble(n2) / 60.0D;   
          50.             temp = String.valueOf(result);   
          51.             if (temp.length() > 8) {   
          52.                 temp = n1 + temp.substring(temp.indexOf("."), 8);   
          53.             }   
          54.         }   
          55.         return temp;   
          56.     }   
          57.     public static void main(String[] args) {   
          58.         String info="(ONE072457A3641.2220N11706.2569E000.000240309C0000400)";           
          59.         info=info.substring(11,info.length()-13);   
          60.         //緯度   
          61.         String N = info.substring(0, info.indexOf("N"));   
          62.         //經(jīng)度   
          63.         String E = info.substring(info.indexOf("N")+1,info.indexOf("E"));   
          64.         //請(qǐng)求gis,獲取地理信息描述   
          65.         double x = Double.parseDouble(CoordConversion.xypase(E,"E"));   
          66.         double y = Double.parseDouble(CoordConversion.xypase(N,"N"));   
          67.         String result =LocationInfo.getLocationInfo("test", x, y); //System.out.println("徑度:"+x+","+"緯度:"+y);   
          68.         System.out.println(result);   
          69.     }   
          70. }  

          運(yùn)行結(jié)果

          在濟(jì)南市,位于輕騎路和八澗堡路附近;在環(huán)保科技園國(guó)際商務(wù)中心和濟(jì)南市區(qū)賢文莊附近。

          posted @ 2009-03-26 17:08 王| 編輯 收藏

          <2009年3月>
          22232425262728
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(3)

          隨筆檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 都兰县| 伊春市| 通许县| 措美县| 安义县| 嘉善县| 东安县| 平凉市| 郴州市| 阿尔山市| 昭通市| 侯马市| 无棣县| 濮阳县| 类乌齐县| 天全县| 黎平县| 广州市| 清镇市| 都昌县| 淅川县| 巨鹿县| 米林县| 金华市| 策勒县| 宣汉县| 象州县| 青州市| 英超| 西峡县| 佛坪县| 新沂市| 沁源县| 宁乡县| 大宁县| 舟山市| 织金县| 凤冈县| 金塔县| 普兰县| 西吉县|