首页 文章 精选 留言 我的

精选列表

搜索[增量模型],共10002篇文章
优秀的个人博客,低调大师

Mysql 流增量写入 Hdfs(二) --Storm + hdfs 的流式处理

一. 概述 上一篇我们介绍了如何将数据从 mysql 抛到 kafka,这次我们就专注于利用 storm 将数据写入到 hdfs 的过程,由于 storm 写入 hdfs 的可定制东西有些多,我们先不从 kafka 读取,而先自己定义一个 Spout 数据充当数据源,下章再进行整合。这里默认你是拥有一定的 storm 知识的基础,起码知道 Spout 和 bolt 是什么。 写入 hdfs 可以有以下的定制策略: 自定义写入文件的名字 定义写入内容格式 满足给定条件后更改写入的文件 更改写入文件时触发的 Action 本篇会先说明如何用 storm 写入 HDFS,写入过程一些 API 的描述,以及最后给定一个例子: storm 每接收到 10 个 Tuple 后就会改变 hdfs 写入文件,新文件的名字就是第几次改变。 ps:storm 版本:1.1.1 。Hadoop 版本:2.7.4 。 接下来我们首先看看 Storm 如何写入 HDFS 。 二. Storm 写入 HDFS Storm 官方有提供了相应的 API 让我们可以使用。可以通过创建 HdfsBolt 以及定义相应的规则,即可写入 HDFS 。 首先通过 maven 配置依赖以及插件。 <properties> <storm.version>1.1.1</storm.version> </properties> <dependencies> <dependency> <groupId>org.apache.storm</groupId> <artifactId>storm-core</artifactId> <version>${storm.version}</version> <!--<scope>provided</scope>--> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>15.0</version> </dependency> <!--hadoop模块--> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>2.7.4</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>2.7.4</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.storm/storm-hdfs --> <dependency> <groupId>org.apache.storm</groupId> <artifactId>storm-hdfs</artifactId> <version>1.1.1</version> <!--<scope>test</scope>--> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <goals> <goal>exec</goal> </goals> </execution> </executions> <configuration> <executable>java</executable> <includeProjectDependencies>true</includeProjectDependencies> <includePluginDependencies>false</includePluginDependencies> <classpathScope>compile</classpathScope> <mainClass>com.learningstorm.kafka.KafkaTopology</mainClass> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>1.7</version> <configuration> <createDependencyReducedPom>true</createDependencyReducedPom> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass></mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> 这里要提一下,如果要打包部署到集群上的话,打包的插件需要使用 maven-shade-plugin 这个插件,然后使用 maven Lifecycle 中的 package 打包。而不是用 Maven-assembly-plugin 插件进行打包。 因为使用 Maven-assembly-plugin 的时候,会将所有依赖的包unpack,然后在pack,这样就会出现,同样的文件被覆盖的情况。发布到集群上的时候就会报 No FileSystem for scheme: hdfs 的错 。 然后是使用 HdfsBolt 写入 Hdfs。这里来看看官方文档中的例子吧。 // 使用 "|" 来替代 ",",来进行字符分割 RecordFormat format = new DelimitedRecordFormat() .withFieldDelimiter("|"); // 每输入 1k 后将内容同步到 Hdfs 中 SyncPolicy syncPolicy = new CountSyncPolicy(1000); // 当文件大小达到 5MB ,转换写入文件,即写入到一个新的文件中 FileRotationPolicy rotationPolicy = new FileSizeRotationPolicy(5.0f, Units.MB); //当转换写入文件时,生成新文件的名字并使用 FileNameFormat fileNameFormat = new DefaultFileNameFormat() .withPath("/foo/"); HdfsBolt bolt = new HdfsBolt() .withFsUrl("hdfs://localhost:9000") .withFileNameFormat(fileNameFormat) .withRecordFormat(format) .withRotationPolicy(rotationPolicy) .withSyncPolicy(syncPolicy); //生成该 bolt topologyBuilder.setBolt("hdfsBolt", bolt, 5).globalGrouping("randomStrSpout"); 到这里就结束了。可以将 HdfsBolt 当作一个 Storm 中特殊一些的 bolt 即可。这个 bolt 的作用即使根据接收信息写入 Hdfs。 而在新建 HdfsBolt 中,Storm 为我们提供了相当强的灵活性,我们可以定义一些策略,比如当达成某个条件的时候转换写入文件,新写入文件的名字,写入时候的分隔符等等。 如果选择使用的话,Storm 有提供部分接口供我们使用,但如果我们觉得不够丰富也可以自定义相应的类。下面我们看看如何控制这些策略吧。 RecordFormat 这是一个接口,允许你自由定义接收到内容的格式。 public interface RecordFormat extends Serializable { byte[] format(Tuple tuple); } Storm 提供了 DelimitedRecordFormat ,使用方法在上面已经有了。这个类默认的分割符是逗号",",而你可以通过 withFieldDelimiter 方法改变分隔符。如果你的初始分隔符不是逗号的话,那么也可以重写写一个类实现 RecordFormat 接口即可。 FileNameFormat 同样是一个接口。 public interface FileNameFormat extends Serializable { void prepare(Map conf, TopologyContext topologyContext); String getName(long rotation, long timeStamp); String getPath(); } Storm 所提供的默认的是 org.apache.storm.hdfs.format.DefaultFileNameFormat 。默认人使用的转换文件名有点长,格式是这样的: {prefix}{componentId}-{taskId}-{rotationNum}-{timestamp}{extension} 例如: MyBolt-5-7-1390579837830.txt 默认情况下,前缀是空的,扩展标识是".txt"。 SyncPolicy 同步策略允许你将 buffered data 缓冲到 Hdfs 文件中(从而client可以读取数据),通过实现org.apache.storm.hdfs.sync.SyncPolicy 接口: public interface SyncPolicy extends Serializable { boolean mark(Tuple tuple, long offset); void reset(); } FileRotationPolicy 这个接口允许你控制什么情况下转换写入文件。 public interface FileRotationPolicy extends Serializable { boolean mark(Tuple tuple, long offset); void reset(); } Storm 有提供三个实现该接口的类: 最简单的就是不进行转换的org.apache.storm.hdfs.bolt.rotation.NoRotationPolicy ,就是什么也不干。 通过文件大小触发转换的 org.apache.storm.hdfs.bolt.rotation.FileSizeRotationPolicy。 通过时间条件来触发转换的 org.apache.storm.hdfs.bolt.rotation.TimedRotationPolicy。 如果有更加复杂的需求也可以自己定义。 RotationAction 这个主要是提供一个或多个 hook ,可加可不加。主要是在触发写入文件转换的时候会启动。 public interface RotationAction extends Serializable { void execute(FileSystem fileSystem, Path filePath) throws IOException; } 三.实现一个例子 了解了上面的情况后,我们会实现一个例子,根据写入记录的多少来控制写入转换(改变写入的文件),并且转换后文件的名字表示当前是第几次转换。 首先来看看 HdfsBolt 的内容: RecordFormat format = new DelimitedRecordFormat().withFieldDelimiter(" "); // sync the filesystem after every 1k tuples SyncPolicy syncPolicy = new CountSyncPolicy(1000); // FileRotationPolicy rotationPolicy = new FileSizeRotationPolicy(1.0f, FileSizeRotationPolicy.Units.KB); /** rotate file with Date,every month create a new file * format:yyyymm.txt */ FileRotationPolicy rotationPolicy = new CountStrRotationPolicy(); FileNameFormat fileNameFormat = new TimesFileNameFormat().withPath("/test/"); RotationAction action = new NewFileAction(); HdfsBolt bolt = new HdfsBolt() .withFsUrl("hdfs://127.0.0.1:9000") .withFileNameFormat(fileNameFormat) .withRecordFormat(format) .withRotationPolicy(rotationPolicy) .withSyncPolicy(syncPolicy) .addRotationAction(action); 然后分别来看各个策略的类。 FileRotationPolicy import org.apache.storm.hdfs.bolt.rotation.FileRotationPolicy; import org.apache.storm.tuple.Tuple; import java.text.SimpleDateFormat; import java.util.Date; /** * 计数以改变Hdfs写入文件的位置,当写入10次的时候,则更改写入文件,更改名字取决于 “TimesFileNameFormat” * 这个类是线程安全 */ public class CountStrRotationPolicy implements FileRotationPolicy { private SimpleDateFormat df = new SimpleDateFormat("yyyyMM"); private String date = null; private int count = 0; public CountStrRotationPolicy(){ this.date = df.format(new Date()); // this.date = df.format(new Date()); } /** * Called for every tuple the HdfsBolt executes. * * @param tuple The tuple executed. * @param offset current offset of file being written * @return true if a file rotation should be performed */ @Override public boolean mark(Tuple tuple, long offset) { count ++; if(count == 10) { System.out.print("num :" +count + " "); count = 0; return true; } else { return false; } } /** * Called after the HdfsBolt rotates a file. */ @Override public void reset() { } @Override public FileRotationPolicy copy() { return new CountStrRotationPolicy(); } } FileNameFormat import org.apache.storm.hdfs.bolt.format.FileNameFormat; import org.apache.storm.task.TopologyContext; import java.util.Map; /** * 决定重新写入文件时候的名字 * 这里会返回是第几次转换写入文件,将这个第几次做为文件名 */ public class TimesFileNameFormat implements FileNameFormat { //默认路径 private String path = "/storm"; //默认后缀 private String extension = ".txt"; private Long times = new Long(0); public TimesFileNameFormat withPath(String path){ this.path = path; return this; } @Override public void prepare(Map conf, TopologyContext topologyContext) { } @Override public String getName(long rotation, long timeStamp) { times ++ ; //返回文件名,文件名为更换写入文件次数 return times.toString() + this.extension; } public String getPath(){ return this.path; } } RotationAction import org.apache.hadoop.fs.FileContext; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.storm.hdfs.common.rotation.RotationAction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.URI; /** 当转换写入文件时候调用的 hook ,这里仅写入日志。 */ public class NewFileAction implements RotationAction { private static final Logger LOG = LoggerFactory.getLogger(NewFileAction.class); @Override public void execute(FileSystem fileSystem, Path filePath) throws IOException { LOG.info("Hdfs change the written file!!"); return; } } OK,这样就大功告成了。通过上面的代码,每接收到 10 个 Tuple 后就会转换写入文件,新文件的名字就是第几次转换。 完整代码包括一个随机生成字符串的 Spout ,可以到我的 github 上查看。 StormHdfsDemo:https://github.com/shezhiming/StormHdfsDemo 更多干货,欢迎关注公众号,哈尔的数据城堡。

