加密货币的起源,发展和价值分析 (三)

作者 IAN LIAO, CEO @ MASSDATA INC.

在本文的创作过程中,加密货币正好经历了一轮大熊市。比特币从2017年底 $20000的高点,跌倒了$6000美金,大量的空气币也纷纷归零。这里继续探讨对加密货币的价值分析,和未来行业的发展。

目前市面上的币种大致可以分为三类,比特币及其竞争币;稳定币;通证。这里逐一分析。

比特币及其竞争币

前面提到了,比特币的价值来自于铸币税的重新分配,来自于人群对分配方案的认同,或者说共识。由于比特币技术上的各种问题,社区推出了各种竞争币。从莱特币,以太坊,比特币现金,到门罗,零币,EOS,各种竞争币都有技术和功能上的优势和特色。这些币的价值来源是一样的,人们期待加密货币作为法币的替代品。每一个币种都是公链,需要矿工参与维护,也都经历了从缺乏矿工,近乎一文不值,到矿工增加,币价增长的过程,也就是“信仰之力”的收集过程。在加密货币的发展过程中,还曾有更多的竞争币出现后,没能够获得足够的认同,最终消亡。

稳定币

和法币挂钩的稳定币是法币和加密货币之间的交换媒介。但稳定币的货币发行过程中,没有铸币税的分配,也就不会有矿工参与网络的维护。所以稳定币一般来说都是中心化的。稳定币最大的风险就是作为中心的发行公司,比如Tether,是否存在造假,资金挪用,跑路的可能。

通证

通证和币相比,缺乏铸币的过程,也缺乏信仰之力的收集过程,所以99%的通证都是没有任何价值的。剩下的1%,一定是有服务背书的通证。也就是说,持有通证的人,一定能够使用通证买到某一项服务。比如说,以太坊提供智能合约服务(发币服务),定价为一个以太坊。类似的,还有网络存储,GPU算力等等,对应Siacoin,Filecoin等。从价值分析上说,这样的通证的币价,是和服务的价格挂钩的。也有的通证目标就是发展自己的公链,比如EOS,Filecoin。

综上所述,有价值的币种都是有背书的,或者是共识背书,或者是法币背书,或者是服务背书。

未来

如果以十年为尺度来看待加密货币。过去的第一个十年应该是加密货币的幼年期,未来的十到二十年是加密货币的成熟期。技术和设计会逐渐完善,币价会趋于稳定。但最终哪个币种能够落地,走入日常支付,现在还难以判断。比特币目前的接受程度最高,信仰之力最多,但设计和技术上的缺陷也非常明显,技术更新迭代也非常缓慢。门罗,零币等快速发展的新币种可能有更多的机会。未来是否有可能设计出去中心化的准稳定币,会是加密货币能否最终落地的决定性因素。

大胆推理一下,在未来十年里,一个或者几个解决比特币技术缺陷的币种会快速发展,随后会出现自发性的去中心化币种储备组织,负责稳定币价,币价稳定后带来日常加密支付的落地,全球化的加密支付货币逐步形成。币价呢?该币种对法币应该是稳定上升,每年的增长近似于通胀吧。

中国的机会

最后闲扯几句,其实加密货币是中国的一大机会。但朝中不知道是否有有识之士能看到这个机会。

  1. 加密货币有机会打破美元的垄断地位,限制美国的全球吸血能力。
  2. 促使芯片业的发展。比特大陆虽然是ASIC,但却是中国第一家大量盈利的芯片设计和销售公司。中国芯片业和操作系统的发展瓶颈不是技术,而是生态。Wintel联盟,iOS+Android基本上垄断了PC和移动互联网时代的生态。在垄断壁垒面前,新公司难以获得市场,也就没有造血和持续投入研发的能力。加密货币挖矿其实给芯片业提供了一个抛开用户生态,在技术层面上直接竞争的机会。新的芯片公司能够有机会迅速从芯片研发中获利,持续迭代升级产品。比特大陆从ASIC起家,走向人工智能芯片,未来甚至走向通用型GPU和CPU芯片都是可能的。
  3. 挖矿一定程度上是消耗电力。为了节省成本,矿场几乎都修建在偏远的地区,靠近便宜可再生的水电资源。这一方面帮助发展了边远地区经济,另一方面,是把难以输出的绿色可再生能源转换成了国际通用货币,这其实是一种出口创汇啊。中国的矿场主应该获得和制造业同等的税收优惠才是。
Advertisements

加密货币的起源,发展和价值分析 (二)

作者 IAN LIAO, CEO @ MASSDATA INC. 2018年8月

