分类目录归档:hadoop

Standard MBean

基本术语

  • MBean:是Managed Bean的简称,可以翻译为“管理构件”。在JMX中MBean代表一个被管理的资源实例,通过MBean中暴露的方法和属性,外界可以获取被管理的资源的状态和操纵MBean的行为。事实上,MBean就是一个Java Object,同JavaBean模型一样,外界使用自醒和反射来获取Object的值和调用Object的方法,只是MBean更为复杂和高级一些。MBean通过公共方法以及遵从特定的设计模式封装了属性和操作,以便暴露给管理应用程序。例如,一个只读属性在管理构件中只有Get方法,既有Get又有Set方法表示是一个可读写的属性。一共有四种类型的MBean: Standard MBean, Dynamic MBean, Open MBean, Model MBean。
  • MBeanServer:MBean生存在一个MBeanServer中。MBeanServer管理这些MBean,并且代理外界对它们的访问。并且MBeanServer提供了一种注册机制,是的外界可以通过名字来得到相应的MBean实例。
  • JMX Agent:Agent只是一个Java进程,它包括这个MBeanServer和一系列附加的MbeanService。当然这些Service也是通过MBean的形式来发布。
  • Protocol Adapters and Connectors:MBeanServer依赖于Protocol Adapters和Connectors来和运行该代理的Java虚拟机之外的管理应用程序进行通信。Protocol Adapters通过特定的协议提供了一张注册在MBeanServer的MBean的视图。例如,一个HTML Adapter可以将所有注册过的MBean显示在Web 页面上。不同的协议,提供不同的视图。Connectors还必须提供管理应用一方的接口以使代理和管理应用程序进行通信,即针对不同的协议,Connectors必须提供同样的远程接口来封装通信过程。当远程应用程序使用这个接口时,就可以通过网络透明的和代理进行交互,而忽略协议本身。Adapters和Connectors使MBean服务器与管理应用程序能进行通信。因此,一个代理要被管理,它必须提供至少一个Protocol Adapter或者Connector。面临多种管理应用时,代理可以包含各种不同的Protocol Adapters和Connectors。当前已经实现和将要实现的Protocol Adapters和Connectors包括: RMI Connector, SNMP Adapter, IIOP Adapter, HTML Adapter, HTTP Connector.

Adapter 和Connector的区别在于:Adapter是使用某种Internet协议来与JMX Agent获得联系,Agent端会有一个对象 (Adapter)来处理有关协议的细节。比如SNMP Adapter和HTTP Adapter。而Connector则是使用类似RPC的方式来访问Agent,在Agent端和客户端都必须有这样一个对象来处理相应的请求与应答。比如RMI Connector。

JMX Agent可以带有任意多个Adapter,因此可以使用多种不同的方式访问Agent。

JMX基本构架

JMX分为三层,分别负责处理不同的事务。它们分别是:

  • Instrumentation 层
    Instrumentation层主要包括了一系列的接口定义和描述如何开发MBean的规范。通常JMX所管理的资源有一个或多个MBean组成,因此这个资源可以是任何由Java语言开发的组件,或是一个JavaWrapper包装的其他语言开发的资源。
  • Agent 层
    Agent 用来管理相应的资源,并且为远端用户提供访问的接口。Agent层构建在Intrumentation层之上,并且使用并管理 Instrumentation层内部描述的组件。Agent层主要定义了各种服务以及通信模型。该层的核心是一MBeanServer,所有的MBean都要向它注册,才能被管理。注册在MBeanServer上的MBean并不直接和远程应用程序进行通信,他们通过协议适配器(Adapter)和连接器(Connector)进行通信。通常Agent由一个MBeanServer和多个系统服务组成。JMX Agent并不关心它所管理的资源是什么。
  • Distributed 层
    Distributed层关心Agent如何被远端用户访问的细节。它定义了一系列用来访问Agent的接口和组件,包括Adapter和Connector的描述。

如果一个Java对象可以由一个遵循JMX规范的管理器应用管理,那么这个Java对象就可以由JMX管理资源。要使一个Java对象可管理,则必须创建相应的MBean对象,并通过这些MBean对象管理相应的Java对象。当拥有MBean类后,需要将其实例化并注册到MBeanServer上。


详述

