大資料架構-使用HBase和Solr配置存儲與索引

來源:互聯網
上載者:User

HBase和Solr可以通過副處理器Coprocessor的方式向Solr發出請求,Solr對於接收到的資料可以做相關的同步:增、刪、改索 引的操作。 將存儲與索引放在不同的機器上,這是大資料架構的必須品,但目前還有很多不懂得此道的同學,他們對於這種思想感到很新奇,不過,這絕對是好的方 向,所以不懂得抓緊學習吧。

有個朋友給我的那篇博客留言,說CDH也可以做這樣的事情,我還沒有試過,他還問我要與此相關的代碼,於是我就稍微整理了一下,作為本篇文章的主要內容。 關於CDH的事,我會儘快嘗試,有知道的同學可以給我留言。

下面我主要講述一下,我測試對HBase和Solr的性能時,使用HBase副處理器向HBase添加資料所編寫的相關代碼,及解釋說明。

一、編寫HBase副處理器Coprocessor

​一旦有資料postPut,就立即對Solr裡相應的Core更新。 這裡使用了ConcurrentUpdateSolrServer,它是Solr速率性能的保證,使用它不要忘記在Solr裡面配置autoCommit喲。

/*   *版權:王安琪   *描述:監視HBase,一有資料postPut就向Solr發送,本類要作為觸發器添加到HBase    *修改時間:2014-05-27   *修改內容:新增   */  package solrHbase.test;      import java.io.UnsupportedEncodingException;     import * **;     public class SorlIndexCoprocessorObserver extends  BaseRegionObserver {         private static final Logger  LOG = LoggerFactory              .getLogger( SorlIndexCoprocessorObserver.class);      private static final String  solrUrl = "HTTP://192.1.11.108:80/solr/core1";      private static final  SolrServer solrServer = new ConcurrentUpdateSolrServer(              solrUrl, 10000, 20);         /**       * 建立solr索引        *        * @throws UnsupportedEncodingException        */      @Override      public void  postPut(final ObserverCoNtext<RegionCoprocessorEnvironment> e,              final Put put, final WALEdit edit, final boolean  writeToWAL)              throws UnsupportedEncodingException {           inputSolr(put);      }         public void inputSolr(Put put) {          try {               solrServer.add(TestSolrMain.getInputDoc(put));          } catch (Exception ex) {          & nbsp;   LOG.error(ex.getMessage());          }      }  }  

    注意:getInputDoc是這個HBase副處理器Coprocessor的精髓所在,它可以把HBase內的Put裡的內容轉化成Solr需 要的值。 其中String fieldName = key.substring(key.indexOf(columnFamily) + 3, key.indexOf(" 我在這")).trim();這裡有一個亂碼字元,在這裡看不到,請大家注意一下。

public static SolrInputDocument getInputDoc(Put put) {          SolrInputDocument doc = new SolrInputDocument();          doc.addField("test_ID", Bytes.toString(put.getRow()));          for ( KeyValue c : put.getFamilyMap().get(Bytes.toBytes(columnFamily))) {              String key = Bytes.toString(c.getKey());      & nbsp;       String value = Bytes.toString(c.getValue());              if (value.isEmpty()) {                  continue;              }              Stri ng fieldName = key.substring(key.indexOf(columnFamily) + 3,                      key.indexOf("")).trim(); & nbsp;            doc.addField(fieldName, value);        & nbsp; }          return doc;      } 

二、編寫測試程式入口代碼main

​這段代碼向HBase請求建了一張表,並將類比的資料,向HBase連續地提交資料內容,在HBase中不斷地插入資料,同時記錄時間,測試插入性能。