在本文第一部分聊了加密货币的鼻祖,比特币,的起源和设计理念。比特币诞生后的十年时间,除了收获“信仰之力”,整个数字货币社区也发展出了一套完整而复杂的行业生态和概念:交易所,采矿业,竞争币,稳定币,智能合约,Dapp,通证,ICO,加密货币基金,等等。行业在创造价值的同时,也充斥着各种一夜暴富的神话,更有各种骗子横行,贪婪的以ICO的名义“割韭菜”。长期来看,就像互联网行业过去30年的发展过程,数字货币行业也会在一次次起飞和泡沫破碎的周期性反复中,找到稳定的商业形态。而新的商业形态一定会催生出数字货币时代的Amazon,Google,阿里巴巴,但这是一个漫长的过程。

这里逐一聊聊上面提到的名词,希望帮助读者一览行业概括。

交易所

交易所和采矿业大概是数字货币发明以后催生的前两个行业。人们在了解接受比特币后下一个问题通常是,怎么样获取比特币。获得比特币只有两种方法,1)从拥有比特币的人那儿买,2)部署电脑来铸币,即挖矿。交易比特币一般有两种方式,一种是OTC场外交易,买卖双方私下约定好数量和价格,在双方的比特币钱包之间直接转账;另一种是场内交易,类似于股票交易,买卖双方的币和资金都保存在交易所账户上,在公开市场随市场价格交易。

有了公开交易所,就有了公开的市场价格波动,成交量,交易员,技术分析等各种和股票交易类似的概念。而交易所通过收取交易佣金, 上币费等也成为了币圈一大赚钱的行业。著名的交易所很多,美国的Coinbase,Gemini,Kraken;源自中国的币安,火币。大量数字货币交易所的出现,也意味着数字货币提供了一项新的投机选择,炒币。对数字货币持反对态度的人甚至极端的认为炒币投机是数字货币的唯一价值。但不可否认的是,交易所极大程度的帮助了数字货币的推广。市场中有坚定的价值投资者,选择HODL(长期持有);也有逐利的投机炒家,通过做波段追涨杀跌来赚钱。而随着ICO的火爆,更是有庄家控盘小币种,采用拉高出货的方式来割韭菜。因为监管的缺失,小币种盘小,市场价格极易被操纵,行业乱象丛生。后面聊到ICO的时候会进一步说。

提到交易所,就不得不提到早期著名的门头沟事件。MTGOX,俗称门头沟,是早期最大的比特币交易所,在2014年2月,门头沟发现75万个比特币被盗,这直接导致比特币价格从$700+下降到了$400+。随后,比特币价格经历了长达3年的冬天,直到2016年底才重回$700,并在2017年创下历史最高的$20000.

交易所都是中心化的,这意味这黑客有可能攻破交易所的防御,盗走资金。目前社区有一些去中心化交易所的尝试,但还没有落地。

采矿业

如前文所述,所有的比特币都是通过“挖矿”产生的。最早期的比特币挖矿还仅仅是技术极客的兴趣爱好。但随着交易所的出现,比特币有了市场价格,挖矿成为一项有利可图的事情,吸引了越来越多的人参与。挖矿可以赚钱是符合中本聪的设计理念的:分享铸币收益。挖矿的人越多,去中心化程度就越高,比特币网络就越安全,比特币的价值就越高,也就能吸引更多的人来挖矿,周而复始。

挖矿消耗的主要是电能。为了降低成本,大型矿场逐渐出现。矿场往往选址于水电资源丰富,气候相对寒冷的地方,这样电力成本和散热成本都比较低,比如中国的云贵川,冰岛,加拿大等地。

但是中本聪一CPU一票的平权设计在比特币的发展过程中没有能够实现。矿工们通过解一个数学游戏来竞争记账权。商业的逐利本性驱使着技术向着更快更低成本的解数学游戏的方向发展。矿工们很快发现,使用GPU来解比CPU快很多,能耗也低;随后出现了更快的FPGA。最终以比特大陆为代表的专有集成电路(ASIC)厂商生产的ASIC矿机彻底淘汰了FPGA,GPU和CPU,比特币挖矿进入了ASIC矿机时代。

为什么说ASIC矿机背弃了比特币的理想?在比特币的设计理念里,每个人大概率的拥有一台电脑,一个CPU,用于日常生活和学习,在闲暇时间也可以用来挖矿。使用CPU挖矿是铸币利益均分的一种近似实现方式。而ASIC矿机除了挖矿以外,没有任何使用价值。这就意味着,只有资本拥有者才会投资矿机。而日常使用的CPU因为算力过去低下,挖矿是入不敷出的。这样普通大众不会有任何动机参与到挖矿中,也就失去了分享铸币收益的机会。另一方面,仅比特大陆一家在2017年的纯利润就超过25亿美金,这意味着矿机厂商攫取了绝大部分的铸币收益,参与挖矿的矿工仅获得小部分。因为技术的发展,新一代矿机的性能对老一代矿机的性能几乎是碾压式的超越。矿机厂商在生产出新一代矿机后,往往还会先预挖半年,赚取足够利润后再高价推向市场。

