paulwong

#

Eclipse下svn的创建分支/合并/切换使用

       最近接项目要求,要在svn主干上创建分支,用分支来进行程序的bug修改,而主干上进行新功能的开发。分支上的bug修改完,发布后,可以合并到主干上。项目程序可以在主干和分支之间进行切换,来实现主干和分支的同时维护。

       1.创建分支

        创建分支实际上就是将程序copy一份到指定的分支目录,如下图示:



在项目名称上点击右键,弹出菜单,选择“Team”,再选择“Branch/Tag”,弹出下面的页面: 



 

上图中的“Copy to URL”填写创建新分支的路径地址,后面会将程序copy到该目录下,形成新的分支。点击“Next:

 

 

选择当前最新的版本,点击“Next



 

如果勾选了上图下面的switch working copy to new branch/tageclipse的程序项目会自动切换到分支下。这里我们不选择,待会自己切换

这样就创建了一个1.0的分支

         2.合并

         可以从主干合并到分支,也可以从分支合并到主干,根据需要可以选择合适的选项,如下图:



 

上图中的选项:

        1) 从主干合并到分支

        2) 从分支合并到主干

        3) 将主干上的修改合并到分支

        4) 合并2个分支到主干

        5) 从主干到分支,手工指定不需要合并的修改

        6) 从主干到分支,手工指定要合并的修改



 

上图显示没有任何修改,所以不用进行合并。

 

3.切换

在项目名称上点击右键,选择“Team –> switch to another Branch/Tag/Revision”。



 

选择需要切换的目的地址,点击ok即可。

 

这样,在项目里就可以在主干和若干分支间进行任意切换,来实现对不同版本/分支的程序进行修改提交操作。

posted @ 2014-12-26 13:19 paulwong 阅读(989) | 评论 (0)编辑 收藏

Tuscany 2 的基本配置与流程

实习期间mentor让看看Tuscany——apache的一个顶级项目。之前一直没有接触过,听mentor说了下用途过后,感觉其像是alibaba的分布式服务框架Dubbo,简要看了看,似乎和RMI也有相关性。总之它也是面向服务的分布式框架。经过一下午的尝试,发现Tuscany 2和Tuscany 1还是有比较大的不同(API方面、设计思想没有深入研究不知道),网上关于Tuscany的资料也不多,所以在此写文章mark一下。

Tuscany 1的API参考这位博主http://blog.csdn.net/ajun_studio/article/details/7770023


1. 准备

首先是在工程中引入Tuscany 2.0.1的jar包,从一个Apache的China镜像上不难找到(PS:Tuscany 1在官网上已经不维护了)。

工程需要实现客户端调用远程服务器端的服务的功能。该项目中调用远程完成“加”的功能。


2. 入门

首先添加IAdd接口

package com.ajun.tuscany.server;  
  
public interface IAdd {  
    double add(double n1,double n2);  
}  
然后是实现类Add

package com.ajun.tuscany.server;  
  
public class Add implements IAdd {  
  
    @Override  
    public double add(double n1, double n2) {  
        // TODO Auto-generated method stub  
        return n1 + n2;  
    }  
  
加减乘除都属于“计算”类,此处为了简便,只实现“加”方法。然后是“计算”的接口。

package com.ajun.tuscany.server;  
  
public interface ICalculator {  
    double add(double n1, double n2);  
}  
然后是“计算”的实现,注意一定要在setter中加入@Reference,否则会报错,这里类似于Spring的注入。

package com.ajun.tuscany.server;  
  
import org.oasisopen.sca.annotation.Reference;  
  
public class Calculator implements ICalculator {  
  
    private IAdd add;  
  
    public IAdd getAdd() {  
        return add;  
    }  
  
    @Reference  
    public void setAdd(IAdd add) {  
        this.add = add;  
    }  
  
    @Override  
    public double add(double n1, double n2) {  
        // TODO Auto-generated method stub  
        return this.add.add(n1, n2);  
    }  
  
}  
到此,基本的业务逻辑类就编写好了,接下来,是Tuscany中重要的配置文件,即XXX.composite,其本质也是一个xml。如果不是面向分布式服务,该xml文件结构类似Spring的application.xml。下面是Calculator.composite,注意配置文件中reference,name标记为add,应该也是同Spring的大写首字母规则,通过settrt注入。

<?xml version="1.0" encoding="UTF-8"?>           
<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"  
           xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1"  
           targetNamespace="http://sample"  
           xmlns:sample="http://sample"  
           xmlns:scallop="http://scallop/xmlns/sca/1.1"   
           name="Calculator" >    
      
    <component name="CalculatorServiceComponent">    
        <implementation.java class="com.ajun.tuscany.server.Calculator" />  
        <reference name="add" target="AddComponent"/>     
    </component>    
          
    <component name="AddComponent">    
        <implementation.java class="com.ajun.tuscany.server.Add" />    
    </component>    
      
</composite>   

最后是运行main的类

package com.ajun.tuscany.server;  
  
import org.apache.tuscany.sca.node.Node;  
import org.apache.tuscany.sca.node.NodeFactory;  
  
public class StartService {  
  
    public static void main(String[] args) {  
        Node node = NodeFactory.newInstance().createNode(  
                "Calculator.composite");  
        node.start();  
        System.out.println("service启动");  
        ICalculator c = node.getService(Calculator.class,  
                "CalculatorServiceComponent");  
        System.out.println(c.add(2, 2));  
    }  
  
运行输出如下

2014-11-10 17:39:24 org.apache.tuscany.sca.node.impl.NodeFactoryImpl loadContributions
信息: Loading contribution: file:/E:/HuRanjie/EclipseWorkspace/Calculatoer_01/bin/
2014-11-10 17:39:24 org.apache.tuscany.sca.host.rmi.DefaultRMIHost registerService
信息: RMI service registered: rmi://127.0.0.1:8099/CalculatorRMIService
2014-11-10 17:39:24 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl addEndpoint
信息: Add endpoint - binding.rmi - rmi://127.0.0.1:8099/CalculatorRMIService
2014-11-10 17:39:24 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl addEndpoint
信息: Add endpoint - binding.sca - AddComponent/Add
service启动
4.0


3. 远程调用rmi

上面并没有将“计算”类作为一个服务,暴露给远程调用,只是实现了本地的装配。下面将其作为服务给远程调用,后面可以看到,只需要暴露一个包括host、port、serviceName


首先,修改配置文件,修改为如下样子——在本地(127.0.0.1)的8099端口暴露出名字为CalculatorRMIService的服务

<?xml version="1.0" encoding="UTF-8"?>           
<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"  
           xmlns:tuscany
="http://tuscany.apache.org/xmlns/sca/1.1"  
           targetNamespace
="http://sample"  
           xmlns:sample
="http://sample"  
           xmlns:scallop
="http://scallop/xmlns/sca/1.1"   
           name
="Calculator" >    
      
