ivaneeo's blog

          自由的力量,自由的生活。

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks

          #

          DBUS_SESSION_BUS_ADDRESS="tcp:host=localhost,port=732"
          posted @ 2011-02-18 15:32 ivaneeo 閱讀(1623) | 評論 (2)編輯 收藏

          這個話題來自: Nutz的issue 361

          在考慮這個issue時, 我一直傾向于使用系統變量file.encoding來改變JVM的默認編碼.

          今天,我想到, 這個系統變量,對JVM的影響到底有多大呢?
          我使用最簡單的方法看看這個變量的影響–在JDK 1.6.0_20的src.zip文件中,查找包含file.encoding字眼的文件.
          共找到4個, 分別是:
          先上重頭戲 java.nio.Charset類:

          View Code JAVA
              public static Charset defaultCharset() {
                      if (defaultCharset == null) {
                      synchronized (Charset.class) {
                      java.security.PrivilegedAction pa =
                      new GetPropertyAction("file.encoding");
                      String csn = (String)AccessController.doPrivileged(pa);
                      Charset cs = lookup(csn);
                      if (cs != null)
                      defaultCharset = cs;
                      else
                      defaultCharset = forName("UTF-8");
                      }
                      }
                      return defaultCharset;
                      }

          java.net.URLEncoder的靜態構造方法,影響到的方法 java.net.URLEncoder.encode(String)

          View Code JAVA

          com.sun.org.apache.xml.internal.serializer.Encoding的getMimeEncoding方法(209行起)

          View Code JAVA

          最后一個javax.print.DocFlavor類的靜態構造方法:

          View Code JAVA

          可以看到,系統變量file.encoding影響到
          1. Charset.defaultCharset() Java環境中最關鍵的編碼設置
          2. URLEncoder.encode(String) Web環境中最常遇到的編碼使用
          3. com.sun.org.apache.xml.internal.serializer.Encoding 影響對無編碼設置的xml文件的讀取
          4. javax.print.DocFlavor 影響打印的編碼

          故,影響還是很大的哦, 可以說是Java中編碼的一個關鍵鑰匙!

          posted @ 2011-01-31 14:28 ivaneeo 閱讀(4044) | 評論 (0)編輯 收藏

          我們大家在做J2EE項目開發的時候,都會用到Application Server,然后配置Connection Pool,Data Source,但不知道大家有沒有留意到,其實我們絕大部分的應用用的都是Apache的DBCP機制。
           
          JES,Weblogic,JBoss等等的大型App Server,其中一個好處就是提供了Admin Console,讓配置做起來就像傻瓜式的,Step By Step就可以了,下面舉個用Tomcat的應用例子,深入一點探討DBCP的配置都做了些什么。(當然得配置Server.xml了,但是其實JES和Weblogic等等的大型App Server,也是可以同樣修改Server.xml或這Domain.xml來達到同一目的的,只不過有了Admin Console,大家容易避免犯錯,但其實我覺得,要深入了解一個App Server,避免不了深入了解配置文件里面的內容)。
           
          當使用DBCP(通常我們都是用Oracle的了)時候,不知道大家有沒有遇到一個情況,當數據庫連接因為某種原因斷掉(有可能時網絡問題,導致App Server跑了一天后,第二天再跑馬上爆錯誤),再從Connection Pool中獲取連接而又不做Validate,這時候取得的Connection實際上已經是無效的了,從而導致程序一跑,馬上爆Connect Reset錯誤。
           
          其實只要你了解一下DBCP的運作機制和相關屬性的話,這個問題就很容易避免了。
           
          DBCP使用Apache的ObjectPool作為Connection Pool的實現,在構造GenericObjectPool的時候,會生成一個Inner Class Evictor,實現Runnable的接口。如果屬性_timeBetweenEvictionRunsMillis > 0,每過_timeBetweenEvictionRunsMillis毫秒后Evictor會調用evict method,檢查Object的idle time是否大于屬性_minEvictableIdleTimeMillis毫秒(如果_minEvictableIdleTimeMillis設置為<=0則忽略,使用default value 30分鐘),如果是則銷毀該Object,否則就激活并進行Validate,然后調用ensureMinIdle method檢查確保Connection Pool中的Object個數不小于屬性_minIdle。在調用returnObject method把Object放回ObjectPool時候,需要檢查該Object是否有效,然后調用PoolableObjectFactory的passivateObject method使Object處于inactive狀態,再檢查ObjectPool中的對象個數是否小于屬性_maxIdle,是則可以把該Object放回到ObjectPool,否則銷毀此Object。
           
          除此之外,還有幾個比較重要的屬性,_testOnBorrow,_testOnReturn,_testWhileIdle,這些屬性的意思是取得,返回對象,空閑時候是否進行Valiadte,檢查對象是否有效。默認都為False,只有把這些屬性設為True,再提供_validationQuery語句就可以保證DBCP始終有效了,例如,Oracle中就完全可以使用select 1 from dual來進行驗證,這里要注意的是,DBCP要求_validationQuery語句查詢的Result Set必須為非空。
           
          在Tomcat的Server.xml,我們可以看看下面的這個例子:
           
          <Resource name="lda/raw"
                        type="javax.sql.DataSource"
                         password="lda_master"
                         driverClassName="oracle.jdbc.driver.OracleDriver"
                         maxIdle="30" minIdle="2" maxWait="60000" maxActive="1000" 
                         testOnBorrow="true" testWhileIdle="true" validationQuery="select 1 from dual"
                         username="lda_master" url="jdbc:oracle:thin:@192.160.100.107:15537:lcststd"/>
           
          這樣一來,就能夠解決Connect Reset的問題了。剛才說了,其實很多App Server都會有相應的配置地方,只是大型的服務器正好提供了Admin Console,上面可以顯式的配置Connection Pool,也有明顯的屬性選擇,這里就不一一詳述了,都是眼見的功夫。

          本文出自 “jayenho” 博客,轉載請與作者聯系!

          posted @ 2011-01-29 11:30 ivaneeo 閱讀(413) | 評論 (0)編輯 收藏

          摘要: 公共安全管理的一般過程分為監測、預警、決策和處置,前兩者屬于安全事故發生前的防范,后兩者屬于事故發生后的緊急處理.公共安全事件發生的隱患越早被識別,處理就可以越及時,損失就越小. 
          關鍵詞: 物聯網

            公共安全是指多數人的生命、健康和公私財產安全,其涵蓋范圍包括自然災害,如地震、洪澇等;技術災害,如交通事故、火災、爆炸等;社會災害,如騷亂、恐怖主義襲擊等;公共衛生事件,如食品、藥品安全和突發疫情等。我國的公共安全形勢嚴峻,每年死亡人數超過20萬,傷殘人數超過200萬;每年經濟損失近9000億元,相當于GDP的3.5%,遠高于中等發達國家1%??2%左右的水平。

            公共安全重在預先感知

            公共安全管理的一般過程分為監測、預警、決策和處置,前兩者屬于安全事故發生前的防范,后兩者屬于事故發生后的緊急處理。公共安全事件發生的隱患越早被識別,處理就可以越及時,損失就越小。管理公共安全事故的重點應該在發生前,而不只是在發生之后。但目前的情況是,安全的防范技術難度大,同時也往往容易被人們所忽視。

            物聯網是安防的重要技術手段,目前公眾所說的物聯網就是帶有傳感/標識器的智能感知信息網絡系統,涵蓋了當初的物聯網、傳感網等概念,是在傳感、識別、接入網、無線通信網、互聯網、計算技術、信息處理和應用軟件、智能控制等信息集成基礎上的新發展。

            公共安全管理的關鍵是預先感知。感知的對象很多,例如地表、堤壩、道路交通、公共區域、危化品、周界、水資源、食品藥品生產環節以及疫情等容易引起公共安全事故發生的源頭、場所和環節;感知的內容包括震動、壓力、流量、圖像、聲音、光線、氣體、溫濕度、濃度、化學成分、標簽信息、生物信息等;感知的目的就是要準確獲取管理對象的異常變化。

            公共安全中需要感知的對象、內容和數量非常巨大,感知之間的關聯關系也錯綜復雜,要做到準確、及時和無遺漏,光靠人工識別基本無法做到、也不現實。物聯網的智能化應用將轉變傳統管理模式,大幅度提高公共管理水平。

            求解技術局限

            物聯網基本層次結構按照普遍的理解劃分為感知層、網絡層和應用層。感知層由傳感器、RFID和傳感網絡組成,負責數據采集;網絡層一般指三大電信公司的寬帶網、Wi-Fi、GPRS/CDMA、3G/4G等,負責數據傳輸;應用層是基于信息數據匯集之上的各類應用。

            感知層上的局限是:目前的傳感器在較為復雜的環境下,難以做到準確、快速感知;高性能傳感器的成本過高,對使用環境要求苛刻,限制了推廣;傳感器標準不統一,大家各自為政。

            網絡層比傳感層和應用層要成熟,幾大電信公司不遺余力地擴展網絡能力;三網合一的推進將進一步擴大覆蓋面、提高傳輸能力。

            應用層上,專業系統條塊分割,形成“信息孤島”,限制了應用進一步提升和發展;各專業系統之間技術體系標準不統一,存在互聯互通的技術障礙。

            另外,在管理層面,也存在條塊分割、難以形成統一指揮的局面;而且創新和產業體系不成熟,創新能力不夠,存在較多簡單模仿和貼牌,不利于形成產業持續、健康發展的局面。

            不過,目前安防行業也出現了一些新的趨勢,將會影響到整個公共安全領域。

            IP化

            安防系統的數字化及網絡的普及為IP化提供了條件;安防系統從分散的單點系統朝分布式監控、集中管理方向發展,聯網監控報警是大勢所趨,“平安城市”等項目的大規模建設也加快了聯網監控的步伐。

            IT化

            傳統IT廠商及電信運營商全面進入安防行業,安防行業面臨重大洗牌;IT行業成熟的結構化、標準化體系架構設計和理念將應用于安防領域,推動安防行業升級。

            網管化

            安防系統規模越來越大、監控范圍越來越廣、監控對象越來越多,海量存儲對系統的管理和維護提出了更高要求,需要做到電信級可管可控。

            面對這些新的趨勢,公共安全的信息系統建設需要邁上一個智能化綜合管理的階梯。

            系統的融合性

            物聯網將橫向整合各個孤立的安防系統,實現信息互通和聯動,形成立體化決策支撐體系,使決策更智能、更科學。

            平臺的開放性

            物聯網采用標準化的開放平臺,帶動整個安防產業鏈發展,形成安防行業規模化的態勢。

            應用的靈活性

            采用安防通用平臺+應用子集的頂層設計架構,在保證系統標準化、可重用的同時,滿足應用的多樣性和不同應用的個性化要求。

            系統的智能性

            智能感知通過多感知協同,在感知階段就完成信息的智能處理,濾除無效、冗余信息,保證信息獲取的真實、全面和有效;智能分析對感知信息進行分析,對數據特征進行準確地識別和判斷;智能決策通過專家系統等形成最優的決策建議;智能處置對異常情況和突發事件進行有效的處置,如結合特定業務和應用的報警聯動;智能管理系統具有智能的自動配置管理、自動診斷和告警、故障自動愈合和多種接入方式的遠程維護功能,盡量減輕人工負擔。

            政策科研雙管齊下

            正如物聯網是信息化發展的更高階段,基于物聯網的智能安防、安監系統也是公共安全行業發展的大勢所趨。

            在政策與管理層面,需要將公共安全信息科技列入國家戰略性發展規劃范圍;整合現有相關資源,引導資源投入和技術、產品創新;推進產學研結合,在有條件的地方開展示范項目建設。

            在技術層面,公共安全中的物聯網關鍵技術研究包括5大方面:

            1. 物聯網智能安防、安監通用平臺的建設,設備的接入和管理,中間件、體系結構和標準的確立。

            2. 高性能傳感器和傳感設備的研發,例如新型材料、納米材料、生物技術、仿生技術、極低功耗、MEMS。

            3. 云計算的利用,包括異構數據海量存儲和管理、智能信息處理、主動決策等。

            4. 基礎資源管理,包括萬億量級節點的標識、異構網絡融合、自治認知。

            5. 物聯網的安全,涉及物的真實性、聯的可靠性、網的健壯性。

            物聯網的發展將極大地拓寬安防、安監的范圍和內涵,未來的安防、安監將會滲透進人們生活的方方面面,成為物聯網的一個基本功能;物聯網對安防、安監行業的推動不僅體現在提升傳統安防、安監的技術上,還將對整個行業的產業格局、業務模式產生重大影響,今后新的安防、安監應用、運營模式也將會層出不窮。

          \
          圖注:物聯網智能安防共性平臺總體架構

          (責編:邱文峰)

          posted @ 2011-01-28 15:49 ivaneeo 閱讀(466) | 評論 (0)編輯 收藏

          chmod 700 ~/.ssh
          chmod 600 ~/.ssh/authorized_keys
          posted @ 2011-01-26 11:25 ivaneeo 閱讀(249) | 評論 (0)編輯 收藏

          一個圖片太大了,只好分割成為兩部分。根據流程圖來說一下具體一個任務執行的情況。

          1. 在分布式環境中客戶端創建任務并提交。
          2. InputFormat做Map前的預處理,主要負責以下工作:
            1. 驗證輸入的格式是否符合JobConfig的輸入定義,這個在實現Map和構建Conf的時候就會知道,不定義可以是Writable的任意子類。
            2. 將input的文件切分為邏輯上的輸入InputSplit,其實這就是在上面提到的在分布式文件系統中blocksize是有大小限制的,因此大文件會被劃分為多個block。
            3. 通過RecordReader來再次處理inputsplit為一組records,輸出給Map。(inputsplit只是邏輯切分的第一步,但是如何根據文件中的信息來切分還需要RecordReader來實現,例如最簡單的默認方式就是回車換行的切分)
          3. RecordReader處理后的結果作為Map的輸入,Map執行定義的Map邏輯,輸出處理后的key和value對應到臨時中間文件。
          4. Combiner可選擇配置,主要作用是在每一個Map執行完分析以后,在本地優先作Reduce的工作,減少在Reduce過程中的數據傳輸量。
          5. Partitioner可選擇配置,主要作用是在多個Reduce的情況下,指定Map的結果由某一個Reduce處理,每一個Reduce都會有單獨的輸出文件。(后面的代碼實例中有介紹使用場景)
          6. Reduce執行具體的業務邏輯,并且將處理結果輸出給OutputFormat。
          7. OutputFormat的職責是,驗證輸出目錄是否已經存在,同時驗證輸出結果類型是否如Config中配置,最后輸出Reduce匯總后的結果。

          業務場景和代碼范例

          業務場景描述:可設定輸入和輸出路徑(操作系統的路徑非HDFS路徑),根據訪問日志分析某一個應用訪問某一個API的總次數和總流量,統計后分別輸出到兩個文件中。這里僅僅為了測試,沒有去細分很多類,將所有的類都歸并于一個類便于說明問題。


          測試代碼類圖

          LogAnalysiser就是主類,主要負責創建、提交任務,并且輸出部分信息。內部的幾個子類用途可以參看流程中提到的角色職責。具體地看看幾個類和方法的代碼片斷:

          LogAnalysiser::MapClass

              public static class MapClass extends MapReduceBase
                  implements Mapper<LongWritable, Text, Text, LongWritable>
              {
                  public void map(LongWritable key, Text value, OutputCollector<Text, LongWritable> output, Reporter reporter)
                          throws IOException
                  {   
                      String line = value.toString();//沒有配置RecordReader,所以默認采用line的實現,key就是行號,value就是行內容
                      if (line == null || line.equals(""))
                          return;
                      String[] words = line.split(",");
                      if (words == null || words.length < 8)
                          return;
                      String appid = words[1];
                      String apiName = words[2];
                      LongWritable recbytes = new LongWritable(Long.parseLong(words[7]));
                      Text record = new Text();
                      record.set(new StringBuffer("flow::").append(appid)
                                      .append("::").append(apiName).toString());
                      reporter.progress();
                      output.collect(record, recbytes);//輸出流量的統計結果,通過flow::作為前綴來標示。
                      record.clear();
                      record.set(new StringBuffer("count::").append(appid).append("::").append(apiName).toString());
                      output.collect(record, new LongWritable(1));//輸出次數的統計結果,通過count::作為前綴來標示
                  }   
              }

          LogAnalysiser:: PartitionerClass

              public static class PartitionerClass implements Partitioner<Text, LongWritable>
              {
                  public int getPartition(Text key, LongWritable value, int numPartitions)
                  {
                      if (numPartitions >= 2)//Reduce 個數,判斷流量還是次數的統計分配到不同的Reduce
                          if (key.toString().startsWith("flow::"))
                              return 0;
                          else
                              return 1;
                      else
                          return 0;
                  }
                  public void configure(JobConf job){}   
          }

          LogAnalysiser:: CombinerClass

          參看ReduceClass,通常兩者可以使用一個,不過這里有些不同的處理就分成了兩個。在ReduceClass中藍色的行表示在CombinerClass中不存在。

          LogAnalysiser:: ReduceClass

              public static class ReduceClass extends MapReduceBase
                  implements Reducer<Text, LongWritable,Text, LongWritable>
              {
                  public void reduce(Text key, Iterator<LongWritable> values,
                          OutputCollector<Text, LongWritable> output, Reporter reporter)throws IOException
                  {
                      Text newkey = new Text();
                      newkey.set(key.toString().substring(key.toString().indexOf("::")+2));
                      LongWritable result = new LongWritable();
                      long tmp = 0;
                      int counter = 0;
                      while(values.hasNext())//累加同一個key的統計結果
                      {
                          tmp = tmp + values.next().get();
                         
                          counter = counter +1;//擔心處理太久,JobTracker長時間沒有收到報告會認為TaskTracker已經失效,因此定時報告一下
                          if (counter == 1000)
                          {
                              counter = 0;
                              reporter.progress();
                          }
                      }
                      result.set(tmp);
                      output.collect(newkey, result);//輸出最后的匯總結果
                  }   
              }

          LogAnalysiser

          	public static void main(String[] args)
          {
          try
          {
          run(args);
          } catch (Exception e)
          {
          e.printStackTrace();
          }
          }
          public static void run(String[] args) throws Exception
          {
          if (args == null || args.length <2)
          {
          System.out.println("need inputpath and outputpath");
          return;
          }
          String inputpath = args[0];
          String outputpath = args[1];
          String shortin = args[0];
          String shortout = args[1];
          if (shortin.indexOf(File.separator) >= 0)
          shortin = shortin.substring(shortin.lastIndexOf(File.separator));
          if (shortout.indexOf(File.separator) >= 0)
          shortout = shortout.substring(shortout.lastIndexOf(File.separator));
          SimpleDateFormat formater = new SimpleDateFormat("yyyy.MM.dd");
          shortout = new StringBuffer(shortout).append("-")
          .append(formater.format(new Date())).toString();


          if (!shortin.startsWith("/"))
          shortin = "/" + shortin;
          if (!shortout.startsWith("/"))
          shortout = "/" + shortout;
          shortin = "/user/root" + shortin;
          shortout = "/user/root" + shortout;
          File inputdir = new File(inputpath);
          File outputdir = new File(outputpath);
          if (!inputdir.exists() || !inputdir.isDirectory())
          {
          System.out.println("inputpath not exist or isn't dir!");
          return;
          }
          if (!outputdir.exists())
          {
          new File(outputpath).mkdirs();
          }

          JobConf conf = new JobConf(new Configuration(),LogAnalysiser.class);//構建Config
          FileSystem fileSys = FileSystem.get(conf);
          fileSys.copyFromLocalFile(new Path(inputpath), new Path(shortin));//將本地文件系統的文件拷貝到HDFS中

          conf.setJobName("analysisjob");
          conf.setOutputKeyClass(Text.class);//輸出的key類型,在OutputFormat會檢查
          conf.setOutputValueClass(LongWritable.class); //輸出的value類型,在OutputFormat會檢查
          conf.setMapperClass(MapClass.class);
          conf.setCombinerClass(CombinerClass.class);
          conf.setReducerClass(ReduceClass.class);
          conf.setPartitionerClass(PartitionerClass.class);
          conf.set("mapred.reduce.tasks", "2");//強制需要有兩個Reduce來分別處理流量和次數的統計
          FileInputFormat.setInputPaths(conf, shortin);//hdfs中的輸入路徑
          FileOutputFormat.setOutputPath(conf, new Path(shortout));//hdfs中輸出路徑

          Date startTime = new Date();
          System.out.println("Job started: " + startTime);
          JobClient.runJob(conf);
          Date end_time = new Date();
          System.out.println("Job ended: " + end_time);
          System.out.println("The job took " + (end_time.getTime() - startTime.getTime()) /1000 + " seconds.");
          //刪除輸入和輸出的臨時文件
          fileSys.copyToLocalFile(new Path(shortout),new Path(outputpath));
          fileSys.delete(new Path(shortin),true);
          fileSys.delete(new Path(shortout),true);
          }

          以上的代碼就完成了所有的邏輯性代碼,然后還需要一個注冊驅動類來注冊業務Class為一個可標示的命令,讓hadoop jar可以執行。

          public class ExampleDriver {
            public static void main(String argv[]){
              ProgramDriver pgd = new ProgramDriver();
              try {
                pgd.addClass("analysislog", LogAnalysiser.class, "A map/reduce program that analysis log .");
                pgd.driver(argv);
              }
              catch(Throwable e){
                e.printStackTrace();
              }
            }
          }

          將代碼打成jar,并且設置jar的mainClass為ExampleDriver這個類。在分布式環境啟動以后執行如下語句:

          hadoop jar analysiser.jar analysislog /home/wenchu/test-in /home/wenchu/test-out

          在/home/wenchu/test-in中是需要分析的日志文件,執行后就會看見整個執行過程,包括了Map和Reduce的進度。執行完畢會在/home/wenchu/test-out下看到輸出的內容。有兩個文件:part-00000和part-00001分別記錄了統計后的結果。 如果需要看執行的具體情況,可以看在輸出目錄下的_logs/history/xxxx_analysisjob,里面羅列了所有的Map,Reduce的創建情況以及執行情況。在運行期也可以通過瀏覽器來查看Map,Reduce的情況:http://MasterIP:50030/jobtracker.jsp

          Hadoop集群測試

          首先這里使用上面的范例作為測試,也沒有做太多的優化配置,這個測試結果只是為了看看集群的效果,以及一些參數配置的影響。

          文件復制數為1,blocksize 5M

          Slave數 處理記錄數(萬條) 執行時間(秒)
          2 95 38
          2 950 337
          4 95 24
          4 950 178
          6 95 21
          6 950 114

          Blocksize 5M

          Slave數 處理記錄數(萬條) 執行時間(秒)
          2(文件復制數為1) 950 337
          2(文件復制數為3) 950 339
          6(文件復制數為1) 950 114
          6(文件復制數為3) 950 117

          文件復制數為1

          Slave數 處理記錄數(萬條) 執行時間(秒)
          6(blocksize 5M) 95 21
          6(blocksize 77M) 95 26
          4(blocksize 5M) 950 178
          4(blocksize 50M) 950 54
          6(blocksize 5M) 950 114
          6(blocksize 50M) 950 44
          6(blocksize 77M) 950 74

          測試的數據結果很穩定,基本測幾次同樣條件下都是一樣。通過測試結果可以看出以下幾點:

          1. 機器數對于性能還是有幫助的(等于沒說^_^)。
          2. 文件復制數的增加只對安全性有幫助,但是對于性能沒有太多幫助。而且現在采取的是將操作系統文件拷貝到HDFS中,所以備份多了,準備的時間很長。
          3. blocksize對于性能影響很大,首先如果將block劃分的太小,那么將會增加job的數量,同時也增加了協作的代價,降低了性能,但是配置的太大也會讓job不能最大化并行處理。所以這個值的配置需要根據數據處理的量來考慮。
          4. 最后就是除了這個表里面列出來的結果,應該去仔細看輸出目錄中的_logs/history中的xxx_analysisjob這個文件,里面記錄了全部的執行過程以及讀寫情況。這個可以更加清楚地了解哪里可能會更加耗時。

          隨想

          “云計算”熱的燙手,就和SAAS、Web2及SNS等一樣,往往都是在搞概念,只有真正踏踏實實的大型互聯網公司,才會投入人力物力去研究符合自己的分布式計算。其實當你的數據量沒有那么大的時候,這種分布式計算也就僅僅只是一個玩具而已,只有在真正解決問題的過程中,它深層次的問題才會被挖掘出來。

          這三篇文章(分布式計算開源框架Hadoop介紹,Hadoop中的集群配置和使用技巧)僅僅是為了給對分布式計算有興趣的朋友拋個磚,要想真的掘到金子,那么就踏踏實實的去用、去想、去分析。或者自己也會更進一步地去研究框架中的實現機制,在解決自己問題的同時,也能夠貢獻一些什么。

          前幾日看到有人跪求成為架構師的方式,看了有些可悲,有些可笑,其實有多少架構師知道什么叫做架構?架構師的職責是什么?與其追求這么一個名號,還不如踏踏實實地做塊石頭沉到水底。要知道,積累和沉淀的過程就是一種成長。

          相關閱讀:

          1. 分布式計算開源框架Hadoop介紹――分布式計算開源框架Hadoop入門實踐(一)
          2. Hadoop中的集群配置和使用技巧――分布式計算開源框架Hadoop入門實踐(二)

          作者介紹:岑文初,就職于阿里軟件公司研發中心平臺一部,任架構師。當前主要工作涉及阿里軟件開發平臺服務框架(ASF)設計與實現,服務集成平臺(SIP)設計與實現。沒有什么擅長或者精通,工作到現在唯一提升的就是學習能力和速度。個人Blog為:http://blog.csdn.net/cenwenchu79

          志愿參與InfoQ中文站內容建設,請郵件至editors@cn.infoq.com。也歡迎大家到InfoQ中文站用戶討論組參與我們的線上討論。

          posted @ 2011-01-25 16:14 ivaneeo 閱讀(421) | 評論 (0)編輯 收藏

               摘要: HBASE松散數據存儲設計初識 - 西湖邊的窮秀才-文初 - BlogJava window.onerror = ignoreError; function ignoreError() { return true; } Date.prototype.Format = function(f...  閱讀全文
          posted @ 2011-01-21 19:31 ivaneeo 閱讀(410) | 評論 (0)編輯 收藏

          一、介紹
          Google的工程師為了方便自己對MapReduce的實現搞了一個叫做Sawzall的工具,Google就放了幾篇論文放在網上,但這玩意在代碼上不開源在設計思想是開源的,在前面一篇文章中我也提到過Hadoop也推出了類似Sawzall的Pig語言,就是根據Google放出來的論文山寨的。

          Pig是對處理超大型數據集的抽象層,在MapReduce中的框架中有map和reduce兩個函數,如果你親手弄一個MapReduce實現從編寫代碼,編譯,部署,放在Hadoop上執行這個MapReduce程序還是耗費你一定的時間的,有了Pig這個東東以后不僅僅可以簡化你對MapReduce的開發,而且還可以對不同的數據之間進行轉換,例如:包含在連接內的一些轉化在MapReduce中不太容易去實現。

          Apache Pig的運行可以純本地的,解壓,敲個“bin/pig -x local”命令直接運行,非常簡單,這就是傳說中的local模式,但是人們往往不是這樣使用,都是將Pig與hdfs/hadoop集群環境進行對接,我看說白了Apache的Pig最大的作用就是對mapreduce算法(框架)實現了一套shell腳本 ,類似我們通常熟悉的SQL語句,在Pig中稱之為Pig Latin,在這套腳本中我們可以對加載出來的數據進行排序、過濾、求和、分組(group by)、關聯(Joining),Pig也可以由用戶自定義一些函數對數據集進行操作,也就是傳說中的UDF(user-defined functions)。

          經過Pig Latin的轉換后變成了一道MapReduce的作業,通過MapReduce多個線程,進程或者獨立系統并行執行處理的結果集進行分類和歸納。Map() 和 Reduce() 兩個函數會并行運行,即使不是在同一的系統的同一時刻也在同時運行一套任務,當所有的處理都完成之后,結果將被排序,格式化,并且保存到一個文件。Pig利用MapReduce將計算分成兩個階段,第一個階段分解成為小塊并且分布到每一個存儲數據的節點上進行執行,對計算的壓力進行分散,第二個階段聚合第一個階段執行的這些結果,這樣可以達到非常高的吞吐量,通過不多的代碼和工作量就能夠驅動上千臺機器并行計算,充分的利用計算機的資源,打消運行中的瓶頸。

          所以用Pig可以對TB級別海量的數據進行查詢非常輕松,并且這些海量的數據都是非結構化的數據,例如:一堆文件可能是log4j輸出日志存又放于跨越多個計算機的多個磁盤上,用來記錄上千臺在線服務器的健康狀態日志,交易日至,IP訪問記錄,應用服務日志等等。我們通常需要統計或者抽取這些記錄,或者查詢異常記錄,對這些記錄形成一些報表,將數據轉化為有價值的信息,這樣的話查詢會較為復雜,此時類似MySQL這樣的產品就并非能滿足我們的對速度、執行效率上的需求,而用Apache的Pig就可以幫助我們去實現這樣的目標。

          反之,你如果在做實驗的時候,把MySQL中的100行數據轉換成文本文件放在在pig中進行查詢,會讓你非常失望,為何這短短的100行數據查詢的效率極低,呵呵,因為中間有一個生成MapReduce作業的過程,這是無法避免的開銷,所以小量的數據查詢是不適合pig做的,就好比用關二哥的大刀切青菜一樣。另外,還可以利用Pig的API在Java環境中調用,對Apache的Pig以上內容請允許我這樣片面的理解,謝謝。

           
          二、基本架構
           
          從整體上來看大量的數據聚集在HDFS系統上,通過輸入類似SQL的腳本簡化對MapReduce的操作,讓這幾行代碼/腳本去驅動上千臺機器進行并行計算。
          如圖所示:
           Apache-Pig-Architect.jpg

          Pig的實現有5個主要的部分構成:
          如圖所示:
          apache zebra

          1.Pig自己實現的一套框架對輸入、輸出的人機交互部分的實現,就是Pig Latin 。
          2.Zebra是Pig與HDFS/Hadoop的中間層、Zebra是MapReduce作業編寫的客戶端,Zerbra用結構化的語言實現了對hadoop物理存儲元數據的管理也是對Hadoop的數據抽象層,在Zebra中有2個核心的類 TableStore(寫)/TableLoad(讀)對Hadoop上的數據進行操作。
          3.Pig中的Streaming主要分為4個組件: 1. Pig Latin 2. 邏輯層(Logical Layer) 3. 物理層(Physical Layer) 4. Streaming具體實現(Implementation),Streaming會創建一個Map/Reduce作業,并把它發送給合適的集群,同時監視這個作業的在集群環境中的整個執行過程。 
          4.MapReduce在每臺機器上進行分布式計算的框架(算法)。
          5.HDFS最終存儲數據的部分。

          三、與Hive對比
          請允許我很無聊的把飛機和火車拿來做比較,因為2者根本沒有深入的可比性,雖然兩者都是一種高速的交通工具,但是具體的作用范圍是截然不同的,就像Hive和Pig都是Hadoop中的項目,并且Hive和pig有很多共同點,但Hive還似乎有點數據庫的影子,而Pig基本就是一個對MapReduce實現的工具(腳本)。兩者都擁有自己的表達語言,其目的是將MapReduce的實現進行簡化,并且讀寫操作數據最終都是存儲在HDFS分布式文件系統上。看起來Pig和Hive有些類似的地方,但也有些不同,來做一個簡單的比較,先來看一張圖:
          hive and pig
          查看大圖請點擊這里

          再讓我說幾句廢話:
          Language
          在Hive中可以執行  插入/刪除 等操作,但是Pig中我沒有發現有可以 插入 數據的方法,請允許我暫且認為這是最大的不同點吧。

          Schemas
          Hive中至少還有一個“表”的概念,但是Pig中我認為是基本沒有表的概念,所謂的表建立在Pig Latin腳本中,對與Pig更不要提metadata了。

          Partitions
          Pig中沒有表的概念,所以說到分區對于Pig來說基本免談,如果跟Hive說“分區”(Partition)他還是能明白的。

          Server
          Hive可以依托于Thrift啟動一個服務器,提供遠程調用。 找了半天壓根沒有發現Pig有這樣的功能,如果你有新發現可以告訴我,就好像有人開發了一個Hive的REST

          Shell
          在Pig 你可以執行一些個 ls 、cat 這樣很經典、很cool的命令,但是在使用Hive的時候我壓根就沒有想過有這樣的需求。

          Web Interface
          Hive有,Pig無

          JDBC/ODBC
          Pig無,Hive有


          四、使用

          1啟動/運行  
          分為2臺服務器,一臺作為pig的服務器,一臺作為hdfs的服務器。
          首先需要在pig的服務器上進行配置,將pig的配置文件指向hdfs服務器,修改pig/conf目錄下的
           vim /work/pig/conf/pig.properties
           添加以下內容:
          fs.default.name=hdfs://192.168.1.201:9000/    #指向HDFS服務器
          mapred.job.tracker=192.168.1.201:9001          #指向MR job服務器地址

          如果是第一次運行請在Hadoop的HDFS的服務器上創建root目錄,并且將etc目錄下的passwd文件放在HDFS的root目錄下,請執行以下兩條命令。
          hadoop fs -mkdir /user/root
          hadoop fs -put /etc/passwd /user/root/passwd

          創建運行腳本,用vim命令在pig的服務器上創建javabloger_testscript.pig 文件,內容如下:
          LoadFile = load 'passwd' using PigStorage(':');
          Result = foreach LoadFile  generate $0 as id;
          dump Result;

          運行pig腳本,例如:pig javabloger_testscript.pig,執行狀態如圖所示:
          pig

          執行結果:

          2.java 代碼  運行并且打印運行結果
          import java.io.IOException;
          import java.util.Iterator;

          import org.apache.pig.PigServer;
          import org.apache.pig.data.Tuple;

          public class  LocalPig {
              public static void main(String[] args) {
                  try {
                      PigServer pigServer = new PigServer("local");
                      runIdQuery(pigServer, "passwd");
                  } catch (Exception e) {
                  }
              }

              public static void runIdQuery(PigServer pigServer, String inputFile)  throws IOException {
                  pigServer.registerQuery("LoadFile = load '" + inputFile+ "' using PigStorage(':');");
                  pigServer.registerQuery("Result = foreach A generate $0 as id;");
                  Iterator<Tuple> result = pigServer.openIterator("Result "); 
                  while (result.hasNext()) { 
                         Tuple t = result.next(); 
                         System.out.println(t); 
                      } 
          //        pigServer.store("B", "output");
                  
              }
          }

          –end–

          本文已經同步到新浪微博,點擊這里訪問“J2EE企業應用 顧問/咨詢- H.E.'s Blog”的官方微博。
          豆瓣讀書  向你推薦有關 Hadoop、 Hive、 MapReduce、 NoSQL、 Pig、 云計算、 架構設計、 類別的圖書。
          posted @ 2011-01-21 19:28 ivaneeo 閱讀(2084) | 評論 (0)編輯 收藏

          http://code.google.com/p/nutla/ 

          1、概述
           不管程序性能有多高,機器處理能力有多強,都會有其極限。能夠快速方便的橫向與縱向擴展是Nut設計最重要的原則。
           Nut是一個Lucene+Hadoop分布式搜索框架,能對千G以上索引提供7*24小時搜索服務。在服務器資源足夠的情況下能達到每秒處理100萬次的搜索請求。
           Nut開發環境:jdk1.6.0.21+lucene3.0.2+eclipse3.6.1+hadoop0.20.2+zookeeper3.3.1+hbase0.20.6+memcached+linux

          2、特新
           a、熱插拔
           b、可擴展
           c、高負載
           d、易使用,與現有項目無縫集成
          e、支持排序
          f、7*24服務
          g、失敗轉移

          3、搜索流程
          Nut由Index、Search、Client、Cache和DB五部分構成。(Cache默認使用memcached,DB默認使用hbase)
          Client處理用戶請求和對搜索結果排序。Search對請求進行搜索,Search上只放索引,數據存儲在DB中,Nut將索引和存儲分離。Cache緩存的是搜索條件和結果文檔id。DB存儲著數據,Client根據搜索排序結果,取出當前頁中的文檔id從DB上讀取數據。

          用戶發起搜索請求給由Nut Client構成的集群,由某個Nut Client根據搜索條件查詢Cache服務器是否有該緩存,如果有緩存根據緩存的文檔id直接從DB讀取數據,如果沒有緩存將隨機選擇一組搜索服務器組(Search Group i),將查詢條件同時發給該組搜索服務器組里的n臺搜索服務器,搜索服務器將搜索結果返回給Nut Client由其排序,取出當前頁文檔id,將搜索條件和當前文檔id緩存,同時從DB讀取數據。


          4、索引流程
          Hadoop Mapper/Reducer 建立索引。再將索引從HDFS分發到各個索引服務器。
          對索引的更新分為兩種:刪除和添加(更新分解為刪除和添加)。
          a、刪除
          在HDFS上刪除索引,將生成的*.del文件分發到所有的索引服務器上去或者對HDFS索引目錄刪除索引再分發到對應的索引服務器上去。
          b、添加
          新添加的數據用另一臺服務器來生成。
          刪除和添加步驟可按不同定時策略來實現。

          5、Zookeeper服務器狀態管理策略

          在架構設計上通過使用多組搜索服務器可以支持每秒處理100萬個搜索請求。
          每組搜索服務器能處理的搜索請求數在1萬—1萬5千之間。如果使用100組搜索服務器,理論上每秒可處理100萬個搜索請求。


          假如每組搜索服務器有100份索引放在100臺正在運行中搜索服務器(run)上,那么將索引按照如下的方式放在備用中搜索服務器(bak)上:index 1,index 2,index 3,index 4,index 5,index 6,index 7,index 8,index 9,index 10放在B 1 上,index 6,index 7,index 8,index 9,index 10,index 11,index 12,index 13,index 14,index 15放在B 2上。。。。。。index 96,index 97,index 98,index 99,index 100,index 5,index 4,index 3,index 2,index 1放在最后一臺備用搜索服務器上。那么每份索引會存在3臺機器中(1份正在運行中,2份備份中)。
          盡管這樣設計每份索引會存在3臺機器中,仍然不是絕對安全的。假如運行中的index 1,index 2,index 3同時宕機的話,那么就會有一份索引搜索服務無法正確啟用。這樣設計,作者認為是在安全性和機器資源兩者之間一個比較適合的方案。

          備用中的搜索服務器會定時檢查運行中搜索服務器的狀態。一旦發現與自己索引對應的服務器宕機就會向lock申請分布式鎖,得到分布式鎖的服務器就將自己加入到運行中搜索服務器組,同時從備用搜索服務器組中刪除自己,并停止運行中搜索服務器檢查服務。

          為能夠更快速的得到搜索結果,設計上將搜索服務器分優先等級。通常是將最新的數據放在一臺或幾臺內存搜索服務器上。通常情況下前幾頁數據能在這幾臺搜索服務器里搜索到。如果在這幾臺搜索服務器上沒有數據時再向其他舊數據搜索服務器上搜索。
          優先搜索等級的邏輯是這樣的:9最大為搜索全部服務器并且9不能作為level標識。當搜索等級level為1,搜索優先級為1的服務器,當level為2時搜索優先級為1和2的服務器,依此類推。

          posted @ 2011-01-21 19:06 ivaneeo 閱讀(255) | 評論 (0)編輯 收藏

          HBase – Hadoop Database,是一個高可靠性、高性能、面向列、可伸縮的分布式存儲系統,利用HBase技術可在廉價PC Server上搭建起大規模結構化存儲集群。

          HBase是Google Bigtable的開源實現,類似Google Bigtable利用GFS作為其文件存儲系統,HBase利用Hadoop HDFS作為其文件存儲系統;Google運行MapReduce來處理Bigtable中的海量數據,HBase同樣利用Hadoop MapReduce來處理HBase中的海量數據;Google Bigtable利用 Chubby作為協同服務,HBase利用Zookeeper作為對應。

          上圖描述了Hadoop EcoSystem中的各層系統,其中HBase位于結構化存儲層,Hadoop HDFS為HBase提供了高可靠性的底層存儲支持,Hadoop MapReduce為HBase提供了高性能的計算能力,Zookeeper為HBase提供了穩定服務和failover機制。

          此外,Pig和Hive還為HBase提供了高層語言支持,使得在HBase上進行數據統計處理變的非常簡單。 Sqoop則為HBase提供了方便的RDBMS數據導入功能,使得傳統數據庫數據向HBase中遷移變的非常方便。

          HBase訪問接口

          1.       Native Java API,最常規和高效的訪問方式,適合Hadoop MapReduce Job并行批處理HBase表數據

          2.       HBase Shell,HBase的命令行工具,最簡單的接口,適合HBase管理使用

          3.       Thrift Gateway,利用Thrift序列化技術,支持C++,PHP,Python等多種語言,適合其他異構系統在線訪問HBase表數據

          4.       REST Gateway,支持REST 風格的Http API訪問HBase, 解除了語言限制

          5.       Pig,可以使用Pig Latin流式編程語言來操作HBase中的數據,和Hive類似,本質最終也是編譯成MapReduce Job來處理HBase表數據,適合做數據統計

          6.       Hive,當前Hive的Release版本尚沒有加入對HBase的支持,但在下一個版本Hive 0.7.0中將會支持HBase,可以使用類似SQL語言來訪問HBase

          HBase數據模型

          Table & Column Family

          Row Key Timestamp Column Family
          URI Parser
          r1 t3 url=http://www.taobao.com title=天天特價
          t2 host=taobao.com
          t1
          r2 t5 url=http://www.alibaba.com content=每天…
          t4 host=alibaba.com

          Ø  Row Key: 行鍵,Table的主鍵,Table中的記錄按照Row Key排序

          Ø  Timestamp: 時間戳,每次數據操作對應的時間戳,可以看作是數據的version number

          Ø  Column Family:列簇,Table在水平方向有一個或者多個Column Family組成,一個Column Family中可以由任意多個Column組成,即Column Family支持動態擴展,無需預先定義Column的數量以及類型,所有Column均以二進制格式存儲,用戶需要自行進行類型轉換。

          Table & Region

          當Table隨著記錄數不斷增加而變大后,會逐漸分裂成多份splits,成為regions,一個region由[startkey,endkey)表示,不同的region會被Master分配給相應的RegionServer進行管理:

          -ROOT- && .META. Table

          HBase中有兩張特殊的Table,-ROOT-和.META.

          Ø  .META.:記錄了用戶表的Region信息,.META.可以有多個regoin

          Ø  -ROOT-:記錄了.META.表的Region信息,-ROOT-只有一個region

          Ø  Zookeeper中記錄了-ROOT-表的location

          Client訪問用戶數據之前需要首先訪問zookeeper,然后訪問-ROOT-表,接著訪問.META.表,最后才能找到用戶數據的位置去訪問,中間需要多次網絡操作,不過client端會做cache緩存。

          MapReduce on HBase

          在HBase系統上運行批處理運算,最方便和實用的模型依然是MapReduce,如下圖:

          HBase Table和Region的關系,比較類似HDFS File和Block的關系,HBase提供了配套的TableInputFormat和TableOutputFormat API,可以方便的將HBase Table作為Hadoop MapReduce的Source和Sink,對于MapReduce Job應用開發人員來說,基本不需要關注HBase系統自身的細節。

          HBase系統架構

          Client

          HBase Client使用HBase的RPC機制與HMaster和HRegionServer進行通信,對于管理類操作,Client與HMaster進行RPC;對于數據讀寫類操作,Client與HRegionServer進行RPC

          Zookeeper

          Zookeeper Quorum中除了存儲了-ROOT-表的地址和HMaster的地址,HRegionServer也會把自己以Ephemeral方式注冊到Zookeeper中,使得HMaster可以隨時感知到各個HRegionServer的健康狀態。此外,Zookeeper也避免了HMaster的單點問題,見下文描述

          HMaster

          HMaster沒有單點問題,HBase中可以啟動多個HMaster,通過Zookeeper的Master Election機制保證總有一個Master運行,HMaster在功能上主要負責Table和Region的管理工作:

          1.       管理用戶對Table的增、刪、改、查操作

          2.       管理HRegionServer的負載均衡,調整Region分布

          3.       在Region Split后,負責新Region的分配

          4.       在HRegionServer停機后,負責失效HRegionServer 上的Regions遷移

          HRegionServer

          HRegionServer主要負責響應用戶I/O請求,向HDFS文件系統中讀寫數據,是HBase中最核心的模塊。

          HRegionServer內部管理了一系列HRegion對象,每個HRegion對應了Table中的一個Region,HRegion中由多個HStore組成。每個HStore對應了Table中的一個Column Family的存儲,可以看出每個Column Family其實就是一個集中的存儲單元,因此最好將具備共同IO特性的column放在一個Column Family中,這樣最高效。

          HStore存儲是HBase存儲的核心了,其中由兩部分組成,一部分是MemStore,一部分是StoreFiles。MemStore是Sorted Memory Buffer,用戶寫入的數據首先會放入MemStore,當MemStore滿了以后會Flush成一個StoreFile(底層實現是HFile),當StoreFile文件數量增長到一定閾值,會觸發Compact合并操作,將多個StoreFiles合并成一個StoreFile,合并過程中會進行版本合并和數據刪除,因此可以看出HBase其實只有增加數據,所有的更新和刪除操作都是在后續的compact過程中進行的,這使得用戶的寫操作只要進入內存中就可以立即返回,保證了HBase I/O的高性能。當StoreFiles Compact后,會逐步形成越來越大的StoreFile,當單個StoreFile大小超過一定閾值后,會觸發Split操作,同時把當前Region Split成2個Region,父Region會下線,新Split出的2個孩子Region會被HMaster分配到相應的HRegionServer上,使得原先1個Region的壓力得以分流到2個Region上。下圖描述了Compaction和Split的過程:

          在理解了上述HStore的基本原理后,還必須了解一下HLog的功能,因為上述的HStore在系統正常工作的前提下是沒有問題的,但是在分布式系統環境中,無法避免系統出錯或者宕機,因此一旦HRegionServer意外退出,MemStore中的內存數據將會丟失,這就需要引入HLog了。每個HRegionServer中都有一個HLog對象,HLog是一個實現Write Ahead Log的類,在每次用戶操作寫入MemStore的同時,也會寫一份數據到HLog文件中(HLog文件格式見后續),HLog文件定期會滾動出新的,并刪除舊的文件(已持久化到StoreFile中的數據)。當HRegionServer意外終止后,HMaster會通過Zookeeper感知到,HMaster首先會處理遺留的 HLog文件,將其中不同Region的Log數據進行拆分,分別放到相應region的目錄下,然后再將失效的region重新分配,領取 到這些region的HRegionServer在Load Region的過程中,會發現有歷史HLog需要處理,因此會Replay HLog中的數據到MemStore中,然后flush到StoreFiles,完成數據恢復。

          HBase存儲格式

          HBase中的所有數據文件都存儲在Hadoop HDFS文件系統上,主要包括上述提出的兩種文件類型:

          1.       HFile, HBase中KeyValue數據的存儲格式,HFile是Hadoop的二進制格式文件,實際上StoreFile就是對HFile做了輕量級包裝,即StoreFile底層就是HFile

          2.       HLog File,HBase中WAL(Write Ahead Log) 的存儲格式,物理上是Hadoop的Sequence File

          HFile

          下圖是HFile的存儲格式:

          首先HFile文件是不定長的,長度固定的只有其中的兩塊:Trailer和FileInfo。正如圖中所示的,Trailer中有指針指向其他數據塊的起始點。File Info中記錄了文件的一些Meta信息,例如:AVG_KEY_LEN, AVG_VALUE_LEN, LAST_KEY, COMPARATOR, MAX_SEQ_ID_KEY等。Data Index和Meta Index塊記錄了每個Data塊和Meta塊的起始點。

          Data Block是HBase I/O的基本單元,為了提高效率,HRegionServer中有基于LRU的Block Cache機制。每個Data塊的大小可以在創建一個Table的時候通過參數指定,大號的Block有利于順序Scan,小號Block利于隨機查詢。每個Data塊除了開頭的Magic以外就是一個個KeyValue對拼接而成, Magic內容就是一些隨機數字,目的是防止數據損壞。后面會詳細介紹每個KeyValue對的內部構造。

          HFile里面的每個KeyValue對就是一個簡單的byte數組。但是這個byte數組里面包含了很多項,并且有固定的結構。我們來看看里面的具體結構:

          開始是兩個固定長度的數值,分別表示Key的長度和Value的長度。緊接著是Key,開始是固定長度的數值,表示RowKey的長度,緊接著是RowKey,然后是固定長度的數值,表示Family的長度,然后是Family,接著是Qualifier,然后是兩個固定長度的數值,表示Time Stamp和Key Type(Put/Delete)。Value部分沒有這么復雜的結構,就是純粹的二進制數據了。

          HLogFile

          上圖中示意了HLog文件的結構,其實HLog文件就是一個普通的Hadoop Sequence File,Sequence File 的Key是HLogKey對象,HLogKey中記錄了寫入數據的歸屬信息,除了table和region名字外,同時還包括 sequence number和timestamp,timestamp是“寫入時間”,sequence number的起始值為0,或者是最近一次存入文件系統中sequence number。

          HLog Sequece File的Value是HBase的KeyValue對象,即對應HFile中的KeyValue,可參見上文描述。

          結束

          本文對HBase技術在功能和設計上進行了大致的介紹,由于篇幅有限,本文沒有過多深入地描述HBase的一些細節技術。目前一淘的存儲系統就是基于HBase技術搭建的,后續將介紹“一淘分布式存儲系統”,通過實際案例來更多的介紹HBase應用。

          posted @ 2011-01-21 19:04 ivaneeo 閱讀(930) | 評論 (0)編輯 收藏

          僅列出標題
          共67頁: First 上一頁 15 16 17 18 19 20 21 22 23 下一頁 Last 
          主站蜘蛛池模板: 湘乡市| 南丰县| 常德市| 长武县| 桑植县| 女性| 和硕县| 隆安县| 巴塘县| 秭归县| 三穗县| 大悟县| 冷水江市| 通海县| 北碚区| 钟祥市| 荥阳市| 高安市| 玉田县| 和顺县| 梁河县| 霍邱县| 萨嘎县| 高唐县| 治多县| 武隆县| 宜兰县| 永胜县| 石景山区| 织金县| 杭州市| 淮阳县| 府谷县| 井陉县| 钟祥市| 桑植县| 佛坪县| 毕节市| 资中县| 惠东县| 弋阳县|