ASIC矿机还带来算力中心化的问题。比如吴忌寒的比特大陆被认为能够控制超过51%的比特币算力,有能力对比特币网络发起恶意攻击。

ASIC矿机几乎毁掉了比特币采矿业,也给了竞争币的机会。

竞争币 (alter-coin)

比特币的代码是开源的,任何人都可以研究他的源代码,也可以稍微修改一下参数,发行一种新币,称为分叉币(fork)。早期的分叉币大都没有任何价值,也难以聚集矿工来维护网络,在发展过程中逐步消亡。

然而,比特币的设计理念几乎完美,但他的技术实现缺离完美很远。就货币的基本属性而言,现有的比特币网络存在几大严重技术问题,社区推出了多种比特币的竞争币,来完善比特币的功能。

  1. 数学游戏的设计不够巧妙,ASIC矿机的出现,导致平权挖矿没有能够实现。所谓平权挖矿,是指CPU,GPU,FPGA,ASIC等不同的计算核心在运行挖矿算法的时候,运算速度和耗电比例差不多,大家都有得玩。以太坊的ethash,门罗币的CryptoNight,Zcash的EquiHash等,都有这方面的设计,但近期也都先后被比特大陆的ASIC矿机攻破。目前社区寄予厚望的是Zcoin的MTP算法,预计在2018年10月发布。
  2. 网络吞吐量太低,仅能支持每秒3-7个交易,难以成为日常支付货币。吞吐量的问题已经造成过多次比特币网络的拥堵。社区也提出了好些解决方案,大部分还在开发中。已经落地的,门罗币目前能够支持1500-2000次交易每秒;EOS能够支持3000次交易每秒。这个速度已经超过了Visa的平均每秒交易次数。如何达到上万次交易每秒,社区也有一些方案,但目前的需求并不急迫。
  3. 账本完全公开,每个账户的余额和所有的交易记录都能够被跟踪和分析。目前提供隐私功能的竞争币主要有门罗币,Dash,Zcash和Zcoin。其中,门罗币和Zcoin的技术实现是比较领先的。

总的来说,社区还在思考和探索,一个真正有实用价值的,去中心化的数字加密货币到底应该是什么样子。比特币并不完美,体量太大也难以改变,以后更可能成为一种类似黄金的价值储存工具。而日常的支付功能会是一种新的加密货币来满足。

 

稳定币

另一个阻止比特币成为日常支付货币的非技术问题,是比特币和法币,比如美元,之间的汇率非常不稳定。所有有的公司推出法币锚定的加密货币,比如USDT,就是Tether公司推出的,有美元锚定的。USDT网络是Tether公司自己在维护,不是去中心化的。Tether公司同时对外宣称,每一枚USDT,都有在银行的一美金作为储备。Tether不定时的公布审计报告来证明自己的美金储备。这种稳定币的最大问题是存在一个中心化的公司来维护,不管是网络,还是美金储备。外界对Tether公司的美金储备一直有一些质疑,储备资金有被挪用的风险。

怎么样稳定加密货币的币价,是当前社区比较关注的一个问题。目前一个有意思的方案是联合成立比特币联合储备组织,类似于美联储。具体的细节社区还在探索。

智能合约

智能合约源自于比特币里的功能,bitcoin scripts。中本聪最初设计bitcoin scripts是为了去中心化的实现复杂的交易,比如担保支付,多重支付,条件支付等等。以条件支付为例,用户A和B约定,A向B支付10个比特币的条件是交易发起后一个月内B的账户余额低于100。交易发起后,A将10个比特币放入bitcoin scripts中,在一个月内,如果B的账户余额低于100,则B可以通过bitcoin scripts要求这10个比特币。Bitcoin scripts自动验证条件,释放比特币给B。如果一个月内B都未能通过验证条件,则这10个比特币被释放回A的账户。这个支付过程由bitcoin scripts自动完成,不需要第三方或者一个中心化被信任的机构参与。支付条件被严格执行,A和B的资金安全都有充分的保证。

Bitcoin scripts的实现方式更接近于汇编语言,可以实现的功能也有限。2014年年仅20岁的天才程序员Vitalik Buterin创建了以太坊项目,其中最突出的成就就是把Bitcoin scripts拓展成了一种图灵完备的高级语言,Solidity,可以实现各种复杂的功能,称为智能合约。

基于智能合约,以太坊可以实现DApp,也就是去中心化的app。最主要的应用就是用来发币(通证,Token)了,下面细说。

 

DApp,通证(Token)和ICO

到底什么是去中心化的app。现在每个人都用微信,微信是腾讯公司运营的,腾讯可以监控每一条聊天记录,可以删除/屏蔽某个用户,甚至可以定向控制用户在朋友圈里看到什么内容。这就是中心化的权威,用户只能相信腾讯公司及其工作人员不会做坏事。

