大数据架构-使用HBase和Solr将存储与索引放在不同的机器上

摘要:HBase可以通过协处理器Coprocessor的方式向Solr发出请求,Solr对于接收到的数据可以做相关的同步:增、删、改索引的操作,这样就可以同时使用HBase存储量大和Solr检索性能高的优点了,更何况HBase和Solr都可以集群。这对海量数据存储、检索提供了一种方式,将存储与索引放在不同的机器上,是大数据架构的必须品。
关键词:HBase, Solr, Coprocessor, 大数据, 架构

 
正如我的之前的博客“Solr与HBase架构设计http://http://www.cnblogs.com/wgp13x/p/a8bb8ccd469c96917652201007ad3c50.html​中所述,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) {
            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());
            String value = Bytes.toString(c.getValue());
            if (value.isEmpty()) {
                continue;
            }
            String fieldName = key.substring(key.indexOf(columnFamily) + 3,
                    key.indexOf("")).trim();
            doc.addField(fieldName, value);
        }
        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() {
                        for (int i = 0; i < 100000; i++) {
                            HbaseInsert.inputData(table,
                                    PutCreater.createPuts(1000, columnFamily));
                            Calendar c = Calendar.getInstance();
                            String dateTime = c.get(Calendar.YEAR) + "-"
                                    + c.get(Calendar.MONTH) + "-"
                                    + c.get(Calendar.DATE) + "T"
                                    + c.get(Calendar.HOUR) + ":"
                                    + c.get(Calendar.MINUTE) + ":"
                                    + c.get(Calendar.SECOND) + ":"
                                    + c.get(Calendar.MILLISECOND) + "Z 写入: "
                                    + i * 1000;
                            System.out.println(dateTime);
                        }
                    }
                };
                t.start();
            }
        } catch (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);
            table.flushCommits();
            puts.clear();
        } 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 SolrServerException, IOException {
        SolrServer solrServer = new ConcurrentUpdateSolrServer(url, 10000, 20);
        for (int i = 0; i < count; i++) {
            solrServer.add(getInputDoc(PutCreater.createPut(columnFamily)));
        }

}

 
 
希望可以帮助到你规格严格-功夫到家。这次的文章代码又偏多了点,但代码是解释思想的最好的语言,我的提倡就是尽可能的减少代码的注释,尽力简化你的代码,使你的代码足够的清晰易懂,甚至于相似于伪代码了,这也是《重构》这本书里所提倡的。

大数据架构-使用HBase和Solr将存储与索引放在不同的机器上的更多相关文章

  1. 【大数据技术】HBase与Solr系统架构设计

    如何在保证存储量的情况下,又能保证数据的检索速度. HBase提供了完善的海量数据存储机制,Solr.SolrCloud提供了一整套的数据检索方案. 使用HBase搭建结构数据存储云,用来存储海量数据 ...

  2. Hbase和Hive在大数据架构中处在不同位置

    先放结论:Hbase和Hive在大数据架构中处在不同位置,Hbase主要解决实时数据查询问题,Hive主要解决数据处理和计算问题,一般是配合使用.一.区别:Hbase: Hadoop database ...

  3. 一篇了解大数据架构及Hadoop生态圈

    一篇了解大数据架构及Hadoop生态圈 阅读建议,有一定基础的阅读顺序为1,2,3,4节,没有基础的阅读顺序为2,3,4,1节. 第一节 集群规划 大数据集群规划(以CDH集群为例),参考链接: ht ...

  4. 大数据架构师必读的NoSQL建模技术

    大数据架构师必读的NoSQL建模技术 从数据建模的角度对NoSQL家族系统做了比较简单的比较,并简要介绍几种常见建模技术. 1.前言 为了适应大数据应用场景的要求,Hadoop以及NoSQL等与传统企 ...

  5. 后Hadoop时代的大数据架构(转)

    原文:http://zhuanlan.zhihu.com/donglaoshi/19962491 作者: 董飞       提到大数据分析平台,不得不说Hadoop系统,Hadoop到现在也超过10年 ...

  6. 大数据架构师基础:hadoop家族,Cloudera产品系列等各种技术

    大数据我们都知道hadoop,可是还会各种各样的技术进入我们的视野:Spark,Storm,impala,让我们都反映不过来.为了能够更好的架构大数据项目,这里整理一下,供技术人员,项目经理,架构师选 ...

  7. 后Hadoop时代的大数据架构

    提到大数据分析平台,不得不说Hadoop系统,Hadoop到现在也超过10年的历史了,很多东西发生了变化,版本也从0.x进化到目前的2.6版本.我把2012年后定义成后Hadoop平台时代,这不是说不 ...

  8. 阿里巴巴飞天大数据架构体系与Hadoop生态系统

    很多人问阿里的飞天大数据平台.云梯2.MaxCompute.实时计算到底是什么,和自建Hadoop平台有什么区别. 先说Hadoop 什么是Hadoop? Hadoop是一个开源.高可靠.可扩展的分布 ...

  9. 大数据篇:Hbase

    大数据篇:Hbase Hbase是什么 Hbase是一个分布式.可扩展.支持海量数据存储的NoSQL数据库,物理结构存储结构(K-V). 如果没有Hbase 如何在大数据场景中,做到上亿数据秒级返回. ...

