量子恒道官方博客 http://linezing.ruoguschool.com Mon, 16 Dec 2013 09:57:30 +0000 zh-CN hourly 1 http://wordpress.org/?v=3.6.1 淘宝商家业务事业部-数据部 隆重招贤纳士! http://linezing.ruoguschool.com/2013/03/%e5%95%86%e5%ae%b6%e4%ba%8b%e4%b8%9a%e9%83%a8-%e6%95%b0%e6%8d%ae%e9%83%a8-%e9%9a%86%e9%87%8d%e6%8b%9b%e8%b4%a4%e7%ba%b3%e5%a3%ab%ef%bc%81 http://linezing.ruoguschool.com/2013/03/%e5%95%86%e5%ae%b6%e4%ba%8b%e4%b8%9a%e9%83%a8-%e6%95%b0%e6%8d%ae%e9%83%a8-%e9%9a%86%e9%87%8d%e6%8b%9b%e8%b4%a4%e7%ba%b3%e5%a3%ab%ef%bc%81#comments Mon, 25 Mar 2013 06:03:18 +0000 yiyun http://linezing.ruoguschool.com/?p=2048

没赶上20年前关系型数据库系统的狂潮,不要紧!
没赶上8年前分布式数据处理系统的突飞猛进,不要紧!
但是现在摆在大家面前的大数据应用浪潮,你不珍惜,那就太可惜了!
未来是你们的,也是我们的,但终究是大数据的!
如果你精通海量数据处理技术or精通数据可视化技术or精通数据挖掘及算法技术or网站和前端开发牛人,对业务及数据敏感,那么请加入淘宝商家数据部吧!
我们的项目神秘、性感而且充满挑战,和我们一起在AWS+Big Data平台的建设中找寻自己的梦想吧!
If not now, when?!  If not you, who?!  此时此刻,非你莫属!

您可以发送简历到adjob@taobao.com,邮件标题“姓名”+应聘+“职位名称”即可。

———————————————–产品相关职位—————————————-

部门最新开放“产品经理”、“运营专员”相关职位

阿里巴巴集团最强的能力之一是商家端的能力,阿里巴巴集团未来十年战略是“数据分享第一平台”。如果你有优秀的电商经验,或者是顶尖的数据人才,如果你还想站在浪潮之巅创造大数据奇迹,欢迎加入我们~!

我们有影响400万卖家的数据驱动的产品,也在创造前所未有的云数据平台产品,如果你加入,那么你将会负责这些产品的设计!记得这些产品一起在为当前中国全年零售总额的10%服务!

然而我们对阿里巴巴巨大数据财富的挖掘,才刚刚启程,用户对我们产品的渴求非常强烈,如果你是如下贤能之一,那么我们热切盼望与你共事:

【职位名称】:产品经理-商家数据部

  [工作地点]:北京、杭州

    • 贤能一(云计算产品专家)
    1. 熟悉服务器、网络和存储设备、数据库技术
    2. 悉云计算IAAS系统、云存储系统、云数据库系统、Hadoop系统
    3. 了解数据挖掘技术
    4. 在以上相关行业工作3年以上
    • 贤能二(数据产品专家)
    1. 负责设计过数据分析、数据挖掘、在线数据产品,有良好的数据可视化经验
    2. 有深入电商、金融、电信等行业业务理解背景
    3. 了解数据挖掘技术,有上述行业数据挖掘工作经验更佳
    4. 在以上相关行业工作3年以上
    • 贤能三(电商IT产品专家)
    1. 负责设计过电商IT系统产品,如ERP、财务等
    2. 深入了解电商IT系统架构和部署
    3. 深入理解电商业务
    4. 在以上相关行业工作3年以上

【职位名称】:运营专员-商家数据部

  [职位描述]:

    1. 独立负责数据部各业务线的运营工作,并根据业务发展,与产品经理共同制定产品的目标和规划
    2. 定期巡店,了解商家痛点;根据商家痛点,挖掘出产品改进点,并跟进落实
    3. 细化目标制定相应的季度工作计划,并独立制定产品的运营策略,策划运营活动,完成产品目标
    4. 为内、外各类合作伙伴提供产品资料和培训,建立并优化产品运营流程并形成知识积累;对客户及合作伙伴提出的需求和问题进行整理和反馈,并跟进落实

  [工作地点]:北京

  [职位要求]:

    1. 出色的逻辑分析能力,数据分析能力和资源整合能力;优秀的文字表达能力
    2. 熟悉卖家经营环节,了解商家痛点
    3. 具备良好的组织、协调、沟通能力,善于调动各个相关团队的积极性;能够实际解决问题及抗压
    4. 积极乐观,勇于担当,充满激情

———————————-技术相关职位————————————————

各类技术职位持续开放热招中

招贤职位列表如下(明细见后文):

  • 数据挖掘技术专家
  • 高级数据开发/数据仓库工程师
  • 高级前端开发工程师
  • 高级Java开发工程师
  • 高级C++/Java开发工程师

 

【职位名称】:数据挖掘技术专家-商家数据部

[职位描述]:

  • 对商家经营中的问题进行建模,并通过聚石塔算法平台和产品帮助商家的成长
  • 基于淘宝的海量数据,搭建聚石塔算法平台并服务于ISV和商家
  • 进行电子商务领域的用户行为,推荐算法的研究与实现

[工作地点]:北京

[职位要求]:

  • 计算机(机器学习、人工智能等方向)、数学、统计或相关专业本科及以上学历,并且至少有1年相关专业工作背景
  • 掌握常用机器学习,数据挖掘方法,并且在工作中有实际使用这些方法的经验
  • 有推荐系统,计算广告,用户行为分析,大数据处理方面经验者优先考虑
  • 熟悉Unix/Linux开发环境,能应用Python,Shell,Perl等其中一种脚本语言
  • 有较强的分析和解决问题能力,较强的工作激情

【职位名称】:高级数据开发/数据仓库工程师-商家数据部

[职位描述]:

  • 基于海量数据的数据仓库建设、数据应用开发
  • 大型分布式云计算平台应用开发(Hadoop/Hive/Hbase)

[工作地点]:北京

[职位要求]:

  • 计算机或相关专业本科以上学历
  • 具有丰富的数据仓库开发经验,有1年以上基于Hadoop/Storm/HIVE/Hbase等应用开发经验,对分布式计算、数据仓库理论有深刻理解
  • 对Hadoop、Hive、Storm等源码有研究优先
  • 精通JAVA或Python,有并发应用或者分布式应用软件开发经验优先
  • 熟悉Oracle/Teradata/Mysql中的一种,BO/BIEE等报表工具中的一种
  • 良好的系统分析、架构设计能力
  • 对数据敏感、对新技术敏感,有数据挖掘技能者优先

【职位名称】:高级前端开发工程师-商家数据部

[职位描述]:

  • 负责商家数据部重要产品的业务研发
  • 参与商家数据部整体前端框架的设计和研发,这里就是你自我成长和历练之地

[工作地点]:北京

[职位要求]:

  • 精通Web前端技术, 包括HTML/CSS/Javascript等,有良好的计算机基础
  • 熟悉JS对象编程,有丰富的基于Ajax或Json的开发经验,对浏览器兼容性问题有较深入的了解
  • 对 NodeJS / Html5 及其相关技术有一定了解
  • 技术视野广阔, 乐于不断学习新知识与新技术, 并能应用到实际工作中
  • 学习能力强,沟通能力好,对互联网最新技术有关注并尝试应用,追求编写优雅的代码,从技术趋势和思路上能影响技术团队

【职位名称】:Java高级开发工程师-商家数据部

[职位描述]:

  • 构建和开发在海量数据下多维分析的数据分析平台
  • 负责相关系统的设计和核心模块开发工作;

[工作地点]:北京

[职位要求]:

  • 2年及以上JAVA开发的经验,熟练掌握JAVA的WEB编程技术,对各种开源的框架如Spring、Hibernate等有深入的应用和优化经验
  • 有良好计算机网络和数据结构基础,理解IO、多线程等基础知识,对JVM原理有一定的了解
  • 掌握大型数据库(Oracle、MySql);对sql优化有丰富的经验
  • 学习能力强,适应能力好,对互联网或J2EE应用开发的最新技术有关注并尝试应用,追求编写优雅的代码,从技术趋势和思路上能影响技术团队
  • 计算机或相关专业,本科以上学历

[符合以下条件者优先]:

  • 对RMDB及NOSQL数据库有一定的应用,可以根据性能和特点,在特定的数据环境下选择合适的数据存储层
  • 掌握OLAP的基本概念及相关应用,对多维分析及MDX熟练掌握
  • 熟悉分布式系统的设计和应用,熟悉分布式缓存、消息等机制;并能合理应用分布式技术,解决问题;

 【职位名称】:高级C++/Java开发工程师- 商家数据部

[职位描述]:

  • 打造支撑海量数据的实时计算服务
  • 大数据高性能分布式处理系统研发

[工作地点]:北京

[职位要求]:

  • 熟悉脚本语言(如php/shell/python/perl,至少一种)
  • 精通Linux平台下C/C++或者Java开发,精通性能调优
  • 熟悉多线程模型编程,熟悉网络编程和IO模型
  • 熟练掌握各类常用数据结构和相关算法
  • 较强的工作责任心和良好的沟通协调能力,能在压力下独立解决问题
  • 有钻研精神,对技术、大数据充满热情,有团队合作精神