一个去中心化的微信呢?我们称D信吧。D信是基于智能合约运行的,每个用户都按照合约的规定来收发消息。没有人或者机构可以监控用户的短信,或者屏蔽用户,或者干涉用户的朋友圈。用户不需要去信任一个中心化的机构就可以知道自己的权益是得到保障的。

DApp还可以做很多事情,比如发起一个投票,或者众筹。用户不会担心计票有黑幕,或者众筹资金被卷走,因为这些规则都是在智能合约里约定好的。

那么可不可以约定发行一种新的货币呢?在智能合约里,预定货币的数量,发行方式,用途,等等。这就是以太坊最主要的应用,发行通证(Token)。通证的发行成本极低,写好智能合约以后,花费一个以太坊(目前约$300+),就可以发布/发行了。

DApp和通证是非常有意思的系统设计和技术实现,也能被用来做很多有意义的事情。但因为炒币,这一项技术催生了一个乱象丛生,鱼龙混杂的行业,ICO(Initial Coin Offer)。在以太坊时代,ICO的过程很简单,新建一个智能合约,发行一种新的通证,然后按照一定的售价来销售这些通证。这样发行的通证,技术上没有任何的差异化,也没有经历过信仰之力收集的过程,99%是没有任何价值的。如果要说有,就是炒币的价值吧。ICO已经产业化了。市场中有机构专门负责写白皮书,有机构负责宣传拉人头,有机构负责拉盘做所谓的市值管理,俗称割韭菜。

ICO一定程度上和IPO类似,都是面向社会的募资行为。但IPO流程有着严格的监管,对发起IPO公司的基本面有严肃的审计。而ICO缺乏监管,欺诈频出,在市场火爆的2017年底,市面上出现了至少上千个ICO项目,而到了2018年近期的熊市,大部分这样的项目都已经归零了。

加密货币基金

本篇的最后聊一聊加密货币基金。使用加密货币投资是一种新的投资形式。在2012年的时候,中科大少年班毕业的“烤猫”,在Bitcoin Forum论坛上发起了IPO,募集了约两万个比特币,成立了第一家ASIC矿机公司。公司在初期非常成功,早期的投资人都获得了超额的回报。这大概是历史上第一次有名的加密货币投资案例。

随着行业的发展,逐渐出现了加密货币基金,Crypto Fund。加密货币基金通常募集主流加密货币,标的资产以加密货币相关的产业为主。管理上一般来说比较松散,契合加密货币社区的自治理念。

比较有名的加密货币基金有,Polychain Capital,Metastable Capital,中国背景的DFund等。

加密货币的起源,发展和价值分析 (一)

作者 Ian Liao, CEO @ MassData Inc.

作为技术创业者,而非专业经济学人士,一直想写一篇相对通俗易懂的文章来介绍加密货币。希望能帮助读者理解加密货币,能够判断出有投资潜力的币,避免各种骗局。文章里尽量不谈技术,会涉及到一些初步的经济学概念。如有错误请指正,转载请注明来源。

比特币的最初设想来自于神秘人物中本聪发布于2008年11月1日的白皮书:“比特币白皮书:一种点对点的电子现金系统”,中文翻译发表在巴比特上,翻译人是巴比特的联合创始人,后来创建比特大陆的吴忌寒。

中本聪在比特币的创世区块里留下了一句话:“The Times 03/Jan/2009 Chancellor on brink of second bailout for banks”,翻译成中文就是,“2009年1月3日,财政大臣正处于实施第二轮银行紧急援助的边缘”。这是当天英国泰晤士报的头版的标题。这句话是一个时间戳,证明比特币的创世是在2009年1月3日以后,同时也是中本聪对货币滥发的现代金融体系的嘲讽。2008年次贷危机以后,银行大而不能倒,政府通过超发货币来避免银行的破产和现代金融体系的崩溃。这被认为是政府和现代金融体系对民间财富的抢夺。中本聪的愿景是设计一种全新的基于密码学和分布式网络的货币,来摆脱极少数人对金融权力的掌握。

为什么比特币可以是一种货币?

首先要理解什么是货币。回顾货币的发展史,从最初的以物易物开始,人类尝试了多种选择作为一般等价物:石头,贝壳,稀有的羽毛,盐,宝石,等等。最终东西方均自发性的逐渐认同以金和银作为一般等价物的选择,称为金属货币。金银为什么成为自发性的一般等价物,这里暂且不说。而随着强有力的中央集权政府的出现,几乎所有的统治者都意识到一个高效的敛财手段:官方铸币。以中国古代为例,各郡县均设有官方铸钱局,铸币原料,以铜为主,掺以铅,锡。政府经济困难时,会在铸币的过程中,降低铜的含量,来获取更多的利润;甚至铸造“虚值大钱”,强制民间使用。比如三国的蜀汉政权发行直百五铢,一枚当一百枚汉代的五铢钱,“直”通“值”,所以叫“值”百(的)五铢。《三国志·蜀书》记载,蜀汉发行直百五铢以后,“以数月之间,府库充实”。铸币这么赚钱,民间自然就有人冒险私铸。比如王莽时期,因为发行多种虚值大钱,利润极高,民间私铸盗铸就异常疯狂。再后来就出现了纸币。最初的纸币以银行信誉背书,后来以国家信誉背书,用纸币一定可以换到固定数量的金银。这就是金本位或者银本位。历史上一英镑可以换到一磅银子。1944年7月至1973年间的布雷顿森林体系规定,35美金可以换到一盎司黄金,而其他国家的货币以美金为锚定,在小范围内浮动。但在1973年布雷顿森林体系彻底崩溃以后,美元和黄金脱钩,成为经济学意义上的法定货币:

法定货币英语:Fiat Money),简称法币,是政府发行的纸币。发行者亦没有将货币兑现为实物的义务,只依靠政府的法令使其成为合法通货的货币。法定货币的价值来自拥有者相信货币将来能维持其购买力,但货币本身并无内在价值(Intrinsic value)。

部分发行法定货币的国家或银行,会将其法定货币与一种或数种外币挂钩,并以政府外汇储备维持其汇价在一定的水平。亦有法定货币是没有任何锚,其价值是自由浮动,倚靠发行者控制发行量来维持。”

货币发展到这一步,已经脱离了内在价值,而成为了货币符号。经济学的基本原理:货币总量*流通率 = GDP。理论上讲,货币发行者应该尽可能的维持货币总量和GDP的对应关系,以维持货币的购买力。同时,经济学研究也认为,保持适度的通货膨胀,有利于经济的发展。但现实中因为各种复杂的利益关系,这是难以做到的。在美国的现有体系里面,即使作为货币发行方的美联储和美国政府并不是统属关系,美联储还是受到压力,在次贷危机中,大量的增发货币,用以援助银行和购买美国国债。三轮量化宽松中,美联储总共购买了3.925万亿美元的美债。比较有意思的是,巴菲特甚至公开讲,美国政府不会债务违约,因为我们可以印钱。

所以看到这里,大家都明白现代货币不需要有内在价值,那么要成为货币需要哪些属性呢。

  • 稀缺性:法币的稀缺性是由发行方控制的。
  • 可互换性:每两个一块钱的购买力都是完全一样。
  • 耐久性:纸币破碎了可以到银行换,事实上现在大部分的美金和人民币都电子化了,印钱只是修改央行电脑里的一个数字而已。
  • 可分性:一块可以分为10个一角。
  • 可交易性:所有权可以在所有人之间流转。

当然最重要的一点,是“拥有者相信货币将来能维持其购买力”。可惜这一点现在已经没有多少人相信了。不管在美国还是在中国,钱都是快速贬值的。大家使用法币更多的是因为政府的法令规定其为合法通货。

回到本文开头,中本聪设计了一种全新的基于密码学和分布式网络的货币体系,比特币。比特币基本上拥有上述五种属性;比如总量只有2100万个,基本可互换,只要比特币网络不彻底死亡,永远存在,几乎无限可分,可以无视地域限制的从一个所有者支付给另一个所有者。那么比特币怎么发行,和拥有者怎么相信他的购买力呢?

首先,中本聪天才的把货币发行和维持比特币网络的稳定联系在了一起。形象的说,比特币网络可以理解为无数电脑参与维护的一个公开大账本,每个人有多少钱。参与维护的电脑,被称为矿工。矿工们通过解一个复杂的数学游戏(挖矿),来竞争谁可以在这个大账本上记下下一笔账。而记账的这个矿工会被奖励一定数量的新发行的比特币。奖励数量是程序约定好,不可更改的。每一枚比特币都是这样产生,给于矿工。货币发行的收益者,仅限于为维护比特币网络作出贡献的矿工。奖励 = 铸币权 = 记账权 = 贡献。

矿工为什么要通过挖矿来竞争记账权呢?这也是比特币的一个核心理念:尽可能的让每个人有均等的记账机会,也就是作出贡献和获得收益的机会。中本聪设想,每个人都有家用电脑,都可以使用CPU,如果能够做到 一个CPU = 一次抽奖机会;再通过解数学游戏的方式来抽奖,就非常接近于每个人的机会均等了。这个设想很巧妙,但技术的发展导致了这个设想没有能够真正实现,这个话题后面再说。

所以中本聪的设计是,奖励 = 铸币权 = 记账权 = 贡献,而且每个人机会均等。这就把国家独有的货币发行收益,均匀的分给了每一个人。而货币总发行量和发行方式,在创始之初就通过代码约定好,这样不会有货币超发的问题。

其次,是货币的购买力的问题。法币的购买力来自于政府的法令,而比特币的购买力则来自于拥有者对他的认同。拥有者认同的对象主要是比特币的设计和实现的技术。当认同比特币的人越多,参与维护比特币网络的人就越多,使用比特币交易的人就越多,比特币的价值就越大。这个认同,就是人群的一种共识。认同比特币的人群可以看作一个虚拟国家,这个国家内部用比特币交易,可以有以比特币计价的GDP;外部交易就有比特币和其他货币,比如美元,的汇率。