    <component name="CalculatorServiceComponent">    
        <implementation.java class="com.ajun.tuscany.server.Calculator" />  
          
        <service name="Calculator">    
            <interface.java interface="com.ajun.tuscany.server.ICalculator"/>    
            <tuscany:binding.rmi uri="rmi://127.0.0.1:8099/CalculatorRMIService"/>    
        </service>  
          
        <reference name="add" target="AddComponent"/>     
    </component>    
          
    <component name="AddComponent">    
        <implementation.java class="com.ajun.tuscany.server.Add" />    
    </component>    
      
</composite>   

服务器端的main主要功能是启动该服务,如下

package com.ajun.tuscany.server;  
  
import org.apache.tuscany.sca.node.Node;  
import org.apache.tuscany.sca.node.NodeFactory;  
  
public class StartService {  
  
    public static void main(String[] args) {  
        Node node = NodeFactory.newInstance().createNode(  
                "Calculator.composite");  
        node.start();  
        System.out.println("service启动");  
    }  
  

客户端通过rmi调用服务器端的服务,来实现功能,如下

package com.ajun.tuscany.client;  
  
import java.rmi.Naming;  
import com.ajun.tuscany.server.ICalculator;  
  
public class CalculatorClient {  
  
    public static void main(String[] args) throws Exception {  
         ICalculator c= (ICalculator) Naming.lookup("//127.0.0.1:8099/CalculatorRMIService");    
         System.out.println(c.add(1, 2));    
    }  
}  

启动服务端输出


2014-11-10 18:00:30 org.apache.tuscany.sca.node.impl.NodeImpl start
信息: Starting node: http://tuscany.apache.org/sca/1.1/nodes/default0 domain: default
2014-11-10 18:00:30 org.apache.tuscany.sca.node.impl.NodeFactoryImpl loadContributions
信息: Loading contribution: file:/E:/HuRanjie/EclipseWorkspace/Calculatoer_01/bin/
2014-11-10 18:00:31 org.apache.tuscany.sca.host.rmi.DefaultRMIHost registerService
信息: RMI service registered: rmi://127.0.0.1:8099/CalculatorRMIService
2014-11-10 18:00:31 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl addEndpoint
信息: Add endpoint - binding.rmi - rmi://127.0.0.1:8099/CalculatorRMIService
2014-11-10 18:00:31 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl addEndpoint
信息: Add endpoint - binding.sca - AddComponent/Add
service启动

客户端输出

3.0

posted @ 2014-12-24 14:07 paulwong 阅读(1836) | 评论 (0)编辑 收藏

SOA资源

Tuscany
档案项目架构文档SOA搭建过程
http://www.open-open.com/doc/view/54781005211b45fda0c15a44110efeaf


大用户量下的系统架构(SOA)
http://www.open-open.com/doc/view/2def65d401e949c1b8fe3bc306701234

posted @ 2014-12-23 23:53 paulwong 阅读(362) | 评论 (0)编辑 收藏

SequoiaDB巨杉数据库

SequoiaDB(巨杉数据库)是一款分布式文档型NoSQL数据库,是业界唯一支持事务和SQL的产品。SequoiaDB既可作为Hadoop与Spark的数据源以满足实时查询和分析的混合负载,也可独立作为高性能、
灵活易用的数据库被应用程序直接使用。SequoiaDB已拥有的客户包括知名IT互联网公司和世界五百强企业。


http://www.sequoiadb.com/index.php?p=demo

posted @ 2014-12-22 23:18 paulwong 阅读(624) | 评论 (0)编辑 收藏

10 个词让你看懂今年的移动互联网

时光荏苒,如白驹过隙。转眼间 2014 年就要过去了,群雄逐鹿、狼烟四起,跌宕与沉浮,光荣与梦想。

这一年,京东上市了,尽管近几年来持续亏损,但其估值却达到了 257 亿美元,刘强东和奶茶妹的故事开始在坊间流传;

这一年,聚美伴随着质疑和批评成功 IPO 了,陈欧这个年轻的帅小伙成功地完成了屌丝的逆袭;

这一年,举世瞩目的阿里以 2613 亿美元的市值超越亚马逊和 EBay 总和,马云也一跃跻身为亚洲新首富;

这一年,以 30 亿美元估值的“约炮神器”陌陌成功登上了纳斯达克,其创始人唐岩也成为最富有争议的 CEO;

……

这一年,微商、众筹、O2O、自媒体、境外电商、互联网金融、P2P 租车、大数据、移动支付、社会化营销等成为最大的移动互联网风口。下面笔者就和大家一起来盘点一下,这一年移动互联网都发生了什么。

1. 微商

微盟 CEO 孙涛勇说,如果今年是 O2O 元年的话,那么 2015 年必是微商元年。笔者基本认可这个预判,微信已经积累了 8 亿的用户,每刷一次朋友圈必有一个是卖货、代购的。因为智能手机的普及,我们已经步入了人人微商、人人营销的时代。

未来零售渠道比例,传统电商占 30%,微商占 30%,线下会占 40%。大家都在讲颠覆,但是未来线下会永远存在,中心化电商会一直存在,每个人都有线下购物的习惯,不可能完全颠覆,但是份额会逐步转到微商。微商到底 有没有未来,这注定是没有答案。看好的依旧看好,看衰的依旧看衰,2015 年的微商注定依旧是在争议中前行。

点评:2015 年注定是不平凡的一年,此起彼伏的微商究竟是道路曲折还是前途光明,也许只有时间才能给我们答案。

2. 众筹

2014 年无疑众筹行业被全面渗透的一年,众筹平台从异军突起到巨头入局经历了不同形态的变化。当前,众筹行业逐渐演变成股权众筹、回报众筹和公益众筹并存的局面。

众筹是指用团购+预购的形式,向网友募集项目资金的模式。无论是娱乐宝众筹电影,还是逻辑思维众筹的“真爱月饼”、朋友圈众筹购物,他们都把众筹玩的风生水起。

除创业大资本外,众筹的玩法也越来越多,内容领域也逐渐扩展到艺术、影视、音乐、出版等各个领域,甚至创造出了众筹建旅馆、买房买地的模式。我们看 到了众筹让很多创业项目得以更好的生存下来,更多更好更富有创意的理念得以展现在大众面前,但同时股权众筹仍然徘徊在法律边缘,而谈到众筹如何落地?如何 落好、落稳?还有很多问题亟待解决。

点评:从异军突起到巨头入局,几家欢乐几家愁?

3. O2O

纵观今年的互联网界,可谓亮点频出,眼球不断地被锁定,注意力也在不断被转移,今年最火的一个词:O2O。提起来这个词大家都知道它意味着什么。无论是资本的流动还是资源的整合,都出现了颠覆性的创新。

2014 年的 O2O 发展的如火如荼,主要有这两个表现:第一,传统多元化行业转型创新。在受 O2O 冲击下,在不断地寻求转型之道,应该来说是以餐饮为起点,进而衍生出很多 O2O 项目,如零售、旅游、社区、汽车、金融、母婴、包括家政、甚至说婚嫁 O2O,烧钱很厉害的打车项目,充满血腥的外卖项目,可能最近的也有很多的项目类似于洗车,便利店,回收等等在不断的被催生着,这些项目都在企业中探索 着。第二,互联网大背景下,网民的消费习惯,智能设备的推进。O2O 催生的 APP 越来越多,手机屏幕越来越丰富。

从长远分析来看,O2O 分三个阶段在发展:第一个阶段需要回归到 2013 年称作 O2O 元年;第二阶段是 2014 年,为井喷式爆发阶段,各行业都在躁动,都在跟进,都在思考。第三阶段是 2015 年之后,可能是生存之战了,也就是融资都花完了之后,看谁的产品能得到市场的认可,谁就能活下来,也可以说是运营模式之争。

点评:赔钱赚吆喝的 O2O,2015 年将迎来大洗牌。

4. 自媒体

据不完全统计,微信公众号数量已经超过 800 万,中国自媒体作者数已超过 15 万 7 千人,微信朋友圈每天阅读数已接近 300 亿。自媒体是 2013 年年度互联网十大词汇之一。从微信公众平台到腾讯大家、知乎、果壳网、虎嗅网,各种网络运营平台更层出不穷,自媒体结合微博、微信、轻博客、新闻客户端、 视频网站各种形式,以文字、语音、视频等方式万箭齐发,自成天地。

先是一个叫罗振宇的胖子创造了媒体圈的传奇,然后微博公知、意见领袖、媒体大佬、各界名人 2013 年纷纷推出了自己的自媒体平台,高晓松携《晓说》在优酷播出,黄健翔联合乐视网推出《黄·段子》,韩寒团队经营《ONE》,方舟子、留一手、孙立平入驻搜 狐新闻,吴晓波、曾航、和菜头、东东枪、张悦然、安妮宝贝开通微信公号……

自媒体有几个重要的特性,一是,都是以个人为单位的,自媒体是副业,比如早期就职腾讯的程苓峰,是第一个通过微信公众平台成功变现的自媒体人。二 是,自媒体的发表渠道依靠其他人,自己不可控。比如博客(新浪博客由新浪控制)、微博(新浪或腾讯控制)、微信(腾讯控制)。不可控,决定了收入和控制权 都大权旁落。这两个重要的特性决定了自媒体的最重要的一个问题,自媒体大都难以商业化,也就是通常所说的“变现”问题。很大程度上这只是个人博客的变异。 另外自媒体亦有许多限制,占用时间,无正规运作流程,无内容监管,无清晰操作思路。

点评:@青龙老贼:“世间再无自媒体”,自媒体可能会消失,但是依托自媒体变现的人会永远存在,无法言说的自媒体,难以变现的痛。

5. 跨境电商

这年头,如果你没在的微信朋友圈刷出一两条代购信息,那只能说你还没有“国际化”。如何理解跨境电商?从交易的走向来讲,跨境电商分为两个部分:一是“买进来”就是所谓的海淘、代购;二是“卖出去”对外贸易中的出口(零售、批发);后者以已在美国上市的兰亭集势为代表。

洋码头、蜜淘、蜜芽宝贝、买个便宜货等 10 家颇具代表性的跨境电商公司露出尖尖角。从模式来看,10 家中仅一两家是综合性交易平台,其余都在垂直细分领域,其中限时特卖模式受追捧,母婴、美妆、服饰类目最为普遍。

跨境电商 2014 年发生了很多变化,虽然市场份额不如国内的电商那么大,运营手段也不如国内那么丰富,但有一点比较肯定,就是执行速度比较快。在地域分布上,采购紧靠货 源,如深圳的 3C、广州的服装、义乌的小商品、福建的玩具等,而运营直接放到南京、杭州等地区,或者是大城市的郊区。海外仓逐步开始完善,物流由于阿里的大力投入,诸 如俄速通、新加坡小包、荷兰邮政等已经比较完善。产品方面变化更大,零售开始逐步和工厂联合,有的直接在国内联合淘品牌,开始做 1688。还有的外贸电商都开始做内贸的生意了,直接入驻天猫国际。

点评:跨境电商注定是 BAT 下一个商战红海。

6. 互联网金融

回顾即将过去的 2014 年,中国互联网金融的有不少进展,但也有曲折的一面。P2P 经过 2013 年的疯狂扩张之后,在监管力度和法规完善后趋于理性;腾讯、阿里先后获银监会批准,拿到民营银行的牌照;众筹平台如雨后春笋般涌现;京东推出了“白条”, 阿里小微金融更名为“蚂蚁金融”产品也从去年的余额宝创新出娱乐宝,在眼球和收益上都有一番斩获。

中国的互联网金融发展迅速,在 2014 年短短的一年时间,互联网金融创业者们融资额度一再创新高,雨后春笋般涌现的各类互联网金融产品让用户眼花缭乱。我们看到了这一行业的发展价值,但是野蛮生长的态势该缓一缓了。

点评:2015 年注定将是互联网金融业进行更多思考的年头,野蛮的发展趋势将或主动或被动地得到缓解,能否真正走上发展的正轨,路途中还有很多荆棘需要互联网金融从业者来跨越。

7. P2P 租车

2014 年,P2P 不仅继续吸引无数投资人进入,P2P 的平台也赢得了各路大资本的青睐。今年一季度包括爱投资、人人投、积木盒子以及拍拍贷等平台均获得了数额不小的投资进入下半年,P2P 平台进入了一个月内数家平台同时获投的疯狂融资阶段,仅 7 月份就有 8 个平台获得千万美元至上亿美元的投资。国有资本的热情涌入,很多业内人士都将此理解为国家态度和宽松政策的预兆,这解决了一直悬而未决的“一刀 切”P2P 政策性风险的问题。

看似繁荣的 P2P 市场实则暗流汹涌,目前大部分的 P2P 平台只能说是披着 P2P 外衣的金融机构,而且大部分是没有资质认证的,所以说政策还将会进一步规范和完善,这将在很大程度上使 P2P 行业发展更加健康。但国有资本等强势资本的引入无疑证明了 P2P 存在以及发展的价值。

点评:混乱的资本市场,已经到了疯狂厮杀的地步,未来的战场,不是你死就是我亡。

8. 大数据

借助大数据的力量进行巫术般的精准营销,年初爆红的美剧《纸牌屋》将大数据引入了普通人的视野。大数据无疑是当下除移动互联网外 IT 领域最热的讨论,简言之,从各种各样类型的数据中,快速获得有价值信息的能力,就是大数据技术。

近期支付宝发布十年对账单,为用户梳理自支付宝诞生至今的购物、理财、生活缴费等全套数据。在一串串光鲜的数字背后,也成就了一段段剁手族的败家 史。不过不少网友在收到自己的账单后,惊呼“不忍直视”、“不知不觉可以买房了”、“原来自己也是高富帅”、“我的首付给了支付宝”等。

数据确实有巨大的价值,但是即便你非常小心,但依然有可能因为数据的歧义以及麻烦而得出错误的答案。因为即便我们拥有所有的数据,但仍然和现实会有 偏差。而且你必须要保证你的数据对于特定的问题来说是准确的,而且遵循最佳的数据归纳法。即使这样,也有可能得出完全意想不到的结果。

点评:人人都在谈论大数据,都在运用大数据,然而大而多的数据,并没有达到精而准的效果。

9. 移动支付

关于第三方支付,不管起步早晚,银联在市场是具备强势的话语权的。汇付天下执行副总裁刘钢回应 79 号文的时候,一句“两年走了四年的路,对于央行的惩罚,我们服。”让不少第三方支付企业都感到了一阵小心酸。

但不得不说的是,央行的“为难 ”也促进了第三方支付行业的自省。POS 机违规套现、违规套用低费率行业商户类别码等问题的频频爆出,让不少人稍微理解了央行总是跳脚的部分原因。乃至于 9 月,央行再次处罚汇付天下、富友、易宝、随行付四家机构,并勒令四家支付机构撤出部分省市收单市场的时候,大家关注的焦点也变成了收单市场的规范问题。

面对“越改越乱”的第三方支付市场,一方面是行业竞争的加剧导致有的企业不惜兵行险招,造成行业乱象;一方面却是要时刻小心拿着大棒的央行叫停开罚单。估计未来大波浪曲线前进的节奏不会有太大改变。但如何获得市场青睐,走正道才是主要的。

点评:2015,曲线前进的移动支付,能否走上康庄大道?

10. 社会化营销

在这一年中,微信从 5.0 升级到 6.0,新增的 6s 短视频在朋友圈中一夜间风靡;微博紧跟潮流升级了新版客户端,尽管效果与反响都不尽人意;豆瓣总算发布了一个真正意义上的移动端应用“豆瓣”APP,虽姗 姗来迟但却也惊喜连连。这一年,有趣的互动营销从未离开过我们的生活,从一开年就席卷微博的“马上体“到后来掀起风潮的”ALS 冰桶挑战“,让我们看到了互动营销的无限可能性。

从“ALS 冰桶挑战”到韩寒《后会无期》的上映,是一场完美的大佬明星吆喝粉丝的社会化营销。然而本年度最好看的营销莫过于“史上网络第一约架”——罗永浩 PK 王自如。两人从一开始的微博呛声到 8 月 27 日晚的优酷直播,整个过程不禁让人感叹自己以前吵过的架都太 nave 了。吵架的原因起源于第三方评测机构 Zealer 做了关于锤子手机的评测视频,视频中王自如对手机的相关配置提出质疑,老罗不服,约架便诞生了。

老罗用情怀做手机,将粉丝经济完美应用,仍无法掩饰锤子手机不是“世界第二好用”手机的事实。当然,这场“互联网第一架”还有一个大赢家,那便是买断这三小时版权的优酷。

点评:移动互联网将我们带到了全民参与、全民营销的时代,未来的营销还能怎么玩,也许不再是大佬名人的“独角戏”了。

结语

即将过去的 2014,对于从事移动互联网的人来说就一个字:累。各种颠覆各种思维铺天盖地,技术的日新月异,市场的千变万化。稍不留神就会错失良机。每个行业都是一 个风口,每个风口都有每个风口的机遇和挑战,能不能飞得起来,还要看最终的实施情况,梦想还是要有的,万一实现了呢?

posted @ 2014-12-21 22:13 paulwong 阅读(366) | 评论 (0)编辑 收藏

编译HADOOP源码

https://github.com/apache/hadoop/blob/trunk/BUILDING.txt

配置 eclipse 编译、开发 Hadoop(MapReduce)源代码
http://blog.csdn.net/basicthinker/article/details/6174442

hadoop2.2.0源代码编译
http://my.oschina.net/cloudcoder/blog/192224

Apache Hadoop 源代码编译环境搭建
http://qq85609655.iteye.com/blog/1986991