[符合以下条件者优先]

  • 精通分布式系统(如Hadoop,Hive,Storm等)
  • 精通Nosql(如Redis,Hbase等)
  • 精通高并发大数据量的数据库SQL开发,深入了解数据库内部存储
  • 精通MOLAP相关技术
  • 热衷开源社区代码贡献
]]>
http://linezing.ruoguschool.com/2013/03/%e5%95%86%e5%ae%b6%e4%ba%8b%e4%b8%9a%e9%83%a8-%e6%95%b0%e6%8d%ae%e9%83%a8-%e9%9a%86%e9%87%8d%e6%8b%9b%e8%b4%a4%e7%ba%b3%e5%a3%ab%ef%bc%81/feed 0
Storm入门教程 第五章 一致性事务 http://linezing.ruoguschool.com/2013/01/storm%e5%85%a5%e9%97%a8%e6%95%99%e7%a8%8b-%e7%ac%ac%e4%ba%94%e7%ab%a0-%e4%b8%80%e8%87%b4%e6%80%a7%e4%ba%8b%e5%8a%a1 http://linezing.ruoguschool.com/2013/01/storm%e5%85%a5%e9%97%a8%e6%95%99%e7%a8%8b-%e7%ac%ac%e4%ba%94%e7%ab%a0-%e4%b8%80%e8%87%b4%e6%80%a7%e4%ba%8b%e5%8a%a1#comments Wed, 09 Jan 2013 08:23:45 +0000 muhan.jc http://linezing.ruoguschool.com/?p=1976 第五章 一致性事务

Storm是一个分布式的流处理系统,利用anchor和ack机制保证所有tuple都被成功处理。如果tuple出错,则可以被重传,但是如何保证出错的tuple只被处理一次呢?Storm提供了一套事务性组件Transaction Topology,用来解决这个问题。

Transactional Topology目前已经不再维护,由Trident来实现事务性topology,但是原理相同。

5.1一致性事务的设计

Storm如何实现即对tuple并行处理,又保证事务性。本节从简单的事务性实现方法入手,逐步引出Transactional Topology的原理。

5.1.1 简单设计一:强顺序流

保证tuple只被处理一次,最简单的方法就是将tuple流变成强顺序的,并且每次只处理一个tuple。从1开始,给每个tuple都顺序加上一个id。在处理tuple的时候,将处理成功的tuple id和计算结果存在数据库中。下一个tuple到来的时候,将其id与数据库中的id做比较。如果相同,则说明这个tuple已经被成功处理过了,忽略它;如果不同,根据强顺序性,说明这个tuple没有被处理过,将它的id及计算结果更新到数据库中。

以统计消息总数为例。每来一个tuple,如果数据库中存储的id 与当前tuple id不同,则数据库中的消息总数加1,同时更新数据库中的当前tuple id值。如图:

强顺序流

         但是这种机制使得系统一次只能处理一个tuple,无法实现分布式计算。

5.1.2 简单设计二:强顺序batch流

为了实现分布式,我们可以每次处理一批tuple,称为一个batch。一个batch中的tuple可以被并行处理。

我们要保证一个batch只被处理一次,机制和上一节类似。只不过数据库中存储的是batch id。batch的中间计算结果先存在局部变量中,当一个batch中的所有tuple都被处理完之后,判断batch id,如果跟数据库中的id不同,则将中间计算结果更新到数据库中。

如何确保一个batch里面的所有tuple都被处理完了呢?可以利用Storm提供的CoordinateBolt。如图:

顺序batches

但是强顺序batch流也有局限,每次只能处理一个batch,batch之间无法并行。要想实现真正的分布式事务处理,可以使用storm提供的Transactional Topology。在此之前,我们先详细介绍一下CoordinateBolt的原理。

5.1.3 CoordinateBolt原理

CoordinateBolt具体原理如下:

  • 真正执行计算的bolt外面封装了一个CoordinateBolt。真正执行任务的bolt我们称为real bolt。
  • 每个CoordinateBolt记录两个值:有哪些task给我发送了tuple(根据topology的grouping信息);我要给哪些tuple发送信息(同样根据groping信息)
  •  Real bolt发出一个tuple后,其外层的CoordinateBolt会记录下这个tuple发送给哪个task了。
  • 等所有的tuple都发送完了之后,CoordinateBolt通过另外一个特殊的stream以emitDirect的方式告诉所有它发送过tuple的task,它发送了多少tuple给这个task。下游task会将这个数字和自己已经接收到的tuple数量做对比,如果相等,则说明处理完了所有的tuple。
  • 下游CoordinateBolt会重复上面的步骤,通知其下游。

整个过程如图所示:

coordinateBolt

CoordinateBolt主要用于两个场景:

  • DRPC
  • Transactional Topology

CoordinatedBolt对于业务是有侵入的,要使用CoordinatedBolt提供的功能,你必须要保证你的每个bolt发送的每个tuple的第一个field是request-id。 所谓的“我已经处理完我的上游”的意思是说当前这个bolt对于当前这个request-id所需要做的工作做完了。这个request-id在DRPC里面代表一个DRPC请求;在Transactional Topology里面代表一个batch。

5.1.4 Trasactional Topology

Storm提供的Transactional Topology将batch计算分为process和commit两个阶段。Process阶段可以同时处理多个batch,不用保证顺序性;commit阶段保证batch的强顺序性,并且一次只能处理一个batch,第1个batch成功提交之前,第2个batch不能被提交。

还是以统计消息总数为例,以下代码来自storm-starter里面的TransactionalGlobalCount。

MemoryTransactionalSpout spout = new MemoryTransactionalSpout(DATA,new Fields(“word“), PARTITION_TAKE_PER_BATCH);

TransactionalTopologyBuilder builder = new TransactionalTopologyBuilder(“global-count“, “spout“, spout, 3);

builder.setBolt(“partial-count“, new BatchCount(), 5).noneGrouping(“spout“);

builder.setBolt(“sum“, new UpdateGlobalCount()).globalGrouping(“partial-count“);

TransactionalTopologyBuilder共接收四个参数。

  • 这个Transactional Topology的id。Id用来在Zookeeper中保存当前topology的进度,如果这个topology重启,可以继续之前的进度执行。
  •  Spout在这个topology中的id
  • 一个TransactionalSpout。一个Trasactional Topology中只能有一个TrasactionalSpout.在本例中是一个MemoryTransactionalSpout,从一个内存变量(DATA)中读取数据。
  • TransactionalSpout的并行度(可选)。

下面是BatchCount的定义:

public static class BatchCount extends BaseBatchBolt {

        Object _id;

        BatchOutputCollector _collector;

        int _count = 0;

        @Override

        public void prepare(Map conf, TopologyContext context,

              BatchOutputCollector collector, Object id) {

            _collector = collector;

            _id = id;

        }

        @Override

        public void execute(Tuple tuple) {

            _count++;

        }

        @Override

        public void finishBatch() {

            _collector.emit(new Values(_id, _count));

        }

        @Override

        public void declareOutputFields(OutputFieldsDeclarer declarer) {

            declarer.declare(new Fields(“id“, “count“));

        }

}

 BatchCount的prepare方法的最后一个参数是batch id,在Transactional Tolpoloyg里面这id是一个TransactionAttempt对象。

Transactional Topology里发送的tuple都必须以TransactionAttempt作为第一个field,storm根据这个field来判断tuple属于哪一个batch。

TransactionAttempt包含两个值:一个transaction id,一个attempt id。transaction id的作用就是我们上面介绍的对于每个batch中的tuple是唯一的,而且不管这个batch replay多少次都是一样的。attempt id是对于每个batch唯一的一个id, 但是对于同一个batch,它replay之后的attempt id跟replay之前就不一样了, 我们可以把attempt id理解成replay-times, storm利用这个id来区别一个batch发射的tuple的不同版本。

execute方法会为batch里面的每个tuple执行一次,你应该把这个batch里面的计算状态保持在一个本地变量里面。对于这个例子来说, 它在execute方法里面递增tuple的个数。

最后, 当这个bolt接收到某个batch的所有的tuple之后, finishBatch方法会被调用。这个例子里面的BatchCount类会在这个时候发射它的局部数量到它的输出流里面去。

下面是UpdateGlobalCount类的定义:

public static class UpdateGlobalCount extends BaseTransactionalBolt

implements ICommitter {

        TransactionAttempt _attempt;

        BatchOutputCollector _collector;

        int _sum = 0;

        @Override

        public void prepare(Map conf, TopologyContext context,

BatchOutputCollector collector, TransactionAttempt attempt) {

            _collector = collector;

            _attempt = attempt;

        }

        @Override

        public void execute(Tuple tuple) {

            _sum+=tuple.getInteger(1);

        }

        @Override

        public void finishBatch() {

            Value val = DATABASE.get(GLOBAL_COUNT_KEY);

            Value newval;

            if(val == null || !val.txid.equals(_attempt.getTransactionId())) {

                newval = new Value();

                newval.txid = _attempt.getTransactionId();

                if(val==null) {

                    newval.count = _sum;

                } else {

                    newval.count = _sum + val.count;

                }

                DATABASE.put(GLOBAL_COUNT_KEY, newval);

            } else {

                newval = val;

            }

            _collector.emit(new Values(_attempt, newval.count));

        }

        @Override

        public void declareOutputFields(OutputFieldsDeclarer declarer) {

            declarer.declare(new Fields(“id“, “sum“));

        }

}

UpdateGlobalCount实现了ICommitter接口,所以storm只会在commit阶段执行finishBatch方法。而execute方法可以在任何阶段完成。

在UpdateGlobalCount的finishBatch方法中,将当前的transaction id与数据库中存储的id做比较。如果相同,则忽略这个batch;如果不同,则把这个batch的计算结果加到总结果中,并更新数据库。

Transactional Topolgy运行示意图如下:

transactional topology

下面总结一下Transactional Topology的一些特性

  •  Transactional Topology将事务性机制都封装好了,其内部使用CoordinateBolt来保证一个batch中的tuple被处理完。
  •  TransactionalSpout只能有一个,它将所有tuple分为一个一个的batch,而且保证同一个batch的transaction id始终一样。
  •  BatchBolt处理batch在一起的tuples。对于每一个tuple调用execute方法,而在整个batch处理完成的时候调用finishBatch方法。
  •  如果BatchBolt被标记成Committer,则只能在commit阶段调用finishBolt方法。一个batch的commit阶段由storm保证只在前一个batch成功提交之后才会执行。并且它会重试直到topology里面的所有bolt在commit完成提交。
  •  Transactional Topology隐藏了anchor/ack框架,它提供一个不同的机制来fail一个batch,从而使得这个batch被replay。

5.2 Trident介绍

