当前位置:  编程技术>移动开发
本页文章导读:
    ▪二维码的20类商业应用模式        二维码的20种商业应用模式   据业内预测,2012年二维码市场规模将达到300亿元,到了2015年,二维码市场将超过1000亿元,会有一万家公司进入二维码行业。 二维码,区别于常见的条形码(一.........
    ▪ 揭秘IT人才特点:中美印日四国软件工程师比较        揭秘IT人才特点:中美印日四国程序员比较       首先是日本程序员。他们的特点是非常仔细。我认为很主要的一个原因是日本公司的需求非常细致。细致到在网页上,连一个像素都不能偏.........
    ▪ R Hadoop 装配和使用       R Hadoop 安装和使用 Author:Lishu Date: 2013-10-23 Weibo: @maggic_rabbit        最近接了一个project要使用R Hadoop,这才零零散散开始学习R和Hadoop,在这里记录下我学习和安装过程中遇到的问题和解决.........

[1]二维码的20类商业应用模式
    来源: 互联网  发布时间: 2014-02-18
二维码的20种商业应用模式

 

据业内预测,2012年二维码市场规模将达到300亿元,到了2015年,二维码市场将超过1000亿元,会有一万家公司进入二维码行业。

二维码,区别于常见的条形码(一维码),是用特定的几何图形按一定规律在平面(水平、垂直二维方向上)记录数据信息,看上去像一个由双色图形相 间组成的方形迷宫。二维码信息容量大,比普通条码信息容量约高几十倍。同时,二维码误码率不超过千万分之一,比普通条码低很多。另外,二维码编码范围广, 可把图片、声音、文字、签字、指纹等可数字化的信息进行编码,易制作,成本低,持久耐用。

目前在日、韩等国家,二维码应用已非常普遍,普及率高达96%以上。早在2006年,国内就开始二维码的商业应用,但由于当时智能手机在并不普 及,第一轮的二维码产业并没有真正形成。2012年成为了中国的二维码元年,据统计,目前全国每月扫码量超过1.6亿次,移动运营商、IT巨头已经抢得先机。

如此神速发展的二维码,究竟可以应用在哪些方面呢?二维码的应用,可以分为主读和被读,被读类应用是以手机等存储二维码作为电子交易或支付的凭 证,可用于电子商务、消费打折等。主读类应用是以安装识读二维码软件的手持工具(包括手机),识读各种载体上的二维码,可用于防伪溯源、执法检查等。下面 初步枚举了二维码的20项应用模式。

1. 网上购物,一扫即得

国内的二维码购物最早起源于一号店。目前国内一些大城市的地铁通道里,已经有二维码商品墙,消费者可以边等地铁边逛超市,看中 哪个扫描哪个,然后通过手机支付,直接下单。如果是宅在家里,家里的米、面、油、沐浴露用完了,只要拿起包装,对着商品的二维码一扫,马上可以查到哪里在 促销、价格是多少,一目了然。而且,通过二维码购物,产品的二维码直接标示了产品的身份证,扫描后调出的产品真实有效,保障了购物安全。将来,二维码加上 O2O(网上到网下),实体店将变成网购体验店。因此,实体店可能更多的是要设在顾客方便的地方如公交站甚至是居民区,而不是商业中心。

2. 消费打折,有码为证

凭二维码可享受消费打折,是目前业内应用最广泛的方式。比如,商家通过短信方式将电子优惠券、电子票发送到顾客手机上,顾客进 行消费时,只要向商家展示手机上的二维码优惠券,并通过商家的识读终端扫码、验证,就可以得到优惠。去年7月,海南蕉农在香蕉滞销时,与淘宝合作进行网上 团购促销,网友在网上预订,网下凭手机二维码提货,成功化解香蕉危机。今年9月,在成都春熙路上的钟表文化节中,依波表举办了限时扫码活动,在规定的时间 内在现场扫描二维码折扣,顾客就能以折扣价买走手表。目前,腾讯也推出了针对IPhone和安卓的微信会员卡,会员只需用手机扫描商家的二维码,就能获得 一张存储于微信中的电子会员卡,享受折扣服务。

3. 二维码付款,简单便捷

近日,支付宝公司宣布推出二维码收款业务,所有支付宝用户均可免费领取“向我付款”的二维码,消费者只需打开手机客户端的扫 码功能,拍下二维码, 即可跳转至付款页面,付款成功后,收款人会收到短信及客户端通知。在福州,有一家华威出租车公司开通了支付宝,打车到目的地后,顾客拿出手机,对车内的二 维码车贴扫描,手机自动跳转到支付页面,然后按照计价器上的车费输入金额,整个付款过程只要20多秒。在星巴克,可以把预付卡和手机绑定,通过扫二维码可 以快捷支付,不用再排长队付款。

4. 资讯阅读,实现延伸

过去,报纸、电视以及其他媒体上的内容,限于媒体介质的特性,是静态的,无法延伸阅读,但是,二维码出现以后,颠覆了这种界 限,实现了跨媒体阅读。比如,在报纸上某则新闻旁边放一个二维码,读者扫描后可以阅读新闻的更多信息,如采访录音、视频录像、图片动漫等。如《骑车游北京》一书便设置了二维码,过手机扫描即可快速登录书中所述网址,可以实现图书、手机上网的时时互动。另外,户外广告、单页广告都可以加印二维码,感兴趣的客户只要用手机一扫,即可快速了解更详细内容,甚至与广告主互动。

5. 二维码管理生产,质量监控有保障

条码在产品制造过程中应用已非常普遍。二维码因为可以存储更多信息,因此,在产品制造过程应用更为深入。比如,在 汽车制造中,DPM二维码(直接零部件标刻二维码,可用针式打标机、激光打标机、喷码机甚至化学蚀刻)技术现已在美国汽车行业得到广泛应用,美国汽车制造 业协会(AIAG)还专门制订了相关标准,从发动机的钢体、钢盖、曲轴、连杆、凸轮轴到变速箱的阀体、阀座、阀盖,再到离合器的关键零部件及电子点火器和 安全气囊。从而使得生产加工质量得以全程跟踪,同时由于跟踪了生产过程中的加工设备,使得其原生产线变成了柔性生产线,可生产多品种产品,并为MES(制 造执行系统)管理的实现提供了完整数据平台。

6. 食品采用二维码溯源,吃得放心

将食品的生产和物流信息加载在二维码里,可实现对食品追踪溯源,消费者只需用手机一扫,就能查询食品从生产到销售的 所有流程。在青岛,肉类蔬菜二维码追溯体系已在利群集团投入使用,市民用手机扫描肉菜的二维码标签,即可显示肉菜的流通过程和食品安全信息。在武汉,中百仓储的蔬菜包装上,除了单价、总量、总价等信息外,还有二维码,扫描后可以追溯蔬菜生产、流通环节的各种信息,如,施了几次肥,打了几次农药、何时采摘、 怎么运输。

7. 二维码电子票务,实现验票、调控一体化

火车票上加入二维码,大家已经知道。由此还可以延伸,景点门票、展会门票、演出门票、飞机票、电影票等等都 可以通过二维码都能实现完全的电子化。比如,用户通过网络购票,完成网上支付,手机即可以收到二维码电子票,用户可以自行打印或保存在手机上作为入场凭 证,验票者只需通过设备识读二维码,即可快速验票,大大降低票务耗材和人工成本。在苏州拙政园、虎丘景区,由税务部门统一监制的二维码电子门票,一票一 码,用后作废。而且,景点当天出售的所有门票都要先激活,即只有从售票处售出的门票才能通关入园。并且激活是有时效的,也利于控制人数,避免黄金周的爆 棚。今年5月17日,在重庆武隆仙女山景区,使用二维码电子票,还可以享受5折优惠。

8. 二维码管理交通参与者,能够强化监控

二维码在交通管理中可应用在管理车辆本身的信息、行车证、驾驶证、年审保险、电子眼等等。比如,采用印有二维 码的行车证,将有关车辆的基本信息,包括车驾号、发动机号、车型、颜色等车辆信息转化保存在二维码中,交警在查车时,就不需要再呼叫总台协助了,直接扫描 车辆的二维码即可。以二维码为基本信息载体,还可以建立全国性的车辆监控网络。

9. 证照应用二维码,有利于防伪防盗版

在日、韩等国家,个人名片普遍采用二维码。传统纸质名片携带、存储都非常不方便,而在名片上加印二维码,客户拿 到名片以后,用手机直接一扫描,便可将名片上的姓名、联系方式、电子邮件、公司地址等存入到手机中,并且还可以直接调用手机功能,拨打电话,发送电子邮件 等。目前,国内已有此类应用,如银河、灵动二维码等公司。其实,举一反三,身份证、护照、驾驶证、军官证等证照资料均可以加入二维码,不但利于查证,关键利于防伪。

10. 会议签到二维码,简单高效低成本

目前,很多大型会议由于来宾众多,签到非常繁琐,花费很多时间,也很容易有会虫混入其中,混吃混喝混礼品。如果采用二维码签到以后,主办方向参会人员发送二维码电子邀请票、邀请函,来宾签到时,只需一扫描验证通过即可完成会议签到,整个签到过程无纸化、低碳环保 、高效便捷、省时省力。省去了过去传统中签名、填表、会后再整理信息的麻烦,可大大提高了签到的速度和效率。

11. 执法部门采用二维码,有利于快速反应

最近,广州番禺区的管理部门启用了“出租屋智能手机巡查系统”,出租屋管理员在上门巡查时,用智能手机读取门 牌上的二维码,即可及时、准确获取该户址的相关信息。同理,如果在商品、检验物品上附上二维码,政府执法部门人员则可以通过专用移动执法终端进行各类执法 检查,及时记录物品、企业的违法行为,并且可以保证数据传输的高度安全性和保密性,有利于政府主管部门提高监管,规范市场秩序,提高执法效率,增强执法部门快速反应能力。

12. 防伪隐形二维码,无法轻易复制

上个世纪90年代,国内的商品激光打标防伪曾经风云一时,但现在非常普遍不再具有独特性了。目前,荧光粉等印刷技术 的发展,一些重要物品开始使用隐形二维码,美国的科研人员也正在试图把这些隐形编码应用到玻璃、塑料胶片、纸质产品、银行票据上。这些隐形二维码用肉眼是 看不到的,必须通过红外激光照射才能进行扫描验证。由于该技术生产过程比较复杂,造假者无法轻易复制。目前,此类二维码需要商家提供红外激光扫射设备,然 后再让智能手机扫描验证,或者使用安装有红外激光摄像头的智能手机才能验证。推而广之,一些商业情报、经济情报、政治情报、军事情报等机密资料均可以通过 这种方式加密。

13. 高端商品用二维码互动营销,有助于打击山寨

世界著名葡萄酒之一的新西兰南极星葡萄酒,掀起了葡萄酒业应用二维码技术的新风潮,以南极星 Invivo黑皮诺葡萄酒为例,只要用智能手机扫描产品背标上的二维码,就能立即显示出该产品的信息详情链接,点击链接,可以看到该产品的原产地、生产年 份、葡萄品种、酒精度、产品介绍、获奖荣誉等信息。消费者在选购葡萄酒时能够更加轻松,全面的了解产品的各项信息,可以更好地与品牌互动,让购买变得简单 有趣,而且可以准确辨识真伪,打击山寨。

14. 传情达意,二维码引领传情Style

近日,中国邮电大学一个男生,以二维码为载体向女友传递情意,在明信片上手绘二维码 “我爱你”,火了一把。如此的“传情style”引发了网友追捧。其实,这个二维码形成并不复杂,先将信息在线生成二维码,然后将图片放大后打印出来,最 后将二维码绘制至明信片上。利用二维码传达情意,确实是一个技术性的Style,有高科技含量但绝对实用,通过二维码表达一定比传统的文字更能打动对方的 心。目前都市里一些时尚的咖啡店里,顾客扫描一下饮料杯上的二维码,还可以下载好听的铃声或音乐。

15. 二维码点餐,个性化客户服务到家了

如果你是一个餐饮店的老顾客,在二维码时代,你将能享受更加个性化的服务。比如,你到达一家餐饮店,用餐饮店的 设备扫描一下手机上的二维码,立即就可顺利地点下自己“最爱”菜品,还可以获得今日优惠信息,如果有VIP折扣券、代金券等,系统可以自动为你计算应付金 额。或者,你用手机扫描菜谱上的二维码,即可随时把点单传递到服务台或厨房,不需要服务员现场点单。用餐完毕,可以通过手机对菜品和服务进行评价,餐饮系统将自动为你积分。

16. 公交二维码,成为城市的移动地图

2010 年,杭州公交和杭州移动联合推出公共出行二维码查询系统,这是二维码技术在公交领域的首次应用,该系统在全市公交车站、公共自行车站布设二维码,市民扫描 二维码即可看到一张所在区域的地图,随时获取周边景点、餐饮、娱乐、道路、公交信息和换乘信息,甚至可以马上查询到你乘坐的公交车离站点还有多远,或者还 有几分钟可到终点站。因此,有了它,就像随身带了张城市地图,吃喝玩乐了然于心。

17. 招聘二维码,求职者可用手机来应聘

今年11月,在银川市举办的2012年冬季人才招聘会上,“二维码企业墙”吸引了众多求职者,使用手机上的“宁 夏12580求职通”客户端扫描二维码,会自动连接移动WIFI网络,求职者就能通过手机方便快捷的详细了解用工单位、岗位信息,并经由客户端投递简历。 这些内容都是储存在求职通平台上,求职者刷二维码的过程实际上是利用手机调取平台上的信息,简单高效,当场就可以完成查询、应聘。

18. 二维码进入医院,挂号、导诊、就医一条龙

对于患者而言,最烦心的莫过于挂号。采用二维码,患者可以通过手机终端预约挂号,凭二维码在预约时间前往 医院直接取号,减少了排队挂号、候诊时间。二维码服务不仅解决了挂号的问题,而且,二维码结合到看病、支付等环节后,可以实现看病、付款、取药一条龙服 务,不再让患者重复排队。另外,还能对医风医德进行评价,医患双方就能够加强沟通了解。目前,很多城市的大医院都至少已经采用了条码,相比以前,医疗信息 化水平大大提高,医院运转的效率也大大提高了。

19. 二维码旅游监督和导游,提高旅游服务的质量

前段时间,央视曝光了北京的一些旅游车宰客现象,这样的问题在一些景区总是屡禁不止。最近,上海的旅游 部门看中了二维码在旅游监督方面的优势,虹口区旅游部门设想,为辖区内旅行社运营的大巴车加装彩色二维码,游客用手机扫描二维码后,便能获悉自己所搭乘车 辆的运营资质,是否黑车,是否接受年检,有没有肇事记录等信息。烟台、莱芜、威海等旅游部门纷纷推出二维码地图,如烟台二维码旅游囊括了烟台十大特色休闲 之旅,市民和游客领取地图后,只要用智能手机对上面的二维码一拍就能看到详细的旅游景点、线路介绍,加油站、休息区、停车场等信息。

20. 二维码墓碑,无限怀念到永恒

目前,大城市地价飞涨,“死不起”已经成为一种社会问题。如何能够缩小墓碑和墓地,减少活人的负担呢?最近,英国一家 葬礼公司的了新创意,推出了二维码墓碑,在逝者的墓碑上增加一个二维码,参与祭奠的亲友用手机拍下这个二维码,就能导航到逝者在网站上的个人主页,看到他的音容笑貌、活动剪影、朋友的怀念等,亲人还可以对逝者的个人网页进行更新。怀念不再受制时间、空间限制,可谓无限怀念到永远了。

如果继续列举,二维码的应用方式还有很多,比如二维码导览,在展品上贴上二维码铭牌,参观者拍下二维码后,耳贴手机就能听到展品的语音介绍。还有二维码婚柬,将二维码发到亲朋好友手机上,对方即可直接连接到网页上查看邀请函内容,确认是否出席。

据业内预测,2012年二维码市场规模将达到300亿元,到了2015年,二维码市场将超过1000亿元,会有一万家公司进入二维码行业。可以说,二维码将成为融合移动互联网、电子商务、云计算等领域的下一个金矿产业。


    
[2] 揭秘IT人才特点:中美印日四国软件工程师比较
    来源: 互联网  发布时间: 2014-02-18
揭秘IT人才特点:中美印日四国程序员比较
  最近以裁判的身份参加了公司举办的编程大赛,发现高手云集,对公司内部的程序员能力也有了更深入的了解。我觉得编程能力对程序员而言,虽然很重要,但并不是全部。那么作为一个程序员,到底应该具备什么样的能力呢?这个话题显然太大。不过我觉得可以看看其它国家的程序员,也许可以得到一些借鉴。我有幸和中国,美国,印度和日本四国程序员有比较深入的合作过。虽然他们不一定有代表性,但我觉得他们的共性还是比较明显的。以下的比较纯属个人见解,欢迎指正。
 
      首先是日本程序员。他们的特点是非常仔细。我认为很主要的一个原因是日本公司的需求非常细致。细致到在网页上,连一个像素都不能偏差的地步。另外,日本人的执行力非常强,对老板的承诺比命还重要。一个项目可以做到连续3个月天天加班,每天只睡4个小时。然而,高执行力背后的代价是低创造力。在日新月异的互联网今天,很少听说日本工程师发明了哪些重要的技术。与其说这些特点是日本程序员的,不如说是大部分日本人的。因为在日本文化中,追求品质和遵守等级制度是根深蒂固的。另外,技术领域中的很多专业词汇是外来语,以英语(论坛)为主。这些专业词汇往往会被翻译成片假名。而片假名的发言有时候和英语大相径庭,导致沟通的困难。比如病毒一词在英语中是Virus,发音为歪儒斯,而日语的发音是味鲁斯。再例如服务器(Server)一词在日语中的发音是萨巴,和英文发言简直风牛马不相及。因此与日本程序员沟通是比较痛苦的,除非你懂日语。
 
     其次来看看印度程序员。我所接触的印度工程师都是在美国工作的。虽然他们和印度本地的工程师肯定有区别,不过相似的地方应该更多一些吧。我觉得他们的普遍优点就一个:流程做得好,文档写得好。但是他们写代码的能力,我个人的观点是一般般。我想这里面有两层原因。一是有相当一部分在美国工作的印度程序员是半路出家。转行做程序员是为了生存而已。二是印度程序员在算法,数据机构等基本功方面的水平明显低于中国程序员的。这就导致他们写的很多代码逻辑性不强和性能不优(以我的标准来看)。不过这两个问题在一定程度上被大量的文档和高性能的硬件设备弥补和掩盖了。在沟通方面,印度人的英语发音对西方人而言几乎没有问题,但很难被中国人听懂,甚至往往被国人怀疑他们是不是在说英文。
 
      从某种意义上讲,日本程序员和印度程序员十分相似。他们都很敬业,都能让领导比较满意,但不要过多地期望他们能做得更好,因为他们的目标就是完成领导指派的任务。日本程序员让领导满意的方法是不折不扣的执行和狂热的加班。而印度程序员让领导满意的方法是通过大量的文档来告诉领导他们的工作意义重大,流程严谨,资料齐全,而且成本很低。夸张一点地讲:日本程序员善于做领导想做的事,印度程序员善于说领导想听的话。
 
      接下来说说美国程序员。美国程序员千奇百怪,好像很难只用几个词来定义他们。可能是因为美国是一个移民国家吧,本来就千奇百怪。但大部分程序员有一个共同的特点:喜欢技术,甚至崇尚技术。这点在硅谷尤为突出。这就导致每个技术领域中都有一些人会废寝忘食地钻研。其实这和打游戏一样,如果你着了迷,自然会忘了吃,忘了喝,拼命地玩。我所认识的美国程序员还有一个特点,才艺能力都不错。以前在波士顿工作的一家公司中,几十位工程师居然可以组成一个交响乐团。有小提琴,大提琴,小号,竖琴,打击乐等各种各样的西洋乐器手。而且这些哥们姐们还不是一般地玩玩,周末都有自己的固定乐队,经常参加社区的表演。更有甚者,在硅谷工作时的一位同事,白天写程序,晚上在自家的车库里练习乒乓球,竟然代表美国参加了悉尼和雅典的两届奥运会。说起写文档的能力,美国程序员绝对不亚于印度人。但是美国人写文档不是为了老板,而是为了自己,为了分享。因此他们的文档往往读起来很有趣,很实用。当然,这会让老板有时候很头疼,因为程序员不那么“听话”。他们不是给老板交差,而是要实现自己的想法,自己的设计,自己的完美。说白了,就是美国程序员有时候想法多了点。
 
      最后是我们中国的程序员。和其他国家的程序员相比,我觉得他们的特点还是比较明显的。他们的算法能力普遍高于其它几个国家的。这可能是我们的教育体制导致的,比较注重理论知识。反过来,实践能力就相对差些。我们的程序员执行能力并不差,但在解决问题的能力上明显不足。往往需要把任务分解得很细以后才能完成,独立解决问题的能力不够。另外在表达能力上也相对差些。相信大家一定见过技术水平很高,但表达能力很差的工程师。最好笑的是,我见过不少工程师拿着一支写不出字的白板笔(我们的白板笔质量也确实不咋样),有模有样地在白板上写字。仿佛听众可以看得到他/她写得是什么。因为他/她完全沉浸在自己的逻辑中,完全不去体会听众的感受。不过我认为这些缺点并不严重。
 
      因为这些是属于技能和经验方面的东西,是可以通过实际工作或者培训来提升的。我认为国内程序员最大的问题还是所处的环境不利,导致相当一部分人比较浮躁和急功近利。真正能够沉下心来钻研技术,热爱技术的是凤毛麟角。我在面试的时候,常常发现工程师知识面还挺广,但深度几乎没有。这样的人很难在技术领域有所作为。我希望找到的人是,敢于承认自己不会的地方,但是只要会的东西,哪怕就一样,就要一定比别人理解得透,钻研得深。我相信一个人如果在某一个问题上比别人做得好,在其它问题上也一定有能力超越别人。
 
      虽然比较下来,看到中国程序员不少的问题。但作为群体,中国的程序员可能是全世界最聪明的工程师群体。因为环境的原因,使得他们不得不想法很多,顾虑很多,无法最大程度地将聪明才智发挥在技术上。改变这种状况首先要从公司的管理层开始。只有技术负责人热爱技术,追求卓越,才可能为技术人员创造环境,激励他们钻研和创新。技术负责人需要深入项目,和工程师们一起讨论技术设计,从而通过具体问题来提升工程师的能力,同时也防止自己的技术能力滑坡。在技术管理上,很多国内的公司把工程师简单地作为资源,过于强调流程管理和资源管理。我的观点是:工程师不是高级蓝领,不能以管理生产线的方式来进行管理。优良的环境只有靠大家一起来创造。中国工程师一定可以成为世界上最优秀的工程师群体。
2楼lian_gong2009昨天 23:21在中国感觉没几个工作是靠技术的了,程序员算一个。其他都是关系户1楼u012550652昨天 21:57明年即将踏上程序猿之路,表示算法还不熟悉啊,日本人很勤奋啊

    
[3] R Hadoop 装配和使用
    来源: 互联网  发布时间: 2014-02-18
R Hadoop 安装和使用

Author:Lishu
Date: 2013-10-23

Weibo: @maggic_rabbit

       最近接了一个project要使用R Hadoop,这才零零散散开始学习R和Hadoop,在这里记录下我学习和安装过程中遇到的问题和解决办法。我搭建的环境是14台server,全部安装Ubuntu Server 12. 04 LTS,关于系统重装这里就不赘述了。我的目标是搭建一个14台机器的Hadoop cluster,并装上R Hadoop。

1. Hadoop 的安装

       关于Hadoop有太多open resource可以利用,这里我用的是O‘Reilly出版的 Hadoop: The Definitive Guide, 3rd Edition. 这本书应该有相应的中文版,正如书名所说,这是最官方最全面的guide,里面基本上对Hadoop方方面面都有讲解。

       关于Hadoop的安装,请参考书的Appendix A 和Chapter 9. 或者这个tutorial.

Running Hadoop on Ubuntu Linux (Single-Node Cluster)

Running Hadoop on Ubuntu Linux (Multi-Node Cluster)


具体步骤如下:

1.预安装

每台机器都需要Java和SSH,对于每台机器都需要做以下事情:

  • 预装Java:
$ sudo apt-get install openjdk-7-jdk

或查看Java版本:

$ java -version
java version "1.7.0_25"
OpenJDK Runtime Environment (Ice(IcedTea 2.3.10) (7u25-2.3.10-1ubuntu0.12.04.2)
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)

  • 安装设置SSH:

$ sudo apt-get install ssh
$ ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa  # 生成无密码的RSA key
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys  # 添加 public key 到 authorized_keys 以允许访问
$ ssh localhost  # 测试是否装成功
理论上来说应该在每台机器上都生成一个RSA key,然后把 public key 添加到其它机器的 authorized_keys,这里为简化这个过程,我在每台机器上都使用了同样的RSA key pair, 即大家都用相同的钥匙去开相同的锁,但是这样是存在安全隐患的。

  • 设置 /etc/hosts:

127.0.0.1       localhost
#127.0.1.1      serv20
10.11.8.27      serv07
10.11.8.34      serv08
10.11.8.42      serv09
10.11.8.44      serv10
10.11.8.48      serv11
10.11.8.47      serv12
10.11.8.49      serv13
10.11.8.51      serv14
10.11.8.52      serv15
10.11.8.55      serv16
10.11.8.53      serv17
10.11.8.36      serv18
10.11.8.54      serv19
10.11.8.56      serv20
注意,我的14台机器 hostname 叫 serv07~20, 这里以 serv20 为例,添加每台机子的IP,并必须注释掉原本的 127.0.1.1, 否则在运行Hadoop时会出现类似这样的错误:

2013-09-03 15:29:04,374 INFO org.apache.hadoop.ipc.Client: Retrying connect to server: serv20/127.0.1.1:54310. 
Already tried 0 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)
2013-09-03 15:29:05,375 INFO org.apache.hadoop.ipc.Client: Retrying connect to server: serv20/127.0.1.1:54310. 
Already tried 1 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)
2013-09-03 15:29:06,376 INFO org.apache.hadoop.ipc.Client: Retrying connect to server: serv20/127.0.1.1:54310. 
Already tried 2 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)
2013-09-03 15:29:07,376 INFO org.apache.hadoop.ipc.Client: Retrying connect to server: serv20/127.0.1.1:54310. 
Already tried 3 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)
2013-09-03 15:29:08,377 INFO org.apache.hadoop.ipc.Client: Retrying connect to server: serv20/127.0.1.1:54310. 
Already tried 4 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)
2013-09-03 15:29:09,377 INFO org.apache.hadoop.ipc.Client: Retrying connect to server: serv20/127.0.1.1:54310. 
Already tried 5 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)