  1. Download code from https://codeload.github.com/apache/hadoop/zip/trunk, then unzip it, there is a folder hadoop-trunk.
    wget https://codeload.github.com/apache/hadoop/zip/trunk
    unzip trunk
  2. Install native libraries
    Ubuntu
    sudo apt-get -y install maven build-essential autoconf automake libtool cmake zlib1g-dev pkg-config libssl-dev

    Cent OS
    yum -y install  lzo-devel  zlib-devel  gcc autoconf automake libtool openssl-devel cmake
    get protobuf zip from http://f.dataguru.cn/thread-459689-1-1.html
    ./configure
    make
    make check
    make install
  3. $vi /etc/profile
    export PROTOC_HOME=/root/java/hadoop-source/protobuf-2.5.0
    export PATH=$PATH:$PROTOC_HOME/src
  4. cd to hadoop-trunk, run 
    mvn compile -Pnative
  5. cd to hadoop-maven-plugins, run
    mvn install
  6. cd to hadoop-trunk
    mvn install -DskipTests
  7. Make sure still in hadoop-trunk folder, Build Eclipse project
    mvn eclipse:eclipse -DskipTests
  8. Import the maven project to Eclipse


posted @ 2014-12-16 01:41 paulwong 阅读(333) | 评论 (0)编辑 收藏

simplehbase

https://github.com/zhang-xzhi/simplehbase/ 
https://github.com/zhang-xzhi/simplehbase/wiki 


simplehbase的主要功能 

数据类型映射:java类型和hbase的bytes之间的数据转换。 
简单操作封装:封装了hbase的put,get,scan等操作为简单的java操作方式。 
hbase query封装:封装了hbase的filter,可以使用sql-like的方式操作hbase。 
动态query封装:类似于myibatis,可以使用xml配置动态语句查询hbase。 
insert,update支持: 建立在hbase的checkAndPut之上。 
hbase多版本支持:提供接口可以对hbase多版本数据进行查询,映射。 
hbase批量操作支持。 
hbase原生接口支持。 
HTablePool管理。 
HTable count和sum功能。 

posted @ 2014-12-15 18:26 paulwong 阅读(291) | 评论 (0)编辑 收藏

街头象棋残局破解

五虎将军
http://v.youku.com/v_show/id_XMjE1MzI1MjM2.html?from=y1.2-1-98.4.25-1.1-1-2-24

错误走法
http://v.youku.com/v_show/id_XNDEwNzM3MzY4.html?from=y1.2-1-176.3.2-1.1-1-1-1


http://v.youku.com/v_show/id_XMTk4NjMyNzM2.html


十八罗汉斗四大金刚
http://v.youku.com/v_show/id_XNDQwMTIyMTUy.html?from=y1.2-1-98.3.2-1.1-1-1-1


http://x.youku.com/tag/lists?t=469108

!晴天霹雳(30:24)
http://www.56.com/u38/v_OTE3MzYzMzE.html

!双兵连营
http://www.56.com/u20/v_MTI3NTA2NjQx.html

http://www.icanju.cn/wodig.asp?Src_Child=-1&order_by=1&Tags_Name=%BD%AD%BA%FE%C6%E5%BE%D6%CB%D1%C3%D8&Tags_ID=&S_Havving=&Page=2&user_id=
a

posted @ 2014-12-09 23:03 paulwong 阅读(3568) | 评论 (0)编辑 收藏

应用系统架构

做任何一个应用系统,比如银行核心、ERP核心、订票系统等等,应用系统都包括三个架构:1)业务架构;2)系统架构;3)实施架构。