Trident是Storm之上的高级抽象,提供了joins,grouping,aggregations,fuctions和filters等接口。如果你使用过Pig或Cascading,对这些接口就不会陌生。

Trident将stream中的tuples分成batches进行处理,API封装了对这些batches的处理过程,保证tuple只被处理一次。处理batches中间结果存储在TridentState对象中。

Trident事务性原理这里不详细介绍,有兴趣的读者请自行查阅资料。

参考:http://xumingming.sinaapp.com/736/twitter-storm-transactional-topolgoy/

http://xumingming.sinaapp.com/811/twitter-storm-code-analysis-coordinated-bolt/

https://github.com/nathanmarz/storm/wiki/Trident-tutorial

作者:木晗

]]>
http://linezing.ruoguschool.com/2013/01/storm%e5%85%a5%e9%97%a8%e6%95%99%e7%a8%8b-%e7%ac%ac%e4%ba%94%e7%ab%a0-%e4%b8%80%e8%87%b4%e6%80%a7%e4%ba%8b%e5%8a%a1/feed 0
storm入门教程 第四章 消息的可靠处理 http://linezing.ruoguschool.com/2013/01/storm%e5%85%a5%e9%97%a8%e6%95%99%e7%a8%8b-%e7%ac%ac%e5%9b%9b%e7%ab%a0-%e6%b6%88%e6%81%af%e7%9a%84%e5%8f%af%e9%9d%a0%e5%a4%84%e7%90%86 http://linezing.ruoguschool.com/2013/01/storm%e5%85%a5%e9%97%a8%e6%95%99%e7%a8%8b-%e7%ac%ac%e5%9b%9b%e7%ab%a0-%e6%b6%88%e6%81%af%e7%9a%84%e5%8f%af%e9%9d%a0%e5%a4%84%e7%90%86#comments Mon, 07 Jan 2013 07:02:27 +0000 taiqi.zyl http://linezing.ruoguschool.com/?p=1898

4.1 简介

storm可以确保spout发送出来的每个消息都会被完整的处理。本章将会描述storm体系是如何达到这个目标的,并将会详述开发者应该如何使用storm的这些机制来实现数据的可靠处理。

4.2 理解消息被完整处理

一个消息(tuple)从spout发送出来,可能会导致成百上千的消息基于此消息被创建。

我们来思考一下流式的“单词统计”的例子:

storm任务从数据源(Kestrel queue)每次读取一个完整的英文句子;将这个句子分解为独立的单词,最后,实时的输出每个单词以及它出现过的次数。

本例中,每个从spout发送出来的消息(每个英文句子)都会触发很多的消息被创建,那些从句子中分隔出来的单词就是被创建出来的新消息。

这些消息构成一个树状结构,我们称之为“tuple tree”,看起来如图1所示:

图1 示例tuple tree

在什么条件下,Storm才会认为一个从spout发送出来的消息被完整处理呢?答案就是下面的条件同时被满足:

  • tuple tree不再生长
  • 树中的任何消息被标识为“已处理”

如果在指定的时间内,一个消息衍生出来的tuple tree未被完全处理成功,则认为此消息未被完整处理。这个超时值可以通过任务级参数Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS 进行配置,默认超时值为30秒。

4.3 消息的生命周期

如果消息被完整处理或者未被完整处理,Storm会如何进行接下来的操作呢?为了弄清这个问题,我们来研究一下从spout发出来的消息的生命周期。这里列出了spout应该实现的接口:

首先, Storm使用spout实例的nextTuple()方法从spout请求一个消息(tuple)。 收到请求以后,spout使用open方法中提供的SpoutOutputCollector向它的输出流发送一个或多个消息。每发送一个消息,Spout会给这个消息提供一个message ID,它将会被用来标识这个消息。

假设我们从kestrel队列中读取消息,Spout会将kestrel 队列为这个消息设置的ID作为此消息的message ID。 向SpoutOutputCollector中发送消息格式如下:

接来下,这些消息会被发送到后续业务处理的bolts, 并且Storm会跟踪由此消息产生出来的新消息。当检测到一个消息衍生出来的tuple tree被完整处理后,Storm会调用Spout中的ack方法,并将此消息的messageID作为参数传入。同理,如果某消息处理超时,则此消息对应的Spout的fail方法会被调用,调用时此消息的messageID会被作为参数传入。

注意:一个消息只会由发送它的那个spout任务来调用ack或fail。如果系统中某个spout由多个任务运行,消息也只会由创建它的spout任务来应答(ack或fail),决不会由其他的spout任务来应答。

我们继续使用从kestrel队列中读取消息的例子来阐述高可靠性下spout需要做些什么(假设这个spout的名字是KestrelSpout)。

我们先简述一下kestrel消息队列:

当KestrelSpout从kestrel队列中读取一个消息,表示它“打开”了队列中某个消息。这意味着,此消息并未从队列中真正的删除,而是将此消息设置为“pending”状态,它等待来自客户端的应答,被应答以后,此消息才会被真正的从队列中删除。处于“pending”状态的消息不会被其他的客户端看到。另外,如果一个客户端意外的断开连接,则由此客户端“打开”的所有消息都会被重新加入到队列中。当消息被“打开”的时候,kestrel队列同时会为这个消息提供一个唯一的标识。

KestrelSpout就是使用这个唯一的标识作为这个tuple的messageID的。稍后当ack或fail被调用的时候,KestrelSpout会把ack或者fail连同messageID一起发送给kestrel队列,kestrel会将消息从队列中真正删除或者将它重新放回队列中。

4.4 可靠相关的API

为了使用Storm提供的可靠处理特性,我们需要做两件事情:

  1. 无论何时在tuple tree中创建了一个新的节点,我们需要明确的通知Storm;
  2. 当处理完一个单独的消息时,我们需要告诉Storm 这棵tuple tree的变化状态。

通过上面的两步,storm就可以检测到一个tuple tree何时被完全处理了,并且会调用相关的ack或fail方法。Storm提供了简单明了的方法来完成上述两步。

为tuple tree中指定的节点增加一个新的节点,我们称之为锚定(anchoring)。锚定是在我们发送消息的同时进行的。为了更容易说明问题,我们使用下面代码作为例子。本示例的bolt将包含整句话的消息分解为一系列的子消息,每个子消息包含一个单词。

每个消息都通过这种方式被锚定:把输入消息作为emit方法的第一个参数。因为word消息被锚定在了输入消息上,这个输入消息是spout发送过来的tuple tree的根节点,如果任意一个word消息处理失败,派生这个tuple tree那个spout 消息将会被重新发送。

与此相反,我们来看看使用下面的方式emit消息时,Storm会如何处理:

如果以这种方式发送消息,将会导致这个消息不会被锚定。如果此tuple tree中的消息处理失败,派生此tuple tree的根消息不会被重新发送。根据任务的容错级别,有时候很适合发送一个非锚定的消息。

一个输出消息可以被锚定在一个或者多个输入消息上,这在做join或聚合的时候是很有用的。一个被多重锚定的消息处理失败,会导致与之关联的多个spout消息被重新发送。多重锚定通过在emit方法中指定多个输入消息来实现:

多重锚定会将被锚定的消息加到多棵tuple tree上。

注意:多重绑定可能会破坏传统的树形结构,从而构成一个DAGs(有向无环图),如图2所示:

图2 多重锚定构成的钻石型结构

Storm的实现可以像处理树那样来处理DAGs。

锚定表明了如何将一个消息加入到指定的tuple tree中,高可靠处理API的接下来部分将向您描述当处理完tuple tree中一个单独的消息时我们该做些什么。这些是通过OutputCollector 的ack和fail方法来实现的。回头看一下例子SplitSentence,可以发现当所有的word消息被发送完成后,输入的表示句子的消息会被应答(acked)。

每个被处理的消息必须表明成功或失败(acked 或者failed)。Storm是使用内存来跟踪每个消息的处理情况的,如果被处理的消息没有应答的话,迟早内存会被耗尽!>

很多bolt遵循特定的处理流程: 读取一个消息、发送它派生出来的子消息、在execute结尾处应答此消息。一般的过滤器(filter)或者是简单的处理功能都是这类的应用。Storm有一个BasicBolt接口封装了上述的流程。示例SplitSentence可以使用BasicBolt来重写:

使用这种方式,代码比之前稍微简单了一些,但是实现的功能是一样的。发送到BasicOutputCollector的消息会被自动的锚定到输入消息,并且,当execute执行完毕的时候,会自动的应答输入消息。

很多情况下,一个消息需要延迟应答,例如聚合或者是join。只有根据一组输入消息得到一个结果之后,才会应答之前所有的输入消息。并且聚合和join大部分时候对输出消息都是多重锚定。然而,这些特性不是IBasicBolt所能处理的。

4.5 高效的实现tuple tree

Storm 系统中有一组叫做“acker”的特殊的任务,它们负责跟踪DAG(有向无环图)中的每个消息。每当发现一个DAG被完全处理,它就向创建这个根消息的spout任务发送一个信号。拓扑中acker任务的并行度可以通过配置参数Config.TOPOLOGY_ACKERS来设置。默认的acker任务并行度为1,当系统中有大量的消息时,应该适当提高acker任务的并发度。

为了理解Storm可靠性处理机制,我们从研究一个消息的生命周期和tuple tree的管理入手。当一个消息被创建的时候(无论是在spout还是bolt中),系统都为该消息分配一个64bit的随机值作为id。这些随机的id是acker用来跟踪由spout消息派生出来的tuple tree的。

每个消息都知道它所在的tuple tree对应的根消息的id。每当bolt新生成一个消息,对应tuple tree中的根消息的messageId就拷贝到这个消息中。当这个消息被应答的时候,它就把关于tuple tree变化的信息发送给跟踪这棵树的acker。例如,他会告诉acker:本消息已经处理完毕,但是我派生出了一些新的消息,帮忙跟踪一下吧。

举个例子,假设消息D和E是由消息C派生出来的,这里演示了消息C被应答时,tuple tree是如何变化的。

因为在C被从树中移除的同时D和E会被加入到tuple tree中,因此tuple tree不会被过早的认为已完全处理。