如果设置正确,你应该能从每台机器上直接用 hostname SSH:

$ ssh serv19 # instead of ssh 10.11.8.54

2. 安装设置Hadoop

在 Apache Hadoop Releases 下载所需Hadoop版本,我使用的是Hadoop 1.2.1 (stable).

  • 解压:

$ tar xzf hadoop-1.2.1.tar.gz

  • 设置环境变量:

$ export HADOOP_HOME=/home/hadoop/hadoop-1.2.1 # 这里我的用户名叫hadoop
$ export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
$ export PATH=$PATH:$HADOOP_HOME/bin
注意,这里想 permanent 设置的话需要在~/.bashrc里面修改,这是个 shell startup file,通常都在 user home directory 下面。如果 home directory 没有的话可以从 root 拷贝过来:
$ sudo cp /root/.bashrc ~

修改完 .bashrc 文件需要重新加载,或者重新登陆:
$ source ~/.bashrc

  • 设置 conf/hadoop-env.sh ,添加以下行:

export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
export HADOOP_OPTS=-Djava.net.preferIPv4Stack=true   # disable IPv6

注意,虽然环境变量里已经设置过 JAVA_HOME, 在Hadoop里还需要再设置一下,否则会找不到 java.

  • 设置 conf/core-site.xml:

<configuration>
        <property>
                <name>hadoop.tmp.dir</name>
                <value>/data/hadoop</value>
        </property>

        <property>
                <name>fs.default.name</name>
                <value>hdfs://serv20:54310</value>                
        </property>