1)业务架构
业务架构是应用系统的业务范围的具体划分和体现。业务架构与将要落地的系统平台无关。
业务架构的搭建,可以在概设阶段完成轮廓的搭建,对一些具体的细节,可以没有,或将会存在。但是,要在架构搭建过程中,把控着,或设计者,要留有充分的包容余地。

业务架构具体内容,要有粗细业务流的体现。每个业务流肯定要行得通。对综合或交叉的业务流要详细划分,按通用性,或者特殊性,划分为各自的子集。

业务架构要包括应用系统项目的当前实施范围,或将要实施的范围。

业务架构应该做到,业务范围内容的增加,不影响已经搭建好的业务架构,并且,比较容易地融合到业务架构中。

在业务架构搭建过程中,对熟悉的、惯例的业务用细业务流按模块划分,进行描述。对没有落地的业务内容,按粗业务流进行模块划分描述。划分好的业务功能模块,在业务架构中是唯一的,不能重叠。

2)系统架构
系统架构是业务架构落实到具体硬件平台的应用,硬件平台如HP-UX、RS6000、ES9000、AS400等等,操作系统如UNIX、AIX、390 Z系统、OS400、LINUX等等。

架构师的责任就是把业务架构的各个模块在一个单独硬件平台上,或一个整体,包括多个层次复杂的综合硬件系统平台上,把应用系统落实在最能体现硬件平台运行效率的地方。