关于Storm如何跟踪tuple tree,我们再深入的探讨一下。前面说过系统中可以有任意个数的acker,那么,每当一个消息被创建或应答的时候,它怎么知道应该通知哪个acker呢?

系统使用一种哈希算法来根据spout消息的messageId确定由哪个acker跟踪此消息派生出来的tuple tree。因为每个消息都知道与之对应的根消息的messageId,因此它知道应该与哪个acker通信。

当spout发送一个消息的时候,它就通知对应的acker一个新的根消息产生了,这时acker就会创建一个新的tuple tree。当acker发现这棵树被完全处理之后,他就会通知对应的spout任务。

tuple是如何被跟踪的呢?系统中有成千上万的消息,如果为每个spout发送的消息都构建一棵树的话,很快内存就会耗尽。所以,必须采用不同的策略来跟踪每个消息。由于使用了新的跟踪算法,Storm只需要固定的内存(大约20字节)就可以跟踪一棵树。这个算法是storm正确运行的核心,也是storm最大的突破。

acker任务保存了spout消息id到一对值的映射。第一个值就是spout的任务id,通过这个id,acker就知道消息处理完成时该通知哪个spout任务。第二个值是一个64bit的数字,我们称之为“ack val”, 它是树中所有消息的随机id的异或结果。ack val表示了整棵树的的状态,无论这棵树多大,只需要这个固定大小的数字就可以跟踪整棵树。当消息被创建和被应答的时候都会有相同的消息id发送过来做异或。

每当acker发现一棵树的ack val值为0的时候,它就知道这棵树已经被完全处理了。因为消息的随机ID是一个64bit的值,因此ack val在树处理完之前被置为0的概率非常小。假设你每秒钟发送一万个消息,从概率上说,至少需要50,000,000年才会有机会发生一次错误。即使如此,也只有在这个消息确实处理失败的情况下才会有数据的丢失!

4.6 选择合适的可靠性级别

Acker任务是轻量级的,所以在拓扑中并不需要太多的acker存在。可以通过Storm UI来观察acker任务的吞吐量,如果看上去吞吐量不够的话,说明需要添加额外的acker。

如果你并不要求每个消息必须被处理(你允许在处理过程中丢失一些信息),那么可以关闭消息的可靠处理机制,从而可以获取较好的性能。关闭消息的可靠处理机制意味着系统中的消息数会减半(每个消息不需要应答了)。另外,关闭消息的可靠处理可以减少消息的大小(不需要每个tuple记录它的根id了),从而节省带宽。

有三种方法可以关系消息的可靠处理机制:

  • 将参数Config.TOPOLOGY_ACKERS设置为0,通过此方法,当Spout发送一个消息的时候,它的ack方法将立刻被调用;
  • 第二个方法是Spout发送一个消息时,不指定此消息的messageID。当需要关闭特定消息可靠性的时候,可以使用此方法;
  • 最后,如果你不在意某个消息派生出来的子孙消息的可靠性,则此消息派生出来的子消息在发送时不要做锚定,即在emit方法中不指定输入消息。因为这些子孙消息没有被锚定在任何tuple tree中,因此他们的失败不会引起任何spout重新发送消息。

4.7 集群的各级容错

到现在为止,大家已经理解了Storm的可靠性机制,并且知道了如何选择不同的可靠性级别来满足需求。接下来我们研究一下Storm如何保证在各种情况下确保数据不丢失。

3.7.1 任务级失败

  • 因为bolt任务crash引起的消息未被应答。此时,acker中所有与此bolt任务关联的消息都会因为超时而失败,对应spout的fail方法将被调用。
  • acker任务失败。如果acker任务本身失败了,它在失败之前持有的所有消息都将会因为超时而失败。Spout的fail方法将被调用。
  • Spout任务失败。这种情况下,Spout任务对接的外部设备(如MQ)负责消息的完整性。例如当客户端异常的情况下,kestrel队列会将处于pending状态的所有的消息重新放回到队列中。

4.7.2  任务槽(slot) 故障

  • worker失败。每个worker中包含数个bolt(或spout)任务。supervisor负责监控这些任务,当worker失败后,supervisor会尝试在本机重启它。
  • supervisor失败。supervisor是无状态的,因此supervisor的失败不会影响当前正在运行的任务,只要及时的将它重新启动即可。supervisor不是自举的,需要外部监控来及时重启。
  • nimbus失败。nimbus是无状态的,因此nimbus的失败不会影响当前正在运行的任务(nimbus失败时,无法提交新的任务),只要及时的将它重新启动即可。nimbus不是自举的,需要外部监控来及时重启。

4.7.3.  集群节点(机器)故障

  • storm集群中的节点故障。此时nimbus会将此机器上所有正在运行的任务转移到其他可用的机器上运行。
  • zookeeper集群中的节点故障。zookeeper保证少于半数的机器宕机仍可正常运行,及时修复故障机器即可。

4.8 小结

本章介绍了storm集群如何实现数据的可靠处理。借助于创新性的tuple tree跟踪技术,storm高效的通过数据的应答机制来保证数据不丢失。

storm集群中除nimbus外,没有单点存在,任何节点都可以出故障而保证数据不会丢失。nimbus被设计为无状态的,只要可以及时重启,就不会影响正在运行的任务。

 

作者:

太奇

 

]]>
http://linezing.ruoguschool.com/2013/01/storm%e5%85%a5%e9%97%a8%e6%95%99%e7%a8%8b-%e7%ac%ac%e5%9b%9b%e7%ab%a0-%e6%b6%88%e6%81%af%e7%9a%84%e5%8f%af%e9%9d%a0%e5%a4%84%e7%90%86/feed 0
Storm入门教程 第三章 Storm安装部署步骤 http://linezing.ruoguschool.com/2013/01/how-to-install-and-deploy-storm-cluster http://linezing.ruoguschool.com/2013/01/how-to-install-and-deploy-storm-cluster#comments Sat, 05 Jan 2013 09:33:50 +0000 原 攀峰 http://linezing.ruoguschool.com/?p=1892 本文以Twitter Storm官方Wiki为基础,详细描述如何快速搭建一个Storm集群,其中,项目实践中遇到的问题及经验总结,在相应章节以“注意事项”的形式给出。

3.1 Storm集群组件

Storm集群中包含两类节点:主控节点(Master Node)和工作节点(Work Node)。其分别对应的角色如下:

1. 主控节点(Master Node)上运行一个被称为Nimbus的后台程序,它负责在Storm集群内分发代码,分配任务给工作机器,并且负责监控集群运行状态。Nimbus的作用类似于Hadoop中JobTracker的角色。

2. 每个工作节点(Work Node)上运行一个被称为Supervisor的后台程序。Supervisor负责监听从Nimbus分配给它执行的任务,据此启动或停止执行任务的工作进程。每一个工作进程执行一个Topology的子集;一个运行中的Topology由分布在不同工作节点上的多个工作进程组成。

 

Storm集群组件

Nimbus和Supervisor节点之间所有的协调工作是通过Zookeeper集群来实现的。此外,Nimbus和Supervisor进程都是快速失败(fail-fast)和无状态(stateless)的;Storm集群所有的状态要么在Zookeeper集群中,要么存储在本地磁盘上。这意味着你可以用kill -9来杀死Nimbus和Supervisor进程,它们在重启后可以继续工作。这个设计使得Storm集群拥有不可思议的稳定性。

3.2 安装Storm集群

这一章节将详细描述如何搭建一个Storm集群。下面是接下来需要依次完成的安装步骤:

1. 搭建Zookeeper集群;

2. 安装Storm依赖库;

3. 下载并解压Storm发布版本;

4. 修改storm.yaml配置文件;

5. 启动Storm各个后台进程。

3.2.1 搭建Zookeeper集群

Storm使用Zookeeper协调集群,由于Zookeeper并不用于消息传递,所以Storm给Zookeeper带来的压力相当低。大多数情况下,单个节点的Zookeeper集群足够胜任,不过为了确保故障恢复或者部署大规模Storm集群,可能需要更大规模节点的Zookeeper集群(对于Zookeeper集群的话,官方推荐的最小节点数为3个)。在Zookeeper集群的每台机器上完成以下安装部署步骤:

1. 下载安装Java JDK,官方下载链接为http://java.sun.com/javase/downloads/index.jsp,JDK版本为JDK 6或以上。

2. 根据Zookeeper集群的负载情况,合理设置Java堆大小,尽可能避免发生swap,导致Zookeeper性能下降。保守起见,4GB内存的机器可以为Zookeeper分配3GB最大堆空间。

3. 下载后解压安装Zookeeper包,官方下载链接为http://hadoop.apache.org/zookeeper/releases.html

4. 根据Zookeeper集群节点情况,在conf目录下创建Zookeeper配置文件zoo.cfg:

tickTime=2000
dataDir=/var/zookeeper/
clientPort=2181
initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

其中,dataDir指定Zookeeper的数据文件目录;其中server.id=host:port:port,id是为每个Zookeeper节点的编号,保存在dataDir目录下的myid文件中,zoo1~zoo3表示各个Zookeeper节点的hostname,第一个port是用于连接leader的端口,第二个port是用于leader选举的端口。

5. 在dataDir目录下创建myid文件,文件中只包含一行,且内容为该节点对应的server.id中的id编号。

6. 启动Zookeeper服务:

java -cp zookeeper.jar:lib/log4j-1.2.15.jar:conf \ org.apache.zookeeper.server.quorum.QuorumPeerMain zoo.cfg

或者

bin/zkServer.sh start

7. 通过Zookeeper客户端测试服务是否可用:

java -cp zookeeper.jar:src/java/lib/log4j-1.2.15.jar:conf:src/java/lib/jline-0.9.94.jar \ org.apache.zookeeper.ZooKeeperMain -server 127.0.0.1:2181

或者

bin/zkCli.sh -server 127.0.0.1:2181