</configuration>

注意,这里我的serv20是我设定的namenode,serv20需要被替换成你想设定成namenode的 hostname / IP address。

* property 的 default value 和 description 参考core-default.

另外,这里的hadoop.tmp.dir必须是已经存在的,所以在此之前需要 mkdir 以下 directory 以备后用:

$ mkdir -p /data
$ mkdir -p /data/hadoop
$ mkdir -p /data/hadoop/dfs
$ mkdir -p /data/hadoop/dfs/data
$ mkdir -p /data/hadoop/dfs/local
$ mkdir -p /data/hadoop/dfs/name
$ mkdir -p /data/hadoop/dfs/namesecondary
$ mkdir -p /tmp/hadoop/mapred
$ mkdir -p /tmp/hadoop/mapred/local

$ chown -R hadoop:hadoop /data
$ chown -R hadoop:hadoop /tmp/hadoop

  • 设置conf/mapred-site.xml:
<configuration>
        <property>
                <name>mapred.job.tracker</name>
                <value>serv20:54311</value>
        </property>

        <property>
                <name>mapred.local.dir</name>
                <value>/data/hadoop/dfs/local</value>
        </property>

        <property>
                <name>mapred.child.java.opts</name>
                <value>-Xmx512m</value>
        </property>

        <property>
                <name>mapred.system.dir</name>
                <value>/tmp/hadoop/mapred/local</value>
        </property>

        <property>
                <name>mapred.tasktracker.map.tasks.maximum</name>
                <value>4</value>
        </property>

        <property>
                <name>mapred.tasktacker.reduce.tasks.maximum</name>
                <value>4</value>
        </property>