业务架构是有范围的,在现有状况下,或将来一定时间段,实现的业务架构都会满足现有项目需求。

优秀的架构师,整体观要非常强,精通当今至少一条行业技术方向和主要技术,熟悉当今IT潮流硬件平台,和在此之下的潮流软件实施技术。

架构师不是万能的,但是,在架构师的统帅下,各分支的模块架构实现,要根据架构师规划和设计的系统架构轮廓进行实施,具体模块实现要team leader,根据模块特征,做具体技术设计和实现。

架构师职责之一,就是把控应用系统项目实施规范。

打个比方,IT架构师,就像建筑总体架构师,业务架构就像一个建筑架构,比如一个社区的建筑规划,哪里是居住区?哪里是电影院?哪里是超市?等等,这些都是在社区建设初期,架构师就要设计和规划出轮廓。对具体细节操作,比如社区中有一块区域要建筑一座楼房,第三层要实现中式复古装修;第四层要实现欧式宫廷式装修,等等,每一层都有各自熟悉精通这方面的team leader设计领导实施。

架构师的职责之一,就是会懂得用人,把各team leader放在最能发挥作用的地方。

一个好的应用系统,不会因为业务扩充或变化,而影响应用系统运行和运行效率。不提倡打补丁的做法。功能唯一,包括功能代码唯一,是好的系统架构的保障,同时也是评价一个优秀架构师的标准。

3)实施架构
实施架构是系统架构具体实现手段,是体系项目实施提升效率的具体实施行为。

posted @ 2014-12-04 22:15 paulwong 阅读(322) | 评论 (0)编辑 收藏

基于Solr的HBase多条件查询测试

背景:

某电信项目中采用HBase来存储用户终端明细数据,供前台页面即时查询。HBase无可置疑拥有其优势,但其本身只对rowkey支持毫秒级的快速检索,对于多字段的组合查询却无能为力。针对HBase的多条件查询也有多种方案,但是这些方案要么太复杂,要么效率太低,本文只对基于Solr的HBase多条件查询方案进行测试和验证。

原理:

基于Solr的HBase多条件查询原理很简单,将HBase表中涉及条件过滤的字段和rowkey在Solr中建立索引,通过Solr的多条件查询快速获得符合过滤条件的rowkey值,拿到这些rowkey之后在HBASE中通过指定rowkey进行查询。

测试环境:

solr 4.0.0版本,使用其自带的jetty服务端容器,单节点;

hbase-0.94.2-cdh4.2.1,10台Lunux服务器组成的HBase集群。

HBase中2512万条数据172个字段;

Solr索引HBase中的100万条数据;