这里采用的是JDK7,JDK7中已经包含了jmx,但是如果用到HtmlAdaptorServer类(后面会看到)还需要用到jmxtools.jar, 可以去这里下载,有两个包:jmx-1_2_1-ri.zip; jmx_remote-1_0_1_03-ri.zip。jmx-1_2_1-ri.zip解压后lib中有jmxri.jar和jmxtools.jar,将jmxtool.jar拷贝出来放入classpath中即可(jmxri.jar在JDK5+已经包被包含了)。

Standard MBean

Standard MBean的设计和实现是最简单的,它们的管理接口通过方法名来描述。Standard MBean的实现依靠一组命名规则,称之为设计模式。这些命名规则定义了属性和操作。
检查Standard MBean接口和应用设计模式的过程被称为内省(Introspection)。JMX代理通过内省来查看每一个注册在MBeanServer上的MBean的方法和超类,看它是否遵从一定设计模式,决定它是否代表了一个MBean,并辨认出它的属性和操作。
Standard MBean是JMX管理构件中最简单的一种,只需要开发一个MBean接口(为了实现Standard MBean,必须遵循一套继承规范。必须每一个MBean定义一个接口,而且这个接口的名字必须是其被管理的资源的对象类的名称后面加上”MBean”),一个实现MBean接口的类,并且把它们注册到MBeanServer中就可以了。

1
2
3
4
5
6
7
8
package com.test.jmx;
public interface HelloMBean {
    public String getName();
    public void setName(String name);
    public void printHello();
    public void printHello(String whoName);
}

接下来是真正的资源对象,因为命名规范的限制,因此对象名称必须为Hello.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.test.jmx;
public class Hello implements HelloMBean {
    private String name;
    @Override
    public String getName() {
        return name;
    }
    @Override
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public void printHello() {
        System.out.println("Hello world, "+ name);
    }
    @Override
    public void printHello(String whoName) {
        System.out.println("Hello, "+whoName);
    }
}

接下去创建一个Agent类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.test.jmx;
import com.sun.jdmk.comm.HtmlAdaptorServer;
import javax.management.*;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class HelloAgent {
    public static void main(String[] args) throws MalformedObjectNameException,
            NotCompliantMBeanException, InstanceAlreadyExistsException,
            MBeanRegistrationException, IOException {
        // 下面这种方式不能再JConsole中使用
//      MBeanServer server = MBeanServerFactory.createMBeanServer();
// 首先建立一个MBeanServer,MBeanServer用来管理我们的MBean,通常是通过MBeanServer来获取我们MBean的信息,间接
// 调用MBean的方法,然后生产我们的资源的一个对象。
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        String domainName = "MyMBean";
//为MBean(下面的new Hello())创建ObjectName实例
        ObjectName helloName = new ObjectName(domainName+":name=HelloWorld");
// 将new Hello()这个对象注册到MBeanServer上去
        mbs.registerMBean(new Hello(),helloName);
// Distributed Layer, 提供了一个HtmlAdaptor。支持Http访问协议,并且有一个不错的HTML界面,这里的Hello就是用这个作为远端管理的界面
// 事实上HtmlAdaptor是一个简单的HttpServer,它将Http请求转换为JMX Agent的请求
        ObjectName adapterName = new ObjectName(domainName+":name=htmladapter,port=8082");
        HtmlAdaptorServer adapter = new HtmlAdaptorServer();
        adapter.start();
        mbs.registerMBean(adapter,adapterName);
        int rmiPort = 1099;
        Registry registry = LocateRegistry.createRegistry(rmiPort);
        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:"+rmiPort+"/"+domainName);
        JMXConnectorServer jmxConnector = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
        jmxConnector.start();
    }
}

编译运行,在浏览器中输入localhost:8082,这样我们就可以对程序进行管理,如图:

可以看到我们注册的MyMBean域下的”name=HelloWorld”,可以点击进去,然后可以修改属性Name和执行2个printHello方法,可以在控制台看到效果。具体不贴图赘述,机智的小伙伴一试就知道怎么玩转了。

上面代码中还通过RMI(JMXServiceURL, JMXConnectorServer )注册URL来提供客户端连接,可以通过JConsole作为客户端来管理MBean. 打开JConsole工具(%JAVA_HOME%/bin/jconsole.exe),如图在远程进程中输入rmi地址“service:jmx:rmi:///jndi/rmi://localhost:1099/MyMBean”:

点击“连接”之后就出现:

这样就可以像HTML一样管理MBean了。

注意上面的代码中:

1
Registry registry = LocateRegistry.createRegistry(rmiPort);

可以在某一特定端口创建名字夫妇,从而用户无需再手工启动rmiregistry,如果不加入这句代码,就会出现Connection Refused的异常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Exception in thread "main" java.io.IOException: Cannot bind to URL [rmi://localhost:1099/MyMBean]: javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host: localhost; nested exception is:
    java.net.ConnectException: Connection refused: connect]
    at javax.management.remote.rmi.RMIConnectorServer.newIOException(Unknown Source)
    at javax.management.remote.rmi.RMIConnectorServer.start(Unknown Source)
    at com.test.jmx.HelloAgent.main(HelloAgent.java:44)
Caused by: javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host: localhost; nested exception is:
    java.net.ConnectException: Connection refused: connect]
    at com.sun.jndi.rmi.registry.RegistryContext.bind(Unknown Source)
    at com.sun.jndi.toolkit.url.GenericURLContext.bind(Unknown Source)
    at javax.naming.InitialContext.bind(Unknown Source)
    at javax.management.remote.rmi.RMIConnectorServer.bind(Unknown Source)
    ... 2 more
Caused by: java.rmi.ConnectException: Connection refused to host: localhost; nested exception is:
    java.net.ConnectException: Connection refused: connect
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
    at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
    at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
    at sun.rmi.server.UnicastRef.newCall(Unknown Source)
    at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
    ... 6 more