那么货币购买力的发展是一个收获认同的过程,可以戏称为信仰之力的收集。以比特币为例,从第一笔交易一万个比特币买一个pizza,到现在的$7000多美金的汇率,发展了10年。时间已经证明了比特币作为货币是可行的。

 

 

Setting up Druid and Hadoop on AWS

 

  • Launch instances

Choose your OS, hardware specs, security group, key pair, etc. In AWS, free tier machines have 1GB memory, which is not enough to host both Hadoop and Druid. Spot Instances are low-cost alternatives.

Instance Public IP Private IP Druid Nodes
Master * 172.31.23.106 CO BR OV
Data Node 0 (SNN?) * 172.31.27.180 HI
Data Node 1 * 172.31.31.205 HI
Data Node 2 * 172.31.27.237 HI
  • Set up client access to AWS instances and connect

Reference: https://letsdobigdata.wordpress.com/2014/01/13/setting-up-hadoop-multi-node-cluster-on-amazon-ec2-part-1/

  • Install Java

Reference: https://www.digitalocean.com/community/tutorials/how-to-install-java-on-ubuntu-with-apt-get

sudo apt-get install python-software-properties
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update

sudo apt-get install oracle-java8-installer

  • Download Hadoop, Druid and Zookeeper

cd ~

get Hadoop

wget http://mirrors.gigenet.com/apache/hadoop/common/hadoop-2.7.1/hadoop-2.7.1.tar.gz

get Druid tarball:

curl http://static.druid.io/artifacts/releases/druid-0.7.3-bin.tar.gz -o druid-0.7.3-bin.tar.gz

get zookeeper:

curl http://www.gtlib.gatech.edu/pub/apache/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz -o zookeeper-3.4.6.tar.gz

unzip all tarballs using `tar -zxvf`

  • Set up environment variables

Reference: https://letsdobigdata.wordpress.com/2014/01/13/setting-up-hadoop-1-2-1-multi-node-cluster-on-amazon-ec2-part-2/

cd

mv hadoop-2.7.1 hadoop

vi .bashrc

Append following to .bashrc

export HADOOP_CONF=/home/ubuntu/hadoop/etc/hadoop

export HADOOP_PREFIX=/home/ubuntu/hadoop

#Set JAVA_HOME

export JAVA_HOME=/usr/lib/jvm/java-8-oracle

# Add Hadoop bin/ directory to path

export PATH=$PATH:$HADOOP_PREFIX/bin

source .bashrc

ls $HADOOP_CONF

  • Set up SSH password-less access on AWS instances

Reference: https://letsdobigdata.wordpress.com/2014/01/13/setting-up-hadoop-1-2-1-multi-node-cluster-on-amazon-ec2-part-2/

Upload your .pem file to the AWS instance using FileZilla or Scp, put it at /home/ubuntu/.ssh.

cd /home/ubuntu/.ssh

chmod 400 OregonKeyPair.pem

eval `ssh-agent`

ssh-add OregonKeyPair.pem

Now you should be able to ssh to other instances, and start service remotely.

  • Set up Hadoop configuration

Reference: https://letsdobigdata.wordpress.com/2014/01/13/setting-up-hadoop-1-2-1-multi-node-cluster-on-amazon-ec2-part-2/

http://hadoop.apache.org/docs/r2.7.1/hadoop-project-dist/hadoop-common/ClusterSetup.html

https://dataheads.wordpress.com/2013/11/21/hadoop-2-setup-on-64-bit-ubuntu-12-04-part-1/

  • Read-only default configuration – core-default.xml, hdfs-default.xml, yarn-default.xml and mapred-default.xml.
  • Site-specific configuration – etc/hadoop/core-site.xml, etc/hadoop/hdfs-site.xml, etc/hadoop/yarn-site.xml and etc/hadoop/mapred-site.xml.
  • Administrators should use the etc/hadoop/hadoop-env.sh and optionally the etc/hadoop/mapred-env.sh and etc/hadoop/yarn-env.sh scripts to do site-specific customization of the Hadoop daemons’ process environment.
  • masters – defines on which machines Hadoop will start secondary NameNodes in our multi-node cluster. (Not found in Hadoop 2.x install)
  • slaves –  defines the lists of hosts, one per line, where the Hadoop slave daemons will run.

hadoop-env.sh

export JAVA_HOME=/usr/lib/jvm/java-8-oracle/

core-site.xml

add two properties

<property>

 <name>fs.default.name</name>

 <value>hdfs://172.31.23.106:8020</value>

 </property>

<property>

 <name>hadoop.tmp.dir</name>

 <value>/home/ubuntu/hdfstmp</value>

</property>

then create hdfstmp folder

cd ~