测试结果:

1、100万条数据在Solr中对8个字段建立索引。在Solr中最多8个过滤条件获取51316条数据的rowkey值,基本在57-80毫秒。根据Solr返回的rowkey值在HBase表中获取所有51316条数据12个字段值,耗时基本在15秒;

2、数据量同上,过滤条件同上,采用Solr分页查询,每次获取20条数据,Solr获得20个rowkey值耗时4-10毫秒,拿到Solr传入的rowkey值在HBase中获取对应20条12个字段的数据,耗时6毫秒。

以下列出测试环境的搭建、以及相关代码实现过程。

一、Solr环境的搭建

因为初衷只是测试Solr的使用,Solr的运行环境也只是用了其自带的jetty,而非大多人用的Tomcat;没有搭建Solr集群,只是一个单一的Solr服务端,也没有任何参数调优。

1)在Apache网站上下载Solr 4:http://lucene.apache.org/solr/downloads.html,我们这里下载的是“apache-solr-4.0.0.tgz”;

2)在当前目录解压Solr压缩包:

 -xvzf apache-solr-..tgz

3)修改Solr的配置文件schema.xml,添加我们需要索引的多个字段(配置文件位于“/opt/apache-solr-4.0.0/example/solr/collection1/conf/”)

   <field name="rowkey" type="string" indexed="true" stored="true" required="true" multiValued="false" />     <field name="time" type="string" indexed="true" stored="true" required="false" multiValued="false" />    <field name="tebid" type="string" indexed="true" stored="true" required="false" multiValued="false" />    <field name="tetid" type="string" indexed="true" stored="true" required="false" multiValued="false" />    <field name="puid" type="string" indexed="true" stored="true" required="false" multiValued="false" />    <field name="mgcvid" type="string" indexed="true" stored="true" required="false" multiValued="false" />    <field name="mtcvid" type="string" indexed="true" stored="true" required="false" multiValued="false" />    <field name="smaid" type="string" indexed="true" stored="true" required="false" multiValued="false" />    <field name="mtlkid" type="string" indexed="true" stored="true" required="false" multiValued="false" />

另外关键的一点是修改原有的uniqueKey,本文设置HBase表的rowkey字段为Solr索引的uniqueKey:

<uniqueKey>rowkey</uniqueKey>

type 参数代表索引数据类型,我这里将type全部设置为string是为了避免异常类型的数据导致索引建立失败,正常情况下应该根据实际字段类型设置,比如整型字段设置为int,更加有利于索引的建立和检索;

indexed 参数代表此字段是否建立索引,根据实际情况设置,建议不参与条件过滤的字段一律设置为false;

stored 参数代表是否存储此字段的值,建议根据实际需求只将需要获取值的字段设置为true,以免浪费存储,比如我们的场景只需要获取rowkey,那么只需把rowkey字段设置为true即可,其他字段全部设置flase;

required 参数代表此字段是否必需,如果数据源某个字段可能存在空值,那么此属性必需设置为false,不然Solr会抛出异常;

multiValued 参数代表此字段是否允许有多个值,通常都设置为false,根据实际需求可设置为true。

4)我们使用Solr自带的example来作为运行环境,定位到example目录,启动服务监听:

cd /opt/apache-solr-4.0.0/example java -jar ./start.jar

如果启动成功,可以通过浏览器打开此页面:http://192.168.1.10:8983/solr/

二、读取HBase源表的数据,在Solr中建立索引

一种方案是通过HBase的普通API获取数据建立索引,此方案的缺点是效率较低每秒只能处理100多条数据(或许可以通过多线程提高效率):

