blogjava-凯发k8网页登录

blogjava-凯发k8网页登录http://www.blogjava.net/paulwong/category/47498.htmlzh-cnsun, 16 jan 2022 12:06:16 gmtsun, 16 jan 2022 12:06:16 gmt60!!!架构网站内容不错http://www.blogjava.net/paulwong/archive/2016/04/19/430154.htmlpaulwongpaulwongtue, 19 apr 2016 09:54:00 gmthttp://www.blogjava.net/paulwong/archive/2016/04/19/430154.htmlhttp://www.blogjava.net/paulwong/comments/430154.htmlhttp://www.blogjava.net/paulwong/archive/2016/04/19/430154.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/430154.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/430154.htmlhttp://colobu.com/categories/架构/page/2/

paulwong 2016-04-19 17:54
]]>
spring cache资源http://www.blogjava.net/paulwong/archive/2015/02/25/423032.htmlpaulwongpaulwongwed, 25 feb 2015 08:04:00 gmthttp://www.blogjava.net/paulwong/archive/2015/02/25/423032.htmlhttp://www.blogjava.net/paulwong/comments/423032.htmlhttp://www.blogjava.net/paulwong/archive/2015/02/25/423032.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/423032.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/423032.html
http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/htmlsingle/#cache

spring concurrentmap manager加过期策略


组合key


spring cache抽象详解


注释驱动的 spring cache 缓存介绍