注意事项:

  1. 由于Zookeeper是快速失败(fail-fast)的,且遇到任何错误情况,进程均会退出,因此,最好能通过监控程序将Zookeeper管理起来,保证Zookeeper退出后能被自动重启。详情参考这里
  2. Zookeeper运行过程中会在dataDir目录下生成很多日志和快照文件,而Zookeeper运行进程并不负责定期清理合并这些文件,导致占用大量磁盘空间,因此,需要通过cron等方式定期清除没用的日志和快照文件。详情参考这里。具体命令格式如下:java -cp zookeeper.jar:log4j.jar:conf org.apache.zookeeper.server.PurgeTxnLog <dataDir> <snapDir> -n <count>

3.2.2 安装Storm依赖库

接下来,需要在Nimbus和Supervisor机器上安装Storm的依赖库,具体如下:

1. ZeroMQ 2.1.7 – 请勿使用2.1.10版本,因为该版本的一些严重bug会导致Storm集群运行时出现奇怪的问题。少数用户在2.1.7版本会遇到”IllegalArgumentException”的异常,此时降为2.1.4版本可修复这一问题。

2. JZMQ

3. Java 6

4. Python 2.6.6

5. unzip

以上依赖库的版本是经过Storm测试的,Storm并不能保证在其他版本的Java或Python库下可运行。

3.2.2.1 安装ZMQ 2.1.7

下载后编译安装ZMQ:

wget http://download.zeromq.org/zeromq-2.1.7.tar.gz
tar -xzf zeromq-2.1.7.tar.gz
cd zeromq-2.1.7
./configure
make
sudo make install

注意事项:

如果安装过程报错uuid找不到,则通过如下的包安装uuid库:
sudo yum install e2fsprogsl
sudo yum install e2fsprogs-devel

3.2.2.2 安装JZMQ

下载后编译安装JZMQ:

git clone https://github.com/nathanmarz/jzmq.git
cd jzmq
./autogen.sh
./configure
make
sudo make install

为了保证JZMQ正常工作,可能需要完成以下配置:

  1. 正确设置 JAVA_HOME环境变量
  2. 安装Java开发包
  3. 升级autoconf
  4. 如果你是Mac OSX,参考这里

注意事项:

  1. 如果运行 ./configure 命令出现问题,参考这里

3.2.2.3 安装Java 6

1. 下载并安装JDK 6,参考这里

2. 配置JAVA_HOME环境变量;

3. 运行java、javac命令,测试java正常安装。

3.2.2.4 安装Python2.6.6

1. 下载Python2.6.6:

wget http://www.python.org/ftp/python/2.6.6/Python-2.6.6.tar.bz2

2. 编译安装Python2.6.6:

tar –jxvf Python-2.6.6.tar.bz2
cd Python-2.6.6
./configure
make
make install

3. 测试Python2.6.6:

python -V
Python 2.6.6

3.2.2.5 安装unzip

1. 如果使用RedHat系列Linux系统,执行以下命令安装unzip:

yum install unzip

2. 如果使用Debian系列Linux系统,执行以下命令安装unzip:

apt-get install unzip

3.2.3 下载并解压Storm发布版本

下一步,需要在Nimbus和Supervisor机器上安装Storm发行版本。

1. 下载Storm发行版本,推荐使用Storm0.8.1:

wget https://github.com/downloads/nathanmarz/storm/storm-0.8.1.zip

2. 解压到安装目录下:

unzip storm-0.8.1.zip

3.2.4 修改storm.yaml配置文件

Storm发行版本解压目录下有一个conf/storm.yaml文件,用于配置Storm。默认配置在这里可以查看。conf/storm.yaml中的配置选项将覆盖defaults.yaml中的默认配置。以下配置选项是必须在conf/storm.yaml中进行配置的:

1) storm.zookeeper.servers: Storm集群使用的Zookeeper集群地址,其格式如下:

storm.zookeeper.servers:
- “111.222.333.444″
- “555.666.777.888″

如果Zookeeper集群使用的不是默认端口,那么还需要storm.zookeeper.port选项

2) storm.local.dir: Nimbus和Supervisor进程用于存储少量状态,如jars、confs等的本地磁盘目录,需要提前创建该目录并给以足够的访问权限。然后在storm.yaml中配置该目录,如:

storm.local.dir: "/home/admin/storm/workdir"

3) java.library.path: Storm使用的本地库(ZMQ和JZMQ)加载路径,默认为”/usr/local/lib:/opt/local/lib:/usr/lib”,一般来说ZMQ和JZMQ默认安装在/usr/local/lib 下,因此不需要配置即可。

4) nimbus.host: Storm集群Nimbus机器地址,各个Supervisor工作节点需要知道哪个机器是Nimbus,以便下载Topologies的jars、confs等文件,如:

nimbus.host: "111.222.333.444"

5) supervisor.slots.ports: 对于每个Supervisor工作节点,需要配置该工作节点可以运行的worker数量。每个worker占用一个单独的端口用于接收消息,该配置选项即用于定义哪些端口是可被worker使用的。默认情况下,每个节点上可运行4个workers,分别在6700、6701、6702和6703端口,如:

supervisor.slots.ports:
    - 6700
    - 6701
    - 6702
    - 6703

3.2.5 启动Storm各个后台进程

最后一步,启动Storm的所有后台进程。和Zookeeper一样,Storm也是快速失败(fail-fast)的系统,这样Storm才能在任意时刻被停止,并且当进程重启后被正确地恢复执行。这也是为什么Storm不在进程内保存状态的原因,即使Nimbus或Supervisors被重启,运行中的Topologies不会受到影响。

以下是启动Storm各个后台进程的方式:

  1. Nimbus: 在Storm主控节点上运行”bin/storm nimbus >/dev/null 2>&1 &”启动Nimbus后台程序,并放到后台执行;
  2. Supervisor: 在Storm各个工作节点上运行”bin/storm supervisor >/dev/null 2>&1 &”启动Supervisor后台程序,并放到后台执行;
  3. UI: 在Storm主控节点上运行”bin/storm ui >/dev/null 2>&1 &”启动UI后台程序,并放到后台执行,启动后可以通过http://{nimbus host}:8080观察集群的worker资源使用情况、Topologies的运行状态等信息。

注意事项:

  1. 启动Storm后台进程时,需要对conf/storm.yaml配置文件中设置的storm.local.dir目录具有写权限。
  2. Storm后台进程被启动后,将在Storm安装部署目录下的logs/子目录下生成各个进程的日志文件。
  3. 经测试,Storm UI必须和Storm Nimbus部署在同一台机器上,否则UI无法正常工作,因为UI进程会检查本机是否存在Nimbus链接。
  4. 为了方便使用,可以将bin/storm加入到系统环境变量中。

至此,Storm集群已经部署、配置完毕,可以向集群提交拓扑运行了。

3.3 向集群提交任务

1. 启动Storm Topology:

storm jar allmycode.jar org.me.MyTopology arg1 arg2 arg3

其中,allmycode.jar是包含Topology实现代码的jar包,org.me.MyTopology的main方法是Topology的入口,arg1、arg2和arg3为org.me.MyTopology执行时需要传入的参数。

2. 停止Storm Topology:

storm kill {toponame}

其中,{toponame}为Topology提交到Storm集群时指定的Topology任务名称。

3.4 参考资料

1. https://github.com/nathanmarz/storm/wiki/Tutorial

2. https://github.com/nathanmarz/storm/wiki/Setting-up-a-Storm-cluster

作者:九翎

]]>
http://linezing.ruoguschool.com/2013/01/how-to-install-and-deploy-storm-cluster/feed 0
Storm入门教程 第二章 构建Topology http://linezing.ruoguschool.com/2013/01/storm%e5%85%a5%e9%97%a8%e6%95%99%e7%a8%8b-%e7%ac%ac%e4%ba%8c%e7%ab%a0-%e6%9e%84%e5%bb%batopology http://linezing.ruoguschool.com/2013/01/storm%e5%85%a5%e9%97%a8%e6%95%99%e7%a8%8b-%e7%ac%ac%e4%ba%8c%e7%ab%a0-%e6%9e%84%e5%bb%batopology#comments Sat, 05 Jan 2013 07:54:24 +0000 muhan.jc http://linezing.ruoguschool.com/?p=1853 2.1 Storm基本概念

在运行一个Storm任务之前,需要了解一些概念:

  1. Topologies
  2. Streams
  3. Spouts
  4. Bolts
  5. Stream groupings
  6. Reliability
  7. Tasks
  8. Workers
  9. Configuration

Storm集群和Hadoop集群表面上看很类似。但是Hadoop上运行的是MapReduce jobs,而在Storm上运行的是拓扑(topology),这两者之间是非常不一样的。一个关键的区别是: 一个MapReduce job最终会结束, 而一个topology永远会运行(除非你手动kill掉)。

在Storm的集群里面有两种节点: 控制节点(master node)和工作节点(worker node)。控制节点上面运行一个叫Nimbus后台程序,它的作用类似Hadoop里面的JobTracker。Nimbus负责在集群里面分发代码,分配计算任务给机器, 并且监控状态。

每一个工作节点上面运行一个叫做Supervisor的节点。Supervisor会监听分配给它那台机器的工作,根据需要启动/关闭工作进程。每一个工作进程执行一个topology的一个子集;一个运行的topology由运行在很多机器上的很多工作进程组成。

Nimbus和Supervisor之间的所有协调工作都是通过Zookeeper集群完成。另外,Nimbus进程和Supervisor进程都是快速失败(fail-fast)和无状态的。所有的状态要么在zookeeper里面, 要么在本地磁盘上。这也就意味着你可以用kill -9来杀死Nimbus和Supervisor进程, 然后再重启它们,就好像什么都没有发生过。这个设计使得Storm异常的稳定。

2.1.1 Topologies

一个topology是spouts和bolts组成的图, 通过stream groupings将图中的spouts和bolts连接起来,如下图:

一个topology会一直运行直到你手动kill掉,Storm自动重新分配执行失败的任务, 并且Storm可以保证你不会有数据丢失(如果开启了高可靠性的话)。如果一些机器意外停机它上面的所有任务会被转移到其他机器上。