</configuration>

注意,这里我设定的 jobtracker 也是serv20, 但是 namenode 和 jobtracker 并不一定非得是同一台机子,我后面会提到。

* property 的 default value 和 description 参考mapred-default.

  • 设置conf/hdfs-site.xml:
<configuration>
        <property>
                <name>dfs.replication</name>
                <value>3</value>
        </property>

        <property>
                <name>fs.checkpoint.dir</name>
                <value>/data/hadoop/dfs/namesecondary</value>
        </property>

        <property>
                <name>fs.chechpoint.size</name>
                <value>1048580</value>
        </property>

        <property>
                <name>dfs.http.address</name>
                <value>hdfs://serv19:50070</value>
        </property>

        <property>
                <name>dfs.name.dir</name>
                <value>/data/hadoop/dfs/name</value>
        </property>

        <property>
                <name>dfs.data.dir</name>
                <value>/data/hadoop/dfs/data</value>
        </property>

        <property>
                <name>dfs.permissions.superusergroup</name>
                <value>hadoop</value>
        </property>
</configuration>

注意,这里我设定了secondarynamenode为serv19.

*property 的 default value 和 description 参考hdfs-default.


到这里为止上面所有的安装和设置都需要在每台机器上进行(设置对每台机器都是一样的),其实完全可以写一个 shell script 完成所有的安装,再 scp 这些 conf 文件到各个机子指定位置,这样比较省时间,但是前提是每台机子的环境都是一样的。


  • 设置conf/masters (master only):