随机推荐

  1. 点餐APP 冲刺三总结

    一转眼所有的冲刺都完成了,而今次的冲刺主要是完善数据库,而我们 也成功地实现了,虽然过程很艰辛,但是我们每一个人都学习到了很多新 知识,这是最好的收获.因为今学期没有软件工程的课程,所以大家都是 利用 ...

  2. C#设计模式——迭代器模式(Iterator Pattern)

    一.概述在软件开发过程中,我们可能会希望在不暴露一个集合对象内部结构的同时,可以让外部代码透明地访问其中包含的元素.迭代器模式可以解决这一问题.二.迭代器模式迭代器模式提供一种方法顺序访问一个集合对象 ...

  3. [水煮 ASP.NET Web API 2 方法论] 目 录

    一.ASP.NET 中的 Web API [水煮 ASP.NET Web API2 方法论](1-1)在MVC 应用程序中添加 ASP.NET Web API 与 ASP.NET MVC 在同一个进程 ...

  4. 【WP8.1】富文本

    之前写过一篇WP8下的富文本的文章,但是写的不是很好,整理了一下,分享一下WP8.1下的富文本处理 富文本处理主要是对表情和链接的处理,一般使用RichTextBlock进行呈现 问题说明: 由于Ri ...

  5. Sql发布订阅设置不初始化订阅库架构的设置

    参考:http://www.cnblogs.com/TeyGao/p/3521231.html

  6. 关于c++数的进制的经验

    默认状态下,数据按十进制输入输出.如果要求按八进制或十六进制输入输出,在cin或cout中必须指明相应的数据形式,oct为八进制,hex为十六进制,dec为十进制. 注意: 1.使用不带.h的头文件& ...

  7. Java文件编码自动转换工具类(只改变编码,不会改变文件内容)

    本篇随笔主要介绍了一个用java语言写的将一个文件编码转换为另一个编码并不改变文件内容的工具类: 通过读取源文件内容,用URLEncoding重新编码解码的方式实现. public class Cha ...

  8. ahjesus C# Flags 位域略说

    class Program { [Flags] public enum Week { [Description("星期一")] Monday = << , [Descr ...

  9. .Net开源项目之开源论坛

    .Net开源项目非常多,但是开源并且直接就能用的BBS项目就很少了,至少最近我在这上面没有找到一个合适的开源论坛.可能是因为我要求比较特殊,不但要开箱即用,还要用MVC+MySql开发. Discuz ...

  10. SQL数据库基础(三)

    认识数据库备份和事务日志备份 数据库备份与日志备份是数据库维护的日常工作,备份的目的是在于当数据库出现故障或者遭到破坏时可以根据备份的数据库及事务日志文件还原到最近的时间点将损失降到最低点. 数据库备 ...