mkdir hdfstmp

hdfs-site.xml

add the following properties

 <property>

 <name>dfs.replication</name>

 <value>2</value>

 </property>

 <property>

 <name>dfs.permissions</name>

 <value>false</value>

 </property>

mapred-site.xml

 <property>

 <name>mapreduce.framework.name</name>

 <value>yarn</value>

 </property>

 <property>

 <name>mapreduce.jobhistory.address</name>

 <value>172.31.23.106:10020</value>

 </property>

 <property>

 <name>mapreduce.jobhistory.webapp.address</name>

 <value>172.31.23.106:19888</value>

 </property>

yarn-site.xml

<property>

<name>yarn.resourcemanager.hostname</name>

<value>172.31.23.106</value>

</property>

<property>

<name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value>

</property>

<property> <name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name> <value>org.apache.hadoop.mapred.ShuffleHandler</value>

</property>

slaves

172.31.27.180

172.31.31.205

172.31.27.237

  • Start Hadoop cluster

Repeat step 3-5 for all other nodes, then copy Hadoop configuration files in step 7 to all slave nodes iteratively.

scp hadoop-env.sh core-site.xml hdfs-site.xml mapred-site.xml yarn-site.xml ubuntu@172.31.27.180:/home/ubuntu/hadoop/etc/hadoop

scp hadoop-env.sh core-site.xml hdfs-site.xml mapred-site.xml yarn-site.xml ubuntu@172.31.31.205:/home/ubuntu/hadoop/etc/hadoop

scp hadoop-env.sh core-site.xml hdfs-site.xml mapred-site.xml yarn-site.xml ubuntu@172.31.27.237:/home/ubuntu/hadoop/etc/hadoop

“In general, it is recommended that HDFS and YARN run as separate users. In the majority of installations, HDFS processes execute as ‘hdfs’. YARN is typically using the ‘yarn’ account.” This is not taken care of.

Now format HDFS.

$HADOOP_PREFIX/bin/hdfs namenode -format <cluster_name>

Start namenode.

$HADOOP_PREFIX/sbin/hadoop-daemon.sh –config $HADOOP_CONF –script hdfs start namenode

Or using start dfs shell script:

$HADOOP_PREFIX/sbin/start-dfs.sh

*secondary namenode is using [0.0.0.0]. Need to figure out where to configure it in Hadoop 2.x.

Start Yarn components:

$HADOOP_PREFIX/sbin/start-yarn.sh

MapReduce job history server:

$HADOOP_PREFIX/sbin/mr-jobhistory-daemon.sh –config $HADOOP_CONF start historyserver

Now Hadoop is up. You can test HDFS by running

hadoop fs -ls hdfs://172.31.23.106:8020/

  • Set up ZooKeeper

Run the following scripts on the master node. A single node version ZooKeeper is enough for this practice.

cd zookeeper-3.4.6
cp conf/zoo_sample.cfg conf/zoo.cfg
sudo ./bin/zkServer.sh start

  • Set up MySQL for Druid metadata, on master node

install APT repository

https://dev.mysql.com/downloads/repo/apt/

install guide

https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/

Download APT repository file: mysql-apt-config_0.3.5-1ubuntu14.04_all.deb, and upload it to the master node.

Add it to APT repository

sudo dpkg -i mysql-apt-config_0.3.5-1ubuntu14.04_all.deb

The update repository info and install MySQL:

sudo apt-get update

sudo apt-get install mysql-server

You can use root/password as username and password combination.

Make mysql a start up service and check status

update-rc.d mysql defaults

sudo service mysql status

To enable remote connect to mysql, modify mysql configuration:

sudo vi /etc/mysql/my.cnf

change bind-address to master private IP.

Now connect to mysql and create Druid metadata database:

mysql -u root -p

mysql> GRANT ALL ON druid.* TO ‘druid’@’%’ IDENTIFIED BY ‘diurd’;

mysql> CREATE DATABASE druid DEFAULT CHARACTER SET utf8;

% above grant remote access for druid user.

Restart mysql:

sudo service mysql restart

  • Set up Druid

Modify zookeeper, mysql and hdfs settings:

vi ~/druid-0.7.3/config/_common/common.runtime.properties

druid.extensions.coordinates=[“io.druid.extensions:druid-examples”,”io.druid.extensions:druid-kafka-eight”,”io.druid.extensions:mysql-metadata-storage”,”io.druid.extensions:druid-hdfs-storage:0.7.3″,”org.apache.hadoop:hadoop-client:2.7.1″]

# Zookeeper

druid.zk.service.host=172.31.23.106

# Metadata Storage (mysql)

druid.metadata.storage.type=mysql

druid.metadata.storage.connector.connectURI=jdbc\:mysql\://172.31.23.106\:3306/druid

druid.metadata.storage.connector.user=druid

druid.metadata.storage.connector.password=diurd

# Deep storage (local filesystem for examples – don’t use this in production)