运行一个topology很简单。首先,把你所有的代码以及所依赖的jar打进一个jar包。然后运行类似下面的这个命令:

 storm jar all-my-code.jar backtype.storm.MyTopology arg1 arg2

这个命令会运行主类: backtype.strom.MyTopology, 参数是arg1, arg2。这个类的main函数定义这个topology并且把它提交给Nimbus。storm jar负责连接到Nimbus并且上传jar包。

Topology的定义是一个Thrift结构,并且Nimbus就是一个Thrift服务, 你可以提交由任何语言创建的topology。上面的方面是用JVM-based语言提交的最简单的方法。

2.1.2 Streams

消息流stream是storm里的关键抽象。一个消息流是一个没有边界的tuple序列, 而这些tuple序列会以一种分布式的方式并行地创建和处理。通过对stream中tuple序列中每个字段命名来定义stream。在默认的情况下,tuple的字段类型可以是:integer,long,short, byte,string,double,float,boolean和byte array。你也可以自定义类型(只要实现相应的序列化器)。

每个消息流在定义的时候会被分配给一个id,因为单向消息流使用的相当普遍, OutputFieldsDeclarer定义了一些方法让你可以定义一个stream而不用指定这个id。在这种情况下这个stream会分配个值为‘default’默认的id 。

Storm提供的最基本的处理stream的原语是spout和bolt。你可以实现spout和bolt提供的接口来处理你的业务逻辑。

2.1.3  Spouts

消息源spout是Storm里面一个topology里面的消息生产者。一般来说消息源会从一个外部源读取数据并且向topology里面发出消息:tuple。Spout可以是可靠的也可以是不可靠的。如果这个tuple没有被storm成功处理,可靠的消息源spouts可以重新发射一个tuple, 但是不可靠的消息源spouts一旦发出一个tuple就不能重发了。

消息源可以发射多条消息流stream。使用OutputFieldsDeclarer.declareStream来定义多个stream,然后使用SpoutOutputCollector来发射指定的stream。

Spout类里面最重要的方法是nextTuple。要么发射一个新的tuple到topology里面或者简单的返回如果已经没有新的tuple。要注意的是nextTuple方法不能阻塞,因为storm在同一个线程上面调用所有消息源spout的方法。

另外两个比较重要的spout方法是ack和fail。storm在检测到一个tuple被整个topology成功处理的时候调用ack,否则调用fail。storm只对可靠的spout调用ack和fail。

2.1.4  Bolts

所有的消息处理逻辑被封装在bolts里面。Bolts可以做很多事情:过滤,聚合,查询数据库等等。

Bolts可以简单的做消息流的传递。复杂的消息流处理往往需要很多步骤,从而也就需要经过很多bolts。比如算出一堆图片里面被转发最多的图片就至少需要两步:第一步算出每个图片的转发数量。第二步找出转发最多的前10个图片。(如果要把这个过程做得更具有扩展性那么可能需要更多的步骤)。

Bolts可以发射多条消息流, 使用OutputFieldsDeclarer.declareStream定义stream,使用OutputCollector.emit来选择要发射的stream。

Bolts的主要方法是execute, 它以一个tuple作为输入,bolts使用OutputCollector来发射tuple,bolts必须要为它处理的每一个tuple调用OutputCollector的ack方法,以通知Storm这个tuple被处理完成了,从而通知这个tuple的发射者spouts。 一般的流程是: bolts处理一个输入tuple,  发射0个或者多个tuple, 然后调用ack通知storm自己已经处理过这个tuple了。storm提供了一个IBasicBolt会自动调用ack。

2.1.5  Stream groupings

定义一个topology的其中一步是定义每个bolt接收什么样的流作为输入。stream grouping就是用来定义一个stream应该如果分配数据给bolts上面的多个tasks。

Storm里面有7种类型的stream grouping

  1. Shuffle Grouping: 随机分组, 随机派发stream里面的tuple,保证每个bolt接收到的tuple数目大致相同。
  2. Fields Grouping:按字段分组, 比如按userid来分组, 具有同样userid的tuple会被分到相同的Bolts里的一个task, 而不同的userid则会被分配到不同的bolts里的task。
  3. All Grouping:广播发送,对于每一个tuple,所有的bolts都会收到。
  4.  Global Grouping:全局分组, 这个tuple被分配到storm中的一个bolt的其中一个task。再具体一点就是分配给id值最低的那个task。
  5. Non Grouping:不分组,这个分组的意思是说stream不关心到底谁会收到它的tuple。目前这种分组和Shuffle grouping是一样的效果, 有一点不同的是storm会把这个bolt放到这个bolt的订阅者同一个线程里面去执行。
  6. Direct Grouping: 直接分组, 这是一种比较特别的分组方法,用这种分组意味着消息的发送者指定由消息接收者的哪个task处理这个消息。 只有被声明为Direct Stream的消息流可以声明这种分组方法。而且这种消息tuple必须使用emitDirect方法来发射。消息处理者可以通过TopologyContext来获取处理它的消息的task的id (OutputCollector.emit方法也会返回task的id)。
  7. Local or shuffle grouping:如果目标bolt有一个或者多个task在同一个工作进程中,tuple将会被随机发生给这些tasks。否则,和普通的Shuffle Grouping行为一致。

2.1.6  Reliability

Storm保证每个tuple会被topology完整的执行。Storm会追踪由每个spout tuple所产生的tuple树(一个bolt处理一个tuple之后可能会发射别的tuple从而形成树状结构),并且跟踪这棵tuple树什么时候成功处理完。每个topology都有一个消息超时的设置,如果storm在这个超时的时间内检测不到某个tuple树到底有没有执行成功, 那么topology会把这个tuple标记为执行失败,并且过一会儿重新发射这个tuple。

为了利用Storm的可靠性特性,在你发出一个新的tuple以及你完成处理一个tuple的时候你必须要通知storm。这一切是由OutputCollector来完成的。通过emit方法来通知一个新的tuple产生了,通过ack方法通知一个tuple处理完成了。

Storm的可靠性我们在第四章会深入介绍。

2.1.7  Tasks

每一个spout和bolt会被当作很多task在整个集群里执行。每一个executor对应到一个线程,在这个线程上运行多个task,而stream grouping则是定义怎么从一堆task发射tuple到另外一堆task。你可以调用TopologyBuilder类的setSpout和setBolt来设置并行度(也就是有多少个task)。

2.1.8  Workers

一个topology可能会在一个或者多个worker(工作进程)里面执行,每个worker是一个物理JVM并且执行整个topology的一部分。比如,对于并行度是300的topology来说,如果我们使用50个工作进程来执行,那么每个工作进程会处理其中的6个tasks。Storm会尽量均匀的工作分配给所有的worker。

2.1.9 Configuration

Storm里面有一堆参数可以配置来调整Nimbus, Supervisor以及正在运行的topology的行为,一些配置是系统级别的,一些配置是topology级别的。default.yaml里面有所有的默认配置。你可以通过定义个storm.yaml在你的classpath里来覆盖这些默认配置。并且你也可以在代码里面设置一些topology相关的配置信息(使用StormSubmitter)。

2.2  构建Topology

1. 实现的目标:

我们将设计一个topology,来实现对一个句子里面的单词出现的频率进行统计。这是一个简单的例子,目的是让大家对于topology快速上手,有一个初步的理解。

2. 设计Topology结构:

在开始开发Storm项目的第一步,就是要设计topology。确定好你的数据处理逻辑,我们今天将的这个简单的例子,topology也非常简单。整个topology如下:

整个topology分为三个部分:

KestrelSpout:数据源,负责发送sentence

Splitsentence:负责将sentence切分

Wordcount:负责对单词的频率进行累加

3. 设计数据流

这个topology从kestrel queue读取句子,并把句子划分成单词,然后汇总每个单词出现的次数,一个tuple负责读取句子,每一个tuple分别对应计算每一个单词出现的次数,大概样子如下所示:

4. 代码实现:

1) 构建maven环境:

为了开发storm topology, 你需要把storm相关的jar包添加到classpath里面去: 要么手动添加所有相关的jar包, 要么使用maven来管理所有的依赖。storm的jar包发布在Clojars(一个maven库), 如果你使用maven的话,把下面的配置添加在你项目的pom.xml里面。

<repository>

    <id>clojars.org</id>

    <url>http://clojars.org/repo</url>

</repository>

<dependency>

     <groupId>storm</groupId>

    <artifactId>storm</artifactId>

     <version>0.5.3</version>

     <scope>test</scope>

</dependency>

2) 定义topology:

TopologyBuilder builder = new TopologyBuilder();

builder.setSpout(1, new KestrelSpout(“kestrel.backtype.com”,22133,

                                                                                    ”sentence_queue”,

                                                                                    new StringScheme()));

builder.setBolt(2, new SplitSentence(), 10)

       .shuffleGrouping(1);

builder.setBolt(3, new WordCount(), 20)

       .fieldsGrouping(2, new Fields(“word”));

这种topology的spout从句子队列中读取句子,在kestrel.backtype.com位于一个Kestrel的服务器端口22133。

Spout用setSpout方法插入一个独特的id到topology。 Topology中的每个节点必须给予一个id,id是由其他bolts用于订阅该节点的输出流。 KestrelSpout在topology中id为1。

setBolt是用于在Topology中插入bolts。 在topology中定义的第个bolts 是切割句子的bolts。 这个bolts 将句子流转成成单词流。

让我们看看SplitSentence实施:

public class SplitSentence implements IBasicBolt{

        public void prepare(Map conf, TopologyContext context) {

         }

       public void execute(Tuple tuple, BasicOutputCollector collector) {

              String sentence = tuple.getString(0);

               for(String word: sentence.split(“ ”)) {

                        collector.emit(new Values(word));

                  }

             }

         public void cleanup() {

        }

        public void declareOutputFields(OutputFieldsDeclarer declarer) {

                declarer.declare(new Fields(“word”));

             }

 }

关键的方法 execute方法。 正如你可以看到,它将句子拆分成单词,并发出每个单词作为一个新的元组。 另一个重要的方法是declareOutputFields其中宣布bolts输出元组的架构。 在这里宣布,它发出一个域为word的元组