Caused by: java.net.ConnectException: Connection refused: connect
    at java.net.DualStackPlainSocketImpl.connect0(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
    at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
    at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
    at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
    at java.net.PlainSocketImpl.connect(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)
    at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(Unknown Source)
    at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(Unknown Source)
    ... 11 more

当然,这也就其他的解决办法:运行 %JAVA_HOME%/bin/rmiregistry.exe 1099就有和那行代码一样的效果。

我们不仅可以通过JConsole作为客户端采用rmi的方式来进行管理,我们同样可以采用自定义程序作为客户端来连接JMXConnectorServer管理MBean.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package com.test.jmx;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import javax.management.Attribute;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
public class Client {
    public static void main(String[] args) throws IOException,
            MalformedObjectNameException, InstanceNotFoundException,
            AttributeNotFoundException, InvalidAttributeValueException,
            MBeanException, ReflectionException, IntrospectionException {
        String domainName = "MyMBean";
        int rmiPort = 1099;
        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:"+rmiPort+"/"+domainName);
        // 可以类比HelloAgent.java中的那句:
        // JMXConnectorServer jmxConnector = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
        JMXConnector jmxc = JMXConnectorFactory.connect(url);
        MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
        //print domains
        System.out.println("Domains:------------------");
        String domains[] = mbsc.getDomains();
        for(int i=0;i<domains.length;i++){
            System.out.println("\tDomain["+i+"] = "+domains[i]);
        }
        //MBean count
        System.out.println("MBean count = "+mbsc.getMBeanCount());
        //process attribute
        ObjectName mBeanName = new ObjectName(domainName+":name=HelloWorld");
        mbsc.setAttribute(mBeanName, new Attribute("Name","zzh"));//注意这里是Name而不是name
        System.out.println("Name = "+mbsc.getAttribute(mBeanName, "Name"));
        //接下去是执行Hello中的printHello方法,分别通过代理和rmi的方式执行
        //via proxy
        HelloMBean proxy = MBeanServerInvocationHandler.newProxyInstance(mbsc, mBeanName, HelloMBean.class, false);
        proxy.printHello();
        proxy.printHello("jizhi boy");
        //via rmi
        mbsc.invoke(mBeanName, "printHello", null, null);
        mbsc.invoke(mBeanName, "printHello", new String[]{"jizhi gril"}, new String[]{String.class.getName()});
        //get mbean information
        MBeanInfo info = mbsc.getMBeanInfo(mBeanName);
        System.out.println("Hello Class: "+info.getClassName());
        for(int i=0;i<info.getAttributes().length;i++){
            System.out.println("Hello Attribute:"+info.getAttributes()[i].getName());
        }
        for(int i=0;i<info.getOperations().length;i++){
            System.out.println("Hello Operation:"+info.getOperations()[i].getName());
        }
        //ObjectName of MBean
        System.out.println("all ObjectName:--------------");
        Set<ObjectInstance> set = mbsc.queryMBeans(null, null);
        for(Iterator<ObjectInstance> it = set.iterator();it.hasNext();){
            ObjectInstance oi = it.next();
            System.out.println("\t"+oi.getObjectName());
        }
        jmxc.close();
    }
}

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Domains:------------------
    Domain[0] = MyMBean
    Domain[1] = java.nio
    Domain[2] = JMImplementation
    Domain[3] = com.sun.management
    Domain[4] = java.lang
    Domain[5] = java.util.logging
MBean count = 21
Name = zzh
Hello Class: com.test.jmx.Hello
Hello Attribute:Name
Hello Operation:printHello
Hello Operation:printHello
all ObjectName:--------------
    java.lang:type=OperatingSystem
    java.lang:type=Compilation
    java.lang:type=MemoryPool,name=PS Old Gen
    java.lang:type=Memory
    JMImplementation:type=MBeanServerDelegate
    java.lang:type=MemoryPool,name=PS Perm Gen
    java.lang:type=Runtime
    MyMBean:name=htmladapter,port=8082
    java.nio:type=BufferPool,name=direct
    java.lang:type=GarbageCollector,name=PS MarkSweep
    java.nio:type=BufferPool,name=mapped
    java.lang:type=Threading
    com.sun.management:type=HotSpotDiagnostic
    java.lang:type=GarbageCollector,name=PS Scavenge
    MyMBean:name=HelloWorld
    java.lang:type=ClassLoading
    java.lang:type=MemoryPool,name=PS Survivor Space
    java.lang:type=MemoryManager,name=CodeCacheManager
    java.lang:type=MemoryPool,name=Code Cache
    java.util.logging:type=Logging
    java.lang:type=MemoryPool,name=PS Eden Space

这是客户端的运行结果,由于在客户端调用了服务端的方法,可以在服务端看到打印结果:

1
2
3
4
Hello world, zzh
Hello, jizhi boy
Hello world, zzh
Hello, jizhi gril

上面代码涉及到辅助原数据的概念:辅助元数据类用来描述管理构件。辅助元数据类不仅被用来内省标准管理构件,也被动态管理构件用来进行自我描述。这些类根据属性、操作、构建器和通告描述了管理接口。JMX代理通过这些元数据类管理所有管理构件,而不管这些管理构件的类型。部分辅助元类如下:

  1. MBeanInfo–包含了属性、操作、构建器和通知的信息。
  2. MBeanFeatureInfo–为下面类的超类。
  3. MBeanAttributeInfo–用来描述管理构件中的属性。
  4. MBeanConstructorInfo–用来描述管理构件中的构建器。
  5. MBeanOperationInfo–用来描述管理构件中的操作。
  6. MBeanParameterInfo–用来描述管理构件操作或构建器的参数。
  7. MBeanNotificationInfo–用来描述管理构件发出的通知。

centos安装apache

1) 卸载系统自带的httpd:
rpm -qa|grep httpd
rpm -e httpd-2.2.15-15.el6.centos –nodeps
rpm -e httpd-tools

2)找到最新版下载链接
从http://httpd.apache.org/download.cgi找到最新版下载链接,现在最版稳定版链接是:http://mirror.bjtu.edu.cn/apache//httpd/httpd-2.2.24.tar.gz

3)开始安装Apache
cd /usr/local/src
wget http://mirror.bjtu.edu.cn/apache//httpd/httpd-2.2.24.tar.gz
tar -zxvf httpd-2.2.19.tar.gz
cd httpd-2.2.19
./configure –prefix=/usr/local/apache –enable-vhost-alias –enable-rewrite –enable-info
make
make install

4)复制初始化文件和设置Apache开机启动
cp build/rpm/httpd.init /etc/init.d/httpd
chmod 755 /etc/init.d/httpd
chkconfig –add httpd
chkconfig –level 35 httpd on