这里有几个概念需要注意, Namenode 是 HDFS 里的概念,即跑 bin/start-dfs.sh 的机器; JobTracker 是 MapReduce 里的概念,即跑 bin/start-mapred.sh 的机器。一般情况下 Namenode 和 Jobtracker 都在同一台机器上跑,这台机器被称为 master,其它跑 Datanode 和 TaskTracker 的机器称为 slave. 这里我的 master 是serv20, 其他机器都是 slave。

但是这里conf/masters定义的却不是上述意义的 master, 而是 SecondaryNamenode. 这里我设置的SecondaryNamenode 是 serv19, 所以在 serv20 (master) 上做如下设置:

serv19
注意,只需设置 master 上的 conf/masters, 不需要设置 slave 上的。

  • 设置conf/slaves (master only):

该文件列出 所有的 slave host, 每行一个。该文件也只需要在 master 上设置。

serv20
serv19
serv18
serv17
serv16
serv15
serv14
serv13
serv12
serv11
serv10
serv09
serv08
serv07

这里serv20也被列为 slave, 意味着 serv20 同时是 master 和 slave. 

3. 格式化HDFS (namenode)


在 Namenode 上格式化 HDFS, 即我的 serv20 上。理论上每次上述设置文件有变动时都需要重新格式化HDFS.

hadoop@serv20:~$ hadoop namenode -format


如果已经跑了上述命令仍然得到类似下面的错误:

13/05/23 04:11:37 ERROR namenode.FSNamesystem: FSNamesystem initialization failed.
java.io.IOException: NameNode is not formatted.
        at org.apache.hadoop.hdfs.server.namenode.FSImage.recoverTransitionRead(FSImage.java:330)
        at org.apache.hadoop.hdfs.server.namenode.FSDirectory.loadFSImage(FSDirectory.java:100)
        at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.initialize(FSNamesystem.java:411)


那么试试下面命令:

hadoop@serv20:~$ hadoop namenode -format -force

如果得到类似下面错误

2013-10-22 14:16:33,269 ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: java.io.IOException: Incompatible namespaceIDs in 
/data/hadoop/dfs/data: namenode namespaceID = 2142266875; datanode namespaceID = 894925905
        at org.apache.hadoop.hdfs.server.datanode.DataStorage.doTransition(DataStorage.java:232)
        at org.apache.hadoop.hdfs.server.datanode.DataStorage.recoverTransitionRead(DataStorage.java:147)
        at org.apache.hadoop.hdfs.server.datanode.DataNode.startDataNode(DataNode.java:414)
        at org.apache.hadoop.hdfs.server.datanode.DataNode.<init>(DataNode.java:321)
        at org.apache.hadoop.hdfs.server.datanode.DataNode.makeInstance(DataNode.java:1712)
        at org.apache.hadoop.hdfs.server.datanode.DataNode.instantiateDataNode(DataNode.java:1651)
        at org.apache.hadoop.hdfs.server.datanode.DataNode.createDataNode(DataNode.java:1669)
        at org.apache.hadoop.hdfs.server.datanode.DataNode.secureMain(DataNode.java:1795)
        at org.apache.hadoop.hdfs.server.datanode.DataNode.main(DataNode.java:1812)