/*   *版權:王安琪   *描述:測試HBaseInsert,HBase插入性能   *修改時間:2014-05-27    *修改內容:新增   */  package solrHbase.test;      import hbaseInput.HbaseInsert;     import ***;     public  class TestHBaseMain {         private static  Configuration config;      private static String tableName = " angelHbase";      private static HTable table = null;       private static final String columnFamily = "wanganqi";          /**       * @param args        */      public static void main(String[] args) {          config = HBaseConfiguration.create();          config.set(" hbase.zookeeper.quorum", "192.103.101.104");          HbaseInsert.createTable( config, tableName, columnFamily);          try {              table = new HTable(config, Bytes.toBytes(tableName));               for (int k = 0; k < 1; k+ +) {                  Thread t = new Thread () {                      public void run()& nbsp; {                          for (int i&nbsp ;= 0; i < 100000; i++) {                              HbaseInsert.inputData(table,&n bsp;                                     PutCreater.createPuts(1000, columnFamily));              & nbsp;               Calendar c = Calendar.getInstance();                               String dateTime&nbs p;= c.get(Calendar.YEAR) + "-"                                      + c.get(Calendar.MONTH) + "-"                                   &nbs p;   + c.get(Calendar.DATE) + "T"                              &nb sp;       + c.get(Calendar.HOUR) + ":"              & nbsp;                       + c.get(Calendar.MINUTE) + ": "                                &nbs p;     + c.get(Calendar.SECOND) + ":"                                      + c.get(Calendar.MILLISECOND)&nbs p;+ "Z 寫入: "                        &nbsp ;             + i * 1000;                              System.out.println(dateTime);                &nb sp;         }                      } &nbs p;                };                & nbsp; t.start();              }          } catch& nbsp;(IOException e1) {              e1.printStackTrace();           }      }     } 

    ​下面的是與HBase相關的操作,把它封裝到一個類中,這裡就只有建表與插入資料的相關代碼。

/*   *版權:王安琪   *描述:與HBase相關操作,建表與插入資料   *修改時間:2014-05-27    *修改內容:新增   */  package hbaseInput;  import ***;   import org.apache.hadoop.hbase.client.Put;     public class  HbaseInsert {         public static void createTable( Configuration config, String tableName,              String  columnFamily) {          HBaseAdmin hBaseAdmin;          try {              hBaseAdmin = new  HBaseAdmin(config);              if (hBaseAdmin.tableExists(tableName))  {                  return;              }              HTableDescriptor tableDescriptor =  new HTableDescriptor(tableName);              tableDescriptor.addFamily(new HColumnDescriptor(columnFamily));              hBaseAdmin.createTable(tableDescriptor);              hBaseAdmin.close ();          } catch (MasterNotRunningException e) {               e.printStackTrace();          } catch  (ZooKeeperConnectionException e) {              e.printStackTrace( );          } catch (IOException e) {              e.printStackTrace();          }      }         public static void inputData(HTable  table, ArrayList<Put> puts) {          try {               table.put(puts);              tabl e.flushCommits();              puts.clear();        & nbsp; } catch (IOException e) {              e.printStackTrace ();          }      }  } 

三、編寫類比資料Put

向HBase中寫入資料需要構造Put,下面是我構造類比資料Put的方式,有字串的生成, 我是由mmseg提供的詞典words.dic中隨機讀取一些詞語連接起來,生成一句字串的,下面的代碼沒有體現,不過很easy,你自己造你自己想要的資料就OK了。

public static Put createPut(String columnFamily) {          String ss = getSentence();          byte[] family =  Bytes.toBytes(columnFamily);          byte[] rowKey =  Bytes.toBytes("" + Math.abs(r.nextLong()));          Put put =  new Put(rowKey);          put.add(family, Bytes.toBytes("DeviceID"),                   Bytes.toBytes("" + Math.abs(r.nextInt()) ));          ******          put.add(family,  Bytes.toBytes("Company_mmsegsm"), Bytes.toBytes("ss"));             return put;      } 

當然在運行上面這個程式之前,需要先在Solr裡面配置好你需要的列資訊,HBase、Solr安裝與配置,它們的基礎使用方法將會在之後的文章中 介紹。 在這裡,Solr的列配置就跟你使用createPut生成的Put搞成一樣的列名就行了,當然也可以使用動態列的形式。

四、直接對Solr效能測試

如果你不想對HBase與Solr的相結合進行測試,只想單獨對Solr的性能進行測試,這就更簡單了,完全可以利用上面的程式碼片段來測試,稍微組裝一下就可以了。

private static void sendConcurrentUpdateSolrServer(final String url,              final int count) throws SolrServerE xception, IOException {          SolrServer solrServer = new ConcurrentUpdateSolrServer(url, 10000, 20);         for (int i = 0; i < count; i++) {      solrServer.add(getInputDoc(PutCreater.createPut(columnFamily)));         }     }

希望可以説明到你規格嚴格-功夫到家。 這次的文章代碼又偏多了點,但代碼是解釋思想的最好的語言,我的提倡就是盡可能的減少代碼的注釋,盡力簡化你的代碼,使你的代碼足夠的清晰易懂,甚至於相似于偽代碼了,這也是《重構》這本書裡所提倡的。

原文連結:HTTP://www.cnblogs.com/wgp13x/p/3927979.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.