优秀的个人博客,低调大师

Greenplum数据增量导入的唯一值自增处理

阿里云的Greenplum(以下简称GP)已经公测了一段时间,陆续接到很多用户的反馈。其中一些使用上的问题比较有趣,在这里与大家分享一下。 其中一个case是字段的唯一键和自增值问题。在导入GP之前,某id字段已经保证了唯一性,但在此次导入之后,可能会有更多的导入,这个时候希望GP在原来最大id值的基础上自增。 GP是在PostgreSQL(以下简称PG)上开发而来,其操作基本沿用。在PG上,实现自增的方法是通过serial: postgres=> create table tuniq(id serial, name text); CREATE TABLE postgres=> insert into tuniq (name) values('zero'); INSERT 0 1 postgres=> insert i

优秀的个人博客,低调大师

新应用成常态增量 企业如何驾驭数字化转型

“我们的一家客户,在做一个项目时,其应用数量在短短一个月内从100个增加到300个,而这种程度的增幅已经是常态。”Dynatrace大中华区总经理琚伟表示,应用已经成为企业的门户和入口,并且呈现井喷式的发展,而企业势必要解决IT生产和运维环境的日益复杂化与业务灵活性之间的平衡难题。 事实上,数字化已经融入到人们生活中的方方面面,企业数字化转型的迫切感更重,企业更关心的是怎样才能将企业的服务和产品更快速地推向市场。“在和企业管理者接触中,感触最深的一点就是互联网+和数字化转型已经成为企业关注的高频词,CIO们也将数字化转型作为其重要的工作。”琚伟如是说。 企业转型需求和困难具突出 琚伟认为,消费者在消费过程中,第一步接触的并不是企业生产销售的产品,而是运营这些产品的App。应用已经成为企业非常重要的入口,因此企业如果没有将入口管理好,就很难去迎接接下来的挑战,这点是企业进行数字化转型过程中的核心之一。 甚至在一些行业中,产品服务所具备的IT属性越来越强。花旗银行CTO就曾经说过,花旗银行是一家有银行牌照的IT公司。 不过,一个很明显的问题是,从前企业旧有的软件开发、测试、上线的研发流程下,应用的推出很难满足市场对新应用迭代更新速度的需要。在这种需求下,很多企业都开始在传统IT运维的基础上,在新的架构上引入了诸如微服务、容器等技术手段,来保证新业务的运维。 2014年,Gartner提出双模式IT的理论,意指在互联网+时代,依托互联网架构的新应用不断出现,应用开发迭代周期不断缩短,从数月到数天。在这样的需求背景下,传统的IT模式已经不能满足企业新业务的发展需要了,除了保障传统IT系统的稳定运行,企业还要解决IT生产和运维环境的日益复杂化以及业务灵活性、自主创新和数字生态系统的建设难题。 Gartner认为在双模式IT架构下,企业一方面要不断提升IT系统运维效率,提高应用性能表现,进而提高用户体验和转化率,另一方面又要提高企业应用开发和交付的能力,打造数字生态系统,使IT成为提升企业创新力和敏捷性的驱动力。如何做,是个难题!云智数齐发力 Dynatrace打造全层级自动化监测 调查发现,很多企业在APM上的投资决策已经超越了传统的 IT 运维范畴,这一趋势反应出在企业业务优先级上,客户体验已经是驱动企业自上向下决策的重要标准。 数字化经济环境下,应用已经变得极其错综复杂,只有那些能将盘根错节的真实互动转变为数字化互动的企业才能提供出色的客户体验。此外,各种容器、微服务及云计算迅速投入使用形成了异常复杂的性能环境,这种向数字化快速迁移促使传统应用性能管理向数字化性能管理的转变。 琚伟认为,企业不可能通过一己之力将这些工作全部完成,企业需要找到合适的合作伙伴,帮助梳理这种动态的业务逻辑,收集动态的用户体验,然后据此帮助业务部门梳理流程、制定新的策略。 据了解,早在四、五年前,Dynatrace 就看到整个行业即将面临巨大的挑战,并不断深化、拓展自身软件的监测能力。如今, APM 不仅要涵盖全方位的客户体验数据,还要延伸到微服务及物联网环境的管理。同时,Dynatrace实现了采用人工智能技术的全层级自动化监测手段。 通过部署Dynatrace 数字化业务管理平台,企业可在业务系统的各个阶段掌握到完整的应用性能表现。诸如在新业务系统上线之前,IT部门可进行高峰期的压力测试,用户行为模拟,通过主动监控的形式快速采集业务信息,并根据模拟到的用户习惯对业务系统做出实时的调整,为企业提供更好的用户体验打下坚实基础,确保新业务成功上线。 此外,琚伟还表示,云计算、大数据、人工智能是三个必然的发展方向。作为主动迎接未来挑战重要一步,Dynatrace还在过去12个月里与多家领先云提供商 AWS、Azure、Pivotal 及 OpenShift达成战略合作,并且是第一家,也是唯一一家向OpenStack提供支持的APM厂商。 而基于Dynatrace结合大数据分析的人工智能功能,客户可在日常的主动监测与被动监测中不断积累用户体验的相关数据,从而逐渐了解用户使用习惯,实现数字化的业务管理与客户体验管理,在提升服务质量的同时还大大提高了IT管理对业务所带来的巨大价值。 去年七月,Gartner在其《市场份额分析:2015 年度全球性能监测》报告中将 Dynatrace 评为第一名。琚伟表示:“很高兴看到近几年来Dynatrace在大中华区市场获得了连年的高速业绩增长,其增长速度超过全球平均水平。2016年,Dynatrace在蓬勃发展的大中华区市场持续深耕,以不断创新的行业技术与深刻洞察力帮助中国多领域的行业客户构建自上而下的数字化战略,布局成功的数字化业务。这一年,Dynatrace同时立足于数字化转型的前景与未来发展趋势,继续深化了自身在技术研发创新上的投入,来更好地帮助客户更好地应对数字化挑战与变革,实现更深层次的业务系统管理。凭借覆盖服务器端、用户端、网络层的全链路解决方案和全球研发创新的深厚资源,Dynatrace将继续助力银行、保险、电商、电信、物流、航空、制造等领域的客户,在新的发展阶段借助Dynatrace所提供的完善的数字化性能管理解决方案,成功迈向数字化未来。” 原文发布时间为:2017年2月16日 本文作者:作者:赵东 本文来自云栖社区合作伙伴至顶网,了解相关信息可以关注至顶网。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册