5)创建符号链接
检查/etc/init.d/httpd看所需要的文件
CONFFILE=/etc/httpd/conf/httpd.conf
httpd=${HTTPD-/usr/sbin/httpd}
pidfile=${PIDFILE-/var/log/httpd/${prog}.pid}
lockfile=${LOCKFILE-/var/lock/subsys/${prog}}

符号链接如下:
ln -s /usr/local/apache/ /etc/httpd
ln -s /usr/local/apache/bin/httpd /usr/sbin/httpd
ln -s /usr/local/apache/bin/apachectl /usr/sbin/apachectl
ln -s /usr/local/apache/logs /var/log/httpd

6)启动/停止服务
service httpd restart
service httpd start
/usr/local/apache/bin/apachectl start
/usr/local/apache/bin/apachectl stop
/usr/local/apache/bin/apachectl status
/etc/init.d/httpd start
/etc/init.d/httpd stop
/etc/init.d/httpd restart

使用pgrep查找启动的进程。
pgrep httpd

7)在浏览器中查看:
http://192.168.0.120:80
如果看到it works,说明apache已经启动了。

8)apache配置文件
vi /usr/local/apache/conf/httpd.conf
更多的configure选项可参考http://httpd.apache.org/docs/2.2/programs/configure.html

9) 默认地apache配置文件中如下:

#
# DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.
#
DocumentRoot “/usr/local/apache/htdocs”

#
# Each directory to which Apache has access can be configured with respect
# to which services and features are allowed and/or disabled in that
# directory (and its subdirectories).
#
# First, we configure the “default” to be a very restrictive set of
# features.
#
<Directory />
Options FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
</Directory>

#
# This should be changed to whatever you set DocumentRoot to.
#
<Directory “/usr/local/apache/htdocs”>
#
# Possible values for the Options directive are “None”, “All”,
# or any combination of:
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
# Note that “MultiViews” must be named *explicitly* — “Options All”
# doesn’t give it to you.
#
# The Options directive is both complicated and important. Please see
# http://httpd.apache.org/docs/2.2/mod/core.html#options
# for more information.
#
Options Indexes FollowSymLinks

#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be “All”, “None”, or any combination of the keywords:
# Options FileInfo AuthConfig Limit
#
AllowOverride None

#
# Controls who can get stuff from this server.
#
Order allow,deny
Allow from all

</Directory>

#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>

如果你需要你的home目录可以访问,需要在documentroot下创建symbollink指向你的home,且确保home目录对所有人都有可执行权限。例如:

[AAA@Centos_AAA cgi-bin]$ ll -d /usr/local/apache/htdocs/~AAA
lrwxrwxrwx. 1 root root 9 Apr 7 09:44 /usr/local/apache/htdocs/~AAA -> /home/AAA
[AAA@Centos_AAA cgi-bin]$ ll -d /home/AAA
drwxr-xr-x. 38 AAA AAA 4096 Apr 7 11:10 /home/AAA

完全分布式HBase集群安装配置

HBase 是一个开源的非关系(NoSQL)的可伸缩性分布式数据库。它是面向列的,并适合于存储超大型松散数据。HBase适合于实时,随机对Big数据进行读写操作的业务环境。关于HBase的更多介绍请参见HBase项目官网

    本文环境与上一讲–完全分布式Hadoop集群配置一致。OS是Ubuntu Server 10.04,HBase版本是0.20.6。

         HRegionServer&HQuorumPeer:dm1,IP:192.168.0.17;

         HRegionServer&HQuorumPeer:dm2,IP:192.168.0.18;

         HRegionServer&HQuorumPeer:dm3,IP:192.168.0.9;

                  HMaster&NameNode:dm4,IP:192.168.0.10;(SecondaryNameNode)

  虽然secondarynamenode和namenode放在同一台机器上比较不合理。但是考虑到这只是个实验的小集群(硬件环境不允许),再者有xenserver的时序快照的保障,就不将SecondaryNameNode部署在其他机器上了。

     主要的还是配置工作,依然将HBase放在/home下,编辑/home/hbase/conf下的hbase-site.xml,hbase-default.xml,hbase-env.sh这几个文件。具体步骤如下:

     一.编辑所有机器上的hbase-site文件,命令如下:

1
vi /home/hbase/conf/hbase-site.xml

      编辑文件如下列代码所示。注意项有2:

    1.其中首先需要注意hdfs://dm4:9000/hbase这里,必须与你的Hadoop集群的core-site.xml文件配置保持完全一致才行,如果你Hadoop的hdfs使用了其它端口,请在这里也修改。再者就是Hbase该项并不识别机器IP,只能使用机器hostname才可行,即若使用dm4的IP(192.168.0.10)是会抛出java错误,至于具体的错误由于时间久远,我就懒得去翻查那大量的log了。

      2.hbase.zookeeper.quorum 的个数必须是奇数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<configuration>
<property>
 <name>hbase.rootdir</name>
 <value>hdfs://dm4:9000/hbase</value>
</property>
<property>
 <name>hbase.cluster.distributed</name>
 <value>true</value>
</property>
<property>
<name>hbase.master</name>
<value>192.168.0.10:60000</value>
</property>
<property>
 <name>hbase.zookeeper.quorum</name>
 <value>192.168.0.9,192.168.0.17,192.168.0.18</value>
</property>
</configuration>

   二.编辑所有机器的 hbase-default.xml,命令如下:

1
vi /home/hbase/conf/hbase-default.xml

    只需修改前面hbase.rootdir 与hbase.cluster.distributed 这两项。修改如下面代码所示:

HBase的数据重启就被擦掉,如果需要数据持久化的,就修改rootdir项,写定你的HDFS目录。

至于default内其它的项的含义与修改,再请参考官网。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<configuration>
 <property>
 <name>hbase.rootdir</name>
<value>hdfs://dm4:9000/hbase_rootdir</value>
 <description>The directory shared by region servers.
 Should be fully-qualified to include the filesystem to use.
 E.g: hdfs://NAMENODE_SERVER:PORT/HBASE_ROOTDIR
 </description>
 </property>
 <property>
 <name>hbase.master.port</name>
 <value>60000</value>
 <description>The port master should bind to.</description>
 </property>
 <property>
 <name>hbase.cluster.distributed</name>
 <value>true</value>
 <description>The mode the cluster will be in. Possible values are
 false: standalone and pseudo-distributed setups with managed Zookeeper
 true: fully-distributed with unmanaged Zookeeper Quorum (see hbase-env.sh)
 </description>
 </property>

   三. 编辑所有机器的hbase-env.sh,命令如下:

1
vi /home/hbase/conf/hbase-env.sh

     修改代码如下所示:

1
2
3
4
5
6
export HBASE_OPTS="$HBASE_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:+UseConcMarkS
weepGC -XX:+CMSIncrementalMode"
 export JAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.22
export HBASE_MANAGES_ZK=true
export HBASE_HOME=/home/hbase
export HADOOP_HOME=/home/hadoop

     四.编辑所有机器的HBase的HMasters和HRegionServers。修改/home/hbase/conf 文件夹下的regionservers文

件。添加DataNode的IP即可。代码如下:

1
2
3
192.168.0.9
192.168.0.17
192.168.0.18

    行文至此,HBase集群的配置已然完成。以下便是启动和测试。

    五.启动.测试HBase数据库。

     在HMaster即Namenode (dm4)启动HBase数据库(Hadoop集群必须已经启动)。 启动命令:

1
/home/hbase/bin/start-hbase.sh

  Hbase启动如下图所示:

2011012217223981

    最好输入JPS命令测试一下你当前Hbase集群进程。如下图:

::__IHACKLOG_REMOTE_IMAGE_AUTODOWN_BLOCK__::1

然后输入如下命令进入hbase的命令行管理界面:

1
/home/hbase/bin/hbase shell

   在hbase shell下 输入list,如下所示,列举你当前数据库的名称,如下图所示。如果你的Hbase没配置成功会抛出java错误。

2011012217360618

   我们也可以通过WEB页面来管理查看HBase数据库。

  HMaster:http://192.168.0.10:60010/master.jsp

  我的HBase数据库截图:

::__IHACKLOG_REMOTE_IMAGE_AUTODOWN_BLOCK__::3

 至于HBase的命令参见:Hadoop Wiki

 HBase数据库的开发应用,包括数据库读写和条件查询等,请参见我未来的文章……

  六.参考文献

   1.HBase: Bigtable-like structured storage for Hadoop HDFS

     http://wiki.apache.org/hadoop/Hbase

   2.HBase Testing Tutorial

        http://wiki.apache.org/hadoop/Hbase/HowToTest

hadoop集群部署

1) 安装jdk
下载jdk-6u21-linux-i586.bin
然后修改/etc/profile:

export JAVA_HOME=/usr/local/jdk  
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH  
export PATH=$PATH:$JAVA_HOME/bin

保存,并执行source /etc/profile

2) 配置host
Namenode的机器,需要配置集群中所有机器的ip
修改/etc/hosts

10.10.236.190   master  
10.10.236.191   slave-A  
10.10.236.193   slave-B

其他的datanode的/etc/hosts 只需要配置namenode的机器ip和本机ip

10.10.236.190   master  
10.10.236.191   slave-A

修改hostname(可选)
vi /proc/sys/kernel/hostname

3) 建立ssh无密码登录
首先进到root目录下

root@master:~# $ssh-keygen  -t  rsa 

进入.ssh目录

root@master:~/.ssh# cp id_rsa.pub authorized_keys  

其余的datanode的机器
新建.ssh目录

root@slave-A:~# mkdir .ssh  

在name(master)上远程拷贝

root@master:~/.ssh# scp authorized_keys slave-A:/root/.ssh/  

测试ssh

4) 安装hadoop
下载Hadoop 解压到每台服务器的/data/soft
解压

root@master:/data/soft# tar zxvf hadoop-0.21.0.tar.gz  

建立软连

root@master:/data/soft# ln -s hadoop-0.21.0 hadoop  

然后修改/etc/profile

export HADOOP_HOME=/data/soft/hadoop  
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin

5) 配置hadoop
1.修改conf/hadoop-env.sh,添加jdk支持

export JAVA_HOME=/usr/local/jdk

  如果ssh端口不是默认的22,在conf/hadoop-env.sh里改下。如:

export HADOOP_SSH_OPTS="-p 1234"

2.修改conf/core-site.xml,增加下面内容

复制代码
<property>   
        <name>fs.default.name</name>    
        <value>hdfs://master:54310</value> //这个才是真正决定namenode  
</property>  
<property>    
        <name>hadoop.tmp.dir</name>    
        <value>/data/hdfs/tmp</value>  //临时文件,有问题的时候,可以删除  
        <description>A base for other temporary directories.</description>  
</property>
复制代码

3.修改conf/hdfs-site.xml,增加下面内容

复制代码
<property>  
        <name>dfs.name.dir</name>  
        <value>/data/hdfs/name</value> //namenode持久存储名字空间,事务日志的本地路径  
</property>  
<property>  
        <name>dfs.data.dir</name>  
        <value>/data/hdfs/data</value> //datanode存放数据的路径  
</property>  
<property>  
        <name>dfs.datanode.max.xcievers</name>  
        <value>4096</value>  
</property>  
<property>  
        <name>dfs.replication</name>  
        <value>1</value> //数据备份的个数,默认是3  
</property>
复制代码

 

3.修改conf/mapred-site.xml,增加下面内容

<property>  
        <name>mapred.job.tracker</name> //jobTracker的主机  
        <value>master:54311</value>  
</property>

4. .修改conf/masters,这个决定那个是secondarynamenode

master

5 .修改conf/slaves,这个是所有datanode的机器

slaves-A
slaves-B

6) 将配置好的hadoop拷贝到所有的datanode

root@master:/data/soft/hadoop/conf# scp -rp /data/soft/hadoop-0.21.0 10.10.236.191:/data/soft/hadoop-0.21.0

在datanode上建立对应的软连

7) 格式化hdfs文件系统的namenode

root@master:/data/soft/hadoop# bin/hadoop namenode –format  

输入Y

8) 启动hadoop集群

root@master:/data/soft/hadoop# bin/start-all.sh 

9) Hdfs操作
建立目录

root@master:/data/soft/hadoop # bin/hadoop dfs -mkdir testdir

查看现有文件

root@master:/data/soft/hadoop # bin/hadoop dfs -ls 

10) 关闭Hdfs

root@master:/data/soft/hadoop# bin/stop-all.sh