package com.ultrapower.hbase.solrhbase;import java.io.IOException;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.hbase.HBaseConfiguration;import org.apache.hadoop.hbase.KeyValue;import org.apache.hadoop.hbase.client.HTable;import org.apache.hadoop.hbase.client.Result;import org.apache.hadoop.hbase.client.ResultScanner;import org.apache.hadoop.hbase.client.Scan;import org.apache.hadoop.hbase.util.Bytes;import org.apache.solr.client.solrj.SolrServerException;import org.apache.solr.client.solrj.impl.HttpSolrServer;import org.apache.solr.common.SolrInputDocument;public class SolrIndexer {    /**      * @param args      * @throws IOException      * @throws SolrServerException     */     public static void main(String[] args) throws IOException,             SolrServerException {         final Configuration conf;         HttpSolrServer solrServer = new HttpSolrServer(                "http://192.168.1.10:8983/solr"); // 因为服务端是用的Solr自带的jetty容器,默认端口号是8983          conf = HBaseConfiguration.create();         HTable table = new HTable(conf, "hb_app_xxxxxx"); // 这里指定HBase表名称         Scan scan = new Scan();         scan.addFamily(Bytes.toBytes("d")); // 这里指定HBase表的列族         scan.setCaching(500);         scan.setCacheBlocks(false);         ResultScanner ss = table.getScanner(scan);          System.out.println("start ...");        int i = 0;        try {            for (Result r : ss) {                 SolrInputDocument solrDoc = new SolrInputDocument();                 solrDoc.addField("rowkey", new String(r.getRow()));                for (KeyValue kv : r.raw()) {                     String fieldName = new String(kv.getQualifier());                     String fieldValue = new String(kv.getValue());                    if (fieldName.equalsIgnoreCase("time")                            || fieldName.equalsIgnoreCase("tebid")                            || fieldName.equalsIgnoreCase("tetid")                            || fieldName.equalsIgnoreCase("puid")                            || fieldName.equalsIgnoreCase("mgcvid")                            || fieldName.equalsIgnoreCase("mtcvid")                            || fieldName.equalsIgnoreCase("smaid")                            || fieldName.equalsIgnoreCase("mtlkid")) {                         solrDoc.addField(fieldName, fieldValue);                     }                 }                 solrServer.add(solrDoc);                 solrServer.commit(true, true, true);                 i = i + 1;                 System.out.println("已经成功处理 " + i + " 条数据");             }             ss.close();             table.close();             System.out.println("done !");         } catch (IOException e) {         } finally {             ss.close();             table.close();             System.out.println("erro !");         }     }  }

另外一种方案是用到HBase的Mapreduce框架,分布式并行执行效率特别高,处理1000万条数据仅需5分钟,但是这种高并发需要对Solr服务器进行配置调优,不然会抛出服务器无法响应的异常:

Error: org.apache.solr.common.SolrException: Server at http://192.168.1.10:8983/solr returned non ok status:503, message:Service Unavailable

MapReduce入口程序:

package com.ultrapower.hbase.solrhbase;import java.io.IOException;import java.net.URISyntaxException;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.hbase.HBaseConfiguration;import org.apache.hadoop.hbase.client.Scan;import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil;import org.apache.hadoop.hbase.util.Bytes;import org.apache.hadoop.mapreduce.Job;import org.apache.hadoop.mapreduce.lib.output.NullOutputFormat;public class SolrHBaseIndexer {    private static void usage() {         System.err.println("输入参数: <配置文件路径> <起始行> <结束行>");         System.exit(1);     }    private static Configuration conf;    public static void main(String[] args) throws IOException,             InterruptedException, ClassNotFoundException, URISyntaxException {        if (args.length == 0 || args.length > 3) {             usage();         }          createHBaseConfiguration(args[0]);         ConfigProperties tutorialProperties = new ConfigProperties(args[0]);         String tbName = tutorialProperties.getHBTbName();         String tbFamily = tutorialProperties.getHBFamily();          Job job = new Job(conf, "SolrHBaseIndexer");         job.setJarByClass(SolrHBaseIndexer.class);          Scan scan = new Scan();        if (args.length == 3) {             scan.setStartRow(Bytes.toBytes(args[1]));             scan.setStopRow(Bytes.toBytes(args[2]));         }          scan.addFamily(Bytes.toBytes(tbFamily));         scan.setCaching(500); // 设置缓存数据量来提高效率         scan.setCacheBlocks(false);        // 创建Map任务        TableMapReduceUtil.initTableMapperJob(tbName, scan,                 SolrHBaseIndexerMapper.class, null, null, job);        // 不需要输出         job.setOutputFormatClass(NullOutputFormat.class);        // job.setNumReduceTasks(0);         System.exit(job.waitForCompletion(true) ? 0 : 1);     }    /**      * 从配置文件读取并设置HBase配置信息      *       * @param propsLocation      * @return      */     private static void createHBaseConfiguration(String propsLocation) {         ConfigProperties tutorialProperties = new ConfigProperties(                 propsLocation);         conf = HBaseConfiguration.create();         conf.set("hbase.zookeeper.quorum", tutorialProperties.getZKQuorum());         conf.set("hbase.zookeeper.property.clientPort",                 tutorialProperties.getZKPort());         conf.set("hbase.master", tutorialProperties.getHBMaster());         conf.set("hbase.rootdir", tutorialProperties.getHBrootDir());         conf.set("solr.server", tutorialProperties.getSolrServer());     } }

对应的Mapper:

package com.ultrapower.hbase.solrhbase;import java.io.IOException;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.hbase.KeyValue;import org.apache.hadoop.hbase.client.Result;import org.apache.hadoop.hbase.io.ImmutableBytesWritable;import org.apache.hadoop.hbase.mapreduce.TableMapper;import org.apache.hadoop.io.Text;import org.apache.solr.client.solrj.SolrServerException;import org.apache.solr.client.solrj.impl.HttpSolrServer;import org.apache.solr.common.SolrInputDocument;public class SolrHBaseIndexerMapper extends TableMapper<Text, Text> {    public void map(ImmutableBytesWritable key, Result hbaseResult,             Context context) throws InterruptedException, IOException {          Configuration conf = context.getConfiguration();          HttpSolrServer solrServer = new HttpSolrServer(conf.get("solr.server"));         solrServer.setDefaultMaxConnectionsPerHost(100);         solrServer.setMaxTotalConnections(1000);         solrServer.setSoTimeout(20000);         solrServer.setConnectionTimeout(20000);         SolrInputDocument solrDoc = new SolrInputDocument();        try {             solrDoc.addField("rowkey", new String(hbaseResult.getRow()));            for (KeyValue rowQualifierAndValue : hbaseResult.list()) {                 String fieldName = new String(                         rowQualifierAndValue.getQualifier());                 String fieldValue = new String(rowQualifierAndValue.getValue());                if (fieldName.equalsIgnoreCase("time")                        || fieldName.equalsIgnoreCase("tebid")                        || fieldName.equalsIgnoreCase("tetid")                        || fieldName.equalsIgnoreCase("puid")                        || fieldName.equalsIgnoreCase("mgcvid")                        || fieldName.equalsIgnoreCase("mtcvid")                        || fieldName.equalsIgnoreCase("smaid")                        || fieldName.equalsIgnoreCase("mtlkid")) {                     solrDoc.addField(fieldName, fieldValue);                 }             }             solrServer.add(solrDoc);             solrServer.commit(true, true, true);         } catch (SolrServerException e) {             System.err.println("更新Solr索引异常:" + new String(hbaseResult.getRow()));         }     } }

读取参数配置文件的辅助类:

package com.ultrapower.hbase.solrhbase;import java.io.File;import java.io.FileReader;import java.io.IOException;import java.util.Properties;public class ConfigProperties {    private static Properties props;    private String HBASE_ZOOKEEPER_QUORUM;    private String HBASE_ZOOKEEPER_PROPERTY_CLIENT_PORT;    private String HBASE_MASTER;    private String HBASE_ROOTDIR;    private String DFS_NAME_DIR;    private String DFS_DATA_DIR;    private String FS_DEFAULT_NAME;    private String SOLR_SERVER; // Solr服务器地址    private String HBASE_TABLE_NAME; // 需要建立Solr索引的HBase表名称    private String HBASE_TABLE_FAMILY; // HBase表的列族    public ConfigProperties(String propLocation) {         props = new Properties();        try {             File file = new File(propLocation);             System.out.println("从以下位置加载配置文件: " + file.getAbsolutePath());             FileReader is = new FileReader(file);             props.load(is);              HBASE_ZOOKEEPER_QUORUM = props.getProperty("HBASE_ZOOKEEPER_QUORUM");             HBASE_ZOOKEEPER_PROPERTY_CLIENT_PORT = props.getProperty("HBASE_ZOOKEEPER_PROPERTY_CLIENT_PORT");             HBASE_MASTER = props.getProperty("HBASE_MASTER");             HBASE_ROOTDIR = props.getProperty("HBASE_ROOTDIR");             DFS_NAME_DIR = props.getProperty("DFS_NAME_DIR");             DFS_DATA_DIR = props.getProperty("DFS_DATA_DIR");             FS_DEFAULT_NAME = props.getProperty("FS_DEFAULT_NAME");             SOLR_SERVER = props.getProperty("SOLR_SERVER");             HBASE_TABLE_NAME = props.getProperty("HBASE_TABLE_NAME");             HBASE_TABLE_FAMILY = props.getProperty("HBASE_TABLE_FAMILY");          } catch (IOException e) {            throw new RuntimeException("加载配置文件出错");         } catch (NullPointerException e) {            throw new RuntimeException("文件不存在");         }     }    public String getZKQuorum() {        return HBASE_ZOOKEEPER_QUORUM;     }    public String getZKPort() {        return HBASE_ZOOKEEPER_PROPERTY_CLIENT_PORT;     }    public String getHBMaster() {        return HBASE_MASTER;     }    public String getHBrootDir() {        return HBASE_ROOTDIR;     }    public String getDFSnameDir() {        return DFS_NAME_DIR;     }    public String getDFSdataDir() {        return DFS_DATA_DIR;     }    public String getFSdefaultName() {        return FS_DEFAULT_NAME;     }    public String getSolrServer() {        return SOLR_SERVER;     }    public String getHBTbName() {        return HBASE_TABLE_NAME;     }    public String getHBFamily() {        return HBASE_TABLE_FAMILY;     } }

参数配置文件“config.properties”:

HBASE_ZOOKEEPER_QUORUM=slave-1,slave-2,slave-3,slave-4,slave-5HBASE_ZOOKEEPER_PROPERTY_CLIENT_PORT=2181HBASE_MASTER=master-1:60000HBASE_ROOTDIR=hdfs:///hbaseDFS_NAME_DIR=/opt/data/dfs/name DFS_DATA_DIR=/opt/data/d0/dfs2/data FS_DEFAULT_NAME=hdfs://192.168.1.10:9000SOLR_SERVER=http://192.168.1.10:8983/solrHBASE_TABLE_NAME=hb_app_m_user_te HBASE_TABLE_FAMILY=d

三、结合Solr进行HBase数据的多条件查询:

可以通过web页面操作Solr索引,

查询:

http://192.168.1.10:8983/solr/select?(time:201307 AND tetid:1 AND mgcvid:101 AND smaid:101 AND puid:102)

删除所有索引:

http://192.168.1.10:8983/solr/update/?stream.body=<delete><query>*:*</query></delete>&stream.contentType=text/xml;charset=utf-8&commit=true

通过java客户端结合Solr查询HBase数据:

package com.ultrapower.hbase.solrhbase;import java.io.IOException;import java.nio.ByteBuffer;import java.util.ArrayList;import java.util.List;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.hbase.HBaseConfiguration;import org.apache.hadoop.hbase.client.Get;import org.apache.hadoop.hbase.client.HTable;import org.apache.hadoop.hbase.client.Result;import org.apache.hadoop.hbase.util.Bytes;import org.apache.solr.client.solrj.SolrQuery;import org.apache.solr.client.solrj.SolrServer;import org.apache.solr.client.solrj.SolrServerException;import org.apache.solr.client.solrj.impl.HttpSolrServer;import org.apache.solr.client.solrj.response.QueryResponse;import org.apache.solr.common.SolrDocument;import org.apache.solr.common.SolrDocumentList;public class QueryData {    /**      * @param args      * @throws SolrServerException       * @throws IOException       */     public static void main(String[] args) throws SolrServerException, IOException {        final Configuration conf;         conf = HBaseConfiguration.create();         HTable table = new HTable(conf, "hb_app_m_user_te");         Get get = null;         List<Get> list = new ArrayList<Get>();                  String url = "http://192.168.1.10:8983/solr";         SolrServer server = new HttpSolrServer(url);         SolrQuery query = new SolrQuery("time:201307 AND tetid:1 AND mgcvid:101 AND smaid:101 AND puid:102");         query.setStart(0); //数据起始行,分页用         query.setRows(10); //返回记录数,分页用         QueryResponse response = server.query(query);         SolrDocumentList docs = response.getResults();         System.out.println("文档个数:" + docs.getNumFound()); //数据总条数也可轻易获取         System.out.println("查询时间:" + response.getQTime());          for (SolrDocument doc : docs) {             get = new Get(Bytes.toBytes((String) doc.getFieldValue("rowkey")));             list.add(get);         }                  Result[] res = table.get(list);                 byte[] bt1 = null;        byte[] bt2 = null;        byte[] bt3 = null;        byte[] bt4 = null;         String str1 = null;         String str2 = null;         String str3 = null;         String str4 = null;        for (Result rs : res) {             bt1 = rs.getValue("d".getBytes(), "3mpon".getBytes());             bt2 = rs.getValue("d".getBytes(), "3mponid".getBytes());             bt3 = rs.getValue("d".getBytes(), "amarpu".getBytes());             bt4 = rs.getValue("d".getBytes(), "amarpuid".getBytes());            if (bt1 != null && bt1.length>0) {str1 = new String(bt1);} else {str1 = "无数据";} //对空值进行new String的话会抛出异常             if (bt2 != null && bt2.length>0) {str2 = new String(bt2);} else {str2 = "无数据";}            if (bt3 != null && bt3.length>0) {str3 = new String(bt3);} else {str3 = "无数据";}            if (bt4 != null && bt4.length>0) {str4 = new String(bt4);} else {str4 = "无数据";}             System.out.print(new String(rs.getRow()) + " ");             System.out.print(str1 + "|");             System.out.print(str2 + "|");             System.out.print(str3 + "|");             System.out.println(str4 + "|");         }         table.close();     } }

小结:

通过测试发现,结合Solr索引可以很好的实现HBase的多条件查询,同时还能解决其两个难点:分页查询、数据总量统计。

实际场景中大多都是分页查询,分页查询返回的数据量很少,采用此种方案完全可以达到前端页面毫秒级的实时响应;若有大批量的数据交互,比如涉及到数据导出,实际上效率也是很高,十万数据仅耗时10秒。

另外,如果真的将Solr纳入使用,Solr以及HBase端都可以不断进行优化,比如可以搭建Solr集群,甚至可以采用SolrCloud基于hadoop的分布式索引服务。

总之,HBase不能多条件过滤查询的先天性缺陷,在Solr的配合之下可以得到较好的弥补,难怪诸如新蛋科技、国美电商、苏宁电商等互联网公司以及众多游戏公司,都使用Solr来支持快速查询。

----end

posted @ 2014-12-04 19:02 paulwong 阅读(1004) | 评论 (0)编辑 收藏

仅列出标题
共115页: First 上一页 41 42 43 44 45 46 47 48 49 下一页 Last