引入

HBase原生的Java客户端是完全同步的,在HBase响应请求的每个动作的时候都会短时间阻塞你的应用线程。
所以我们引入了asynchbase ,其也是由Java编写,并且是完全异步的,线程安全的。
asynchbase是在async的异步库上创建的。
不同于原生的HBase client,asynchbase 只能被实例化一次,只有在对不同的集群操作的时候才有可能生成多个实例。

使用asynchbase客户端
asynchbase的主入口是HBaseClient

  • asynchbase和HTable的性能对比 http://www.tsunanet.net/~tsuna/asynchbase/benchmark/viz.html
  • OpenTSDB is a distributed, scalable Time Series Database (TSDB) http://opentsdb.net/index.html
    从看asynchbase介绍来看,我猜想asynchbase用在MR范围还是有限的。
  • asynchbase就是一个异步client,能够很好地解决一个app里面对于hbase有很多个连接的场景。
  • 但是在MR里面,拿我们现在的HourlyProcedure来说,每次get都是一个同步过程,一定要取回结果才能够进行下一步的操作。整个MR框架就限制了异步client的作用。
  • asynchbase现在使用的场景应该是OpenTSDB,因为没有MR框架限制,所以异步client可以工作很好。
    note@2012-12-10: code/java/asynchbase下面有一些使用的示例代码,并且在自己的fast-hbase-rest里面也使用了asynchbase. 使用还是比较方便的。 实现上asynchbase没有使用任何org.apache.hbase的代码,从头完成了自己的协议访问,这个可以从HBaseClient的构造参数可以看到,在里面没有使用configuration, 而是直接传入quorumSpec就是zookeeper的地址。

Sample

HBase Table准备

1
2
3
4
5
6
hbase(main):023:0> create 'users',{NAME => 'info',VERSIONS => 1,TTL => 5184000,BLOCKCACHE => true}
0 row(s) in 2.3090 seconds

=> Hbase::Table - users

hbase(main):024:0> put 'users','1111','info:password','123456'
0 row(s) in 0.1140 seconds

参考资料

问题描述

HBase操作只能在内网进行,在本地IDE里操作HBase则会报错。
这里我使用了asynchbase客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
13:47:38,201  WARN HBaseClient:3217 - Couldn't connect to the RegionServer @ xx.xx.xx.148:16020
13:47:38,208 ERROR RegionClient:1219 - Unexpected exception from downstream on [id: 0xa853c05b]
java.net.ConnectException: Connection refused: no further information: /xx.xx.xx.148:16020
at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:739)
at org.jboss.netty.channel.socket.nio.NioClientBoss.connect(NioClientBoss.java:152)
at org.jboss.netty.channel.socket.nio.NioClientBoss.processSelectedKeys(NioClientBoss.java:105)
at org.jboss.netty.channel.socket.nio.NioClientBoss.process(NioClientBoss.java:79)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:337)
at org.jboss.netty.channel.socket.nio.NioClientBoss.run(NioClientBoss.java:42)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)

查看该机器上16020的端口情况:

1
2
3
4
[root@HADOOP-SLAVE-148 ~]# netstat -anp|grep 16020
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 ::ffff:10.1.6.148:16020 :::* LISTEN 14684/java
tcp 0 0 ::ffff:10.1.6.148:16020 ::ffff:10.128.122.153:39679 ESTABLISHED 14684/java

解读:

::ffff is the IPv6 prefix for an IPv4 address mapped into IPv6 space
(something along those lines).
And it means that it is an IPv6 socket that is used for IPv4
communication. Application and socket-wise, it is IPv6 but network and
packet-wise it is IPv4. This is allowed as a transition mechanism if
net.ipv6.bindv6only=0 and the application didn’t set the socket option
IPV6_V6ONLY.
It seems that some recent OSes disable this option by default so that
IPv6 sockets can handle only real IPv6 communications.

后来询问了下Hadoop群里的大神,

要想让外网访问的话配置hostname为外网,或者通过nginx指向。

之前配置的hostname确实是内网的。怪不得外网无法访问,在开发机开通了内网权限后就能访问了。

无法连接的问题集锦

问题描述:

我现在用10多台物理服务器组建了一个hadoop集群,这10多台服务器组建成一个局域网,其中只有namenode服务器连接到外网
遇到的问题:我在外网无法访问到datanode节点数据
各位大哥,谁有好的解决方案?

外网为什么要访问datanode数据?访问namenode 就是不对的做法,为何不拿出来一台做service

问题

某一天增加计算的节点后发现在遍历节点List出现如下问题:

1
2
3
4
5
6
7
8
9
10
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at com.sdg.mir.sync.impl.SyncThreeDegreeDetail.exec(SyncThreeDegreeDetail.java:70)
at com.sdg.mir.sync.impl.SyncThreeDegreeDetail.main(SyncThreeDegreeDetail.java:199)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

原因

原来ArrayList只有一个元素不会出现这种问题。当增加节点后,ArrayList中的元素增加,由于ArrayList是线程不安全的。
foreach遍历arraylist是使用Iterator迭代器的。
一般是不允许一个线程在用迭代器遍历的同时,另一个线程在修改的。
后来在发现代码里在循环的最后居然清空了list,o(╯□╰)o.所以报了错。及时修正代码解决了问题
不过之前眼瞎没有看到这个时候把ArrayList换成了CopyOnWriteArrayList也是解决了问题。
CopyOnWriteArrayList创建迭代器时使用了对数组状态的引用。此数组在迭代器的生存期内不会更改,因此不可能发生冲突,
并且迭代器保证不会抛出 ConcurrentModificationException。创建迭代器以后,迭代器就不会反映列表的添加、移除或者更改。
在迭代器上进行的元素更改操作(remove、set 和 add)不受支持。这些方法将抛出 UnsupportedOperationException。