setBolt的最后一个参数是你想为bolts的并行量。 SplitSentence bolts 是10个并发,这将导致在storm集群中有十个线程并行执行。 你所要做的的是增加bolts的并行量在遇到topology的瓶颈时。

 setBolt方法返回一个对象,用来定义bolts的输入。 例如SplitSentence螺栓订阅组件“1”使用随机分组的输出流。 “1”是指已经定义KestrelSpout 我将解释在某一时刻的随机分组的一部分。 到目前为止,最要紧的是SplitSentence bolts会消耗KestrelSpout发出的每一个元组。

下面在让我们看看wordcount的实现:

public class WordCount implements IBasicBolt {

        private Map<String, Integer> _counts = new HashMap<String, Integer>();

        public void prepare(Map conf, TopologyContext context) {

        }

       public void execute(Tuple tuple, BasicOutputCollector collector) {

              String word = tuple.getString(0);

              int count;

              if(_counts.containsKey(word)) {

                     count = _counts.get(word);

              } else {

                     count = 0;

}

              count++;

              _counts.put(word, count);

              collector.emit(new Values(word, count));

       }

       public void cleanup() {

       }

       public void declareOutputFields(OutputFieldsDeclarer declarer) {

              declarer.declare(new Fields(“word”, “count”));

       }

}

SplitSentence对于句子里面的每个单词发射一个新的tuple, WordCount在内存里面维护一个单词->次数的mapping, WordCount每收到一个单词, 它就更新内存里面的统计状态。

5. 运行Topology

storm的运行有两种模式: 本地模式和分布式模式.

1) 本地模式:

storm用一个进程里面的线程来模拟所有的spout和bolt. 本地模式对开发和测试来说比较有用。 你运行storm-starter里面的topology的时候它们就是以本地模式运行的, 你可以看到topology里面的每一个组件在发射什么消息。

2) 分布式模式:

storm由一堆机器组成。当你提交topology给master的时候, 你同时也把topology的代码提交了。master负责分发你的代码并且负责给你的topolgoy分配工作进程。如果一个工作进程挂掉了, master节点会把认为重新分配到其它节点。

3) 下面是以本地模式运行的代码:

         Config conf = new Config();

         conf.setDebug(true);

         conf.setNumWorkers(2);

         LocalCluster cluster = new LocalCluster();

         cluster.submitTopology(“test”, conf, builder.createTopology());

          Utils.sleep(10000);

          cluster.killTopology(“test”);

          cluster.shutdown();

首先, 这个代码定义通过定义一个LocalCluster对象来定义一个进程内的集群。提交topology给这个虚拟的集群和提交topology给分布式集群是一样的。通过调用submitTopology方法来提交topology, 它接受三个参数:要运行的topology的名字,一个配置对象以及要运行的topology本身。

topology的名字是用来唯一区别一个topology的,这样你然后可以用这个名字来杀死这个topology的。前面已经说过了, 你必须显式的杀掉一个topology, 否则它会一直运行。

Conf对象可以配置很多东西, 下面两个是最常见的:

 TOPOLOGY_WORKERS(setNumWorkers) 定义你希望集群分配多少个工作进程给你来执行这个topology. topology里面的每个组件会被需要线程来执行。每个组件到底用多少个线程是通过setBolt和setSpout来指定的。这些线程都运行在工作进程里面. 每一个工作进程包含一些节点的一些工作线程。比如, 如果你指定300个线程,60个进程, 那么每个工作进程里面要执行6个线程, 而这6个线程可能属于不同的组件(Spout, Bolt)。你可以通过调整每个组件的并行度以及这些线程所在的进程数量来调整topology的性能。

 TOPOLOGY_DEBUG(setDebug), 当它被设置成true的话, storm会记录下每个组件所发射的每条消息。这在本地环境调试topology很有用, 但是在线上这么做的话会影响性能的。

结论:

本章从storm的基本对象的定义,到广泛的介绍了storm的开发环境,从一个简单的例子讲解了topology的构建和定义。希望大家可以从本章的内容对storm有一个基本的理解和概念,并且已经可以构建一个简单的topology!!

作者:毅山,宋智

]]>
http://linezing.ruoguschool.com/2013/01/storm%e5%85%a5%e9%97%a8%e6%95%99%e7%a8%8b-%e7%ac%ac%e4%ba%8c%e7%ab%a0-%e6%9e%84%e5%bb%batopology/feed 0
storm入门教程 第一章 前言 http://linezing.ruoguschool.com/2012/12/storm%e5%85%a5%e9%97%a8%e6%95%99%e7%a8%8b-%e7%ac%ac%e4%b8%80%e7%ab%a0-%e5%89%8d%e8%a8%80 http://linezing.ruoguschool.com/2012/12/storm%e5%85%a5%e9%97%a8%e6%95%99%e7%a8%8b-%e7%ac%ac%e4%b8%80%e7%ab%a0-%e5%89%8d%e8%a8%80#comments Thu, 27 Dec 2012 05:45:55 +0000 muhan.jc http://linezing.ruoguschool.com/?p=1847 1.1   实时流计算

互联网从诞生的第一时间起,对世界的最大的改变就是让信息能够实时交互,从而大大加速了各个环节的效率。正因为大家对信息实时响应、实时交互的需求,软件行业除了个人操作系统之外,数据库(更精确的说是关系型数据库)应该是软件行业发展最快、收益最为丰厚的产品了。记得十年前,很多银行别说实时转账,连实时查询都做不到,但是数据库和高速网络改变了这个情况。

随着互联网的更进一步发展,从Portal信息浏览型到Search信息搜索型到SNS关系交互传递型,以及电子商务、互联网旅游生活产品等将生活中的流通环节在线化。对效率的要求让大家对于实时性的要求进一步提升,而信息的交互和沟通正在从点对点往信息链甚至信息网的方向发展,这样必然带来数据在各个维度的交叉关联,数据爆炸已不可避免。因此流式处理加NoSQL产品应运而生,分别解决实时框架和数据大规模存储计算的问题。

早在7、8年前诸如UC伯克利、斯坦福等大学就开始了对流式数据处理的研究,但是由于更多的关注于金融行业的业务场景或者互联网流量监控的业务场景,以及当时互联网数据场景的限制,造成了研究多是基于对传统数据库处理的流式化,对流式框架本身的研究偏少。目前这样的研究逐渐没有了声音,工业界更多的精力转向了实时数据库。

2010年Yahoo!对S4的开源,2011年twitter对Storm的开源,改变了这个情况。以前互联网的开发人员在做一个实时应用的时候,除了要关注应用逻辑计算处理本身,还要为了数据的实时流转、交互、分布大伤脑筋。但是现在情况却大为不同,以Storm为例,开发人员可以快速的搭建一套健壮、易用的实时流处理框架,配合SQL产品或者NoSQL产品或者MapReduce计算平台,就可以低成本的做出很多以前很难想象的实时产品:比如一淘数据部的量子恒道品牌旗下的多个产品就是构建在实时流处理平台上的。

本教程是一本对storm的基础介绍手册,但是我们也希望它不仅仅是一本storm的使用手册,我们会在其中加入更多我们在实际数据生产过程的经验和应用的架构,最后的目的是帮助所有愿意使用实时流处理框架的技术同仁,同时也默默的改变这个世界。

1.2   Storm特点

Storm是一个开源的分布式实时计算系统,可以简单、可靠的处理大量的数据流。Storm有很多使用场景:如实时分析,在线机器学习,持续计算,分布式RPC,ETL等等。Storm支持水平扩展,具有高容错性,保证每个消息都会得到处理,而且处理速度很快(在一个小集群中,每个结点每秒可以处理数以百万计的消息)。Storm的部署和运维都很便捷,而且更为重要的是可以使用任意编程语言来开发应用。

Storm有如下特点:

  • 编程模型简单

在大数据处理方面相信大家对hadoop已经耳熟能详,基于Google Map/Reduce来实现的Hadoop为开发者提供了map、reduce原语,使并行批处理程序变得非常地简单和优美。同样,Storm也为大数据的实时计算提供了一些简单优美的原语,这大大降低了开发并行实时处理的任务的复杂性,帮助你快速、高效的开发应用。

  • 可扩展

在Storm集群中真正运行topology的主要有三个实体:工作进程、线程和任务。Storm集群中的每台机器上都可以运行多个工作进程,每个工作进程又可创建多个线程,每个线程可以执行多个任务,任务是真正进行数据处理的实体,我们开发的spout、bolt就是作为一个或者多个任务的方式执行的。

因此,计算任务在多个线程、进程和服务器之间并行进行,支持灵活的水平扩展。

  • 高可靠性

Storm可以保证spout发出的每条消息都能被“完全处理”,这也是直接区别于其他实时系统的地方,如S4。

请注意,spout发出的消息后续可能会触发产生成千上万条消息,可以形象的理解为一棵消息树,其中spout发出的消息为树根,Storm会跟踪这棵消息树的处理情况,只有当这棵消息树中的所有消息都被处理了,Storm才会认为spout发出的这个消息已经被“完全处理”。如果这棵消息树中的任何一个消息处理失败了,或者整棵消息树在限定的时间内没有“完全处理”,那么spout发出的消息就会重发。

考虑到尽可能减少对内存的消耗,Storm并不会跟踪消息树中的每个消息,而是采用了一些特殊的策略,它把消息树当作一个整体来跟踪,对消息树中所有消息的唯一id进行异或计算,通过是否为零来判定spout发出的消息是否被“完全处理”,这极大的节约了内存和简化了判定逻辑,后面会对这种机制进行详细介绍。

这种模式,每发送一个消息,都会同步发送一个ack/fail,对于网络的带宽会有一定的消耗,如果对于可靠性要求不高,可通过使用不同的emit接口关闭该模式。

上面所说的,Storm保证了每个消息至少被处理一次,但是对于有些计算场合,会严格要求每个消息只被处理一次,幸而Storm的0.7.0引入了事务性拓扑,解决了这个问题,后面会有详述。

  •  高容错性