paulwong 2015-02-25 16:04
]]>
使用wildfly中的分布式缓存infishpanhttp://www.blogjava.net/paulwong/archive/2015/02/23/422998.htmlpaulwongpaulwongmon, 23 feb 2015 05:40:00 gmthttp://www.blogjava.net/paulwong/archive/2015/02/23/422998.htmlhttp://www.blogjava.net/paulwong/comments/422998.htmlhttp://www.blogjava.net/paulwong/archive/2015/02/23/422998.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/422998.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/422998.html
  • 通过http://127.0.0.1:9991/console/app.html#infinispan添加cache
    <cache-container name="tickets" default-cache="default" jndi-name="java:jboss/infinispan/tickets">
           <local-cache name="default" batching="true">
                  <locking isolation="repeatable_read"/>
           local-cache>
    cache-container>

  • pom.xml添加依赖包
            <dependency>
                <groupid>org.infinispangroupid>
                <artifactid>infinispan-coreartifactid>
                <scope>providedscope>
            dependency>
            
            <dependency>
                <groupid>org.infinispangroupid>
                <artifactid>infinispan-client-hotrodartifactid>
                <scope>providedscope>
            dependency>

        <dependency>
            <groupid>org.jgroupsgroupid>
            <artifactid>jgroupsartifactid>
            <scope>providedscope>
        dependency>

            <dependency>
                <groupid>org.infinispangroupid>
                <artifactid>infinispan-springartifactid>
                <version>6.0.2.finalversion>
            dependency>
            
            <dependency>
                <groupid>org.infinispangroupid>
                <artifactid>infinispan-jcacheartifactid>
                <version>6.0.2.finalversion>
            dependency>

  • 添加拦截器,web-inf/beans.xml
    xml version="1.0"?>
    <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
        xsi:schemalocation
    ="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd">
        <interceptors>
            <class>org.infinispan.jcache.annotation.cacheresultinterceptorclass>
            <class>org.infinispan.jcache.annotation.cacheputinterceptorclass>
            <class>org.infinispan.jcache.annotation.cacheremoveentryinterceptorclass>
            <class>org.infinispan.jcache.annotation.cacheremoveallinterceptorclass>
        interceptors>
    beans>

  • 添加项目的全局依赖,web-inf/jboss-deployment-structure.xml
    xml version="1.0" encoding="utf-8"?>
    <jboss-deployment-structure>
        <deployment>
            <dependencies>
                <module name="org.jboss.xnio" />
                <module name="org.infinispan" export="true"/>
                <module name="org.infinispan.commons" export="true"/>
                <module name="org.infinispan.client.hotrod" export="true"/>
            dependencies>
        deployment>
    jboss-deployment-structure>

  • 在cdi bean中使用cache
    package com.paul.myejb;

    import javax.annotation.resource;
    import javax.cache.annotation.cacheresult;
    import javax.ejb.remote;
    import javax.ejb.stateless;
    import javax.interceptor.interceptors;

    import org.infinispan.cache;
    import org.infinispan.manager.embeddedcachemanager;
    //import org.springframework.cache.annotation.cacheable;
    import org.springframework.ejb.interceptor.springbeanautowiringinterceptor;

    /**
     * session bean implementation class helloworldbean
     
    */
    @stateless
    //@local(helloworld.class)
    @remote(helloworld.class)
    @interceptors(springbeanautowiringinterceptor.class)
    //@rolesallowed({roles.admin})
    public class helloworldbean implements helloworld {
        
        @resource(lookup = "java:jboss/infinispan/tickets")
        private embeddedcachemanager container;
        
        
        /**
         * default constructor. 
         
    */
        public helloworldbean() {
        }

    //    @transactional
    //    @cacheable(value = "books", key = "#name")
        @cacheresult
        public string sayhello(string name) {
            system.out.println("no cache");
            string result = "hello "   name   ", i am helloworldbean.";
            cache cache = this.container.getcache();
            cache.put(name, result);
            return result;
        }

    }


  • 修改modules/system/layers/base/org/infinispan/client/hotrod/main/modules.xml
    xml version="1.0" encoding="utf-8"?>

    <module xmlns="urn:jboss:module:1.3" name="org.infinispan.client.hotrod">
        <properties>
            <property name="jboss.api" value="private"/>
        properties>

        <resources>
            <resource-root path="infinispan-client-hotrod-6.0.2.final.jar"/>
        resources>

        <dependencies>
            <module name="javax.api"/>
            
            
            <module name="org.apache.commons.pool"/>
            <module name="org.infinispan.commons"/>
            <module name="org.infinispan.query.dsl"/>
            <module name="org.jboss.logging"/>
        dependencies>
    module>

  • 以下是spring版本
    1. 添加依赖的spring bean
      xml version="1.0" encoding="utf-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi
      ="http://www.w3.org/2001/xmlschema-instance" xmlns:context="http://www.springframework.org/schema/context"
          xmlns:cache
      ="http://www.springframework.org/schema/cache"
          xmlns:p
      ="http://www.springframework.org/schema/p"
          xmlns:jee
      ="http://www.springframework.org/schema/jee"
          xsi:schemalocation
      ="http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-3.0.xsd
                http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/cache
                http://www.springframework.org/schema/cache/spring-cache.xsd
                http://www.springframework.org/schema/jee 
                http://www.springframework.org/schema/jee/spring-jee.xsd"
      >

          <cache:annotation-driven />
          
          <bean id="cachemanager"
                class
      ="org.infinispan.spring.provider.containercachemanagerfactorybean">
                <constructor-arg ref="cachecontainer"  />
          bean>
          
          <jee:jndi-lookup id="cachecontainer" jndi-name="java:jboss/infinispan/tickets" > 
          jee:jndi-lookup>
          
          
          
      beans>

    2. 使用cache
      package com.paul.myejb.spring;

      import org.springframework.beans.factory.annotation.autowired;
      import org.springframework.cache.cachemanager;
      import org.springframework.cache.annotation.cacheable;
      import org.springframework.stereotype.component;

      @component
      public class myspringbean {
          
          @autowired
          private cachemanager cachemanager;
          
          @cacheable(value = "my-local-cache", key = "#name")
          public string sayhello(string name)
          {
              system.out.println("myspringbean no cache");
              string result = "hi "   name   ", i am spring!";
              org.springframework.cache.cache springcache = this.cachemanager.getcache("my-local-cache");
              system.out.println(springcache.get(name) == null ? "null" : springcache.get(name).get());
              springcache.put(name, result);
              return result;
          }

      }




    paulwong 2015-02-23 13:40
    ]]>
    spring-sessionhttp://www.blogjava.net/paulwong/archive/2014/11/19/420309.htmlpaulwongpaulwongwed, 19 nov 2014 10:23:00 gmthttp://www.blogjava.net/paulwong/archive/2014/11/19/420309.htmlhttp://www.blogjava.net/paulwong/comments/420309.htmlhttp://www.blogjava.net/paulwong/archive/2014/11/19/420309.html#feedback1http://www.blogjava.net/paulwong/comments/commentrss/420309.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/420309.html阅读全文

    paulwong 2014-11-19 18:23
    ]]>
    分布式调度quartz springhttp://www.blogjava.net/paulwong/archive/2014/11/14/420104.htmlpaulwongpaulwongfri, 14 nov 2014 10:46:00 gmthttp://www.blogjava.net/paulwong/archive/2014/11/14/420104.htmlhttp://www.blogjava.net/paulwong/comments/420104.htmlhttp://www.blogjava.net/paulwong/archive/2014/11/14/420104.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/420104.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/420104.html触发器:存放时间排程
    任务:蔟业务代码
    排程器:负责调度,即在指定的时间执行对应的任务

    如果是分布式quartz,则各个节点会上报任务,存到数据库中,执行时会从数据库中取出触发器来执行,如果触发器的名称和执行时间相同,则只有一个节点去执行此任务。
    如果此节点执行失败,则此任务则会被分派到另一节点执行。

    quartz.properties
    #============================================================================
    #
     configure jobstore  
    #
     using spring datasource in quartzjobsconfig.xml
    #
     spring uses localdatasourcejobstore extension of jobstorecmt
    #
    ============================================================================
    org.quartz.jobstore.useproperties=true
    org.quartz.jobstore.tableprefix = qrtz_
    org.quartz.jobstore.isclustered = true
    org.quartz.jobstore.clustercheckininterval = 5000
    org.quartz.jobstore.misfirethreshold = 60000
    org.quartz.jobstore.txisolationlevelreadcommitted = true
     
    # change this to match your db vendor
    org.quartz.jobstore.class = org.quartz.impl.jdbcjobstore.jobstoretx
    org.quartz.jobstore.driverdelegateclass = org.quartz.impl.jdbcjobstore.stdjdbcdelegate
     

    #============================================================================
    #
     configure main scheduler properties  
    #
     needed to manage cluster instances
    #
    ============================================================================
    org.quartz.scheduler.instanceid=auto
    org.quartz.scheduler.instancename=my_clustered_job_scheduler
    org.quartz.scheduler.rmi.export = false
    org.quartz.scheduler.rmi.proxy = false


    #============================================================================
    #
     configure threadpool  
    #
    ============================================================================
    org.quartz.threadpool.class = org.quartz.simpl.simplethreadpool
    org.quartz.threadpool.threadcount = 10
    org.quartz.threadpool.threadpriority = 5
    org.quartz.threadpool.threadsinheritcontextclassloaderofinitializingthread = true


    web-schedule-applicationcontext.xml
    xml version="1.0" encoding="utf-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi
    ="http://www.w3.org/2001/xmlschema-instance" xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mongo
    ="http://www.springframework.org/schema/data/mongo"
        xsi:schemalocation
    ="http://www.springframework.org/schema/context
              http://www.springframework.org/schema/context/spring-context-3.0.xsd
              http://www.springframework.org/schema/data/mongo
              http://www.springframework.org/schema/data/mongo/spring-mongo-1.3.xsd
              http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
    >


        
        
        <bean id="executor" class="org.springframework.scheduling.concurrent.threadpooltaskexecutor">
             <property name="corepoolsize" value="10" />
             <property name="maxpoolsize" value="100" />
             <property name="queuecapacity" value="500" />
        bean>

        
        <bean id="webscheduler"
            class
    ="org.springframework.scheduling.quartz.schedulerfactorybean">

            <property name="configlocation" value="classpath:/properties/config/quartz.properties" />
            <property name="datasource" ref="datasourcecms" />
            <property name="transactionmanager" ref="txmanager" />

            
            <property name="schedulername" value="quartzscheduler" />

            
            <property name="overwriteexistingjobs" value="true" />

            <property name="startupdelay" value="5"/>
            <property name="applicationcontextschedulercontextkey" value="applicationcontext" />
            <property name="jobfactory">
                <bean class="com.tcl.project7.boss.common.scheduling.autowiringspringbeanjobfactory" />
            property>
            
            <property name="triggers">
                  <list>
                           <ref bean="springquertzclustertaskschedulertestertigger" />
                  list>
             property>
            <property name="jobdetails">
                <list>
                    <ref bean="springquertzclustertaskschedulertesterjobdetail" />
                list>
            property>
             <property name="taskexecutor" ref="executor" />

        bean>


        
        
        
        
        <bean id="springquertzclustertaskschedulertestertigger" class="common.scheduling.persistablecrontriggerfactorybean">
            <property name="jobdetail" ref="springquertzclustertaskschedulertesterjobdetail"/>
            <property name="cronexpression" value="* * * * * ?" />    
        bean>
        
        <bean id="springquertzclustertaskschedulertesterjobdetail" class="org.springframework.scheduling.quartz.jobdetailbean">
            <property name="jobclass" value="common.scheduling.springquertzclustertaskschedulertester" />
            
            
            <property name="requestsrecovery" value="false"/>
        bean>
        
        
        
    beans>


    job文件:springquertzclustertaskschedulertester.java
    package common.scheduling;

    import java.util.date;

    import org.quartz.jobexecutioncontext;
    import org.quartz.jobexecutionexception;
    import org.slf4j.logger;
    import org.slf4j.loggerfactory;
    import org.springframework.beans.factory.annotation.autowired;
    import org.springframework.scheduling.quartz.quartzjobbean;

    import com.tcl.project7.boss.common.util.urlutil;
    import com.tcl.project7.boss.common.util.time.timeutils;
    /**
     * 

    title:springquertzclustertaskschedulertester


     * 

    description:
     * 应为要持久化等特性操作,需要继承 quartzjobbean
     * 
    由于要被持久化,所以不能存放xxxxmanager类似对象,
     * 只能从每次从quartzjobbean注入的applicationcontext 中去取出
     *
     * 

        
     *
     *
     
    */
    public class springquertzclustertaskschedulertester extends quartzjobbean {
        
        private static logger logger = loggerfactory.getlogger(springquertzclustertaskschedulertester.class);
        
        @autowired
        private urlutil urlutil;
        
        
        protected void executeinternal(jobexecutioncontext arg0)
                throws jobexecutionexception {
            logger.info("------"   timeutils.formattime(new date())   "------"   urlutil.getnginxhost());
            system.out.println("------"   timeutils.formattime(new date())   "------"   urlutil.getnginxhost());
        }
        
    }


    如果job中有需要调用spring的bean,则需要此文件autowiringspringbeanjobfactory.java
    package common.scheduling;

    import org.quartz.spi.triggerfiredbundle;
    import org.springframework.beans.factory.config.autowirecapablebeanfactory;
    import org.springframework.context.applicationcontext;
    import org.springframework.context.applicationcontextaware;
    import org.springframework.scheduling.quartz.springbeanjobfactory;

    /**
     * autowire quartz jobs with spring context dependencies
     * 
    @see http://stackoverflow.com/questions/6990767/inject-bean-reference-into-a-quartz-job-in-spring/15211030#15211030
     
    */
    public final class autowiringspringbeanjobfactory extends springbeanjobfactory implements applicationcontextaware {
        
        private transient autowirecapablebeanfactory beanfactory;
     
        public void setapplicationcontext(final applicationcontext context) {
            beanfactory = context.getautowirecapablebeanfactory();
        }
     
        @override
        protected object createjobinstance(final triggerfiredbundle bundle) throws exception {
            final object job = super.createjobinstance(bundle);
            beanfactory.autowirebean(job);
            return job;
        }
    }


    由于job需要存储到数据库中,会产生property的问题,需剔除job-data,需此文件persistablecrontriggerfactorybean.java
    package common.scheduling;

    import org.springframework.scheduling.quartz.crontriggerfactorybean;
    import org.springframework.scheduling.quartz.jobdetailawaretrigger;

    /**
     * needed to set quartz useproperties=true when using spring classes,
     * because spring sets an object reference on jobdatamap that is not a string
     * 
     * 
    @see http://site.trimplement.com/using-spring-and-quartz-with-jobstore-properties/
     * 
    @see http://forum.springsource.org/showthread.php?130984-quartz-error-ioexception
     
    */
    public class persistablecrontriggerfactorybean extends crontriggerfactorybean {
        @override
        public void afterpropertiesset() {
            super.afterpropertiesset();
     
            //remove the jobdetail element
            getjobdatamap().remove(jobdetailawaretrigger.job_detail_key);
        }
    }


    建表语句,mysql:quartztables.sql
    #
    # quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
    #
    in your quartz properties file, you'll need to set 
    # org.quartz.jobstore.driverdelegateclass = org.quartz.impl.jdbcjobstore.stdjdbcdelegate
    #

    drop table if exists qrtz_job_listeners;
    drop table if exists qrtz_trigger_listeners;
    drop table if exists qrtz_fired_triggers;
    drop table if exists qrtz_paused_trigger_grps;
    drop table if exists qrtz_scheduler_state;
    drop table if exists qrtz_locks;
    drop table if exists qrtz_simple_triggers;
    drop table if exists qrtz_cron_triggers;
    drop table if exists qrtz_blob_triggers;
    drop table if exists qrtz_triggers;
    drop table if exists qrtz_job_details;
    drop table if exists qrtz_calendars;


    create table qrtz_job_details
      (
        job_name  varchar(200) not null,
        job_group varchar(200) not null,
        description varchar(250) null,
        job_class_name   varchar(250) not null,
        is_durable varchar(1) not null,
        is_volatile varchar(1) not null,
        is_stateful varchar(1) not null,
        requests_recovery varchar(1) not null,
        job_data blob null,
        primary key (job_name,job_group)
    );

    create table qrtz_job_listeners
      (
        job_name  varchar(200) not null,
        job_group varchar(200) not null,
        job_listener varchar(200) not null,
        primary key (job_name,job_group,job_listener),
        foreign key (job_name,job_group)
            references qrtz_job_details(job_name,job_group)
    );

    create table qrtz_triggers
      (
        trigger_name varchar(200) not null,
        trigger_group varchar(200) not null,
        job_name  varchar(200) not null,
        job_group varchar(200) not null,
        is_volatile varchar(1) not null,
        description varchar(250) null,
        next_fire_time bigint(13) null,
        prev_fire_time bigint(13) null,
        priority integer null,
        trigger_state varchar(16) not null,
        trigger_type varchar(8) not null,
        start_time bigint(13) not null,
        end_time bigint(13) null,
        calendar_name varchar(200) null,
        misfire_instr smallint(2) null,
        job_data blob null,
        primary key (trigger_name,trigger_group),
        foreign key (job_name,job_group)
            references qrtz_job_details(job_name,job_group)
    );

    create table qrtz_simple_triggers
      (
        trigger_name varchar(200) not null,
        trigger_group varchar(200) not null,
        repeat_count bigint(7) not null,
        repeat_interval bigint(12) not null,
        times_triggered bigint(10) not null,
        primary key (trigger_name,trigger_group),
        foreign key (trigger_name,trigger_group)
            references qrtz_triggers(trigger_name,trigger_group)
    );

    create table qrtz_cron_triggers
      (
        trigger_name varchar(200) not null,
        trigger_group varchar(200) not null,
        cron_expression varchar(200) not null,
        time_zone_id varchar(80),
        primary key (trigger_name,trigger_group),
        foreign key (trigger_name,trigger_group)
            references qrtz_triggers(trigger_name,trigger_group)
    );

    create table qrtz_blob_triggers
      (
        trigger_name varchar(200) not null,
        trigger_group varchar(200) not null,
        blob_data blob null,
        primary key (trigger_name,trigger_group),
        foreign key (trigger_name,trigger_group)
            references qrtz_triggers(trigger_name,trigger_group)
    );

    create table qrtz_trigger_listeners
      (
        trigger_name  varchar(200) not null,
        trigger_group varchar(200) not null,
        trigger_listener varchar(200) not null,
        primary key (trigger_name,trigger_group,trigger_listener),
        foreign key (trigger_name,trigger_group)
            references qrtz_triggers(trigger_name,trigger_group)
    );


    create table qrtz_calendars
      (
        calendar_name  varchar(200) not null,
        calendar blob not null,
        primary key (calendar_name)
    );



    create table qrtz_paused_trigger_grps
      (
        trigger_group  varchar(200) not null, 
        primary key (trigger_group)
    );

    create table qrtz_fired_triggers
      (
        entry_id varchar(95) not null,
        trigger_name varchar(200) not null,
        trigger_group varchar(200) not null,
        is_volatile varchar(1) not null,
        instance_name varchar(200) not null,
        fired_time bigint(13) not null,
        priority integer not null,
        state varchar(16) not null,
        job_name varchar(200) null,
        job_group varchar(200) null,
        is_stateful varchar(1) null,
        requests_recovery varchar(1) null,
        primary key (entry_id)
    );

    create table qrtz_scheduler_state
      (
        instance_name varchar(200) not null,
        last_checkin_time bigint(13) not null,
        checkin_interval bigint(13) not null,
        primary key (instance_name)
    );

    create table qrtz_locks
      (
        lock_name  varchar(40) not null, 
        primary key (lock_name)
    );


    insert into qrtz_locks values(
    'trigger_access');
    insert into qrtz_locks values(
    'job_access');
    insert into qrtz_locks values(
    'calendar_access');
    insert into qrtz_locks values(
    'state_access');
    insert into qrtz_locks values(
    'misfire_access');


    commit;


    参考:


    quartz集成springmvc 的方案二(持久化任务、集群和分布式)


















    paulwong 2014-11-14 18:46
    ]]>
    樂視 tv 載入 4k 片點解咁快?cdn 網絡解構http://www.blogjava.net/paulwong/archive/2014/11/07/419670.htmlpaulwongpaulwongfri, 07 nov 2014 09:03:00 gmthttp://www.blogjava.net/paulwong/archive/2014/11/07/419670.htmlhttp://www.blogjava.net/paulwong/comments/419670.htmlhttp://www.blogjava.net/paulwong/archive/2014/11/07/419670.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/419670.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/419670.html
    而它提供的內容中,最吸引的肯定是 4k 影片及劇集。相信大家都知道,4k 內容檔案本身容量十分大,還要透過網絡進行串流,一般情況也會「窒下窒下」,但為何在 x50 air 上會如此順暢?以下小編就為大家解構一下:

     

    好了,謎底揭曉!

    其實很多時候欣賞串流內容(streaming)時要等,是因為 cache 時間十分長,導致影響載入時候。

    而 letv 就採用了 cdn(content delivery / distribution network;內容傳遞網路)網路,它的總承載量比單一骨幹最大的頻寬還要大,而且有異地備援,萬一某個伺服器出現故障,系統就會自動調用其他鄰近地區的伺服器資源,所以可靠度極之接近 100%;

    就算沒有故障時,樂視香港的 cdn 網絡亦可有效回避繁忙擠塞的網絡,並自動尋找距離用家最接近的快取伺服器接收內容,因此可以改善內容存取速度,大大縮短下載時間,自然可以用串流網絡,順暢欣賞極致 4k 影片內容啦。

    paulwong 2014-11-07 17:03
    ]]>
    java并行处理框架 jppfhttp://www.blogjava.net/paulwong/archive/2014/07/19/415998.htmlpaulwongpaulwongsat, 19 jul 2014 01:55:00 gmthttp://www.blogjava.net/paulwong/archive/2014/07/19/415998.htmlhttp://www.blogjava.net/paulwong/comments/415998.htmlhttp://www.blogjava.net/paulwong/archive/2014/07/19/415998.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/415998.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/415998.html


    paulwong 2014-07-19 09:55
    ]]>
    腾讯ckv海量分布式存储系统http://www.blogjava.net/paulwong/archive/2014/07/16/415866.htmlpaulwongpaulwongtue, 15 jul 2014 23:58:00 gmthttp://www.blogjava.net/paulwong/archive/2014/07/16/415866.htmlhttp://www.blogjava.net/paulwong/comments/415866.htmlhttp://www.blogjava.net/paulwong/archive/2014/07/16/415866.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/415866.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/415866.html

    paulwong 2014-07-16 07:58
    ]]>
    【转载】经典漫画讲解hdfs原理 http://www.blogjava.net/paulwong/archive/2013/10/26/405663.htmlpaulwongpaulwongsat, 26 oct 2013 01:15:00 gmthttp://www.blogjava.net/paulwong/archive/2013/10/26/405663.htmlhttp://www.blogjava.net/paulwong/comments/405663.htmlhttp://www.blogjava.net/paulwong/archive/2013/10/26/405663.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/405663.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/405663.html分布式文件系统比较出名的有hdfs  和 gfs,其中hdfs比较简单一点。本文是一篇描述非常简洁易懂的漫画形式讲解hdfs的原理。比一般ppt要通俗易懂很多。不难得的学习资料。


    1、三个部分: 客户端、nameserver(可理解为主控和文件索引,类似linux的inode)、datanode(存放实际数据)

    在这里,client的形式我所了解的有两种,通过hadoop提供的api所编写的程序可以和hdfs进行交互,另外一种就是安装了hadoop的datanode其也可以通过命令行与hdfs系统进行交互,如在datanode上上传则使用如下命令行:bin/hadoop fs -put example1 user/chunk/


    2、如何写数据过程





    3、读取数据过程



    4、容错:第一部分:故障类型及其检测方法(nodeserver 故障,和网络故障,和脏数据问题)




    5、容错第二部分:读写容错



    6、容错第三部分:datanode 失效



    7、备份规则



    8、结束语


    paulwong 2013-10-26 09:15
    ]]>
    一些数据切分、缓存、rpc框架、nosql方案资料http://www.blogjava.net/paulwong/archive/2013/10/14/404954.htmlpaulwongpaulwongmon, 14 oct 2013 02:14:00 gmthttp://www.blogjava.net/paulwong/archive/2013/10/14/404954.htmlhttp://www.blogjava.net/paulwong/comments/404954.htmlhttp://www.blogjava.net/paulwong/archive/2013/10/14/404954.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/404954.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/404954.html1、数据切分

            1.1、 

            1.2、

            1.3、

            1.4、

    2、缓存

            2.1、

            2.2、

            2.3、

            2.4、

            2.5、

            2.6、

            2.7、

    3、rpc框架

            3.1、

            3.2、hsf 未开源

            3.3、

    4、nosql

            4.1、



    paulwong 2013-10-14 10:14
    ]]>
    分布式搜索资源http://www.blogjava.net/paulwong/archive/2013/08/31/403522.htmlpaulwongpaulwongsat, 31 aug 2013 07:52:00 gmthttp://www.blogjava.net/paulwong/archive/2013/08/31/403522.htmlhttp://www.blogjava.net/paulwong/comments/403522.htmlhttp://www.blogjava.net/paulwong/archive/2013/08/31/403522.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/403522.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/403522.html


    elasticsearch中文社区






    welcome to the apache nutch wiki



    elasticsearch客户端大全



    客户端




     

    paulwong 2013-08-31 15:52
    ]]>
    install hadoop hbase nutch elasticsearchhttp://www.blogjava.net/paulwong/archive/2013/08/31/403513.htmlpaulwongpaulwongfri, 30 aug 2013 17:17:00 gmthttp://www.blogjava.net/paulwong/archive/2013/08/31/403513.htmlhttp://www.blogjava.net/paulwong/comments/403513.htmlhttp://www.blogjava.net/paulwong/archive/2013/08/31/403513.html#feedback3http://www.blogjava.net/paulwong/comments/commentrss/403513.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/403513.htmlh...  

    paulwong 2013-08-31 01:17
    ]]>
    implementation for combinefileinputformat hadoop 0.20.205http://www.blogjava.net/paulwong/archive/2013/08/29/403442.htmlpaulwongpaulwongthu, 29 aug 2013 08:08:00 gmthttp://www.blogjava.net/paulwong/archive/2013/08/29/403442.htmlhttp://www.blogjava.net/paulwong/comments/403442.htmlhttp://www.blogjava.net/paulwong/archive/2013/08/29/403442.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/403442.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/403442.html
    具体的原理是下述三步:

    1.根据输入目录下的每个文件,如果其长度超过mapred.max.split.size,以block为单位分成多个split(一个split是一个map的输入),每个split的长度都大于mapred.max.split.size, 因为以block为单位, 因此也会大于blocksize, 此文件剩下的长度如果大于mapred.min.split.size.per.node, 则生成一个split, 否则先暂时保留.

    2. 现在剩下的都是一些长度效短的碎片,把每个rack下碎片合并, 只要长度超过mapred.max.split.size就合并成一个split, 最后如果剩下的碎片比mapred.min.split.size.per.rack大, 就合并成一个split, 否则暂时保留.

    3. 把不同rack下的碎片合并, 只要长度超过mapred.max.split.size就合并成一个split, 剩下的碎片无论长度, 合并成一个split.
    举例: mapred.max.split.size=1000
    mapred.min.split.size.per.node=300
    mapred.min.split.size.per.rack=100
    输入目录下五个文件,rack1下三个文件,长度为2050,1499,10, rack2下两个文件,长度为1010,80. 另外blocksize为500.
    经过第一步, 生成五个split: 1000,1000,1000,499,1000. 剩下的碎片为rack1下:50,10; rack2下10:80
    由于两个rack下的碎片和都不超过100, 所以经过第二步, split和碎片都没有变化.
    第三步,合并四个碎片成一个split, 长度为150.

    如果要减少map数量, 可以调大mapred.max.split.size, 否则调小即可.

    其特点是: 一个块至多作为一个map的输入,一个文件可能有多个块,一个文件可能因为块多分给做为不同map的输入, 一个map可能处理多个块,可能处理多个文件。

    注:combinefileinputformat是一个抽象类,需要编写一个继承类。


    import java.io.ioexception;

    import org.apache.hadoop.conf.configuration;
    import org.apache.hadoop.io.longwritable;
    import org.apache.hadoop.io.text;
    import org.apache.hadoop.mapred.filesplit;
    import org.apache.hadoop.mapred.inputsplit;
    import org.apache.hadoop.mapred.jobconf;
    import org.apache.hadoop.mapred.linerecordreader;
    import org.apache.hadoop.mapred.recordreader;
    import org.apache.hadoop.mapred.reporter;
    import org.apache.hadoop.mapred.lib.combinefileinputformat;
    import org.apache.hadoop.mapred.lib.combinefilerecordreader;
    import org.apache.hadoop.mapred.lib.combinefilesplit;

    @suppresswarnings("deprecation")
    public class combinedinputformat extends combinefileinputformat {

        @suppresswarnings({ "unchecked", "rawtypes" })
        @override
        public recordreader getrecordreader(inputsplit split, jobconf conf, reporter reporter) throws ioexception {

            return new combinefilerecordreader(conf, (combinefilesplit) split, reporter, (class) mycombinefilerecordreader.class);
        }

        public static class mycombinefilerecordreader implements recordreader {
            private final linerecordreader linerecord;

            public mycombinefilerecordreader(combinefilesplit split, configuration conf, reporter reporter, integer index) throws ioexception {
                filesplit filesplit = new filesplit(split.getpath(index), split.getoffset(index), split.getlength(index), split.getlocations());
                linerecord = new linerecordreader(conf, filesplit);
            }

            @override
            public void close() throws ioexception {
                linerecord.close();

            }

            @override
            public longwritable createkey() {
                // todo auto-generated method stub
                return linerecord.createkey();
            }

            @override
            public text createvalue() {
                // todo auto-generated method stub
                return linerecord.createvalue();
            }

            @override
            public long getpos() throws ioexception {
                // todo auto-generated method stub
                return linerecord.getpos();
            }

            @override
            public float getprogress() throws ioexception {
                // todo auto-generated method stub
                return linerecord.getprogress();
            }

            @override
            public boolean next(longwritable key, text value) throws ioexception {

                // todo auto-generated method stub
                return linerecord.next(key, value);
            }

        }
    }


    在运行时这样设置:

    if (argument != null) {
                    conf.set("mapred.max.split.size", argument);
                } else {
                    conf.set("mapred.max.split.size", "134217728"); // 128 mb
                }
    //

                conf.setinputformat(combinedinputformat.class);




    paulwong 2013-08-29 16:08
    ]]>
    使用sqoop实现hdfs与mysql互转http://www.blogjava.net/paulwong/archive/2013/05/11/399153.htmlpaulwongpaulwongsat, 11 may 2013 13:27:00 gmthttp://www.blogjava.net/paulwong/archive/2013/05/11/399153.htmlhttp://www.blogjava.net/paulwong/comments/399153.htmlhttp://www.blogjava.net/paulwong/archive/2013/05/11/399153.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/399153.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/399153.html 简介
    sqoop是一个用来将hadoop和关系型数据库中的数据相互转移的工具,可以将一个关系型数据库(例如 : mysql ,oracle ,postgres等)中的数据导入到hadoop的hdfs中,也可以将hdfs的数据导入到关系型数据库中。

    http://sqoop.apache.org/

    环境
    当调试过程出现incompatibleclasschangeerror一般都是版本兼容问题。

    为了保证hadoop和sqoop版本的兼容性,使用cloudera,

    cloudera简介:

    cloudera为了让hadoop的配置标准化,可以帮助企业安装,配置,运行hadoop以达到大规模企业数据的处理和分析。

    http://www.cloudera.com/content/cloudera-content/cloudera-docs/cdhtarballs/3.25.2013/cdh4-downloadable-tarballs/cdh4-downloadable-tarballs.html

    下载安装hadoop-0.20.2-cdh3u6,sqoop-1.3.0-cdh3u6。

    安装
    安装比较简单,直接解压即可

    唯一需要做的就是将mysql的jdbc适配包mysql-connector-java-5.0.7-bin.jar copy到$sqoop_home/lib下。

    配置好环境变量:/etc/profile

    export sqoop_home=/home/hadoop/sqoop-1.3.0-cdh3u6/

    export path=$sqoop_home/bin:$path

    mysql转hdfs-示例
    ./sqoop import --connect jdbc:mysql://10.8.210.166:3306/recsys --username root --password root --table shop -m 1 --target-dir /user/recsys/input/shop/$today


    hdfs转mysq-示例
    ./sqoop export --connect jdbc:mysql://10.8.210.166:3306/recsys --username root --password root --table shopassoc --fields-terminated-by ',' --export-dir /user/recsys/output/shop/$today

    示例参数说明
    (其他参数我未使用,故不作解释,未使用,就没有发言权,详见命令help)


    参数类型

    参数名

    解释

    公共

    connect

    jdbc-url

    公共

    username

    ---

    公共

    password

    ---

    公共

    table

    表名

    import

    target-dir

    制定输出hdfs目录,默认输出到/user/$loginname/

    export

    fields-terminated-by

    hdfs文件中的字段分割符,默认是“\t”

    export

    export-dir

    hdfs文件的路径

    paulwong 2013-05-11 21:27
    ]]>
    全方位的技术服务及相关技术凯发天生赢家一触即发官网的解决方案(纯java凯发天生赢家一触即发官网的解决方案)http://www.blogjava.net/paulwong/archive/2013/05/11/399132.htmlpaulwongpaulwongfri, 10 may 2013 16:17:00 gmthttp://www.blogjava.net/paulwong/archive/2013/05/11/399132.htmlhttp://www.blogjava.net/paulwong/comments/399132.htmlhttp://www.blogjava.net/paulwong/archive/2013/05/11/399132.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/399132.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/399132.htmlhttp://www.iteye.com/topic/1128561 @import ;@import url(/uploads/css/css/cuteeditor.css);

    paulwong 2013-05-11 00:17
    ]]>
    一网打尽13款开源java大数据工具http://www.blogjava.net/paulwong/archive/2013/05/03/398700.htmlpaulwongpaulwongfri, 03 may 2013 01:05:00 gmthttp://www.blogjava.net/paulwong/archive/2013/05/03/398700.htmlhttp://www.blogjava.net/paulwong/comments/398700.htmlhttp://www.blogjava.net/paulwong/archive/2013/05/03/398700.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/398700.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/398700.html下面将介绍大数据领域支持java的主流开源工具

    1. hdfs

    hdfs是hadoop应用程序中主要的分布式储存系统, hdfs集群包含了一个namenode(主节点),这个节点负责管理所有文件系统的元数据及存储了真实数据的datanode(数据节点,可以有很多)。hdfs针对海量数据所设计,所以相比传统文件系统在大批量小文件上的优化,hdfs优化的则是对小批量大型文件的访问和存储。

    2. mapreduce

    hadoop mapreduce是一个软件框架,用以轻松编写处理海量(tb级)数据的并行应用程序,以可靠和容错的方式连接大型集群中上万个节点(商用硬件)。

    3. hbase

    apache hbase是hadoop数据库,一个分布式、可扩展的大数据存储。它提供了大数据集上随机和实时的读/写访问,并针对了商用服务器集群上的大型表格做出优化——上百亿行,上千万列。其核心是google bigtable论文的开源实现,分布式列式存储。就像bigtable利用gfs(google file system)提供的分布式数据存储一样,它是apache hadoop在hdfs基础上提供的一个类bigatable。

    4. cassandra

    apache cassandra是一个高性能、可线性扩展、高有效性数据库,可以运行在商用硬件或云基础设施上打造完美的任务关键性数据平台。在横跨数据中心的复制中,cassandra同类最佳,为用户提供更低的延时以及更可靠的灾难备份。通过log-structured update、反规范化和物化视图的强支持以及强大的内置缓存,cassandra的数据模型提供了方便的二级索引(column indexe)。

    5. hive

    apache hive是hadoop的一个数据仓库系统,促进了数据的综述(将结构化的数据文件映射为一张数据库表)、即席查询以及存储在hadoop兼容系统中的大型数据集分析。hive提供完整的sql查询功能——hiveql语言,同时当使用这个语言表达一个逻辑变得低效和繁琐时,hiveql还允许传统的map/reduce程序员使用自己定制的mapper和reducer。

    6. pig

    apache pig是一个用于大型数据集分析的平台,它包含了一个用于数据分析应用的高级语言以及评估这些应用的基础设施。pig应用的闪光特性在于它们的结构经得起大量的并行,也就是说让它们支撑起非常大的数据集。pig的基础设施层包含了产生map-reduce任务的编译器。pig的语言层当前包含了一个原生语言——pig latin,开发的初衷是易于编程和保证可扩展性。

    7. chukwa

    apache chukwa是个开源的数据收集系统,用以监视大型分布系统。建立于hdfs和map/reduce框架之上,继承了hadoop的可扩展性和稳定性。chukwa同样包含了一个灵活和强大的工具包,用以显示、监视和分析结果,以保证数据的使用达到最佳效果。

    8. ambari

    apache ambari是一个基于web的工具,用于配置、管理和监视apache hadoop集群,支持hadoop hdfs,、hadoop mapreduce、hive、hcatalog,、hbase、zookeeper、oozie、pig和sqoop。ambari同样还提供了集群状况仪表盘,比如heatmaps和查看mapreduce、pig、hive应用程序的能力,以友好的用户界面对它们的性能特性进行诊断。

    9. zookeeper

    apache zookeeper是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护、命名服务、分布式同步、组服务等。zookeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。

    10. sqoop

    sqoop是一个用来将hadoop和关系型数据库中的数据相互转移的工具,可以将一个关系型数据库中数据导入hadoop的hdfs中,也可以将hdfs中数据导入关系型数据库中。

    11. oozie

    apache oozie是一个可扩展、可靠及可扩充的工作流调度系统,用以管理hadoop作业。oozie workflow作业是活动的directed acyclical graphs(dags)。oozie coordinator作业是由周期性的oozie workflow作业触发,周期一般决定于时间(频率)和数据可用性。oozie与余下的hadoop堆栈结合使用,开箱即用的支持多种类型hadoop作业(比如:java map-reduce、streaming map-reduce、pig、 hive、sqoop和distcp)以及其它系统作业(比如java程序和shell脚本)。

    12. mahout

    apache mahout是个可扩展的机器学习和数据挖掘库,当前mahout支持主要的4个用例:

    • 推荐挖掘:搜集用户动作并以此给用户推荐可能喜欢的事物。
    • 聚集:收集文件并进行相关文件分组。
    • 分类:从现有的分类文档中学习,寻找文档中的相似特征,并为无标签的文档进行正确的归类。
    • 频繁项集挖掘:将一组项分组,并识别哪些个别项会经常一起出现。

    13. hcatalog

    apache hcatalog是hadoop建立数据的映射表和存储管理服务,它包括:

    • 提供一个共享模式和数据类型机制。
    • 提供一个抽象表,这样用户就不需要关注数据存储的方式和地址。
    • 为类似pig、mapreduce及hive这些数据处理工具提供互操作性。


    paulwong 2013-05-03 09:05
    ]]>
    一个pig脚本例子分析http://www.blogjava.net/paulwong/archive/2013/04/13/397791.htmlpaulwongpaulwongsat, 13 apr 2013 07:21:00 gmthttp://www.blogjava.net/paulwong/archive/2013/04/13/397791.htmlhttp://www.blogjava.net/paulwong/comments/397791.htmlhttp://www.blogjava.net/paulwong/archive/2013/04/13/397791.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/397791.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/397791.html
    piggybank_path=$pig_home/contrib/piggybank/java/piggybank.jar
    input=pig/input/test-pig-full.txt
    output=pig/output/test-pig-output-$(date   %y%m%d%h%m%s)
    pigscript=analyst_status_logs.pig

    #analyst_500_404_month.pig
    #
    analyst_500_404_day.pig
    #
    analyst_404_percentage.pig
    #
    analyst_500_percentage.pig
    #
    analyst_unique_path.pig
    #
    analyst_user_logs.pig
    #
    analyst_status_logs.pig


    pig -p piggybank_path=$piggybank_path -p input=$input -p output=$output $pigscript


    要分析的数据源,log 文件
    46.20.45.18 - - [25/dec/2012:23:00:25  0100] "get / http/1.0" 302 - "-" "pingdom.com_bot_version_1.4_(http://www.pingdom.com/)" "-" "-" 46.20.45.18 "" 11011aec9542db0983093a100e8733f8 0
    46.20.45.18 - - [25/dec/2012:23:00:25  0100] "get /sign-in.jspx http/1.0" 200 3926 "-" "pingdom.com_bot_version_1.4_(http://www.pingdom.com/)" "-" "-" 46.20.45.18 "" 11011aec9542db0983093a100e8733f8 0
    69.59.28.19 - - [25/dec/2012:23:01:25  0100] "get / http/1.0" 302 - "-" "pingdom.com_bot_version_1.4_(http://www.pingdom.com/)" "-" "-" 69.59.28.19 "" 36d80de7fe52a2d89a8f53a012307b0a 15


    pig脚本:
    --注册jar包,因为要用到dateextractor
    register '$piggybank_path';

    --声明一个短函数名
    define date_extract_mm 
    org.apache.pig.piggybank.evaluation.util.apachelogparser.dateextractor('yyyy-mm');

    define date_extract_dd 
    org.apache.pig.piggybank.evaluation.util.apachelogparser.dateextractor('yyyy-mm-dd');

    -- pig/input/test-pig-full.txt
    --把数据从变量所指的文件加载到pig中,并定义数据列名,此时的数据集为数组(a,b,c)
    raw_logs = load '$input' using org.apache.pig.piggybank.storage.myregexloader('^(\\s ) (\\s ) (\\s ) \\[([\\w:/] \\s[ \\-]\\d{4})\\] "(\\s ) (\\s ) (http[^"] )" (\\s ) (\\s ) "([^"]*)" "([^"]*)" "(\\s )" "(\\s )" (\\s ) "(.*)" (\\s ) (\\s )')
    as (remoteaddr: chararray, 
    n2: chararray, 
    n3: chararray, 
    time: chararray, 
    method: chararray,
    path:chararray,
    protocol:chararray,
    status: int, 
    bytes_string: chararray, 
    referrer: chararray, 
    browser: chararray, 
    n10:chararray,
    remotelogname: chararray, 
    remoteaddr12: chararray, 
    path2: chararray, 
    sessionid: chararray, 
    n15: chararray
    );

    --过滤数据
    filter_logs = filter raw_logs by not (browser matches '.*pingdom.*');
    --item_logs = foreach raw_logs generate browser;

    --percent 500 logs
    --重定义数据项,数据集只取2项status,month
    reitem_percent_500_logs = foreach filter_logs generate status,date_extract_mm(time) as month;
    --分组数据集,此时的数据结构为map(a{(aa,bb,cc),(dd,ee,ff)},b{(bb,cc,dd),(ff,gg,hh)})
    group_month_percent_500_logs = group reitem_percent_500_logs by (month);
    --重定义分组数据集数据项,进行分组统计,此时要联合分组数据集和原数据集统计
    final_month_500_logs = foreach group_month_percent_500_logs 
    {
        --对原数据集做count,因为是在foreachj里做count的,即使是对原数据集,也会自动会加month==group的条件
        --从这里可以看出对于group里的数据集,完全没用到
        --这时是以每一行为单位的,统计map中的key-a对应的数组在原数据集中的个数
        total = count(reitem_percent_500_logs);
        --对原数据集做filter,因为是在foreachj里做count的,即使是对原数据集,也会自动会加month==group的条件
        --重新过滤一下原数据集,得到status==500,month==group的数据集
        t = filter reitem_percent_500_logs by status== 500; --create a bag which contains only t values
        --重定义数据项,取group,统计结果
        generate flatten(group) as col1, 100*(double)count(t)/(double)total;
    }
    store final_month_500_logs into '$output' using pigstorage(',');



    paulwong 2013-04-13 15:21
    ]]>
    把命令行中的值传进pig中http://www.blogjava.net/paulwong/archive/2013/04/10/397645.htmlpaulwongpaulwongwed, 10 apr 2013 07:32:00 gmthttp://www.blogjava.net/paulwong/archive/2013/04/10/397645.htmlhttp://www.blogjava.net/paulwong/comments/397645.htmlhttp://www.blogjava.net/paulwong/archive/2013/04/10/397645.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/397645.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/397645.htmlhttp://wiki.apache.org/pig/parametersubstitution


    %pig -param input=/user/paul/sample.txt -param output=/user/paul/output/


    pig中获取
    records = load $input;


    paulwong 2013-04-10 15:32
    ]]>
    pig小议http://www.blogjava.net/paulwong/archive/2013/04/05/397411.htmlpaulwongpaulwongfri, 05 apr 2013 13:33:00 gmthttp://www.blogjava.net/paulwong/archive/2013/04/05/397411.htmlhttp://www.blogjava.net/paulwong/comments/397411.htmlhttp://www.blogjava.net/paulwong/archive/2013/04/05/397411.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/397411.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/397411.html什么是pig
    是一种设计语言,通过设计数据怎么流动,然后由相应的引擎将此变成mapreduce job去hadoop中运行。
    pig与sql
    两者有相同之处,执行一个或多个语句,然后出来一些结果。
    但不同的是,sql要先把数据导到表中才能执行,sql不关心中间如何做,即发一个sql语句过去,就有结果出来。
    pig,无须导数据到表中,但要设计直到出结果的中间过程,步骤如何等等。


    paulwong 2013-04-05 21:33
    ]]>
    hadoop集群中添加节点步骤http://www.blogjava.net/paulwong/archive/2013/03/16/396544.htmlpaulwongpaulwongsat, 16 mar 2013 15:04:00 gmthttp://www.blogjava.net/paulwong/archive/2013/03/16/396544.htmlhttp://www.blogjava.net/paulwong/comments/396544.htmlhttp://www.blogjava.net/paulwong/archive/2013/03/16/396544.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/396544.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/396544.html

    把namenode的有关配置文件复制到该节点


    修改masters和slaves文件,增加该节点


    设置ssh免密码进出该节点


    单独启动该节点上的datanode和tasktracker(hadoop-daemon.sh start datanode/tasktracker)


    运行start-balancer.sh进行数据负载均衡


    负载均衡:作用:当节点出现故障,或新增加节点时,数据块分布可能不均匀,负载均衡可以重新平衡各个datanode上数据块的分布

    paulwong 2013-03-16 23:04
    ]]>
    phoenix: hbase终于有sql接口了~http://www.blogjava.net/paulwong/archive/2013/02/19/395432.htmlpaulwongpaulwongtue, 19 feb 2013 15:15:00 gmthttp://www.blogjava.net/paulwong/archive/2013/02/19/395432.htmlhttp://www.blogjava.net/paulwong/comments/395432.htmlhttp://www.blogjava.net/paulwong/archive/2013/02/19/395432.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/395432.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/395432.html
    具体详见:

    支持select,from,where,groupby,having,orderby和建表操作,未来将支持二级索引,join操作,动态列簇等功能。

    是建立在原生hbase api基础上的,响应时间10m级别的数据是毫秒,100m级别是秒。




    paulwong 2013-02-19 23:15
    ]]>
    监控hbasehttp://www.blogjava.net/paulwong/archive/2013/02/04/395107.htmlpaulwongpaulwongmon, 04 feb 2013 07:08:00 gmthttp://www.blogjava.net/paulwong/archive/2013/02/04/395107.htmlhttp://www.blogjava.net/paulwong/comments/395107.htmlhttp://www.blogjava.net/paulwong/archive/2013/02/04/395107.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/395107.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/395107.htmlhadoop/hbase是开源版的google bigtable, gfs, mapreduce的实现,随着互联网的发展,大数据的处理显得越发重要,hadoop/hbase的用武之地也越发广泛。为了更好的使用hadoop/hbase系统,需要有一套完善的监控系统,来了解系统运行的实时状态,做到一切尽在掌握。hadoop/hbase有自己非常完善的metrics framework, 里面包种各种维度的系统指标的统计,另外,这套metrics framework设计的也非常不错,用户可以很方便地添加自定义的metrics。更为重要的一点是metrics的展示方式,目前它支持三种方式:一种是落地到本地文件,一种是report给ganglia系统,另一种是通过jmx来展示。本文主要介绍怎么把hadoop/hbase的metrics report给ganglia系统,通过浏览器来查看。

    介绍后面的内容之前有必要先简单介绍一下ganglia系统。ganglia是一个开源的用于系统监控的系统,它由三部分组成:gmond, gmetad, webfrontend, 三部分是这样分工的:

    gmond: 是一个守护进程,运行在每一个需要监测的节点上,收集监测统计,发送和接受在同一个组播或单播通道上的统计信息
    gmetad: 是一个守护进程,定期检查gmond,从那里拉取数据,并将他们的指标存储在rrd存储引擎中
    webfrontend: 安装在有gmetad运行的机器上,以便读取rrd文件,用来做前台展示

    简单总结它们三者的各自的功用,gmond收集数据各个node上的metrics数据,gmetad汇总gmond收集到的数据,webfrontend在前台展示gmetad汇总的数据。ganglia缺省是对系统的一些metric进行监控,比如cpu/memory/net等。不过hadoop/hbase内部做了对ganglia的支持,只需要简单的改配置就可以将hadoop/hbase的metrics也接入到ganglia系统中进行监控。

    接下来介绍如何把hadoop/hbase接入到ganglia系统,这里的hadoop/hbase的版本号是0.94.2,早期的版本可能会有一些不同,请注意区别。hbase本来是hadoop下面的子项目,因此所用的metrics framework原本是同一套hadoop metrics,但后面hadoop有了改进版本的metrics framework:metrics2(metrics version 2), hadoop下面的项目都已经开始使用metrics2, 而hbase成了apache的顶级子项目,和hadoop成为平行的项目后,目前还没跟进metrics2,它用的还是原始的metrics.因此这里需要把hadoop和hbase的metrics分开介绍。

    hadoop接入ganglia:

    1. hadoop metrics2对应的配置文件为:hadoop-metrics2.properties
    2. hadoop metrics2中引用了source和sink的概念,source是用来收集数据的, sink是用来把source收集的数据consume的(包括落地文件,上报ganglia,jmx等)
    3. hadoop metrics2配置支持ganglia:
    #*.sink.ganglia.class=org.apache.hadoop.metrics2.sink.ganglia.gangliasink30
    *.sink.ganglia.class=org.apache.hadoop.metrics2.sink.ganglia.gangliasink31
     
    *.sink.ganglia.period=10
    *.sink.ganglia.supportsparse=true
    *.sink.ganglia.slope=jvm.metrics.gccount=zero,jvm.metrics.memheapusedm=both
    *.sink.ganglia.dmax=jvm.metrics.threadsblocked=70,jvm.metrics.memheapusedm=40
     
    #uncomment as your needs
    namenode.sink.ganglia.servers=10.235.6.156:8649
    #datanode.sink.ganglia.servers=10.235.6.156:8649
    #jobtracker.sink.ganglia.servers=10.0.3.99:8649
    #tasktracker.sink.ganglia.servers=10.0.3.99:8649
    #maptask.sink.ganglia.servers=10.0.3.99:8649
    #reducetask.sink.ganglia.servers=10.0.3.99:8649


    这里需要注意的几点:

    (1) 因为ganglia3.1与3.0不兼容,需要根据ganglia的版本选择使用gangliasink30或者gangliasink31
    (2) period配置上报周期,单位是秒(s)
    (3) namenode.sink.ganglia.servers指定ganglia gmetad所在的host:port,用来向其上报数据
    (4) 如果同一个物理机器上同时启动了多个hadoop进程(namenode/datanode, etc),根据需要把相应的进程的sink.ganglia.servers配置好即可
    hbase接入ganglia:

    1. hbase所用的hadoop metrics对应的配置文件是: hadoop-metrics.properties
    2. hadoop metrics里核心是context,写文件有写文件的timestampingfilecontext, 向ganglia上报有gangliacontext/gangliacontext31
    3. hadoop metrics配置支持ganglia:
    # configuration of the "hbase" context for ganglia
    # pick one: ganglia 3.0 (former) or ganglia 3.1 (latter)
    # hbase.class=org.apache.hadoop.metrics.ganglia.gangliacontext
    hbase.class=org.apache.hadoop.metrics.ganglia.gangliacontext31
    hbase.period=10
    hbase.servers=10.235.6.156:8649

    这里需要注意几点:

    (1) 因为ganglia3.1和3.0不兼容,所以如果是3.1以前的版本,需要用gangliacontext, 如果是3.1版的ganglia,需要用gangliacontext31
    (2) period的单位是秒(s),通过period可以配置向ganglia上报数据的周期
    (3) servers指定的是ganglia gmetad所在的host:port,把数据上报到指定的gmetad
    (4) 对rpc和jvm相关的指标都可以进行类似的配置







    paulwong 2013-02-04 15:08
    ]]>
    hbase部署要点http://www.blogjava.net/paulwong/archive/2013/02/04/395101.htmlpaulwongpaulwongmon, 04 feb 2013 04:10:00 gmthttp://www.blogjava.net/paulwong/archive/2013/02/04/395101.htmlhttp://www.blogjava.net/paulwong/comments/395101.htmlhttp://www.blogjava.net/paulwong/archive/2013/02/04/395101.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/395101.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/395101.htmlregions server和task tracker server不要在同一台机器上,最好如果有mapreduce job运行的话,应该分开两个cluster,即两群不同的服务器上,这样mapreduce 的线下负载不会影响到scaner这些线上负载。

    如果主要是做mapreduce job的话,将regions server和task tracker server放在一起是可以的。


    原始集群模式

    10个或以下节点,无mapreduce job,主要用于低延迟的访问。每个节点上的配置为:cpu4-6core,内存24-32g,4个sata硬盘。hadoop namenode, jobtracker, hbase master, 和zookeeper全都在同一个node上。


    小型集群模式(10-20台服务器)

    hbase master放在单独一台机器上, 以便于使用较低配置的机器。zookeeper也放在单独一台机器上,namenode和jobtracker放在同一台机器上。

    中型集群模式(20-50台服务器)

    由于无须再节省费用,可以将hbase master和zookeeper放在同一台机器上, zookeeper和hbase master要三个实例。namenode和jobtracker放在同一台机器上。

    大型集群模式(>50台服务器)

    和中型集群模式相似,但zookeeper和hbase master要五个实例。namenode和second namenode要有足够大的内存。

    hadoop master节点

    namenode和second namenode服务器配置要求:(小型)8core cpu,16g内存,1g网卡和sata 硬盘,中弄再增加多16g内存,大型则再增加多32g内存。

    hbase master节点

    服务器配置要求:4core cpu,8-16g内存,1g网卡和2个sata 硬盘,一个用于操作系统,另一个用于hbase master logs。

    hadoop data nodes和hbase region server节点

    data node和region server应在同一台服务器上,且不应该和task tracker在一起。服务器配置要求:8-12core cpu,24-32g内存,1g网卡和12*1tb sata 硬盘,一个用于操作系统,另一个用于hbase master logs。

    zoopkeepers节点

    服务器配置和hbase master相似,也可以与hbase master放在一起,但就要多增加一个硬盘单独给zoopkeeper使用。

    安装各节点

    jvm配置:
    -xmx8g—设置heap的最大值到8g,不建议设到15 gb.
    -xms8g—设置heap的最小值到8gs.
    -xmn128m—设置新生代的值到128 mb,默认值太小。
    -xx: useparnewgc—设置对于新生代的垃圾回收器类型,这种类型是会停止java进程,然后再进行回收的,但由于新生代体积比较小,持续时间通常只有几毫秒,因此可以接受。
    -xx: useconcmarksweepgc—设置老生代的垃圾回收类型,如果用新生代的那个会不合适,即会导致java进程停止的时间太长,用这种不会停止java进程,而是在java进程运行的同时,并行的进行回收。
    -xx:cmsinitiatingoccupancyfraction—设置cms回收器运行的频率。






    paulwong 2013-02-04 12:10
    ]]>
    hbase读书笔记http://www.blogjava.net/paulwong/archive/2013/02/01/395020.htmlpaulwongpaulwongfri, 01 feb 2013 05:55:00 gmthttp://www.blogjava.net/paulwong/archive/2013/02/01/395020.htmlhttp://www.blogjava.net/paulwong/comments/395020.htmlhttp://www.blogjava.net/paulwong/archive/2013/02/01/395020.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/395020.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/395020.htmlget、put是online的操作,mapreduce是offline的操作

    hdfs写流程
    客户端收到要保存文件的请求后,将文件以64m为单位拆成若干份block,形成一个列表,即由几个block组成,将这些信息告诉name node,我要保存这个,name node算出一个列表,哪段block应该写到哪个data node,客户端将第一个block传到第一个节点data node a,通知其保存,同时让它通知data node d和data node b也保存一份,data node d收到信息后进行了保存,同时通知data node b保存一份,data node b保存完成后则通知客户端保存完成,客户端再去向name node中取下一个block要保存的位置,重复以上的动作,直到所有的block都保存完成。

    hdfs读流程
    客户端向name node请求读一个文件,name node返回这个文件所构成的所有block的data node ip及block id,客户端并行的向各data node发出请求,要取某个block id的block,data node发回所要的block给客户端,客户端收集到所有的block后,整合成一个完整的文件后,此流程结束。


    mapreduce流程
    输入数据 -- 非多线程了,而是多进程的挑选数据,即将输入数据分成多块,每个进程处理一块 -- 分组 -- 多进程的汇集数据 -- 输出

    hbase表结构
    hbase中将一个大表数据分成不同的小表,每个小表叫region,存放region的服务器叫regionserver,一个regionserver可以存放多个region。通常regionserver和data node是在同一服务器,以减少network io。
    -root-表存放于master server上,记录了一共有多少个regionserver,每个region server上都有一个.meta.表,上面记录了本region server放有哪几个表的哪几个region。如果要知道某个表共有几个region,就得去所有的region server上查.meta.表,进行汇总才能得知。
    客户端如果要查row009的信息,先去咨询zoopkeeper,-root-表在哪里,然后问-root-表,哪个.meta.知道这个信息,然后去问.meta.表,哪个region有这个信息,然后去那个region问row009的信息,然后那个region返回此信息。


    hbase mapreduce
    一个region一个map任务,而任务里的map方法执行多少次,则由查询出来的记录有多少条,则执行多少次。
    reduce任务负责向region写数据,但写到哪个region则由那个key归属哪个region管,则写到哪个region,有可能reduce任务会和所有的region server交互。


    在hbase的mapreduce job中使用join
    reduce-side join
    利用现有的shuttle分组机制,在reduce阶段做join,但由于map阶段数据大,可能会有性能问题。
    map-side join
    将数据较少的一表读到一公共文件中,然后在mpa方法中循环另一表的数据,再将要的数据从公共文件中读取。这样可以减少shuttle和sort的时间,同时也不需要reduce任务。


    paulwong 2013-02-01 13:55
    ]]>
    hadoop的几种join方法http://www.blogjava.net/paulwong/archive/2013/01/31/395000.htmlpaulwongpaulwongthu, 31 jan 2013 10:24:00 gmthttp://www.blogjava.net/paulwong/archive/2013/01/31/395000.htmlhttp://www.blogjava.net/paulwong/comments/395000.htmlhttp://www.blogjava.net/paulwong/archive/2013/01/31/395000.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/395000.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/395000.html2) 压缩字段,对数据预处理,过滤不需要的字段.
    3) 最后一步就是在mapper阶段过滤,这个就是bloom filter的用武之地了.也就是需要详细说明的地方.


    下面就拿一个我们大家都熟悉的场景来说明这个问题: 找出上个月动感地带的客户资费的使用情况,包括接入和拨出.

    (这个只是我臆想出来的例子,根据实际的db数据存储结构,在这个场景下肯定有更好的凯发天生赢家一触即发官网的解决方案,大家不要太较真哦)

    这个时候的两个个数据集都是比较大的,这两个数据集分别是:上个月的通话记录,动感地带的手机号码列表.


    比较直接的处理方法有2种:

    1)在 reduce 阶段,通过动感地带号码来过滤.

    优点:这样需要处理的数据相对比较少,这个也是比较常用的方法.

    缺点:很多数据在mapper阶段花了老鼻子力气汇总了,还通过网络shuffle到reduce节点,结果到这个阶段给过滤了.



    2)在 mapper 阶段时,通过动感地带号码来过滤数据.

    优点:这样可以过滤很多不是动感地带的数据,比如神州行,全球通.这些过滤的数据就可以节省很多网络带宽了.

    缺点:就是动感地带的号码不是小数目,如果这样处理就需要把这个大块头复制到所有的mapper节点,甚至是distributed cache.(bloom filter就是用来解决这个问题的)


    bloom filter就是用来解决上面方法2的缺点的.

    方法2的缺点就是大量的数据需要在多个节点复制.bloom filter通过多个hash算法, 把这个号码列表压缩到了一个bitmap里面. 通过允许一定的错误率来换空间, 这个和我们平时经常提到的时间和空间的互换类似.详细情况可以参考:

    http://blog.csdn.net/jiaomeng/article/details/1495500

    但是这个算法也是有缺陷的,就是会把很多神州行,全球通之类的号码当成动感地带.但在这个场景中,这根本不是问题.因为这个算法只是过滤一些号码,漏网之鱼会在reduce阶段进行精确匹配时顾虑掉.

    这个方法改进之后基本上完全回避了方法2的缺点:

    1) 没有大量的动感地带号码发送到所有的mapper节点.
    2) 很多非动感地带号码在mapper阶段就过滤了(虽然不是100%),避免了网络带宽的开销及延时.


    继续需要学习的地方:bitmap的大小, hash函数的多少, 以及存储的数据的多少. 这3个变量如何取值才能才能在存储空间与错误率之间取得一个平衡.

    paulwong 2013-01-31 18:24
    ]]>
    配置secondarynamenodehttp://www.blogjava.net/paulwong/archive/2013/01/31/394998.htmlpaulwongpaulwongthu, 31 jan 2013 09:39:00 gmthttp://www.blogjava.net/paulwong/archive/2013/01/31/394998.htmlhttp://www.blogjava.net/paulwong/comments/394998.htmlhttp://www.blogjava.net/paulwong/archive/2013/01/31/394998.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/394998.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/394998.html

    second name node会以http的方式向name node要这两个文件,当name node收到请求时,就会韦一个新的editlog来记录,这时second name node就会将取得的这两个文件合并,成一个新的fsimage,再发给name node,name node收到后,就会以这个为准,旧的就会归档不用。


    second name node还有一个用途就是当name node down了的时候,可以改second name node的ip为name node所用的ip,当name node用。

    secondary namenoded 配置很容易被忽视,如果jps检查都正常,大家通常不会太关心,除非namenode发生问题的时候,才会想起还有个secondary namenode,它的配置共两步:

    1. 集群配置文件conf/master中添加secondarynamenode的机器
    2. 修改/添加 hdfs-site.xml中如下属性:

    <property>
     <name>dfs.http.addressname>
     <value>{your_namenode_ip}:50070value>
     <description>
     the address and the base port where the dfs namenode web ui will listen on.
     if the port is 0 then the server will start on a free port.
     description>
     property>


    这两项配置ok后,启动集群。进入secondary namenode 机器,检查fs.checkpoint.dir(core-site.xml文件,默认为${hadoop.tmp.dir}/dfs/namesecondary)目录同步状态是否和namenode一致的。

    如果不配置第二项则,secondary namenode同步文件夹永远为空,这时查看secondary namenode的log显示错误为:


    2011-06-09 11:06:41,430 info org.apache.hadoop.hdfs.server.common.storage: recovering storage directory /tmp/hadoop-hadoop/dfs/namesecondary from failed checkpoint.
    2011-06-09 11:06:41,433 error org.apache.hadoop.hdfs.server.namenode.secondarynamenode: exception in docheckpoint: 
    2011-06-09 11:06:41,434 error org.apache.hadoop.hdfs.server.namenode.secondarynamenode: java.net.connectexception: connection refused
    at java.net.plainsocketimpl.socketconnect(native method)
    at java.net.plainsocketimpl.doconnect(plainsocketimpl.java:351)
    at java.net.plainsocketimpl.connecttoaddress(plainsocketimpl.java:211)
    at java.net.plainsocketimpl.connect(plainsocketimpl.java:200)
    at java.net.sockssocketimpl.connect(sockssocketimpl.java:366)
    at java.net.socket.connect(socket.java:529)
    at java.net.socket.connect(socket.java:478)
    at sun.net.networkclient.doconnect(networkclient.java:163)
    at sun.net.www.http.httpclient.openserver(httpclient.java:394)
    at sun.net.www.http.httpclient.openserver(httpclient.java:529)
    at sun.net.www.http.httpclient.(httpclient.java:233)
    at sun.net.www.http.httpclient.new(httpclient.java:306)
    at sun.net.www.http.httpclient.new(httpclient.java:323)
    at sun.net.www.protocol.http.httpurlconnection.getnewhttpclient(httpurlconnection.java:970)
    at sun.net.www.protocol.http.httpurlconnection.plainconnect(httpurlconnection.java:911)
    at sun.net.www.protocol.http.httpurlconnection.connect(httpurlconnection.java:836)
    at sun.net.www.protocol.http.httpurlconnection.getinputstream(httpurlconnection.java:1172)
    at org.apache.hadoop.hdfs.server.namenode.transferfsimage.getfileclient(transferfsimage.java:151)
    at org.apache.hadoop.hdfs.server.namenode.secondarynamenode.downloadcheckpointfiles(secondarynamenode.java:256)
    at org.apache.hadoop.hdfs.server.namenode.secondarynamenode.docheckpoint(secondarynamenode.java:313)
    at org.apache.hadoop.hdfs.server.namenode.secondarynamenode.run(secondarynamenode.java:225)
    at java.lang.thread.run(thread.java:662)


    可能用到的core-site.xml文件相关属性

    <property>
    <name>fs.checkpoint.periodname>
    <value>300value>
    <description>the number of seconds between two periodic checkpoints.
    description>
    property>

    <property>
     <name>fs.checkpoint.dirname>
     <value>${hadoop.tmp.dir}/dfs/namesecondaryvalue>
     <description>determines where on the local filesystem the dfs secondary
     name node should store the temporary images to merge.
     if this is a comma-delimited list of directories then the image is
     replicated in all of the directories for redundancy.
     description>
    property>


    paulwong 2013-01-31 17:39
    ]]>
    大规模数据查重的多种方法,及bloom filter的应用http://www.blogjava.net/paulwong/archive/2013/01/31/394980.htmlpaulwongpaulwongthu, 31 jan 2013 05:55:00 gmthttp://www.blogjava.net/paulwong/archive/2013/01/31/394980.htmlhttp://www.blogjava.net/paulwong/comments/394980.htmlhttp://www.blogjava.net/paulwong/archive/2013/01/31/394980.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/394980.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/394980.html

    1. 给你a,b两个文件,各存放50亿条url,每条url占用64字节,内存限制是4g,让你找出:a,b文件共同的url。
    解法一:hash成内存大小的小块文件,然后分块内存内查交集。
    解法二:bloom filter(广泛应用于url过滤、查重。参考http://en.wikipedia.org/wiki/bloom_filter、http://blog.csdn.net/jiaomeng/archive/2007/01/28/1496329.aspx)


    2. 有10个文件,每个文件1g, 每个文件的每一行都存放的是用户的query,每个文件的query都可能重复。要你按照query的频度排序。
    解法一:根据数据稀疏程度算法会有不同,通用方法是用hash把文件重排,让相同query一定会在同一个文件,同时进行计数,然后归并,用最小堆来统计频度最大的。
    解法二:类似1,但是用的是与简单bloom filter稍有不同的cbf(counting bloom filter)或者更进一步的sbf(spectral bloom filter,参考http://blog.csdn.net/jiaomeng/archive/2007/03/19/1534238.aspx)
    解法三:mapreduce,几分钟可以在hadoop集群上搞定。参考http://en.wikipedia.org/wiki/mapreduce


    3. 有一个1g大小的一个文件,里面每一行是一个词,词的大小不超过16个字节,内存限制大小是1m。返回频数最高的100个词。
    解法一:跟2类似,只是不需要排序,各个文件分别统计前100,然后一起找前100。

    paulwong 2013-01-31 13:55
    ]]>
    windows环境下用eclipse提交mapreduce job至远程hbase中运行http://www.blogjava.net/paulwong/archive/2013/01/29/394851.htmlpaulwongpaulwongmon, 28 jan 2013 16:19:00 gmthttp://www.blogjava.net/paulwong/archive/2013/01/29/394851.htmlhttp://www.blogjava.net/paulwong/comments/394851.htmlhttp://www.blogjava.net/paulwong/archive/2013/01/29/394851.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/394851.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/394851.html
  • 假设远程hadoop主机名为ubuntu,则应在hosts文件中加上192.168.58.130       ubuntu


  • 新建maven项目,加上相应的配置
    pom.xml
    <project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
      xsi:schemalocation
    ="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelversion>4.0.0modelversion>

      <groupid>com.cloudputinggroupid>
      <artifactid>bigdataartifactid>
      <version>1.0version>
      <packaging>jarpackaging>

      <name>bigdataname>
      <url>http://maven.apache.orgurl>

      <properties>
        <project.build.sourceencoding>utf-8project.build.sourceencoding>
      properties>

        <dependencies>
            <dependency>
                <groupid>junitgroupid>
                <artifactid>junitartifactid>
                <version>3.8.1version>
                <scope>testscope>
            dependency>
            <dependency>
                <groupid>org.springframework.datagroupid>
                <artifactid>spring-data-hadoopartifactid>
                <version>0.9.0.releaseversion>
            dependency>
            <dependency>
                <groupid>org.apache.hbasegroupid>
                <artifactid>hbaseartifactid>
                <version>0.94.1version>
            dependency>
            
            
            <dependency>
                <groupid>org.apache.hadoopgroupid>
                <artifactid>hadoop-coreartifactid>
                <version>1.0.3version>
            dependency>
            <dependency>
                <groupid>org.springframeworkgroupid>
                <artifactid>spring-testartifactid>
                <version>3.0.5.releaseversion>
            dependency>
        dependencies>
    project>


  • hbase-site.xml
    xml version="1.0"?>
    xml-stylesheet type="text/xsl" href="configuration.xsl"?>

    <configuration>

        <property>
            <name>hbase.rootdirname>
            <value>hdfs://ubuntu:9000/hbasevalue>
        property>

        
        <property>
            <name>mapred.job.trackername>
            <value>ubuntu:9001value>
        property>
        
        <property>
            <name>hbase.cluster.distributedname>
            <value>truevalue>
        property>
        
        
        <property>
            <name>hbase.zookeeper.quorumname>
            <value>ubuntuvalue>
        property>
        <property skipindoc="true">
            <name>hbase.defaults.for.versionname>
            <value>0.94.1value>
        property>

    configuration>


  • 测试文件:mapreducetest.java
    package com.cloudputing.mapreduce;

    import java.io.ioexception;

    import junit.framework.testcase;

    public class mapreducetest extends testcase{
        
        public void testreadjob() throws ioexception, interruptedexception, classnotfoundexception
        {
            mapreduceread.read();
        }

    }


  • mapreduceread.java
    package com.cloudputing.mapreduce;

    import java.io.ioexception;

    import org.apache.hadoop.conf.configuration;
    import org.apache.hadoop.fs.filesystem;
    import org.apache.hadoop.fs.path;
    import org.apache.hadoop.hbase.hbaseconfiguration;
    import org.apache.hadoop.hbase.client.result;
    import org.apache.hadoop.hbase.client.scan;
    import org.apache.hadoop.hbase.io.immutablebyteswritable;
    import org.apache.hadoop.hbase.mapreduce.tablemapreduceutil;
    import org.apache.hadoop.hbase.mapreduce.tablemapper;
    import org.apache.hadoop.hbase.util.bytes;
    import org.apache.hadoop.io.text;
    import org.apache.hadoop.mapreduce.job;
    import org.apache.hadoop.mapreduce.lib.output.nulloutputformat;

    public class mapreduceread {
        
        public static void read() throws ioexception, interruptedexception, classnotfoundexception
        {
            // add these statements. xxx
    //        file jarfile = ejob.createtempjar("target/classes");
    //        ejob.addclasspath("d:/paul/work/work-spaces/test1/cloudputing/src/main/resources");
    //        classloader classloader = ejob.getclassloader();
    //        thread.currentthread().setcontextclassloader(classloader);

            configuration config = hbaseconfiguration.create();
            addtmpjar("file:/d:/paul/work/work-spaces/test1/cloudputing/target/bigdata-1.0.jar",config);
            
            job job = new job(config, "exampleread");
            // and add this statement. xxx
    //        ((jobconf) job.getconfiguration()).setjar(jarfile.tostring());

    //        tablemapreduceutil.adddependencyjars(job);
    //        tablemapreduceutil.adddependencyjars(job.getconfiguration(),
    //                mapreduceread.class,mymapper.class);
            
            job.setjarbyclass(mapreduceread.class);     // class that contains mapper
            
            scan scan = new scan();
            scan.setcaching(500);        // 1 is the default in scan, which will be bad for mapreduce jobs
            scan.setcacheblocks(false);  // don't set to true for mr jobs
            
    // set other scan attrs
            
            tablemapreduceutil.inittablemapperjob(
                    "wiki",        // input hbase table name
                    scan,             // scan instance to control cf and attribute selection
                    mapreduceread.mymapper.class,   // mapper
                    null,             // mapper output key 
                    null,             // mapper output value
                    job);
            job.setoutputformatclass(nulloutputformat.class);   // because we aren't emitting anything from mapper
            
    //        distributedcache.addfiletoclasspath(new path("hdfs://node.tracker1:9000/user/root/lib/stat-analysis-mapred-1.0-snapshot.jar"),job.getconfiguration());
            
            boolean b = job.waitforcompletion(true);
            if (!b) {
                throw new ioexception("error with job!");
            }
            
        }
        
        /**
         * 为mapreduce添加第三方jar包
         * 
         * 
    @param jarpath
         *            举例:d:/java/new_java_workspace/scm/lib/guava-r08.jar
         * 
    @param conf
         * 
    @throws ioexception
         
    */
        public static void addtmpjar(string jarpath, configuration conf) throws ioexception {
            system.setproperty("path.separator", ":");
            filesystem fs = filesystem.getlocal(conf);
            string newjarpath = new path(jarpath).makequalified(fs).tostring();
            string tmpjars = conf.get("tmpjars");
            if (tmpjars == null || tmpjars.length() == 0) {
                conf.set("tmpjars", newjarpath);
            } else {
                conf.set("tmpjars", tmpjars   ":"   newjarpath);
            }
        }
        
        public static class mymapper extends tablemapper {

            public void map(immutablebyteswritable row, result value,
                    context context) throws interruptedexception, ioexception {
                string val1 = getvalue(value.getvalue(bytes.tobytes("text"), bytes.tobytes("qual1")));
                string val2 = getvalue(value.getvalue(bytes.tobytes("text"), bytes.tobytes("qual2")));
                system.out.println(val1   " -- "   val2);
            }
            
            private string getvalue(byte [] value)
            {
                return value == null? "null" : new string(value);
            }
        } 

    }


  • paulwong 2013-01-29 00:19
    ]]>
    某hadoop视频教程内容http://www.blogjava.net/paulwong/archive/2013/01/05/393807.htmlpaulwongpaulwongsat, 05 jan 2013 04:59:00 gmthttp://www.blogjava.net/paulwong/archive/2013/01/05/393807.html > hadoop背景
    > hdfs设计目标
    > hdfs不适合的场景
    > hdfs架构详尽分析
    > mapreduce的基本原理



    第2章节
    > hadoop的版本介绍
    > 安装单机版hadoop
    > 安装hadoop集群



    第3章节
    > hdfs命令行基本操作
    > namenode的工作机制
    > hdfs基本配置管理



    第4章节
    > hdfs应用实战:图片服务器(1) - 系统设计
    > 应用的环境搭建 php bootstrap java
    > 使用hadoop java api实现向hdfs写入文件



    第5章节
    > hdfs应用实战:图片服务器(2)
    > 使用hadoop java api实现读取hdfs中的文件
    > 使用hadoop java api实现获取hdfs目录列表
    > 使用hadoop java api实现删除hdfs中的文件


    第6章节
    > mapreduce的基本原理
    > mapreduce的运行过程
    > 搭建mapreduce的java开发环境
    > 使用mapreduce的java接口实现wordcount



    第7章节
    > wordcount运算过程分析
    > mapreduce的combiner
    > 使用mapreduce实现数据去重
    > 使用mapreduce实现数据排序
    > 使用mapreduce实现数据平均成绩计算



    第8章节
    > hbase详细介绍
    > hbase的系统架构
    > hbase的表结构,rowkey,列族和时间戳
    > hbase中的master,region以及region server


    第9章节
    > 使用hbase实现微博应用(1)
    > 用户注册,登陆和注销的设计
    > 搭建环境 struts2 jsp bootstrap jquery hbase java api
    > hbase和用户相关的表结构设计
    > 用户注册的实现



    第10章节
    > 使用hbase实现微博应用(2)
    > 使用session实现用户登录和注销
    > “关注"功能的设计
    > “关注"功能的表结构设计
    > “关注"功能的实现


    第11章节
    > 使用hbase实现微博应用(3)
    > “发微博"功能的设计
    > “发微博"功能的表结构设计
    > “发微博"功能的实现
    > 展现整个应用的运行



    第12章节
    > hbase与mapreduce介绍
    > hbase如何使用mapreduce



    第13章节

    > hbase应用实战:话单查询与统计(1)
    > 应用的整体设计
    > 开发环境搭建
    > 表结构设计



    第14章节
    > hbase应用实战:话单查询与统计(2)
    > 话单入库单设计与实现
    > 话单查询的设计与实现



    第15章节
    > hbase应用实战:话单查询与统计(3)
    > 统计功能设计
    > 统计功能实现



    第16章节
    > 深入mapreduce(1)
    > split的实现详解
    > 自定义输入的实现
    > 实例讲解



    第17章节
    > 深入mapreduce(2)
    > reduce的partition
    > 实例讲解



    第18章节
    > hive入门
    > 安装hive
    > 使用hive向hdfs存入结构化数据
    > hive的基本使用


    第19章节
    > 使用mysql作为hive的元数据库
    > hive结合mapreduce



    第20章节
    > hive应用实战:数据统计(1)
    > 应用设计,表结构设计



    第21章节
    > hive应用实战:数据统计(2)
    > 数据录入与统计的实现 

    paulwong 2013-01-05 12:59
    ]]>
    hbase的一些应用设计tiphttp://www.blogjava.net/paulwong/archive/2013/01/02/393701.htmlpaulwongpaulwongwed, 02 jan 2013 15:09:00 gmthttp://www.blogjava.net/paulwong/archive/2013/01/02/393701.htmlhttp://www.blogjava.net/paulwong/comments/393701.htmlhttp://www.blogjava.net/paulwong/archive/2013/01/02/393701.html#feedback0http://www.blogjava.net/paulwong/comments/commentrss/393701.htmlhttp://www.blogjava.net/paulwong/services/trackbacks/393701.html 

    2,从逻辑存储结构到实际的物理存储结构要经历一个fold过程,所有的columnfamily下的内容被有序的合并,因为hbase把一个columnfamily存储为一个storefile。

    3,把hbase的查询等价为一个逐层过滤的行为,那么在设计存储时就应该明白,使设计越趋向单一的keyvalue性能会越好;如果是因为复杂的业务逻辑导致查询需要确定rowkey、column、timestamp,甚至更夸张的是用到了hbase的filter在server端做value的处理,那么整个性能会非常低。 

    4,因此在表结构设计时,hbase里有tall narrow和flat wide两种设计模式,前者行多列少,整个表结构高且窄;后者行少列多,表结构平且宽;但是由于hbase只能在行的边界做split,因此如果选择flat wide的结构,那么在特殊行变的超级大(超过file或region的上限)时,那么这种行为会导致compaction,而这样做是要把row读内存的~~因此,强烈推荐使用tall narrow模式设计表结构,这样结构更趋近于keyvalue,性能更好。 

    5,一种优雅的行设计叫做partial row scan,我们一般rowkey会设计为--...,每个key都是查询条件,中间用某种分隔符分开,对于只想查key1的所有这样的情况,在不使用filter的情况下(更高性能),我们可以为每个key设定一个起始和结束的值,比如key1作为开始,key1 1作为结束,这样scan的时候可以通过设定start row和stop row就能查到所有的key1的value,同理迭代,每个子key都可以这样被设计到rowkey中。 

    6,对于分页查询,推荐的设计方式也不是利用filter,而是在scan中通过offset和limit的设定来模拟类似rdbms的分页。具体过程就是首先定位start row,接着跳过offset行,读取limit行,最后关闭scan,整个流程结束。 

    7,对于带有时间范围的查询,一种设计是把时间放到一个key的位置,这样设计有个弊端就是查询时一定要先知道查询哪个维度的时间范围值,而不能直接通过时间查询所有维度的值;另一种设计是把timestamp放到前面,同时利用hashcode或者md5这样的形式将其打散,这样对于实时的时序数据,因为将其打散导致自动分到其他region可以提供更好的并发写优势。 

    8,对于读写的平衡,下面这张图更好的说明了key的设计:salting等价于hash,promoted等价于在key中加入其他维度,而random就是md这样的形式了。
     

    9,还有一种高级的设计方式是利用column来当做rdbms类似二级索引的应用设计,rowkey的存储达到一定程度后,利用column的有序,完成类似索引的设计,比如,一个cf叫做data存放数据本身,columnqualifier是一个md5形式的index,而value是实际的数据;再建一个cf叫做index存储刚才的md5,这个index的cf的columnqualifier是真正的索引字段(比如名字或者任意的表字段,这样可以允许多个),而value是这个索引字段的md5。每次查询时就可以先在index里找到这个索引(查询条件不同,选择的索引字段不同),然后利用这个索引到data里找到数据,两次查询实现真正的复杂条件业务查询。

    10,实现二级索引还有其他途径,
    比如:
    1,客户端控制,即一次读取将所有数据取回,在客户端做各种过滤操作,优点自然是控制力比较强,但是缺点在性能和一致性的保证上;
    2,indexed-transactional hbase,这是个开源项目,扩展了hbase,在客户端和服务端加入了扩展实现了事务和二级索引;
    3,indexed-hbase;
    4,coprocessor。 

    11,hbase集成搜索的方式有多种:1,客户端控制,同上;2,lucene;3,hbasene,4,coprocessor。 

    12,hbase集成事务的方式:1,ithbase;2,zookeeper,通过分布式锁。 

    13,timestamp虽然叫这个名字,但是完全可以存放任何内容来形成用户自定义的版本信息。


    paulwong 2013-01-02 23:09
    ]]>
    网站地图