#
NAME NODE起保存DATA NODE上文件的位置信息用,主要有两个保存文件:FsImage和EditLog,FsImage保存了上一次NAME NODE启动时的状态,EditLog则记录每次成功后的对HDFS的操作行为。当NAME NODE重启时,会合并FsImage和EditLog成为一个新的FsImage,清空EditLog,如果EditLog非常大的时候,则NAME NODE启动的时间会非常长。因此就有SECOND NAME NODE。
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,它的配置共两步:
- 集群配置文件conf/master中添加secondarynamenode的机器
- 修改/添加 hdfs-site.xml中如下属性:
<property>
<name>dfs.http.address</name>
<value>{your_namenode_ip}:50070</value>
<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.<init>(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.period</name>
<value>300</value>
<description>The number of seconds between two periodic checkpoints.
</description>
</property>
<property>
<name>fs.checkpoint.dir</name>
<value>${hadoop.tmp.dir}/dfs/namesecondary</value>
<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>
采用Cloudera版本的hadoop/hbase:
hadoop-0.20.2-cdh3u0
hbase-0.90.1-cdh3u0
zookeeper-3.3.3-cdh3u0
默认已支持FairScheduler调度算法.
只需改配置使期用FairSchedule而非默认的JobQueueTaskScheduler即可.
配置fair-scheduler.xml (/$HADOOP_HOME/conf/):
<?xml version="1.0"?>
<property>
<name>mapred.fairscheduler.allocation.file</name>
<value>[HADOOP_HOME]/conf/fair-scheduler.xml</value>
</property>
<allocations>
<pool name="qiji-task-pool">
<minMaps>5</minMaps>
<minReduces>5</minReduces>
<maxRunningJobs>
<maxRunningJobs>5</maxRunningJobs>
<minSharePreemptionTimeout>300</minSharePreemptionTimeout>
<weight>1.0</weight>
</pool>
<user name="ecap">
<maxRunningJobs>
<maxRunningJobs>6</maxRunningJobs>
</user>
<poolMaxJobsDefault>10</poolMaxJobsDefault>
<userMaxJobsDefault>8</userMaxJobsDefault>
<defaultMinSharePreemptionTimeout>600
</defaultMinSharePreemptionTimeout>
<fairSharePreemptionTimeout>600</fairSharePreemptionTimeout>
</allocations>
配置$HADOOP_HOME/conf/mapred-site.xml,最后添加:
<property>
<name>mapred.jobtracker.taskScheduler</name>
<value>org.apache.hadoop.mapred.FairScheduler</value>
</property>
<property>
<name>mapred.fairscheduler.allocation.file</name>
<value>/opt/hadoop/conf/fair-scheduler.xml</value>
</property>
<property>
<name>mapred.fairscheduler.assignmultiple</name>
<value>true</value>
</property>
<property>
<name>mapred.fairscheduler.sizebasedweight</name>
<value>true</value>
</property>
然后重新运行集群,这样有几个Job(上面配置是5个并行)并行运行时,不会因为一个Job把Map/Reduce占满而使其它Job处于Pending状态.
可从: http://<masterip>:50030/scheduler查看并行运行的状态.
挺有意思的题目。
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。
摘取了一部分,全文请查看
http://blog.sina.com.cn/s/blog_633f4ab20100r9nm.html
背景
“这是最好的时代,也是最坏的时代。”
每个时代的人都在这么形容自己所处的时代。在一次次IT浪潮下面,有人觉得当下乏味无聊,有人却能锐意进取,找到突破。数据存储这个话题自从有了计算机之后,就一直是一个有趣或者无聊的主题。上世纪七十年代,关系数据库理论的出现,造就了一批又一批传奇,并推动整个世界信息化到了一个新的高度。而进入新千年以来,随着SNS等应用的出现,传统的SQL数据库已经越来越不适应海量数据的处理了。于是,这几年NoSQL数据库的呼声也越来越高。
在NoSQL数据库当中,呼声最高的是HBase和Cassandra两个。虽然严格意义上来说,两者服务的目的有所不同,侧重点也不尽相同,但是作为当前开源NoSQL数据库的佼佼者,两者经常被用来做各种比较。
去年十月,Facebook推出了他的新的Message系统。Facebook宣布他们采用HBase作为后台存储系统。这引起了一片喧哗声。因为Cassandra恰恰是Facebook开发,并且于2008年开源。这让很多人惊呼,是否是Cassandra已经被Facebook放弃了?HBase在这场NoSQL数据库的角力当中取得了决定性的胜利?本文打算主要从技术角度分析,HBase和Cassandra的异同,并非要给出任何结论,只是共享自己研究的一些结果。
选手简介
HBase
HBase是一个开源的分布式存储系统。他可以看作是Google的Bigtable的开源实现。如同Google的Bigtable使用Google File System一样,HBase构建于和Google File System类似的Hadoop HDFS之上。
Cassandra
Cassandra可以看作是Amazon Dynamo的开源实现。和Dynamo不同之处在于,Cassandra结合了Google Bigtable的ColumnFamily的数据模型。可以简单地认为,Cassandra是一个P2P的,高可靠性并具有丰富的数据模型的分布式文件系统。
分布式文件系统的指标
根据UC Berkeley的教授Eric Brewer于2000年提出猜测- CAP定理,一个分布式计算机系统,不可能同时满足以下三个指标:
Consistency 所有节点在同一时刻保持同一状态Availability 某个节点失败,不会影响系统的正常运行Partition tolerance 系统可以因为网络故障等原因被分裂成小的子系统,而不影响系统的运行
Brewer教授推测,任何一个系统,同时只能满足以上两个指标。
在2002年,MIT的Seth Gilbert和Nancy Lynch发表正式论文论证了CAP定理。
而HBase和Cassandra两者都属于分布式计算机系统。但是其设计的侧重点则有所不同。HBase继承于Bigtable的设计,侧重于CA。而Cassandra则继承于Dynamo的设计,侧重于AP。
。。。。。。。。。。。。。。。。。。。
特性比较
由于HBase和Cassandra的数据模型比较接近,所以这里就不再比较两者之间数据模型的异同了。接下来主要比较双方在数据一致性、多拷贝复制的特性。
HBase
HBase保证写入的一致性。当一份数据被要求复制N份的时候,只有N份数据都被真正复制到N台服务器上之后,客户端才会成功返回。如果在复制过程中出现失败,所有的复制都将失败。连接上任何一台服务器的客户端都无法看到被复制的数据。HBase提供行锁,但是不提供多行锁和事务。HBase基于HDFS,因此数据的多份复制功能和可靠性将由HDFS提供。HBase和MapReduce天然集成。
Cassandra
写入的时候,有多种模式可以选择。当一份数据模式被要求复制N份的时候,可以立即返回,可以成功复制到一个服务器之后返回,可以等到全部复制到N份服务器之后返回,还可以设定一个复制到quorum份服务器之后返回。Quorum后面会有具体解释。复制不会失败。最终所有节点数据都将被写入。而在未被完全写入的时间间隙,连接到不同服务器的客户端有可能读到不同的数据。在集群里面,所有的服务器都是等价的。不存在任何一个单点故障。节点和节点之间通过Gossip协议互相通信。写入顺序按照timestamp排序,不提供行锁。新版本的Cassandra已经集成了MapReduce了。
相对于配置Cassandra,配置HBase是一个艰辛、复杂充满陷阱的工作。Facebook关于为何采取HBase,里面有一句,大意是,Facebook长期以来一直关注HBase的开发并且有一只专门的经验丰富的HBase维护的team来负责HBase的安装和维护。可以想象,Facebook内部关于使用HBase和Cassandra有过激烈的斗争,最终人数更多的HBase team占据了上风。对于大公司来说,养一只相对庞大的类似DBA的team来维护HBase不算什么大的开销,但是对于小公司,这实在不是一个可以负担的起的开销。
另外HBase在高可靠性上有一个很大的缺陷,就是HBase依赖HDFS。HDFS是Google File System的复制品,NameNode是HDFS的单点故障点。而到目前为止,HDFS还没有加入NameNode的自我恢复功能。不过我相信,Facebook在内部一定有恢复NameNode的手段,只是没有开源出来而已。
相反,Cassandra的P2P和去中心化设计,没有可能出现单点故障。从设计上来看,Cassandra比HBase更加可靠。
关于数据一致性,实际上,Cassandra也可以以牺牲响应时间的代价来获得和HBase一样的一致性。而且,通过对Quorum的合适的设置,可以在响应时间和数据一致性得到一个很好的折衷值。
Cassandra优缺点
主要表现在:
配置简单,不需要多模块协同操作。功能灵活性强,数据一致性和性能之间,可以根据应用不同而做不同的设置。 可靠性更强,没有单点故障。
尽管如此,Cassandra就没有弱点吗?当然不是,Cassandra有一个致命的弱点。
这就是存储大文件。虽然说,Cassandra的设计初衷就不是存储大文件,但是Amazon的S3实际上就是基于Dynamo构建的,总是会让人想入非非地让Cassandra去存储超大文件。而和Cassandra不同,HBase基于HDFS,HDFS的设计初衷就是存储超大规模文件并且提供最大吞吐量和最可靠的可访问性。因此,从这一点来说,Cassandra由于背后不是一个类似HDFS的超大文件存储的文件系统,对于存储那种巨大的(几百T甚至P)的超大文件目前是无能为力的。而且就算由Client手工去分割,这实际上是非常不明智和消耗Client CPU的工作的。
因此,如果我们要构建一个类似Google的搜索引擎,最少,HDFS是我们所必不可少的。虽然目前HDFS的NameNode还是一个单点故障点,但是相应的Hack可以让NameNode变得更皮实。基于HDFS的HBase相应地,也更适合做搜索引擎的背后倒排索引数据库。事实上,Lucene和HBase的结合,远比Lucene结合Cassandra的项目Lucandra要顺畅和高效的多。(Lucandra要求Cassandra使用OrderPreservingPartitioner,这将可能导致Key的分布不均匀,而无法做负载均衡,产生访问热点机器)。
所以我的结论是,在这个需求多样化的年代,没有赢者通吃的事情。而且我也越来越不相信在工程界存在一劳永逸和一成不变的解决方案。当你仅仅是存储海量增长的消息数据,存储海量增长的图片,小视频的时候,你要求数据不能丢失,你要求人工维护尽可能少,你要求能迅速通过添加机器扩充存储,那么毫无疑问,Cassandra现在是占据上风的。
但是如果你希望构建一个超大规模的搜索引擎,产生超大规模的倒排索引文件(当然是逻辑上的文件,真实文件实际上被切分存储于不同的节点上),那么目前HDFS+HBase是你的首选。
就让这个看起来永远正确的结论结尾吧,上帝的归上帝,凯撒的归凯撒。大家都有自己的地盘,野百合也会有春天的!
http://www.jdon.com/38244最近因为项目原因,研究了Cassandra,Hbase等几个NoSQL数据库,最终决定采用HBase。在这里,我就向大家分享一下自己对HBase的理解。
在说HBase之前,我想再唠叨几句。做互联网应用的哥们儿应该都清楚,互联网应用这东西,你没办法预测你的系统什么时候会被多少人访问,你面临的用户到底有多少,说不定今天你的用户还少,明天系统用户就变多了,结果您的系统应付不过来了了,不干了,这岂不是咱哥几个的悲哀,说时髦点就叫“杯具啊”。
其实说白了,这些就是事先没有认清楚互联网应用什么才是最重要的。从系统架构的角度来说,互联网应用更加看重系统性能以及伸缩性,而传统企业级应用都是比较看重数据完整性和数据安全性。那么我们就来说说互联网应用伸缩性这事儿.对于伸缩性这事儿,哥们儿我也写了几篇博文,想看的兄弟可以参考我以前的博文,对于web server,app server的伸缩性,我在这里先不说了,因为这部分的伸缩性相对来说比较容易一点,我主要来回顾一些一个慢慢变大的互联网应用如何应对数据库这一层的伸缩。
首先刚开始,人不多,压力也不大,搞一台数据库服务器就搞定了,此时所有的东东都塞进一个Server里,包括web server,app server,db server,但是随着人越来越多,系统压力越来越多,这个时候可能你把web server,app server和db server分离了,好歹这样可以应付一阵子,但是随着用户量的不断增加,你会发现,数据库这哥们不行了,速度老慢了,有时候还会宕掉,所以这个时候,你得给数据库这哥们找几个伴,这个时候Master-Salve就出现了,这个时候有一个Master Server专门负责接收写操作,另外的几个Salve Server专门进行读取,这样Master这哥们终于不抱怨了,总算读写分离了,压力总算轻点了,这个时候其实主要是对读取操作进行了水平扩张,通过增加多个Salve来克服查询时CPU瓶颈。一般这样下来,你的系统可以应付一定的压力,但是随着用户数量的增多,压力的不断增加,你会发现Master server这哥们的写压力还是变的太大,没办法,这个时候怎么办呢?你就得切分啊,俗话说“只有切分了,才会有伸缩性嘛”,所以啊,这个时候只能分库了,这也是我们常说的数据库“垂直切分”,比如将一些不关联的数据存放到不同的库中,分开部署,这样终于可以带走一部分的读取和写入压力了,Master又可以轻松一点了,但是随着数据的不断增多,你的数据库表中的数据又变的非常的大,这样查询效率非常低,这个时候就需要进行“水平分区”了,比如通过将User表中的数据按照10W来划分,这样每张表不会超过10W了。
综上所述,一般一个流行的web站点都会经历一个从单台DB,到主从复制,到垂直分区再到水平分区的痛苦的过程。其实数据库切分这事儿,看起来原理貌似很简单,如果真正做起来,我想凡是sharding过数据库的哥们儿都深受其苦啊。对于数据库伸缩的文章,哥们儿可以看看后面的参考资料介绍。
好了,从上面的那一堆废话中,我们也发现数据库存储水平扩张scale out是多么痛苦的一件事情,不过幸好技术在进步,业界的其它弟兄也在努力,09年这一年出现了非常多的NoSQL数据库,更准确的应该说是No relation数据库,这些数据库多数都会对非结构化的数据提供透明的水平扩张能力,大大减轻了哥们儿设计时候的压力。下面我就拿Hbase这分布式列存储系统来说说。
一 Hbase是个啥东东?
在说Hase是个啥家伙之前,首先我们来看看两个概念,面向行存储和面向列存储。面向行存储,我相信大伙儿应该都清楚,我们熟悉的RDBMS就是此种类型的,面向行存储的数据库主要适合于事务性要求严格场合,或者说面向行存储的存储系统适合OLTP,但是根据CAP理论,传统的RDBMS,为了实现强一致性,通过严格的ACID事务来进行同步,这就造成了系统的可用性和伸缩性方面大大折扣,而目前的很多NoSQL产品,包括Hbase,它们都是一种最终一致性的系统,它们为了高的可用性牺牲了一部分的一致性。好像,我上面说了面向列存储,那么到底什么是面向列存储呢?Hbase,Casandra,Bigtable都属于面向列存储的分布式存储系统。看到这里,如果您不明白Hbase是个啥东东,不要紧,我再总结一下下:
Hbase是一个面向列存储的分布式存储系统,它的优点在于可以实现高性能的并发读写操作,同时Hbase还会对数据进行透明的切分,这样就使得存储本身具有了水平伸缩性。
二 Hbase数据模型
HBase,Cassandra的数据模型非常类似,他们的思想都是来源于Google的Bigtable,因此这三者的数据模型非常类似,唯一不同的就是Cassandra具有Super cloumn family的概念,而Hbase目前我没发现。好了,废话少说,我们来看看Hbase的数据模型到底是个啥东东。
在Hbase里面有以下两个主要的概念,Row key,Column Family,我们首先来看看Column family,Column family中文又名“列族”,Column family是在系统启动之前预先定义好的,每一个Column Family都可以根据“限定符”有多个column.下面我们来举个例子就会非常的清晰了。
假如系统中有一个User表,如果按照传统的RDBMS的话,User表中的列是固定的,比如schema 定义了name,age,sex等属性,User的属性是不能动态增加的。但是如果采用列存储系统,比如Hbase,那么我们可以定义User表,然后定义info 列族,User的数据可以分为:info:name = zhangsan,info:age=30,info:sex=male等,如果后来你又想增加另外的属性,这样很方便只需要info:newProperty就可以了。
也许前面的这个例子还不够清晰,我们再举个例子来解释一下,熟悉SNS的朋友,应该都知道有好友Feed,一般设计Feed,我们都是按照“某人在某时做了标题为某某的事情”,但是同时一般我们也会预留一下关键字,比如有时候feed也许需要url,feed需要image属性等,这样来说,feed本身的属性是不确定的,因此如果采用传统的关系数据库将非常麻烦,况且关系数据库会造成一些为null的单元浪费,而列存储就不会出现这个问题,在Hbase里,如果每一个column 单元没有值,那么是占用空间的。下面我们通过两张图来形象的表示这种关系:
上图是传统的RDBMS设计的Feed表,我们可以看出feed有多少列是固定的,不能增加,并且为null的列浪费了空间。但是我们再看看下图,下图为Hbase,Cassandra,Bigtable的数据模型图,从下图可以看出,Feed表的列可以动态的增加,并且为空的列是不存储的,这就大大节约了空间,关键是Feed这东西随着系统的运行,各种各样的Feed会出现,我们事先没办法预测有多少种Feed,那么我们也就没有办法确定Feed表有多少列,因此Hbase,Cassandra,Bigtable的基于列存储的数据模型就非常适合此场景。说到这里,采用Hbase的这种方式,还有一个非常重要的好处就是Feed会自动切分,当Feed表中的数据超过某一个阀值以后,Hbase会自动为我们切分数据,这样的话,查询就具有了伸缩性,而再加上Hbase的弱事务性的特性,对Hbase的写入操作也将变得非常快。
上面说了Column family,那么我之前说的Row key是啥东东,其实你可以理解row key为RDBMS中的某一个行的主键,但是因为Hbase不支持条件查询以及Order by等查询,因此Row key的设计就要根据你系统的查询需求来设计了额。我还拿刚才那个Feed的列子来说,我们一般是查询某个人最新的一些Feed,因此我们Feed的Row key可以有以下三个部分构成<userId><timestamp><feedId>,这样以来当我们要查询某个人的最进的Feed就可以指定Start Rowkey为<userId><0><0>,End Rowkey为<userId><Long.MAX_VALUE><Long.MAX_VALUE>来查询了,同时因为Hbase中的记录是按照rowkey来排序的,这样就使得查询变得非常快。
三 Hbase的优缺点
1 列的可以动态增加,并且列为空就不存储数据,节省存储空间.
2 Hbase自动切分数据,使得数据存储自动具有水平scalability.
3 Hbase可以提供高并发读写操作的支持
Hbase的缺点:
1 不能支持条件查询,只支持按照Row key来查询.
2 暂时不能支持Master server的故障切换,当Master宕机后,整个存储系统就会挂掉.
关于数据库伸缩性的一点资料:
http://www.jurriaanpersyn.com/archives/2009/02/12/database-sharding-at-netlog-with-mysql-and-php/http://adam.blog.heroku.com/past/2009/7/6/sql_databases_dont_scale/
- 将INPUT通过SPLIT成M个MAP任务
- JOB TRACKER将这M个任务分派给TASK TRACKER执行
- TASK TRACKER执行完MAP任务后,会在本地生成文件,然后通知JOB TRACKER
- JOB TRACKER收到通知后,将此任务标记为已完成,如果收到失败的消息,会将此任务重置为原始状态,再分派给另一TASK TRACKER执行
- 当所有的MAP任务完成后,JOB TRACKER将MAP执行后生成的LIST重新整理,整合相同的KEY,根据KEY的数量生成R个REDUCE任务,再分派给TASK TRACKER执行
- TASK TRACKER执行完REDUCE任务后,会在HDFS生成文件,然后通知JOB TRACKER
- JOB TRACKER等到所有的REDUCE任务执行完后,进行合并,产生最后结果,通知CLIENT
- TASK TRACKER执行完MAP任务时,可以重新生成新的KEY VALUE对,从而影响REDUCE个数
- 假设远程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.0</modelVersion>
<groupId>com.cloudputing</groupId>
<artifactId>bigdata</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>bigdata</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-hadoop</artifactId>
<version>0.9.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase</artifactId>
<version>0.94.1</version>
</dependency>
<!-- <dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase</artifactId>
<version>0.90.2</version>
</dependency> -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
</dependencies>
</project>
-
hbase-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
/**
* Copyright 2010 The Apache Software Foundation
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-->
<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://ubuntu:9000/hbase</value>
</property>
<!-- 在构造JOB时,会新建一文件夹来准备所需文件。
如果这一段没写,则默认本地环境为LINUX,将用LINUX命令去实施,在WINDOWS环境下会出错 -->
<property>
<name>mapred.job.tracker</name>
<value>ubuntu:9001</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<!-- 此处会向ZOOKEEPER咨询JOB TRACKER的可用IP -->
<property>
<name>hbase.zookeeper.quorum</name>
<value>ubuntu</value>
</property>
<property skipInDoc="true">
<name>hbase.defaults.for.version</name>
<value>0.94.1</value>
</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<Text, Text> {
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);
}
}
}
界面:
算法:
说明:
http://lilyproject.org/books/daisy_docs_book--2_3/publications/html-chunked/output/s182.html
注意:
此处的ACL可以是一个系统多个的,如某些情况用不同的ACL。
资源:可以指文档ID,页面ID之类的,由于文档可能很多个,因此用表达式代替之。
角色:指ROLE/USER之类的。
动作(PERMISSION):指操作类型,如读、写、删除等。
结果(ACTION):指GRANT、DENNY等。
具体实现方式:根据表达式进行运算,看哪个表达式为TRUE,则用哪个,再传入PERMISSION 类型,角色,看ACTION是GRANT还是DENNY,如果是GRANT则授权通过,DENNY则授权不通过。
gartner十大战略性技术分析如下:
1. 移动设备战争
移动设备多样化,Windows仅仅是IT需要支持的多种环境之一,IT需要支持多样化环境。
2. 移动应用与HTML5
HTML5将变得愈发重要,以满足多元化的需求,以满足对安全性非常看重的企业级应用。
3. 个人云
个人云将把重心从客户端设备向跨设备交付基于云的服务转移。
4. 企业应用商店
有了企业应用商店,IT的角色将从集权式规划者转变为市场管理者,并为用户提供监管和经纪服务,甚至可能为应用程序专家提供生态系统支持。
5. 物联网
物联网是一个概念,描述了互联网将如何作为物理实物扩展,如消费电子设备和实物资产都连接到互联网上。
6. 混合型IT和云计算
打造私有云并搭建相应的管理平台,再利用该平台来管理内外部服务
7. 战略性大数据
企业应当将大数据看成变革性的构架,用多元化数据库代替基于同质划分的关系数据库。
8. 可行性分析
大数据的核心在于为企业提供可行的创意。受移动网络、社交网络、海量数据等因素的驱动,企业需要改变分析方式以应对新观点
9. 内存计算
内存计算以云服务的形式提供给内部或外部用户,数以百万的事件能在几十毫秒内被扫描以检测相关性和规律。
10. 整合生态系统
市场正在经历从松散耦合的异构系统向更为整合的系统和生态系统转移,应用程序与硬件、软件、软件及服务打包形成整合生态系统。
结合应用实践及客户需求,可以有以下结论:
1. 大数据时代已经到来
物联网发展及非结构化、半结构化数据的剧增推动了大数据应用需求发展。大数据高效应用是挖掘企业数据资源价值的趋势与发展方向。
2. 云计算依旧是主题,云将更加关注个体
云计算是改变IT现状的核心技术之一,云计算将是大数据、应用商店交付的基础。个人云的发展将促使云端服务更关注个体。
3. 移动趋势,企业应用商店将改变传统软件交付模式
Windows将逐步不再是客户端主流平台,IT技术需要逐步转向支持多平台服务。在云平台上构建企业应用商店,逐步促成IT的角色将从集权式规划者转变为应用市场管理者
4. 物联网将持续改变工作及生活方式
物联网将改变生活及工作方式,物联网将是一种革新的力量。在物联网方向,IPV6将是值得研究的一个技术。
未来企业IT架构图如下:
架构说明:
1.应用将被拆分,客户端将变得极简,用户只需要关注极小部分和自己有关的内容,打开系统后不再是上百个业务菜单。
2.企业后端架构将以分布式架构为主,大数据服务能力将成为企业核心竞争力的集中体现。
3.非结构化数据处理及分析相关技术将会得到前所未有的重视。
受个人水平有限,仅供参考,不当之处,欢迎拍砖!
http://blog.csdn.net/sdhustyh/article/details/8484780