2013-10-22 14:16:33,270 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down DataNode at serv07/127.0.1.1
************************************************************/

说明 Datanode 的 namespaceID 和 Namenode 的不一致,这可能是重新 format namenode导致的。在 hdfs-site 里定义的 dfs.data.dir 目录下找 VERSION 文件,这里我定义的是 /data/hadoop/dfs/data, 那么用下面命令修改 VERSION 文件:

$ vim /data/hadoop/dfs/data/current/VERSION 
#Tue Oct 22 14:49:40 CDT 2013
namespaceID=894925905 -> 改成 2142266875
storageID=DS-1631780027-10.11.8.27-50010-1380139765131
cTime=0
storageType=DATA_NODE
layoutVersion=-41

如果得到类似下面错误

2013-07-05 14:04:40,557 INFO org.apache.hadoop.ipc.Server: Stopping server on 50010 
2013-07-05 14:04:40,564 ERROR org.apache.hadoop.hdfs.server.namenode.NameNode: org.apache.hadoop.hdfs.server.common.
InconsistentFSStateException: Directory /tmp/haloop/dfs/name is in an inconsistent state: storage directory does not exist or 
is not accessible. 
        at org.apache.hadoop.hdfs.server.namenode.FSImage.recoverTransitionRead(FSImage.java:290) 
        at org.apache.hadoop.hdfs.server.namenode.FSDirectory.loadFSImage(FSDirectory.java:87) 
        at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.initialize(FSNamesystem.java:311) 
        at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.(FSNamesystem.java:292) 
        at org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(NameNode.java:201) 
        at org.apache.hadoop.hdfs.server.namenode.NameNode.(NameNode.java:279) 
        at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:956) 
        at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:965)
2013-07-05 14:04:40,572 INFO org.apache.hadoop.hdfs.server.namenode.NameNode: SHUTDOWN_MSG: 
/********************************** 
SHUTDOWN_MSG: Shutting down NameNode at elmorsy/127.0.1.1
 **********************************/

这个错误是说设定的namenode directory inconsistent, 像这里设定的/tmp就是 inconsistent 的, 它可能会更新或被删除,所以最后我是用了 /data/hadoop/dfs/name。这个问题也可能出现在 SecondaryNamenode 上。



4. 运行Hadoop


运行 Hadoop 有两个步骤, 即运行 HDFS 和 运行 MapReduce:

$ bin/start-dfs.sh
$ bin/start-mapred.sh

这里我的 Namenode 和 Jobtracker 是用一台机子,所以可以用下面命令:

$ bin/start-all.sh
其实看这个 script 里面内容也就是分别运行了上面两句。


要查看每台机子是否正常运行可以用 jps (需要先安装):

hadoop@serv20:~$ jps
13121 JobTracker
29872 Jps
13434 TaskTracker
12937 DataNode
12634 NameNode
hadoop@serv19:~$ jps
17291 TaskTracker
17051 SecondaryNameNode
16793 DataNode
27317 Jps
hadoop@serv18:~$ jps
13764 Jps
16157 DataNode
16386 TaskTracker

这里 serv20 是master同时也是slave,所以上面运行了 Namenode, JobTracker, Datanode, TaskTracker.

serv19 是 SecondaryNamenode 和 slave, 所以上面运行了 SecondaryNamenode, Datanode, TaskTracker.

serv18 只是 slave,所以上面只有 Datanode, TaskTracker.


5. 调试 Hadoop 程序

  • 要查看 Hadoop WebUI, 参考下表:

更多请参看:hadoop default ports quick reference

  Daemon Default Port Configuration Parameter HDFS Namenode 50070 dfs.http.address Datanodes 50075 dfs.datanode.http.address Secondarynamenode 50090 dfs.secondary.http.address Backup/Checkpoint node? 50105 dfs.backup.http.address MR Jobracker 50030 mapred.job.tracker.http.address Tasktrackers 50060 mapred.task.tracker.http.address ? Replaces secondarynamenode in 0.21.

  • 要查看 Hadoop 日志,
    • On the jobtracker:
HADOOP_HOME/logs
              /hadoop-username-jobtracker-hostname.log* => daemon logs
              /job_*.xml => job configuration XML logs
              /history
                     /*_conf.xml => job configuration logs
                     < everything else > => job statistics logs
  • On the namenode:
    HADOOP_HOME/logs
                  /hadoop-username-namenode-hostname.log* => daemon logs
  • On the secondary namenode:
    HADOOP_HOME/logs
                  /hadoop-username-secondarynamenode-hostname.log* => daemon logs
  • On the datanode:
    HADOOP_HOME/logs
                  /hadoop-username-datanode-hostname.log* => daemon logs
  • On the tasktracker:
    HADOOP_HOME/logs
                  /hadoop-username-tasktacker-hostname.log* => daemon logs
                  /userlogs
                          /attempt_*
                                   /stderr => standard error logs
                                   /stdout => standard out logs
                                   /syslog => log4j logs
  • 更多请参看:apache hadoop log files where to find them in cdh and what info they contain

    更多Hadoop command 请参考 commands manual.

    • WordCount
      详情请参看:wordcount v1.0

    2. R的安装

    R的安装可以用 apt-get 完成:

    $ sudo apt-get install r-base

    查看 R 版本信息:

    $ R --version
    R version 2.14.1 (2011-12-22)
    Copyright (C) 2011 The R Foundation for Statistical Computing
    ISBN 3-900051-07-0
    Platform: x86_64-pc-linux-gnu (64-bit)
    
    R is free software and comes with ABSOLUTELY NO WARRANTY.
    You are welcome to redistribute it under the terms of the
    GNU General Public License version 2.
    For more information about these matters see
    http://www.gnu.org/licenses/.
    

    这里安装的是R 2.14, 目前最新的版本是 R 3.0, 要安装最新版本,需更新 apt source list:

    $ sudo apt-get remove r-base-core   #   Uninstall old R
    $ sudo vim /etc/apt/sources.list   # Adding deb to sources.list
    # 添加这一行
    deb http://cran.r-project.org/bin/linux/ubuntu precise/ # precise is your ubuntu name (may be different)
    $ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9    # Add key to sign CRAN packages
    
    $ sudo apt-get update
    $ sudo apt-get upgrade
    $ sudo apt-get install r-base

    Ubuntu release name 参考这里.

    再查看版本:

    $ R --version
    R version 3.0.2 (2013-09-25) -- "Frisbee Sailing"
    Copyright (C) 2013 The R Foundation for Statistical Computing
    Platform: x86_64-pc-linux-gnu (64-bit)
    
    R is free software and comes with ABSOLUTELY NO WARRANTY.
    You are welcome to redistribute it under the terms of the
    GNU General Public License versions 2 or 3.
    For more information about these matters see
    http://www.gnu.org/licenses/.
    

    到这里R就安装好了,鉴于我使用的是Ubuntu server,所以这里所说的 R 是 command line, 不是 RStudio, 也不是 Revolution R.



    3. R Hadoop的安装

    所谓的 RHadoop 安装并不是一个另外的单独的 software,而是 R package: rhdfs, rmr2, rhbase. 

    从名字不难推断每个包的用途,rhdfs 是对应 HDFS 的 R interface, rmr2 是对应 MapReduce, rhbase 是对应 HBase. 这里我没有用到 HBase, 所以暂时先不谈 rhbase 的安装,以后如果要用再补上。

    • 预装依赖库
    $ sudo apt-get install git libboost-dev libboost-test-dev libboost-program-options-dev libevent-dev automake libtool 
    flex bison pkg-config g++ libssl-dev
    • 设置 Java 配置
    $ sudo R CMD javareconf

    注意这里需要root权限,否则会得到 Permission Denied.

    • 设置环境变量

    同前面提到的一样,有两种方式,直接 export 和修改 .bashrc 文件。

    export HADOOP_CMD=$HADOOP_HOME/bin/hadoop
    export HADOOP_STREAMING=$HADOOP_HOME/contrib/streaming/hadoop-streaming-1.2.1.jar
    export LD_LIBRARY_PATH=/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/server

    另一种方式是在 R 里面设置:

    > Sys.setenv("HADOOP_CMD"="/home/hadoop/hadoop-1.2.1/bin/hadoop")
    > Sys.setenv("HADOOP_STREAMING"="/home/hadoop/hadoop-1.2.1/contrib/streaming/hadoop-streaming-1.2.1.jar")
    > Sys.setenv("LD_LIBRARY_PATH"="/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/server")
    这里需要注意的是权限问题,如果修改的是hadoop user 的 .bashrc 文件或者以 hadoop 身份export, 这些环境变量就只对 hadoop user 有用,但是下面一个步骤需要 root 权限,所以可能需要重新在 R 里重新设置一下。检查 R 是否设置了这些环境变量,用下面命令:

    > Sys.getenv("HADOOP_CMD")

    • 预装R依赖库

    这里需要以 root 权限启动R:

    $ sudo R
    > install.packages(c("rJava", "Rcpp", "RJSONIO", "bitops", "digest", "functional", "stringr", "plyr", "reshape2"))
    这样这些包就被安装到默认的 R 路径下: /usr/lib/R/library/

    若不是这样,R 会提示是否使用 personal library:

    > install.packages("Rcpp")
    Installing package into ‘/usr/local/lib/R/site-library’
    (as ‘lib’ is unspecified)
    Warning in install.packages("Rcpp") :
      'lib = "/usr/local/lib/R/site-library"' is not writable
    Would you like to use a personal library instead?  (y/n) y
    Would you like to create a personal library
    ~/R/x86_64-pc-linux-gnu-library/3.0
    to install packages into?  (y/n)

    如上面显示的,如果使用 personal library, 它会新建一个 R directory 在你的 $HOME. 这样是可以成功安装并加载这个包的:

    > library(rmr2)
    Loading required package: Rcpp
    Loading required package: RJSONIO
    Loading required package: bitops
    Loading required package: digest
    Loading required package: functional
    Loading required package: stringr
    Loading required package: plyr
    Loading required package: reshape2
    
    但是我发现之后运行RHadoop的时候会出现类似下面错误(能在 WebUI 看到):
    java.lang.RuntimeException: PipeMapRed.waitOutputThreads(): subprocess failed with code 1
    	at org.apache.hadoop.streaming.PipeMapRed.waitOutputThreads(PipeMapRed.java:362)
    	at org.apache.hadoop.streaming.PipeMapRed.mapRedFinished(PipeMapRed.java:576)
    	at org.apache.hadoop.streaming.PipeMapper.close(PipeMapper.java:135)
    	at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:57)
    	at org.apache.hadoop.streaming.PipeMapRunner.run(PipeMapRunner.java:36)
    	at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:436)
    	at org.apache.hadoop.mapred.MapTask.run(MapTask.java:372)
    	at org.apache.hadoop.mapred.Child$4.run(Child.java:255)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at javax.security.auth.Subject.doAs(Subject.java:415)
    	at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1149)
    	at org.apache.hadoop.mapred.Child.main(Child.java:249)


    或者在 command line里看到类似这样的提示:

    13/08/21 18:30:25 ERROR streaming.StreamJob: Job not Successful!
    Streaming Command Failed!
    Error in mr(map = map, reduce = reduce, combine = combine, in.folder = if (is.list(input)) { :
      hadoop streaming failed with error code 1

    这两个提示都只是 general 的 Hadoop 提示和 Java 提示,并没有明确表示原因。错误原因需要从上述 takstracker log strerr里去找:
    $ vim $HADOOP_HOME/logs/userlogs/job_201310221441_0002/attempt_201310221441_0002_m_000000_1/stderr
    Error in loadNamespace(name) : there is no package called ‘Rcpp’
    Calls: <Anonymous> ... tryCatch -> tryCatchList -> tryCatchOne -> <Anonymous>
    Execution halted
    java.lang.RuntimeException: PipeMapRed.waitOutputThreads(): subprocess failed with code 1
    	at org.apache.hadoop.streaming.PipeMapRed.waitOutputThreads(PipeMapRed.java:362)
    	at org.apache.hadoop.streaming.PipeMapRed.mapRedFinished(PipeMapRed.java:576)
    	at org.apache.hadoop.streaming.PipeMapper.close(PipeMapper.java:135)
    	at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:57)
    	at org.apache.hadoop.streaming.PipeMapRunner.run(PipeMapRunner.java:36)
    	at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:436)
    	at org.apache.hadoop.mapred.MapTask.run(MapTask.java:372)
    	at org.apache.hadoop.mapred.Child$4.run(Child.java:255)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at javax.security.auth.Subject.doAs(Subject.java:415)
    	at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1149)
    	at org.apache.hadoop.mapred.Child.main(Child.java:249)
    原因是这个包装在了personal directory, R知道到哪里去找这个包,但是Hadoop只会在默认的R system directory 即/usr/local/lib/R/下面去找。一个简单的解决办法就是把该包从 personal library 拷贝到 system directory.
    • 安装 rmr2,rhdfs

    由于这三个库不能在CRAN中找到,所以需要自己下载。
    https://github.com/RevolutionAnalytics/RHadoop/wiki

    下载好后用下面命令安装:

    > install.packages('/home/hadoop/rmr2_2.3.0.tar.gz',repo=NULL,type="source")
    > install.packages('/home/hadoop/rhdfs_1.0.7.tar.gz',repo=NULL,type="source")
    
    这里如果上面都是以root运行R, 那么安装不会有问题,可是当运行RHadoop的时候会出现Permission Denied错误:

    org.apache.hadoop.security.AccessControlException: Permission denied: user=root, access=WRITE, inode="":
    hadoop:supergroup:rwxr-xr-x
    那是因为root并不是我的hadoop cluster 的user, 解决办法有两个,要么修改 hadoop 权限设置,在conf/hdfs-site.xml里添加下面

    <property>
        <name>dfs.permissions</name>
        <value>false</value>
    </property>
    要么以 hadoop 运行R, 可是这样又会出现这样错误:

    > library(rhdfs)
    Loading required package: rJava
    Error : .onLoad failed in loadNamespace() for 'rJava', details:
      call: dyn.load(file, DLLpath = DLLpath, ...)
      error: unable to load shared object '/usr/lib/R/site-library/rJava/libs/rJava.so':
      libjvm.so: cannot open shared object file: No such file or directory
    Error: package ‘rJava’ could not be loaded
    这是因为我之前没有设置 LD_LIBRARY_PATH 指向 rJava.so,如果按照我前面写的设置了LD_LIBRARY_PATH就不会出现这个问题了.

    如果看到下面错误:

    > library("rhdfs")
    Error : .onLoad failed in loadNamespace() for 'rhdfs', details:
    call: fun(libname, pkgname)
    error: Environment variable HADOOP_CMD must be set before loading package rhdfs
    Error: package/namespace load failed for ‘rhdfs’
    说明当前R user 没有设置 HADOOP_CMD,就是我前面讲到的如果sudo R, 那么user是root, 而我前面只设置了hadoop的环境变量。

    如果load rmr2和rhdfs都没有问题,那么RHadoop就算安装成功了。

    • 运行RHadoop 程序

    > library(rmr2)
    Loading required package: Rcpp
    Loading required package: RJSONIO
    Loading required package: bitops
    Loading required package: digest
    Loading required package: functional
    Loading required package: stringr
    Loading required package: plyr
    Loading required package: reshape2
    > library(rhdfs)
    Loading required package: rJava
    
    HADOOP_CMD=/home/hadoop/hadoop-1.2.1/bin/hadoop
    
    Be sure to run hdfs.init()
    > map <- function(k,lines) {
    + words.list <- strsplit(lines, '\\s')
    + words <- unlist(words.list)
    + return( keyval(words, 1) )
    + }
    > reduce <- function(word, counts) { 
    + keyval(word, sum(counts))
    + }
    > wordcount <- function (input, output=NULL) { 
    + mapreduce(input=input, output=output, input.format="text", map=map, reduce=reduce)
    + }
    > hdfs.data <- '/user/hadoop/input'
    > hdfs.out <- '/user/hadoop/output'
    > out <- wordcount(hdfs.data, hdfs.out)
    packageJobJar: [/tmp/RtmpbgF5IT/rmr-local-env6eb71e7e6c51, /tmp/RtmpbgF5IT/rmr-global-env6eb74c4d3f75, /tmp/RtmpbgF5IT/rmr-streaming-map6eb75e339403, /tmp/RtmpbgF5IT/rmr-streaming-reduce6eb711a6cae0, /data/hadoop/hadoop-unjar7453012150899590081/] [] /tmp/streamjob5631425967008143655.jar tmpDir=null
    13/10/23 10:31:26 INFO util.NativeCodeLoader: Loaded the native-hadoop library
    13/10/23 10:31:26 WARN snappy.LoadSnappy: Snappy native library not loaded
    13/10/23 10:31:26 INFO mapred.FileInputFormat: Total input paths to process : 3
    13/10/23 10:31:26 INFO streaming.StreamJob: getLocalDirs(): [/data/hadoop/dfs/local]
    13/10/23 10:31:26 INFO streaming.StreamJob: Running job: job_201310221441_0004
    13/10/23 10:31:26 INFO streaming.StreamJob: To kill this job, run:
    13/10/23 10:31:26 INFO streaming.StreamJob: /home/hadoop/hadoop-1.2.1/libexec/../bin/hadoop job  -Dmapred.job.tracker=serv20:54311 -kill job_201310221441_0004
    13/10/23 10:31:26 INFO streaming.StreamJob: Tracking URL: http://serv20:50030/jobdetails.jsp?jobid=job_201310221441_0004
    13/10/23 10:31:27 INFO streaming.StreamJob:  map 0%  reduce 0%
    13/10/23 10:31:32 INFO streaming.StreamJob:  map 33%  reduce 0%
    13/10/23 10:31:33 INFO streaming.StreamJob:  map 67%  reduce 0%
    13/10/23 10:31:34 INFO streaming.StreamJob:  map 100%  reduce 0%
    13/10/23 10:31:39 INFO streaming.StreamJob:  map 100%  reduce 33%
    13/10/23 10:31:42 INFO streaming.StreamJob:  map 100%  reduce 82%
    13/10/23 10:31:45 INFO streaming.StreamJob:  map 100%  reduce 94%
    13/10/23 10:31:48 INFO streaming.StreamJob:  map 100%  reduce 100%
    13/10/23 10:31:51 INFO streaming.StreamJob: Job complete: job_201310221441_0004
    13/10/23 10:31:51 INFO streaming.StreamJob: Output: /user/hadoop/output
    > results <- from.dfs(out)
    > results.df <- as.data.frame(results, stringsAsFactors=F) 
    > colnames(results.df) <- c('word', 'count') 
    > head(results.df)
      word count
    1      17259
    2    %     2
    3    &    21
    4    (     1
    5    )     3
    6    *    90
    










        
    最新技术文章:
    ▪Android开发之登录验证实例教程
    ▪Android开发之注册登录方法示例
    ▪Android获取手机SIM卡运营商信息的方法
    ▪Android实现将已发送的短信写入短信数据库的...
    ▪Android发送短信功能代码
    ▪Android根据电话号码获得联系人头像实例代码
    ▪Android中GPS定位的用法实例
    ▪Android实现退出时关闭所有Activity的方法
    ▪Android实现文件的分割和组装
    ▪Android录音应用实例教程
    ▪Android双击返回键退出程序的实现方法
    ▪Android实现侦听电池状态显示、电量及充电动...
    ▪Android获取当前已连接的wifi信号强度的方法
    ▪Android实现动态显示或隐藏密码输入框的内容
    ▪根据USER-AGENT判断手机类型并跳转到相应的app...
    ▪Android Touch事件分发过程详解
    ▪Android中实现为TextView添加多个可点击的文本
    ▪Android程序设计之AIDL实例详解
    ▪Android显式启动与隐式启动Activity的区别介绍
    ▪Android按钮单击事件的四种常用写法总结
    ▪Android消息处理机制Looper和Handler详解
    ▪Android实现Back功能代码片段总结
    ▪Android实用的代码片段 常用代码总结
    ▪Android实现弹出键盘的方法
    ▪Android中通过view方式获取当前Activity的屏幕截...
    ▪Android提高之自定义Menu(TabMenu)实现方法
    ▪Android提高之多方向抽屉实现方法
    ▪Android提高之MediaPlayer播放网络音频的实现方法...
    ▪Android提高之MediaPlayer播放网络视频的实现方法...
    ▪Android提高之手游转电视游戏的模拟操控
     


    站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3