如果在消息处理过程中出了一些异常,Storm会重新安排这个出问题的处理单元。Storm保证一个处理单元永远运行(除非你显式杀掉这个处理单元)。

当然,如果处理单元中存储了中间状态,那么当处理单元重新被Storm启动的时候,需要应用自己处理中间状态的恢复。

  • 支持多种编程语言

除了用java实现spout和bolt,你还可以使用任何你熟悉的编程语言来完成这项工作,这一切得益于Storm所谓的多语言协议。多语言协议是Storm内部的一种特殊协议,允许spout或者bolt使用标准输入和标准输出来进行消息传递,传递的消息为单行文本或者是json编码的多行。

Storm支持多语言编程主要是通过ShellBolt, ShellSpout和ShellProcess这些类来实现的,这些类都实现了IBolt 和 ISpout接口,以及让shell通过java的ProcessBuilder类来执行脚本或者程序的协议。

可以看到,采用这种方式,每个tuple在处理的时候都需要进行json的编解码,因此在吞吐量上会有较大影响。

  • 支持本地模式

Storm有一种“本地模式”,也就是在进程中模拟一个Storm集群的所有功能,以本地模式运行topology跟在集群上运行topology类似,这对于我们开发和测试来说非常有用。

  • 高效

用ZeroMQ作为底层消息队列, 保证消息能快速被处理

作者:张中,澄苍

]]>
http://linezing.ruoguschool.com/2012/12/storm%e5%85%a5%e9%97%a8%e6%95%99%e7%a8%8b-%e7%ac%ac%e4%b8%80%e7%ab%a0-%e5%89%8d%e8%a8%80/feed 0
一淘数据部-Linux上进程的表示以及入门 http://linezing.ruoguschool.com/2012/12/%e4%b8%80%e6%b7%98%e6%95%b0%e6%8d%ae%e9%83%a8-linux%e4%b8%8a%e8%bf%9b%e7%a8%8b%e7%9a%84%e8%a1%a8%e7%a4%ba%e4%bb%a5%e5%8f%8a%e5%85%a5%e9%97%a8 http://linezing.ruoguschool.com/2012/12/%e4%b8%80%e6%b7%98%e6%95%b0%e6%8d%ae%e9%83%a8-linux%e4%b8%8a%e8%bf%9b%e7%a8%8b%e7%9a%84%e8%a1%a8%e7%a4%ba%e4%bb%a5%e5%8f%8a%e5%85%a5%e9%97%a8#comments Wed, 26 Dec 2012 03:38:04 +0000 gang.yug http://linezing.ruoguschool.com/?p=1841 本博客会陆续更新一淘数据部 各位技术同学分享的资料。
本次分享的内容来自太奇同学:
受众:
对Linux系统感兴趣的同学。
简介:

1.理解linux系统上进程的原理以及实现
2. 信号处理简述
3. 了解内存管理初步知识
4. 打开通向linux内核的大门

文件下载:linux进程的表示及入门-PDF文件

]]>
http://linezing.ruoguschool.com/2012/12/%e4%b8%80%e6%b7%98%e6%95%b0%e6%8d%ae%e9%83%a8-linux%e4%b8%8a%e8%bf%9b%e7%a8%8b%e7%9a%84%e8%a1%a8%e7%a4%ba%e4%bb%a5%e5%8f%8a%e5%85%a5%e9%97%a8/feed 0
一淘数据部-基数估计的概率算法 http://linezing.ruoguschool.com/2012/12/%e4%b8%80%e6%b7%98%e6%95%b0%e6%8d%ae%e9%83%a8-%e5%9f%ba%e6%95%b0%e4%bc%b0%e8%ae%a1%e7%9a%84%e6%a6%82%e7%8e%87%e7%ae%97%e6%b3%95 http://linezing.ruoguschool.com/2012/12/%e4%b8%80%e6%b7%98%e6%95%b0%e6%8d%ae%e9%83%a8-%e5%9f%ba%e6%95%b0%e4%bc%b0%e8%ae%a1%e7%9a%84%e6%a6%82%e7%8e%87%e7%ae%97%e6%b3%95#comments Wed, 26 Dec 2012 03:35:26 +0000 gang.yug http://linezing.ruoguschool.com/?p=1837 本博客会陆续更新一淘数据部 各位技术同学分享的资料。
本次分享的内容来自夜沨同学:
受众:
对基数 概率算法感兴趣的同学。
简介:
内容:
1、基数的概念、应用、传统计算方式极其局限;

2、三种计算基数的概率算法、相关数理分析、比较及实现重点

文件下载:基数估计的概率算法及uv计算中的应用-PDF文件

]]>
http://linezing.ruoguschool.com/2012/12/%e4%b8%80%e6%b7%98%e6%95%b0%e6%8d%ae%e9%83%a8-%e5%9f%ba%e6%95%b0%e4%bc%b0%e8%ae%a1%e7%9a%84%e6%a6%82%e7%8e%87%e7%ae%97%e6%b3%95/feed 0
一淘数据部-月光宝盒双11 HBase集群应用和优化经验 http://linezing.ruoguschool.com/2012/12/%e4%b8%80%e6%b7%98%e6%95%b0%e6%8d%ae%e9%83%a8-%e6%9c%88%e5%85%89%e5%ae%9d%e7%9b%92%e5%8f%8c11-hbase%e9%9b%86%e7%be%a4%e5%ba%94%e7%94%a8%e5%92%8c%e4%bc%98%e5%8c%96%e7%bb%8f%e9%aa%8c http://linezing.ruoguschool.com/2012/12/%e4%b8%80%e6%b7%98%e6%95%b0%e6%8d%ae%e9%83%a8-%e6%9c%88%e5%85%89%e5%ae%9d%e7%9b%92%e5%8f%8c11-hbase%e9%9b%86%e7%be%a4%e5%ba%94%e7%94%a8%e5%92%8c%e4%bc%98%e5%8c%96%e7%bb%8f%e9%aa%8c#comments Tue, 25 Dec 2012 09:45:59 +0000 gang.yug http://linezing.ruoguschool.com/?p=1828 本博客会陆续更新一淘数据部 各位技术同学分享的资料。
本次分享的内容来自九翎同学:
受众:
对HBase集群应用感兴趣的同学。
简介:
培训内容:
月光宝盒项目为了满足双11当天天猫所有会场坑位效果计算的需求,尝试对HBase集群进行了一系列的应用和优化,顺利支撑双11当天各个流量峰值时刻的读写压力。本次是对这些经验的总结与分享,和大家探讨交流HBase在高并发读写应用场景下的实践方法。
内容大纲:
1). 月光宝盒项目简介
2). HBase集群双11相关工作
3). 月光宝盒双11优化工作
4). 总结的话
5). Q&A

文件下载:月光宝盒双11 HBase集群应用和优化经验-PDF文件

]]>
http://linezing.ruoguschool.com/2012/12/%e4%b8%80%e6%b7%98%e6%95%b0%e6%8d%ae%e9%83%a8-%e6%9c%88%e5%85%89%e5%ae%9d%e7%9b%92%e5%8f%8c11-hbase%e9%9b%86%e7%be%a4%e5%ba%94%e7%94%a8%e5%92%8c%e4%bc%98%e5%8c%96%e7%bb%8f%e9%aa%8c/feed 0
基于storm引擎的虫洞系统 http://linezing.ruoguschool.com/2012/12/%e5%9f%ba%e4%ba%8estorm%e5%bc%95%e6%93%8e%e7%9a%84%e8%99%ab%e6%b4%9e%e7%b3%bb%e7%bb%9f http://linezing.ruoguschool.com/2012/12/%e5%9f%ba%e4%ba%8estorm%e5%bc%95%e6%93%8e%e7%9a%84%e8%99%ab%e6%b4%9e%e7%b3%bb%e7%bb%9f#comments Thu, 20 Dec 2012 01:42:50 +0000 taiqi.zyl http://linezing.ruoguschool.com/?p=1813 虫洞系统是吸星大法项目衍生出来实时计算的基础平台。

它以storm实时流处理引擎为基础,提供了计算力、数据源整合、数据交换、监控几大功能模块。任务的权限控制正在筹划中。

这几个功能模块是此实时计算平台提供稳定运行的基础,虫洞系统承载的业务包括:月光宝盒、一淘首页个性化(实时用户个性化指标的计算)、吸星大法实时日志接入(数据源整合)。
  • 计算能力
    基于storm的流式处理任务可以直接运行在虫洞系统上,避免了搭建、维护集群的成本,极大的节约了业务的成本、提高了开发的效率和系统的稳定性
  • 数据源整合
    目前虫洞系统整合了多个实时数据源,这些数据源组合起来,可以实现完整的业务分析。 吸星大法实时数据接入将数据源接入、归一化,为使用方提供格式一致的数据,简化了日志使用的成本和难度。目前接入的主要数据源有:
            – 全网Aplus日志
            – 订单
            – 支付宝交易
            – 站外B2C
            – 实时购物车、收藏夹等
  •   数据交换
    基础日志经过归一化之后,根据业务场景需求,可以有两种方式来使用:
                     1) Hbase, 如果需要回溯历史数据,可以使用Hbase接口来访问
                     2)虫洞(动态端口), 高效、便捷的数据交换形式,支持日志的横向和纵向任意裁剪,支持客户端的动态负载均衡;高容错性等很多特性
             上述两种方式都提供了客户端sdk供使用
  • 监控系统
    监控系统是虫洞系统稳定运行的基础。它有两个主要功能: 1) storm task级状态的汇总 2)异常状态的报警,目前支持短信、旺旺报警
storm task级监控室为storm量身定做的监控系统,使得集群中不同机器间的状态统一监控,监控指标丰富、并且可自定义,是任务开发、调试、运维的利器。
]]>
http://linezing.ruoguschool.com/2012/12/%e5%9f%ba%e4%ba%8estorm%e5%bc%95%e6%93%8e%e7%9a%84%e8%99%ab%e6%b4%9e%e7%b3%bb%e7%bb%9f/feed 0