druid.storage.type=hdfs

druid.storage.storageDirectory=/druidStorage

# Query Cache (we use a simple 10mb heap-based local cache on the broker)

druid.cache.type=local

druid.cache.sizeInBytes=10000000

# Indexing service discovery

druid.selectors.indexing.serviceName=overlord

# Monitoring (disabled for examples, if you enable SysMonitor, make sure to include sigar jar in your cp)

#druid.monitoring.monitors=[“com.metamx.metrics.SysMonitor”,”com.metamx.metrics.JvmMonitor”]

# Metrics logging (disabled for examples – change this to logging or http in production)

druid.emitter=noop

Copy Druid configuration file to all nodes:

scp -r ~/druid-0.7.3/config/* ubuntu@172.31.27.180:/home/ubuntu/druid-0.7.3/config/

scp -r ~/druid-0.7.3/config/* ubuntu@172.31.31.205:/home/ubuntu/druid-0.7.3/config/

scp -r ~/druid-0.7.3/config/* ubuntu@172.31.27.237:/home/ubuntu/druid-0.7.3/config/

Create druid storage folder in HDFS

hadoop fs -mkdir hdfs://172.31.23.106:8020/druidStorage

Start Druid

cd ~/druid-0.7.3

java -Xmx512m -Duser.timezone=UTC -Dfile.encoding=UTF-8 -classpath config/_common:config/coordinator:lib/*:$HADOOP_CONF:/home/ubuntu/hadoop/share/hadoop/hdfs/*:/home/ubuntu/hadoop/share/hadoop/common/*:/home/ubuntu/hadoop/share/hadoop/common/lib/*:/home/ubuntu/hadoop/share/hadoop/hdfs/lib/*:/home/ubuntu/hadoop/share/hadoop/tools/lib/* io.druid.cli.Main server coordinator &

java -Xmx512m -Duser.timezone=UTC -Dfile.encoding=UTF-8 -classpath config/_common:config/historical:lib/*:$HADOOP_CONF:/home/ubuntu/hadoop/share/hadoop/hdfs/*:/home/ubuntu/hadoop/share/hadoop/common/*:/home/ubuntu/hadoop/share/hadoop/common/lib/*:/home/ubuntu/hadoop/share/hadoop/hdfs/lib/*:/home/ubuntu/hadoop/share/hadoop/tools/lib/* io.druid.cli.Main server historical &

java -Xmx512m -Duser.timezone=UTC -Dfile.encoding=UTF-8 -classpath config/_common:config/broker:lib/*:$HADOOP_CONF:/home/ubuntu/hadoop/share/hadoop/hdfs/*:/home/ubuntu/hadoop/share/hadoop/common/*:/home/ubuntu/hadoop/share/hadoop/common/lib/*:/home/ubuntu/hadoop/share/hadoop/hdfs/lib/*:/home/ubuntu/hadoop/share/hadoop/tools/lib/* io.druid.cli.Main server broker &

java -Xmx2g -Duser.timezone=UTC -Dfile.encoding=UTF-8 -classpath config/_common:config/overlord:lib/*:$HADOOP_CONF:/home/ubuntu/hadoop/share/hadoop/hdfs/*:/home/ubuntu/hadoop/share/hadoop/common/*:/home/ubuntu/hadoop/share/hadoop/common/lib/*:/home/ubuntu/hadoop/share/hadoop/hdfs/lib/*:/home/ubuntu/hadoop/share/hadoop/tools/lib/* io.druid.cli.Main server overlord &

*need to find a way to make druid a background program.

Batch upload through Hadoop

First copy the data file from druid-0.7.3/examples/indexing/wikipedia_data.json to hdfs, then modify the task spec file  wikipedia_index_hadoop_task.json.

 “ioConfig”: {

   “type”: “hadoop”,

   “inputSpec”: {

     “type”: “static”,

     “paths”: “/tmp/wikipedia_data.json”

   },

   “metadataUpdateSpec”: {

     “type”: “db”,

     “connectURI”: “jdbc:mysql:\/\/172.31.23.106:3306\/druid”,

     “user”: “druid”,

     “password”: “diurd”,

     “segmentTable”: “druid_segments”

   },

   “segmentOutputPath”: “\/tmp\/segments”

 }

Run the following to initiate the hadoop indexing task:

curl -X ‘POST’ ‘http://172.31.23.106:8090/druid/indexer/v1/task&#8217; -H ‘Content-Type:application/json’ -d @examples/indexing/wikipedia_index_hadoop_task.json

Query data:

to broker node:

curl -X POST ‘http://:172.31.23.106:8082/druid/v2/?pretty&#8217; -H ‘content-type: application/json’ -d@examples/wikipedia/query.body

to historical node:

curl -X POST ‘http://172.31.27.237:8083/druid/v2/?pretty&#8217; -H ‘content-type: application/json’ -d @examples/wikipedia/query.body