下载HIVE

1
2
3
4
su - hadoop
wget http://apache.fayea.com/hive/hive-1.2.1/apache-hive-1.2.1-bin.tar.gz
tar -zxvf apache-hive-1.2.1-bin.tar.gz
mv apache-hive-1.2.1-bin hive

环境配置

在/etc/profile中追加:

1
2
export HIVE_HOME=/home/hadoop/hive
export PATH=$HIVE_HOME/bin:$PATH

安装MySQL

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
yum install gcc gcc- c ++ ncurses-devel  -y



groupadd mysql
useradd -g mysql mysql
wget http://dev.mysql.com/get/downloads/mysql/mysql-5.6.25.tar.gz
tar zxvf mysql-5.6.25.tar.gz
cd mysql-5.6.25
cmake \
-DCMAKE_INSTALL_PREFIX=/data/mysql \
-DMYSQL_UNIX_ADDR=/data/mysql/mysql.sock \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DMYSQL_DATADIR=/data/mysql/data \
-DMYSQL_TCP_PORT=3306 \
-DENABLE_DOWNLOADS=1

make && make install

chmod +w /data/mysql/
chown -R mysql:mysql /data/mysql/
ln -s /data/mysql/lib/libmysqlclient.so.18 /usr/lib/libmysqlclient.so.18
ln -s /data/mysql/mysql.sock /tmp/mysql.sock

cp /data/mysql/support-files/my-default.cnf /etc/my.cnf
cp /data/mysql/support-files/mysql.server /etc/init.d/mysqld
/data/mysql/scripts/mysql_install_db --user=mysql --defaults-file=/etc/my.cnf --basedir=/data/mysql --datadir=/data/mysql/data


#创建hive数据库
create database hive ;
阅读全文 »

单单git diff 不过是显示还没有暂存起来的改动,而不是这次工作和上次提交之间的差异。所以有时候你一下子暂存了所有更新过的文件后,运行 git diff 后却什么也没有
git diff --cached查看已经暂存起来的变化

git 增量包打包命令 :

1
git archive -o update.zip NEW_COMMIT_ID_HERE $(git diff --name-only OLD_COMMIT_ID_HERE NEW_COMMIT_ID_HERE)

git 获得最近一次commit id

1
git rev-parse HEAD

或者

1
git log -1 --pretty="%H"

可以把其中1改为2则是最近两次的修改记录.这样就可以写脚本了XD

机器准备:

8核32G
平时写程序还是会在伪分布式环境下调试。

添加hadoop用户(笔记里为了方便还是用了root)

1
2
adduser hadoop  #添加hadoop用户
passwd hadoop #为hadoop用户设置密码

添加Java环境

解压jdk压缩包后添加下列配置信息

1
2
3
export JAVA_HOME=/usr/local/java/jdk1.7.0_80
export JRE_HOME=/usr/local/java/jdk1.7.0_80/jre
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin

安装hadoop

wget http://mirror.bit.edu.cn/apache/hadoop/common/stable2/hadoop-2.7.1.tar.gz

解压完成后单机hadoop就算是完成了可以运行如下命令进行测试:

bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.1.jar grep input outout 'dfs[a-z.]+'

阅读全文 »

简介

本文以Hadoop实战为主,另外参考hadoop权威指南,hadoop技术内幕还有网上的资料给出的一个hadoop生态圈的一个简介,
主要以要点为主。

Hadoop历史

hadoop的历史blablabla….
主要记下hadoop不同版本的特性。

特性 1.x 0.22 2.x
安全认证
旧的配置名称 弃用 弃用
新的配置名称
旧的MapReduce API
新的MapReduce API 是(加入部分缺失类库)
MR1运行环境(经典)
MR2 运行环境(YARN)
HDFS联邦管理
HDFS高可用
阅读全文 »

出现这种问题一般来说是Hadoop1.x和2.x冲突了。

之前一直使用

1
2
3
4
5
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>1.2.1</version>
</dependency>

这个依赖包, hadoop-core 1.2.1是最新的,但是还是1.x的client。

Counter是class

解决这个问题需要把这个依赖包换成:

1
2
3
4
5
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.7.1</version>
</dependency>

Ok,问题解决.

前言

现在hadoop生态发展的这么完善,实际这些书讲的也已经非常好了,还有一些大神的博客,废话不多说。

本书建了一个以hbase为数据库的twitter作为实例用来介绍hbase。

连接管理

创建表

create 'user','info'
其中表名是user,info是列族(column family)

HBase中的的列组成列族.

列族

检查表模式

HBase创建表时没提到任何列或者数据类型,除了列族HBase什么也不需要。

HBase:无模式数据库

HBase使用JRuby实现。

阅读全文 »

对这本书没什么很大的期待,但是看完之后感觉对我的职业观产生了冲击了。而且很多观点其实我一直在想的,但是经验和觉悟太低一直都没能写出来,看到文中写的就深有同感。

编程语言里的宗教

语言本身不给力,类库再牛也是有限的

额这不是在吐槽Java吗,但是至少现在看来Java还是挺牛逼的呀。还是自己接触的语言太少了。作者在后面提到语言就是程序员的宗教。此言不差。

Java 在语言层面上和C++也就打个平手,其实Java 要好的多,至少他有了字符串,连字符串都支持不好的语言哪是人用的。

这个把C++喷的,其实还是赞同的哈哈哈,不过貌似作者对字符串有执念,所以对perl也非常喜欢。

阅读全文 »