From b5f452fa0ab16b520031eaf15322d8296bd51580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E7=A5=A5?= <1366971433@qq.com> Date: Fri, 19 Apr 2019 17:58:15 +0800 Subject: [PATCH] =?UTF-8?q?storm=E6=95=B4=E5=90=88=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/Storm/storm-hdfs-integration/pom.xml | 97 ++- code/Storm/storm-kafka-integration/pom.xml | 46 +- .../kafka/write/WritingToKafkaApp.java | 2 +- code/Storm/storm-redis-integration/pom.xml | 30 +- .../component/WordCountStoreMapper.java | 2 +- notes/Storm多种打包方式对比分析.md | 309 +++++++++ notes/Storm编程模型详解.md | 2 +- notes/Storm集成HBase和HDFS.md | 472 +++++++++++++ notes/Storm集成Kakfa.md | 344 ++++++++++ notes/Storm集成Redis详解.md | 625 ++++++++++++++++++ ...于Zookeeper搭建Kafka高可用集群.md | 118 ++++ pictures/jar-with-dependencies.png | Bin 0 -> 68149 bytes pictures/kafka-cluster-shell.png | Bin 0 -> 18090 bytes pictures/storm-Redis-Mapper.png | Bin 0 -> 23758 bytes pictures/storm-abstractRedisBolt.png | Bin 0 -> 18244 bytes pictures/storm-jar2.png | Bin 0 -> 21074 bytes pictures/storm-jedicCommands.png | Bin 0 -> 5943 bytes 17 files changed, 1955 insertions(+), 92 deletions(-) create mode 100644 notes/Storm多种打包方式对比分析.md create mode 100644 notes/Storm集成HBase和HDFS.md create mode 100644 notes/Storm集成Kakfa.md create mode 100644 notes/Storm集成Redis详解.md create mode 100644 pictures/jar-with-dependencies.png create mode 100644 pictures/kafka-cluster-shell.png create mode 100644 pictures/storm-Redis-Mapper.png create mode 100644 pictures/storm-abstractRedisBolt.png create mode 100644 pictures/storm-jar2.png create mode 100644 pictures/storm-jedicCommands.png diff --git a/code/Storm/storm-hdfs-integration/pom.xml b/code/Storm/storm-hdfs-integration/pom.xml index f65e03c..643b3de 100644 --- a/code/Storm/storm-hdfs-integration/pom.xml +++ b/code/Storm/storm-hdfs-integration/pom.xml @@ -9,7 +9,6 @@ 1.0 - UTF-8 1.2.2 @@ -20,6 +19,53 @@ + + + org.apache.storm + storm-core + ${storm.version} + + + + org.apache.storm + storm-hdfs + ${storm.version} + + + org.apache.hadoop + hadoop-common + 2.6.0-cdh5.15.2 + + + org.slf4j + slf4j-log4j12 + + + + + org.apache.hadoop + hadoop-client + 2.6.0-cdh5.15.2 + + + org.slf4j + slf4j-log4j12 + + + + + org.apache.hadoop + hadoop-hdfs + 2.6.0-cdh5.15.2 + + + org.slf4j + slf4j-log4j12 + + + + + @@ -83,53 +129,4 @@ - - - - org.apache.storm - storm-core - ${storm.version} - - - - org.apache.storm - storm-hdfs - ${storm.version} - - - org.apache.hadoop - hadoop-common - 2.6.0-cdh5.15.2 - - - org.slf4j - slf4j-log4j12 - - - - - org.apache.hadoop - hadoop-client - 2.6.0-cdh5.15.2 - - - org.slf4j - slf4j-log4j12 - - - - - org.apache.hadoop - hadoop-hdfs - 2.6.0-cdh5.15.2 - - - org.slf4j - slf4j-log4j12 - - - - - - \ No newline at end of file diff --git a/code/Storm/storm-kafka-integration/pom.xml b/code/Storm/storm-kafka-integration/pom.xml index f1ffe16..48afea3 100644 --- a/code/Storm/storm-kafka-integration/pom.xml +++ b/code/Storm/storm-kafka-integration/pom.xml @@ -8,6 +8,29 @@ storm-kafka-integration 1.0 + + 1.2.2 + 2.2.0 + + + + + org.apache.storm + storm-core + ${storm.version} + + + org.apache.storm + storm-kafka-client + ${storm.version} + + + org.apache.kafka + kafka-clients + ${kafka.version} + + + @@ -68,27 +91,4 @@ - - 1.2.2 - 2.2.0 - - - - - org.apache.storm - storm-core - ${storm.version} - - - org.apache.storm - storm-kafka-client - ${storm.version} - - - org.apache.kafka - kafka-clients - ${kafka.version} - - - \ No newline at end of file diff --git a/code/Storm/storm-kafka-integration/src/main/java/com/heibaiying/kafka/write/WritingToKafkaApp.java b/code/Storm/storm-kafka-integration/src/main/java/com/heibaiying/kafka/write/WritingToKafkaApp.java index 281824b..56814e3 100644 --- a/code/Storm/storm-kafka-integration/src/main/java/com/heibaiying/kafka/write/WritingToKafkaApp.java +++ b/code/Storm/storm-kafka-integration/src/main/java/com/heibaiying/kafka/write/WritingToKafkaApp.java @@ -14,7 +14,7 @@ import org.apache.storm.topology.TopologyBuilder; import java.util.Properties; /** - * 写入数据到Kafka的特定主题中 + * 写入数据到Kafka中 */ public class WritingToKafkaApp { diff --git a/code/Storm/storm-redis-integration/pom.xml b/code/Storm/storm-redis-integration/pom.xml index 52ee5b8..c3c91dd 100644 --- a/code/Storm/storm-redis-integration/pom.xml +++ b/code/Storm/storm-redis-integration/pom.xml @@ -9,10 +9,23 @@ 1.0 - UTF-8 1.2.2 + + + org.apache.storm + storm-core + ${storm.version} + + + org.apache.storm + storm-redis + ${storm.version} + + + + @@ -73,19 +86,4 @@ - - - - org.apache.storm - storm-core - ${storm.version} - - - org.apache.storm - storm-redis - ${storm.version} - - - - \ No newline at end of file diff --git a/code/Storm/storm-redis-integration/src/main/java/com/heibaiying/component/WordCountStoreMapper.java b/code/Storm/storm-redis-integration/src/main/java/com/heibaiying/component/WordCountStoreMapper.java index 6343e9f..d75e568 100644 --- a/code/Storm/storm-redis-integration/src/main/java/com/heibaiying/component/WordCountStoreMapper.java +++ b/code/Storm/storm-redis-integration/src/main/java/com/heibaiying/component/WordCountStoreMapper.java @@ -5,7 +5,7 @@ import org.apache.storm.redis.common.mapper.RedisStoreMapper; import org.apache.storm.tuple.ITuple; /** - * 定义流数据与Redis中数据的映射关系 + * 定义tuple与Redis中数据的映射关系 */ public class WordCountStoreMapper implements RedisStoreMapper { private RedisDataTypeDescription description; diff --git a/notes/Storm多种打包方式对比分析.md b/notes/Storm多种打包方式对比分析.md new file mode 100644 index 0000000..c74e8ed --- /dev/null +++ b/notes/Storm多种打包方式对比分析.md @@ -0,0 +1,309 @@ +# Storm多种打包方式对比分析 + +## 一、简介 + +在将Storm Topology提交到服务器集群进行运行时,需要先将项目进行打包,本文主要对比分析各种打包方式,并将打包过程中需要注意的事项进行说明。主要打包方式有以下三种: + ++ 第一种:不加任何插件,直接使用mvn package打包; ++ 第二种:使用maven-assembly-plugin插件进行打包; ++ 第三种:使用maven-shade-plugin进行打包。 + +以下分别进行详细的说明。 + + + +## 二、mvn package + +### 2.1 mvn package的局限 + +不在POM中配置任何插件,直接使用`mvn package`进行项目打包,这对于没有使用外部依赖包的项目是可行的。 + +但如果项目中使用了第三方JAR包,就会出现问题,因为`mvn package`打包后的JAR中是不含有依赖包的,如果此时你提交到服务器上运行,就会出现找不到第三方依赖的异常。 + +如果你想采用这种方式进行打包,但是又使用了第三方JAR包,有没有解决办法?答案是有的,这一点在官方文档中[Command Line Client](http://storm.apache.org/releases/2.0.0-SNAPSHOT/Command-line-client.html)这部分有所讲解,主要解决办法如下。 + +### 2.2 解决办法 + +在使用`storm jar topology-jar-path class ...`提交Topology的时候,需要指定第三方依赖时候,可以进行如下操作: + ++ 如果第三方JAR包在本地,可以使用`--jars`指定; ++ 如果第三方JAR包在远程中央仓库,可以使用`--artifacts` 指定,此时如果想要排除某些依赖,可以使用 `^` 符号; ++ 如果第三方JAR包在其他仓库,还需要使用 `--artifactRepositories`指明仓库地址,库名和地址使用 `^` 符号分隔。 + +以下是包含上面三种情况的一个例子: + +```shell +./bin/storm jar example/storm-starter/storm-starter-topologies-*.jar org.apache.storm.starter.RollingTopWords blobstore-remote2 remote --jars "./external/storm-redis/storm-redis-1.1.0.jar,./external/storm-kafka/storm-kafka-1.1.0.jar" --artifacts "redis.clients:jedis:2.9.0,org.apache.kafka:kafka_2.10:0.8.2.2^org.slf4j:slf4j-log4j12" --artifactRepositories "jboss-repository^http://repository.jboss.com/maven2,HDPRepo^http://repo.hortonworks.com/content/groups/public/" +``` + + + +## 三、maven-assembly-plugin插件 + +### 3.1 官方文档说明 + +maven-assembly-plugin是官方文档中介绍的打包方法,以下表述来源于官方文档:[Running Topologies on a Production Cluster](http://storm.apache.org/releases/2.0.0-SNAPSHOT/Running-topologies-on-a-production-cluster.html) + +> If you're using Maven, the [Maven Assembly Plugin](http://maven.apache.org/plugins/maven-assembly-plugin/) can do the packaging for you. Just add this to your pom.xml: +> +> ```xml +> +> maven-assembly-plugin +> +> +> jar-with-dependencies +> +> +> +> com.path.to.main.Class +> +> +> +> +> ``` +> +> Then run mvn assembly:assembly to get an appropriately packaged jar. Make sure you [exclude](http://maven.apache.org/plugins/maven-assembly-plugin/examples/single/including-and-excluding-artifacts.html) the Storm jars since the cluster already has Storm on the classpath. + +主要是两点: + +- 使用maven-assembly-plugin进行打包,因为maven-assembly-plugin会把所有的依赖一并打包到最后的JAR中; +- 排除掉Storm集群环境中已经提供的Storm jars。 + +maven-assembly-plugin的使用非常简单,只需要在POM.xml中引入即可,并且在\标签指定打包格式为`jar-with-dependencies`。那么就剩下一个问题:如何排除Storm jars ? + +### 3.2 排除Storm jars + +这里说明一下,`jar-with-dependencies`是Maven官方内置的一种打包格式,Maven官方文档[Pre-defined Descriptor Files](http://maven.apache.org/plugins/maven-assembly-plugin/descriptor-refs.html)中有所说明: + +![jar-with-dependencies](D:\BigData-Notes\pictures\jar-with-dependencies.png) + +如果你想排除某个依赖,这里以排除`storm-core`为例,你可以在`jar-with-dependencies`的XML上进行修改。 + +```xml + + + jar-with-dependencies + + + + jar + + + false + + + / + true + true + runtime + + + org.apache.storm:storm-core + + + + +``` + +### 3.3 最终配置 + +采用maven-assembly-plugin进行打包时候,最终的配置应该如下: + +#### 1.引入插件 + +在POM.xml中引入插件,并指定打包格式的配置文件`assembly.xml`(名称可自定义): + +```xml + + + + maven-assembly-plugin + + + src/main/resources/assembly.xml + + + + com.heibaiying.wordcount.ClusterWordCountApp + + + + + + +``` + +assembly.xml文件内容如下: + +```xml + + + jar-with-dependencies + + + + jar + + + false + + + / + true + true + runtime + + + org.apache.storm:storm-core + + + + +``` + +>在配置文件中不仅可以排除依赖,还可以排除指定的文件,更多的配置规则可以参考官方文档:[Descriptor Format](http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html#) + +#### 2. 打包命令 + +采用maven-assembly-plugin进行打包时命令如下: + +```shell +# mvn assembly:assembly +``` + +打包后会同时生成两个JAR包,其中后缀为`jar-with-dependencies`是含有第三方依赖的JAR包,后缀是由`assembly.xml`中``标签指定的,可以自定义修改。提交该JAR到集群环境即可直接使用。 + +![storm-jar](D:\BigData-Notes\pictures\storm-jar.png) + + + +## 四、maven-shade-plugin插件 + +### 4.1 官方文档说明 + +第三种方式是使用maven-shade-plugin,既然已经有了maven-assembly-plugin,为什么还需要maven-shade-plugin,这一点在官方文档中也是有所说明的,来自于官方对HDFS整合讲解的章节[Storm HDFS Integration](http://storm.apache.org/releases/2.0.0-SNAPSHOT/storm-hdfs.html),原文如下: + +>When packaging your topology, it's important that you use the [maven-shade-plugin](http://storm.apache.org/releases/2.0.0-SNAPSHOT/storm-hdfs.html) as opposed to the [maven-assembly-plugin](http://storm.apache.org/releases/2.0.0-SNAPSHOT/storm-hdfs.html). +> +>The shade plugin provides facilities for merging JAR manifest entries, which the hadoop client leverages for URL scheme resolution. +> +>If you experience errors such as the following: +> +>``` +>java.lang.RuntimeException: Error preparing HdfsBolt: No FileSystem for scheme: hdfs +>``` +> +>it's an indication that your topology jar file isn't packaged properly. +> +>If you are using maven to create your topology jar, you should use the following `maven-shade-plugin` configuration to create your topology jar。 + +这里第一句就说的比较清晰,在集成HDFS时候,你必须使用maven-shade-plugin来代替maven-assembly-plugin,否则会抛出 + +RuntimeException异常。 + +采用maven-shade-plugin有很多好处,比如你的工程依赖很多的JAR包,而被依赖的JAR又会依赖其他的JAR包,这样,当工程中依赖到不同的版本的 JAR时,并且JAR中具有相同名称的资源文件时,shade插件会尝试将所有资源文件打包在一起时,而不是和assembly一样执行覆盖操作。 + +### 4.2 配置 + +配置示例如下: + +```xml + + org.apache.maven.plugins + maven-shade-plugin + + true + + + *:* + + META-INF/*.SF + META-INF/*.sf + META-INF/*.DSA + META-INF/*.dsa + META-INF/*.RSA + META-INF/*.rsa + META-INF/*.EC + META-INF/*.ec + META-INF/MSFTSIG.SF + META-INF/MSFTSIG.RSA + + + + + + org.apache.storm:storm-core + + + + + + package + + shade + + + + + + + + + + + +``` + +配置说明: + +有些jar包生成时,会使用jarsigner生成文件签名(完成性校验),分为两个文件存放在META-INF目录下。 + ++ a signature file, with a .SF extension; ++ a signature block file, with a .DSA, .RSA, or .EC extension; + +如果某些包的存在重复引用,这可能会导致在打包时候出现`Invalid signature file digest for Manifest main attributes`异常,所以在配置中排除这些文件。 + +### 4.3 打包命令 + +使用maven-shade-plugin进行打包的时候,打包命令和普通的一样: + +```shell +# mvn package +``` + +打包后会生成两个JAR包,提交到服务器集群时使用非original开头的JAR. + +![storm-jar2](D:\BigData-Notes\pictures\storm-jar2.png) + +## 五、结论 + +通过以上三种打包方式的详细介绍,这里给出最后的结论:**建议使用maven-shade-plugin插件进行打包**,因为其通用性最强,操作最简单,并且storm官方Github中给的所有[examples](https://github.com/apache/storm/tree/master/examples)都是采用的第三种打包方式。 + + + +## 六、打包注意事项 + +无论采用任何打包方式,都必须排除集群环境中已经提供的storm jars。这里比较典型的是storm-core,其在安装目录的lib目录下已经存在。 + +![storm-lib](D:\BigData-Notes\pictures\storm-lib.png) + + + +如果你不排除storm-core,通常会抛出下面的异常: + +```properties +Caused by: java.lang.RuntimeException: java.io.IOException: Found multiple defaults.yaml resources. You're probably bundling the Storm jars with your topology jar. [jar:file:/usr/app/apache-storm-1.2.2/lib/storm-core-1.2.2.jar!/defaults.yaml, jar:file:/usr/appjar/storm-hdfs-integration-1.0.jar!/defaults.yaml] + at org.apache.storm.utils.Utils.findAndReadConfigFile(Utils.java:384) + at org.apache.storm.utils.Utils.readDefaultConfig(Utils.java:428) + at org.apache.storm.utils.Utils.readStormConfig(Utils.java:464) + at org.apache.storm.utils.Utils.(Utils.java:178) + ... 39 more +``` + +![storm-jar-complie-error](D:\BigData-Notes\pictures\storm-jar-complie-error.png) \ No newline at end of file diff --git a/notes/Storm编程模型详解.md b/notes/Storm编程模型详解.md index 0b74a3a..3c01401 100644 --- a/notes/Storm编程模型详解.md +++ b/notes/Storm编程模型详解.md @@ -471,7 +471,7 @@ storm kill ClusterWordCountApp -w 3 ### 1. mvn package的局限性 -上面我们直接使用`mvn package`进行项目打包,这对于没有使用外部依赖包的项目是可行的。但如果项目中使用了第三方JAR包,就会出现问题,因为`package`打包后的JAR中是不含有依赖包的,如果此时你提交到服务器上运行,就会出现找不到第三方依赖的异常。 +上面我们没有在POM中配置任何插件,直接使用`mvn package`进行项目打包,这对于没有使用外部依赖包的项目是可行的。但如果项目中使用了第三方JAR包,就会出现问题,因为`package`打包后的JAR中是不含有依赖包的,如果此时你提交到服务器上运行,就会出现找不到第三方依赖的异常。 这时候可能大家会有疑惑,在我们的项目中不是使用了`storm-core`这个依赖吗?其实上面之所以我们能运行成功,是因为在Storm的集群环境中提供了这个JAR包,在安装目录的lib目录下: diff --git a/notes/Storm集成HBase和HDFS.md b/notes/Storm集成HBase和HDFS.md new file mode 100644 index 0000000..d424740 --- /dev/null +++ b/notes/Storm集成HBase和HDFS.md @@ -0,0 +1,472 @@ +# Storm集成HDFS和HBase + +## 一、Storm集成HDFS + +### 1.1 项目结构 + +> 本用例源码下载地址:[storm-hdfs-integration](https://github.com/heibaiying/BigData-Notes/tree/master/code/Storm/storm-hdfs-integration) + +### 1.2 项目主要依赖 + +项目主要依赖如下,有两个需要注意: + ++ 这里由于我服务器上安装的是CDH版本的Hadoop,在导入依赖时引入的也是CDH版本的依赖,需要使用``标签指定CDH的仓库地址; ++ `hadoop-common`、`hadoop-client`、`hadoop-hdfs`均需要排除`slf4j-log4j12`依赖,原因是`storm-core`中已经有该依赖,不排除的话有JAR包冲突的风险; + +```xml + + 1.2.2 + + + + + cloudera + https://repository.cloudera.com/artifactory/cloudera-repos/ + + + + + + org.apache.storm + storm-core + ${storm.version} + + + + org.apache.storm + storm-hdfs + ${storm.version} + + + org.apache.hadoop + hadoop-common + 2.6.0-cdh5.15.2 + + + org.slf4j + slf4j-log4j12 + + + + + org.apache.hadoop + hadoop-client + 2.6.0-cdh5.15.2 + + + org.slf4j + slf4j-log4j12 + + + + + org.apache.hadoop + hadoop-hdfs + 2.6.0-cdh5.15.2 + + + org.slf4j + slf4j-log4j12 + + + + +``` + +### 1.3 DataSourceSpout + +```java +/** + * 产生词频样本的数据源 + */ +public class DataSourceSpout extends BaseRichSpout { + + private List list = Arrays.asList("Spark", "Hadoop", "HBase", "Storm", "Flink", "Hive"); + + private SpoutOutputCollector spoutOutputCollector; + + @Override + public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) { + this.spoutOutputCollector = spoutOutputCollector; + } + + @Override + public void nextTuple() { + // 模拟产生数据 + String lineData = productData(); + spoutOutputCollector.emit(new Values(lineData)); + Utils.sleep(1000); + } + + @Override + public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) { + outputFieldsDeclarer.declare(new Fields("line")); + } + + + /** + * 模拟数据 + */ + private String productData() { + Collections.shuffle(list); + Random random = new Random(); + int endIndex = random.nextInt(list.size()) % (list.size()) + 1; + return StringUtils.join(list.toArray(), "\t", 0, endIndex); + } + +} +``` + +产生的模拟数据格式如下: + +```properties +Spark HBase +Hive Flink Storm Hadoop HBase Spark +Flink +HBase Storm +HBase Hadoop Hive Flink +HBase Flink Hive Storm +Hive Flink Hadoop +HBase Hive +Hadoop Spark HBase Storm +``` + +### 1.4 将数据存储到HDFS + +这里HDFS的地址和数据存储路径均使用了硬编码,在实际开发中可以通过外部传参指定,这样程序更为灵活。 + +```java +public class DataToHdfsApp { + + private static final String DATA_SOURCE_SPOUT = "dataSourceSpout"; + private static final String HDFS_BOLT = "hdfsBolt"; + + public static void main(String[] args) { + + // 指定Hadoop的用户名 如果不指定,则在HDFS创建目录时候有可能抛出无权限的异常(RemoteException: Permission denied) + System.setProperty("HADOOP_USER_NAME", "root"); + + // 定义输出字段(Field)之间的分隔符 + RecordFormat format = new DelimitedRecordFormat() + .withFieldDelimiter("|"); + + // 同步策略: 每100个tuples之后就会把数据从缓存刷新到HDFS中 + SyncPolicy syncPolicy = new CountSyncPolicy(100); + + // 文件策略: 每个文件大小上限1M,超过限定时,创建新文件并继续写入 + FileRotationPolicy rotationPolicy = new FileSizeRotationPolicy(1.0f, Units.MB); + + // 定义存储路径 + FileNameFormat fileNameFormat = new DefaultFileNameFormat() + .withPath("/storm-hdfs/"); + + // 定义HdfsBolt + HdfsBolt hdfsBolt = new HdfsBolt() + .withFsUrl("hdfs://hadoop001:8020") + .withFileNameFormat(fileNameFormat) + .withRecordFormat(format) + .withRotationPolicy(rotationPolicy) + .withSyncPolicy(syncPolicy); + + + // 构建Topology + TopologyBuilder builder = new TopologyBuilder(); + builder.setSpout(DATA_SOURCE_SPOUT, new DataSourceSpout()); + // save to HDFS + builder.setBolt(HDFS_BOLT, hdfsBolt, 1).shuffleGrouping(DATA_SOURCE_SPOUT); + + + // 如果外部传参cluster则代表线上环境启动,否则代表本地启动 + if (args.length > 0 && args[0].equals("cluster")) { + try { + StormSubmitter.submitTopology("ClusterDataToHdfsApp", new Config(), builder.createTopology()); + } catch (AlreadyAliveException | InvalidTopologyException | AuthorizationException e) { + e.printStackTrace(); + } + } else { + LocalCluster cluster = new LocalCluster(); + cluster.submitTopology("LocalDataToHdfsApp", + new Config(), builder.createTopology()); + } + } +} +``` + +### 1.5 启动测试 + +可以用直接使用本地模式运行,也可以打包后提交到服务器集群运行。本仓库提供的源码默认采用`maven-shade-plugin`进行打包,打包命令如下: + +```shell +# mvn clean package -D maven.test.skip=true +``` + +运行后,数据会存储到HDFS的`/storm-hdfs`目录下。使用以下命令可以查看目录内容: + +```shell +# 查看目录内容 +hadoop fs -ls /storm-hdfs +# 监听文内容变化 +hadoop fs -tail -f /strom-hdfs/文件名 +``` + + + +![storm-hdfs-result](D:\BigData-Notes\pictures\storm-hdfs-result.png) + + + +## 二、Storm集成HBase + +### 2.1 项目结构 + +本用例源码下载地址:[storm-hbase-integration](https://github.com/heibaiying/BigData-Notes/tree/master/code/Storm/storm-hbase-integration) + +### 2.2 项目主要依赖 + +```xml + + 1.2.2 + + + + + + org.apache.storm + storm-core + ${storm.version} + + + + org.apache.storm + storm-hbase + ${storm.version} + + +``` + +### 2.3 DataSourceSpout + +```java +/** + * 产生词频样本的数据源 + */ +public class DataSourceSpout extends BaseRichSpout { + + private List list = Arrays.asList("Spark", "Hadoop", "HBase", "Storm", "Flink", "Hive"); + + private SpoutOutputCollector spoutOutputCollector; + + @Override + public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) { + this.spoutOutputCollector = spoutOutputCollector; + } + + @Override + public void nextTuple() { + // 模拟产生数据 + String lineData = productData(); + spoutOutputCollector.emit(new Values(lineData)); + Utils.sleep(1000); + } + + @Override + public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) { + outputFieldsDeclarer.declare(new Fields("line")); + } + + + /** + * 模拟数据 + */ + private String productData() { + Collections.shuffle(list); + Random random = new Random(); + int endIndex = random.nextInt(list.size()) % (list.size()) + 1; + return StringUtils.join(list.toArray(), "\t", 0, endIndex); + } + +} +``` + +产生的模拟数据格式如下: + +```properties +Spark HBase +Hive Flink Storm Hadoop HBase Spark +Flink +HBase Storm +HBase Hadoop Hive Flink +HBase Flink Hive Storm +Hive Flink Hadoop +HBase Hive +Hadoop Spark HBase Storm +``` + + + +### 2.4 SplitBolt + +```java +/** + * 将每行数据按照指定分隔符进行拆分 + */ +public class SplitBolt extends BaseRichBolt { + + private OutputCollector collector; + + @Override + public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) { + this.collector = collector; + } + + @Override + public void execute(Tuple input) { + String line = input.getStringByField("line"); + String[] words = line.split("\t"); + for (String word : words) { + collector.emit(tuple(word, 1)); + } + } + + @Override + public void declareOutputFields(OutputFieldsDeclarer declarer) { + declarer.declare(new Fields("word", "count")); + } +} +``` + +### 2.5 CountBolt + +```java +/** + * 进行词频统计 + */ +public class CountBolt extends BaseRichBolt { + + private Map counts = new HashMap<>(); + + private OutputCollector collector; + + + @Override + public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) { + this.collector=collector; + } + + @Override + public void execute(Tuple input) { + String word = input.getStringByField("word"); + Integer count = counts.get(word); + if (count == null) { + count = 0; + } + count++; + counts.put(word, count); + // 输出 + collector.emit(new Values(word, String.valueOf(count))); + + } + + @Override + public void declareOutputFields(OutputFieldsDeclarer declarer) { + declarer.declare(new Fields("word", "count")); + } +} +``` + +### 2.6 WordCountToHBaseApp + +```java +/** + * 进行词频统计 并将统计结果存储到HBase中 + */ +public class WordCountToHBaseApp { + + private static final String DATA_SOURCE_SPOUT = "dataSourceSpout"; + private static final String SPLIT_BOLT = "splitBolt"; + private static final String COUNT_BOLT = "countBolt"; + private static final String HBASE_BOLT = "hbaseBolt"; + + public static void main(String[] args) { + + // storm的配置 + Config config = new Config(); + + // HBase的配置 + Map hbConf = new HashMap<>(); + hbConf.put("hbase.rootdir", "hdfs://hadoop001:8020/hbase"); + hbConf.put("hbase.zookeeper.quorum", "hadoop001:2181"); + + // 将HBase的配置传入Storm的配置中 + config.put("hbase.conf", hbConf); + + // 定义流数据与HBase中数据的映射 + SimpleHBaseMapper mapper = new SimpleHBaseMapper() + .withRowKeyField("word") + .withColumnFields(new Fields("word","count")) + .withColumnFamily("info"); + + /* + * 给HBaseBolt传入表名、数据映射关系、和HBase的配置信息 + * 表需要预先创建: create 'WordCount','info' + */ + HBaseBolt hbase = new HBaseBolt("WordCount", mapper) + .withConfigKey("hbase.conf"); + + // 构建Topology + TopologyBuilder builder = new TopologyBuilder(); + builder.setSpout(DATA_SOURCE_SPOUT, new DataSourceSpout(),1); + // split + builder.setBolt(SPLIT_BOLT, new SplitBolt(), 1).shuffleGrouping(DATA_SOURCE_SPOUT); + // count + builder.setBolt(COUNT_BOLT, new CountBolt(),1).shuffleGrouping(SPLIT_BOLT); + // save to HBase + builder.setBolt(HBASE_BOLT, hbase, 1).shuffleGrouping(COUNT_BOLT); + + + // 如果外部传参cluster则代表线上环境启动,否则代表本地启动 + if (args.length > 0 && args[0].equals("cluster")) { + try { + StormSubmitter.submitTopology("ClusterWordCountToRedisApp", config, builder.createTopology()); + } catch (AlreadyAliveException | InvalidTopologyException | AuthorizationException e) { + e.printStackTrace(); + } + } else { + LocalCluster cluster = new LocalCluster(); + cluster.submitTopology("LocalWordCountToRedisApp", + config, builder.createTopology()); + } + } +} +``` + +### 2.7 启动测试 + +可以用直接使用本地模式运行,也可以打包后提交到服务器集群运行。本仓库提供的源码默认采用`maven-shade-plugin`进行打包,打包命令如下: + +```shell +# mvn clean package -D maven.test.skip=true +``` + +运行后,数据会存储到HBase的`WordCount`表中。使用以下命令查看表的内容: + +```shell +hbase > scan 'WordCount' +``` + +![storm-hbase-result](D:\BigData-Notes\pictures\storm-hbase-result.png) + + + +### 2.8 withCounterFields + +在上面的用例中我们是手动编码来实现词频统计,并将最后的结果存储到HBase中。其实也可以在构建`SimpleHBaseMapper`的时候通过`withCounterFields`指定count字段,被指定的字段会自动进行累加操作,这样也可以实现词频统计。需要注意的是withCounterFields指定的字段必须是Long类型,不能是String类型。 + +```java +SimpleHBaseMapper mapper = new SimpleHBaseMapper() + .withRowKeyField("word") + .withColumnFields(new Fields("word")) + .withCounterFields(new Fields("count")) + .withColumnFamily("cf"); +``` + diff --git a/notes/Storm集成Kakfa.md b/notes/Storm集成Kakfa.md new file mode 100644 index 0000000..20d7ed0 --- /dev/null +++ b/notes/Storm集成Kakfa.md @@ -0,0 +1,344 @@ +# Storm集成Kafka + +## 一、整合说明 + +Storm官方对Kafka的整合分为两个版本,官方说明文档分别如下: + ++ [Storm Kafka Integration](http://storm.apache.org/releases/2.0.0-SNAPSHOT/storm-kafka.html) : 主要是针对0.8.x版本的Kafka提供整合支持; ++ [Storm Kafka Integration (0.10.x+)]() : 包含Kafka 新版本的 consumer API,主要对Kafka 0.10.x +提供整合支持。 + +这里我服务端安装的Kafka版本为2.2.0(Released Mar 22, 2019) ,按照官方0.10.x+的整合文档进行整合,不适用于0.8.x版本的Kafka。 + +## 二、写入数据到Kafka + +### 2.1 项目结构 + + + +### 2.2 项目主要依赖 + +```xml + + 1.2.2 + 2.2.0 + + + + + org.apache.storm + storm-core + ${storm.version} + + + org.apache.storm + storm-kafka-client + ${storm.version} + + + org.apache.kafka + kafka-clients + ${kafka.version} + + +``` + +### 2.3 DataSourceSpout + +```java +/** + * 产生词频样本的数据源 + */ +public class DataSourceSpout extends BaseRichSpout { + + private List list = Arrays.asList("Spark", "Hadoop", "HBase", "Storm", "Flink", "Hive"); + + private SpoutOutputCollector spoutOutputCollector; + + @Override + public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) { + this.spoutOutputCollector = spoutOutputCollector; + } + + @Override + public void nextTuple() { + // 模拟产生数据 + String lineData = productData(); + spoutOutputCollector.emit(new Values(lineData)); + Utils.sleep(1000); + } + + @Override + public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) { + outputFieldsDeclarer.declare(new Fields("line")); + } + + + /** + * 模拟数据 + */ + private String productData() { + Collections.shuffle(list); + Random random = new Random(); + int endIndex = random.nextInt(list.size()) % (list.size()) + 1; + return StringUtils.join(list.toArray(), "\t", 0, endIndex); + } + +} +``` + +产生的模拟数据格式如下: + +```properties +Spark HBase +Hive Flink Storm Hadoop HBase Spark +Flink +HBase Storm +HBase Hadoop Hive Flink +HBase Flink Hive Storm +Hive Flink Hadoop +HBase Hive +Hadoop Spark HBase Storm +``` + +### 2.4 WritingToKafkaApp + +```java +/** + * 写入数据到Kafka中 + */ +public class WritingToKafkaApp { + + private static final String BOOTSTRAP_SERVERS = "hadoop001:9092"; + private static final String TOPIC_NAME = "storm-topic"; + + public static void main(String[] args) { + + + TopologyBuilder builder = new TopologyBuilder(); + + // 定义Kafka生产者属性 + Properties props = new Properties(); + /* + * 指定broker的地址清单,清单里不需要包含所有的broker地址,生产者会从给定的broker里查找其他broker的信息。 + * 不过建议至少要提供两个broker的信息作为容错。 + */ + props.put("bootstrap.servers", BOOTSTRAP_SERVERS); + /* + * acks 参数指定了必须要有多少个分区副本收到消息,生产者才会认为消息写入是成功的。 + * acks=0 : 生产者在成功写入消息之前不会等待任何来自服务器的响应。 + * acks=1 : 只要集群的首领节点收到消息,生产者就会收到一个来自服务器成功响应。 + * acks=all : 只有当所有参与复制的节点全部收到消息时,生产者才会收到一个来自服务器的成功响应。 + */ + props.put("acks", "1"); + props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + + KafkaBolt bolt = new KafkaBolt() + .withProducerProperties(props) + .withTopicSelector(new DefaultTopicSelector(TOPIC_NAME)) + .withTupleToKafkaMapper(new FieldNameBasedTupleToKafkaMapper<>()); + + builder.setSpout("sourceSpout", new DataSourceSpout(), 1); + builder.setBolt("kafkaBolt", bolt, 1).shuffleGrouping("sourceSpout"); + + + if (args.length > 0 && args[0].equals("cluster")) { + try { + StormSubmitter.submitTopology("ClusterWritingToKafkaApp", new Config(), builder.createTopology()); + } catch (AlreadyAliveException | InvalidTopologyException | AuthorizationException e) { + e.printStackTrace(); + } + } else { + LocalCluster cluster = new LocalCluster(); + cluster.submitTopology("LocalWritingToKafkaApp", + new Config(), builder.createTopology()); + } + } +} +``` + +### 2.5 测试准备工作 + +进行测试前需要启动Kakfa。 + +#### 1. 启动Kakfa + +Kafka的运行依赖于zookeeper,需要预先启动,可以启动Kafka内置的zookeeper,也可以启动自己安装的。 + +```shell +# zookeeper启动命令 +bin/zkServer.sh start + +# 内置zookeeper启动命令 +bin/zookeeper-server-start.sh config/zookeeper.properties +``` + +启动单节点kafka: + +```shell +# bin/kafka-server-start.sh config/server.properties +``` + +#### 2. 创建topic + +```shell +# 创建用于测试主题 +bin/kafka-topics.sh --create --bootstrap-server hadoop001:9092 --replication-factor 1 --partitions 1 --topic storm-topic + +# 查看所有主题 + bin/kafka-topics.sh --list --bootstrap-server hadoop001:9092 +``` + +#### 3. 启动一个消费者用于观察写入情况 + +```shell +# bin/kafka-console-consumer.sh --bootstrap-server hadoop001:9092 --topic storm-topic --from-beginning +``` + +### 2.6 测试 + +可以用直接使用本地模式运行,也可以打包后提交到服务器集群运行。本仓库提供的源码默认采用`maven-shade-plugin`进行打包,打包命令如下: + +```shell +# mvn clean package -D maven.test.skip=true +``` + +启动后,消费者监听情况如下: + +![strom-kafka-consumer](D:\BigData-Notes\pictures\strom-kafka-consumer.png) + + + +## 三、从Kafka中读取数据 + +### 3.1 项目结构 + + + +### 3.2 ReadingFromKafkaApp + +```java +/** + * 从Kafka中读取数据 + */ +public class ReadingFromKafkaApp { + + private static final String BOOTSTRAP_SERVERS = "hadoop001:9092"; + private static final String TOPIC_NAME = "storm-topic"; + + public static void main(String[] args) { + + final TopologyBuilder builder = new TopologyBuilder(); + builder.setSpout("kafka_spout", new KafkaSpout<>(getKafkaSpoutConfig(BOOTSTRAP_SERVERS, TOPIC_NAME)), 1); + builder.setBolt("bolt", new LogConsoleBolt()).shuffleGrouping("kafka_spout"); + + // 如果外部传参cluster则代表线上环境启动,否则代表本地启动 + if (args.length > 0 && args[0].equals("cluster")) { + try { + StormSubmitter.submitTopology("ClusterReadingFromKafkaApp", new Config(), builder.createTopology()); + } catch (AlreadyAliveException | InvalidTopologyException | AuthorizationException e) { + e.printStackTrace(); + } + } else { + LocalCluster cluster = new LocalCluster(); + cluster.submitTopology("LocalReadingFromKafkaApp", + new Config(), builder.createTopology()); + } + } + + private static KafkaSpoutConfig getKafkaSpoutConfig(String bootstrapServers, String topic) { + return KafkaSpoutConfig.builder(bootstrapServers, topic) + // 除了分组ID,以下配置都是可选的。分组ID必须指定,否则会抛出InvalidGroupIdException异常 + .setProp(ConsumerConfig.GROUP_ID_CONFIG, "kafkaSpoutTestGroup") + // 定义重试策略 + .setRetry(getRetryService()) + // 定时提交偏移量的时间间隔,默认是15s + .setOffsetCommitPeriodMs(10_000) + .build(); + } + + // 定义重试策略 + private static KafkaSpoutRetryService getRetryService() { + return new KafkaSpoutRetryExponentialBackoff(TimeInterval.microSeconds(500), + TimeInterval.milliSeconds(2), Integer.MAX_VALUE, TimeInterval.seconds(10)); + } +} + +``` + +### 3.3 LogConsoleBolt + +```java +/** + * 打印从Kafka中获取的数据 + */ +public class LogConsoleBolt extends BaseRichBolt { + + + private OutputCollector collector; + + public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) { + this.collector=collector; + } + + public void execute(Tuple input) { + try { + String value = input.getStringByField("value"); + System.out.println("received from kafka : "+ value); + // 必须ack,否则会重复消费kafka中的消息 + collector.ack(input); + }catch (Exception e){ + e.printStackTrace(); + collector.fail(input); + } + + } + + public void declareOutputFields(OutputFieldsDeclarer declarer) { + + } +} +``` + +这里从`value`字段中获取kafka输出的值数据。 + +默认情况下,我们可以通过继承`RecordTranslator`接口定义了Kafka中Record与输出流之间的转换关系,可以在构建`KafkaSpoutConfig`的时候通过构造器或者`setRecordTranslator()`传入,并最后传递给具体的`KafkaSpout`。如果不指定的情况下,则默认使用内置的`DefaultRecordTranslator`,其源码如下,`FIELDS`中 定义了tuple中所有可用的字段: + +```java +public class DefaultRecordTranslator implements RecordTranslator { + private static final long serialVersionUID = -5782462870112305750L; + public static final Fields FIELDS = new Fields("topic", "partition", "offset", "key", "value"); + @Override + public List apply(ConsumerRecord record) { + return new Values(record.topic(), + record.partition(), + record.offset(), + record.key(), + record.value()); + } + + @Override + public Fields getFieldsFor(String stream) { + return FIELDS; + } + + @Override + public List streams() { + return DEFAULT_STREAM; + } +} +``` + +### 3.4 启动测试 + +这里启动一个生产者用于发送测试数据,启动命令如下: + +```shell +# bin/kafka-console-producer.sh --broker-list hadoop001:9092 --topic storm-topic +``` + +![storm-kafka-producer](D:\BigData-Notes\pictures\storm-kafka-producer.png) + +本地运行的项目接收到从Kafka发送过来的数据: + +![storm-kafka-receiver](D:\BigData-Notes\pictures\storm-kafka-receiver.png) \ No newline at end of file diff --git a/notes/Storm集成Redis详解.md b/notes/Storm集成Redis详解.md new file mode 100644 index 0000000..9a9516c --- /dev/null +++ b/notes/Storm集成Redis详解.md @@ -0,0 +1,625 @@ +# Storm 集成 Redis 详解 + +## 一、简介 + +storm-redis提供了Storm与Redis的集成支持,你只需要引入对应的依赖即可使用。Storm-redis使用Jedis为Redis客户端,提供了基本的Bolt实现, `RedisLookupBolt` and `RedisStoreBolt`。 + ++ RedisLookupBolt:从Redis中查询数据; ++ RedisStoreBolt:存储数据到Redis; ++ RedisFilterBolt : 查询符合条件的数据; + +`RedisLookupBolt`和`RedisStoreBolt`都继承自`AbstractRedisBolt`抽象类,我们也可以继承自该抽象类,然后按照我们自己的的业务逻辑进行功能的拓展。 + +```xml + + org.apache.storm + storm-redis + ${storm.version} + jar + +``` + +## 二、集成案例 + +### 2.1 项目结构 + +### 2.2 项目依赖 + +项目主要依赖如下: + +```xml + + 1.2.2 + + + + + org.apache.storm + storm-core + ${storm.version} + + + org.apache.storm + storm-redis + ${storm.version} + + +``` + +### 2.3 DataSourceSpout + +```java +/** + * 产生词频样本的数据源 + */ +public class DataSourceSpout extends BaseRichSpout { + + private List list = Arrays.asList("Spark", "Hadoop", "HBase", "Storm", "Flink", "Hive"); + + private SpoutOutputCollector spoutOutputCollector; + + @Override + public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) { + this.spoutOutputCollector = spoutOutputCollector; + } + + @Override + public void nextTuple() { + // 模拟产生数据 + String lineData = productData(); + spoutOutputCollector.emit(new Values(lineData)); + Utils.sleep(1000); + } + + @Override + public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) { + outputFieldsDeclarer.declare(new Fields("line")); + } + + + /** + * 模拟数据 + */ + private String productData() { + Collections.shuffle(list); + Random random = new Random(); + int endIndex = random.nextInt(list.size()) % (list.size()) + 1; + return StringUtils.join(list.toArray(), "\t", 0, endIndex); + } + +} +``` + +产生的模拟数据格式如下: + +```properties +Spark HBase +Hive Flink Storm Hadoop HBase Spark +Flink +HBase Storm +HBase Hadoop Hive Flink +HBase Flink Hive Storm +Hive Flink Hadoop +HBase Hive +Hadoop Spark HBase Storm +``` + +### 2.4 SplitBolt + +```java +/** + * 将每行数据按照指定分隔符进行拆分 + */ +public class SplitBolt extends BaseRichBolt { + + private OutputCollector collector; + + @Override + public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) { + this.collector = collector; + } + + @Override + public void execute(Tuple input) { + String line = input.getStringByField("line"); + String[] words = line.split("\t"); + for (String word : words) { + collector.emit(new Values(word, String.valueOf(1))); + } + } + + @Override + public void declareOutputFields(OutputFieldsDeclarer declarer) { + declarer.declare(new Fields("word", "count")); + } +} +``` + +### 2.5 CountBolt + +```java +/** + * 进行词频统计 + */ +public class CountBolt extends BaseRichBolt { + + private Map counts = new HashMap<>(); + + private OutputCollector collector; + + + @Override + public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) { + this.collector=collector; + } + + @Override + public void execute(Tuple input) { + String word = input.getStringByField("word"); + Integer count = counts.get(word); + if (count == null) { + count = 0; + } + count++; + counts.put(word, count); + // 输出 + collector.emit(new Values(word, String.valueOf(count))); + + } + + @Override + public void declareOutputFields(OutputFieldsDeclarer declarer) { + declarer.declare(new Fields("word", "count")); + } +} +``` + +### 2.6 WordCountStoreMapper + +实现RedisStoreMapper,并定义定义tuple与Redis中数据的映射关系,Redis存储的是Key/Value键值对,并且支持多种数据结构,你需要指定tuple中的那个字段为key,那个字段为value,并且存储为什么数据结构。 + +```java +/** + * 定义tuple与Redis中数据的映射关系 + */ +public class WordCountStoreMapper implements RedisStoreMapper { + private RedisDataTypeDescription description; + private final String hashKey = "wordCount"; + + public WordCountStoreMapper() { + description = new RedisDataTypeDescription( + RedisDataTypeDescription.RedisDataType.HASH, hashKey); + } + + @Override + public RedisDataTypeDescription getDataTypeDescription() { + return description; + } + + @Override + public String getKeyFromTuple(ITuple tuple) { + return tuple.getStringByField("word"); + } + + @Override + public String getValueFromTuple(ITuple tuple) { + return tuple.getStringByField("count"); + } +} +``` + +### 2.7 WordCountToRedisApp + +```java +/** + * 进行词频统计 并将统计结果存储到Redis中 + */ +public class WordCountToRedisApp { + + private static final String DATA_SOURCE_SPOUT = "dataSourceSpout"; + private static final String SPLIT_BOLT = "splitBolt"; + private static final String COUNT_BOLT = "countBolt"; + private static final String STORE_BOLT = "storeBolt"; + + //在实际开发中这些参数可以将通过外部传入 使得程序更加灵活 + private static final String REDIS_HOST = "192.168.200.226"; + private static final int REDIS_PORT = 6379; + + public static void main(String[] args) { + TopologyBuilder builder = new TopologyBuilder(); + builder.setSpout(DATA_SOURCE_SPOUT, new DataSourceSpout()); + // split + builder.setBolt(SPLIT_BOLT, new SplitBolt()).shuffleGrouping(DATA_SOURCE_SPOUT); + // count + builder.setBolt(COUNT_BOLT, new CountBolt()).shuffleGrouping(SPLIT_BOLT); + // save to redis + JedisPoolConfig poolConfig = new JedisPoolConfig.Builder() + .setHost(REDIS_HOST).setPort(REDIS_PORT).build(); + RedisStoreMapper storeMapper = new WordCountStoreMapper(); + RedisStoreBolt storeBolt = new RedisStoreBolt(poolConfig, storeMapper); + builder.setBolt(STORE_BOLT, storeBolt).shuffleGrouping(COUNT_BOLT); + + // 如果外部传参cluster则代表线上环境启动否则代表本地启动 + if (args.length > 0 && args[0].equals("cluster")) { + try { + StormSubmitter.submitTopology("ClusterWordCountToRedisApp", new Config(), builder.createTopology()); + } catch (AlreadyAliveException | InvalidTopologyException | AuthorizationException e) { + e.printStackTrace(); + } + } else { + LocalCluster cluster = new LocalCluster(); + cluster.submitTopology("LocalWordCountToRedisApp", + new Config(), builder.createTopology()); + } + } +} +``` + +### 2.8 启动测试 + +可以用直接使用本地模式运行,也可以打包后提交到服务器集群运行。本仓库提供的源码默认采用`maven-shade-plugin`进行打包,打包命令如下: + +```shell +# mvn clean package -D maven.test.skip=true +``` + +启动后,查看Redis中的数据: + +![store-redis-manager](D:\BigData-Notes\pictures\store-redis-manager.png) + + + +## 三、storm-redis 实现原理 + +### 3.1 AbstractRedisBolt + +`RedisLookupBolt`和`RedisStoreBolt`都继承自`AbstractRedisBolt`抽象类,和我们自定义实现Bolt一样,`AbstractRedisBolt`间接继承自`BaseRichBolt`。 + + + +![storm-abstractRedisBolt](D:\BigData-Notes\pictures\storm-abstractRedisBolt.png) + +`AbstractRedisBolt`中比较重要的是prepare方法,在该方法中通过外部传入的jedis连接池配置( jedisPoolConfig/jedisClusterConfig) 创建用于管理Jedis实例的容器`JedisCommandsInstanceContainer`。 + +```java +public abstract class AbstractRedisBolt extends BaseTickTupleAwareRichBolt { + protected OutputCollector collector; + + private transient JedisCommandsInstanceContainer container; + + private JedisPoolConfig jedisPoolConfig; + private JedisClusterConfig jedisClusterConfig; + + ...... + + @Override + public void prepare(Map map, TopologyContext topologyContext, OutputCollector collector) { + // FIXME: stores map (stormConf), topologyContext and expose these to derived classes + this.collector = collector; + + if (jedisPoolConfig != null) { + this.container = JedisCommandsContainerBuilder.build(jedisPoolConfig); + } else if (jedisClusterConfig != null) { + this.container = JedisCommandsContainerBuilder.build(jedisClusterConfig); + } else { + throw new IllegalArgumentException("Jedis configuration not found"); + } + } + + ....... +} +``` + +`JedisCommandsInstanceContainer`的`build()`方法如下,实际上就是创建JedisPool或JedisCluster并传入容器中。 + +```java +public static JedisCommandsInstanceContainer build(JedisPoolConfig config) { + JedisPool jedisPool = new JedisPool(DEFAULT_POOL_CONFIG, config.getHost(), config.getPort(), config.getTimeout(), config.getPassword(), config.getDatabase()); + return new JedisContainer(jedisPool); + } + + public static JedisCommandsInstanceContainer build(JedisClusterConfig config) { + JedisCluster jedisCluster = new JedisCluster(config.getNodes(), config.getTimeout(), config.getTimeout(), config.getMaxRedirections(), config.getPassword(), DEFAULT_POOL_CONFIG); + return new JedisClusterContainer(jedisCluster); + } +``` + +### 3.2 RedisStoreBolt和RedisLookupBolt + +`RedisStoreBolt`中比较重要的是process方法,该方法主要从storeMapper中获取传入key/value的值,并按照其存储类型`dataType`调用jedisCommand的对应方法进行存储。 + +RedisLookupBolt 的实现基本类似,从lookupMapper中获取传入的key值,并进行查询操作。 + +```java +public class RedisStoreBolt extends AbstractRedisBolt { + private final RedisStoreMapper storeMapper; + private final RedisDataTypeDescription.RedisDataType dataType; + private final String additionalKey; + + public RedisStoreBolt(JedisPoolConfig config, RedisStoreMapper storeMapper) { + super(config); + this.storeMapper = storeMapper; + + RedisDataTypeDescription dataTypeDescription = storeMapper.getDataTypeDescription(); + this.dataType = dataTypeDescription.getDataType(); + this.additionalKey = dataTypeDescription.getAdditionalKey(); + } + + public RedisStoreBolt(JedisClusterConfig config, RedisStoreMapper storeMapper) { + super(config); + this.storeMapper = storeMapper; + + RedisDataTypeDescription dataTypeDescription = storeMapper.getDataTypeDescription(); + this.dataType = dataTypeDescription.getDataType(); + this.additionalKey = dataTypeDescription.getAdditionalKey(); + } + + + @Override + public void process(Tuple input) { + String key = storeMapper.getKeyFromTuple(input); + String value = storeMapper.getValueFromTuple(input); + + JedisCommands jedisCommand = null; + try { + jedisCommand = getInstance(); + + switch (dataType) { + case STRING: + jedisCommand.set(key, value); + break; + + case LIST: + jedisCommand.rpush(key, value); + break; + + case HASH: + jedisCommand.hset(additionalKey, key, value); + break; + + case SET: + jedisCommand.sadd(key, value); + break; + + case SORTED_SET: + jedisCommand.zadd(additionalKey, Double.valueOf(value), key); + break; + + case HYPER_LOG_LOG: + jedisCommand.pfadd(key, value); + break; + + case GEO: + String[] array = value.split(":"); + if (array.length != 2) { + throw new IllegalArgumentException("value structure should be longitude:latitude"); + } + + double longitude = Double.valueOf(array[0]); + double latitude = Double.valueOf(array[1]); + jedisCommand.geoadd(additionalKey, longitude, latitude, key); + break; + + default: + throw new IllegalArgumentException("Cannot process such data type: " + dataType); + } + + collector.ack(input); + } catch (Exception e) { + this.collector.reportError(e); + this.collector.fail(input); + } finally { + returnInstance(jedisCommand); + } + } + + ......... +} + +``` + +### 3.3 JedisCommands + +JedisCommands接口中定义了所有的 Redis 客户端命令,它有以下三个实现类,分别是Jedis、JedisCluster、ShardedJedis。Strom中主要使用前两种实现类,具体调用哪一个实现类来执行命令,由传入的是jedisPoolConfig还是jedisClusterConfig来决定。 + +![storm-jedicCommands](D:\BigData-Notes\pictures\storm-jedicCommands.png) + +### 3.4 RedisMapper 和 TupleMapper + +RedisMapper 和 TupleMapper 定义了 tuple 和 Redis 中的数据如何进行映射转换。 + +![storm-Redis-Mapper](D:\BigData-Notes\pictures\storm-Redis-Mapper.png) + +#### 1. TupleMapper + +TupleMapper 主要定义了两个方法: + ++ getKeyFromTuple(ITuple tuple): 从tuple中获取那个字段作为Key; + ++ getValueFromTuple(ITuple tuple):从tuple中获取那个字段作为Value; + +#### 2. RedisMapper + +定义了获取数据类型的方法`getDataTypeDescription()`,RedisDataTypeDescription中RedisDataType枚举类定义了所有可用的Redis数据类型: + +```java +public class RedisDataTypeDescription implements Serializable { + + public enum RedisDataType { STRING, HASH, LIST, SET, SORTED_SET, HYPER_LOG_LOG, GEO } + ...... + } +``` + +#### 3. RedisStoreMapper + +RedisStoreMapper继承TupleMapper和RedisMapper接口,用于存储数据时,没有定义额外方法。 + +#### 4. RedisLookupMapper + +RedisLookupMapper继承TupleMapper和RedisMapper接口, + ++ 定义了declareOutputFields方法,声明输出的字段。 ++ 定义了toTuple方法,将查询结果组装为Storm的Values的集合,并用于发送。 + +下面的例子表示从输入`Tuple`的获取`word`字段作为key,使用`RedisLookupBolt`进行查询后,将key和查询结果value组装为values并发送到下一个处理单元。 + +```java +class WordCountRedisLookupMapper implements RedisLookupMapper { + private RedisDataTypeDescription description; + private final String hashKey = "wordCount"; + + public WordCountRedisLookupMapper() { + description = new RedisDataTypeDescription( + RedisDataTypeDescription.RedisDataType.HASH, hashKey); + } + + @Override + public List toTuple(ITuple input, Object value) { + String member = getKeyFromTuple(input); + List values = Lists.newArrayList(); + values.add(new Values(member, value)); + return values; + } + + @Override + public void declareOutputFields(OutputFieldsDeclarer declarer) { + declarer.declare(new Fields("wordName", "count")); + } + + @Override + public RedisDataTypeDescription getDataTypeDescription() { + return description; + } + + @Override + public String getKeyFromTuple(ITuple tuple) { + return tuple.getStringByField("word"); + } + + @Override + public String getValueFromTuple(ITuple tuple) { + return null; + } +} +``` + +#### 5. RedisFilterMapper + +RedisFilterMapper继承TupleMapper和RedisMapper接口,用于查询数据时,定义了declareOutputFields方法,声明输出的字段。如下面的实现: + +```java +@Override +public void declareOutputFields(OutputFieldsDeclarer declarer) { + declarer.declare(new Fields("wordName", "count")); +} + +``` + +## 四、自定义RedisBolt实现词频统计 + +自定义RedisBolt:利用Redis中哈希结构的hincrby key field命令进行词频统计。在Redis中`hincrby`的执行效果如下,如果在执行时字段不存在,则在执行操作之前将值设置为0。通过这个命令可以非常轻松的实现词频统计功能。 + +```shell +redis> HSET myhash field 5 +(integer) 1 +redis> HINCRBY myhash field 1 +(integer) 6 +redis> HINCRBY myhash field -1 +(integer) 5 +redis> HINCRBY myhash field -10 +(integer) -5 +redis> +``` + +### 4.1 自定义RedisBolt的代码实现 + +```java +/** + * 自定义RedisBolt 利用Redis的哈希数据结构的hincrby key field命令进行词频统计 + */ +public class RedisCountStoreBolt extends AbstractRedisBolt { + + private final RedisStoreMapper storeMapper; + private final RedisDataTypeDescription.RedisDataType dataType; + private final String additionalKey; + + public RedisCountStoreBolt(JedisPoolConfig config, RedisStoreMapper storeMapper) { + super(config); + this.storeMapper = storeMapper; + RedisDataTypeDescription dataTypeDescription = storeMapper.getDataTypeDescription(); + this.dataType = dataTypeDescription.getDataType(); + this.additionalKey = dataTypeDescription.getAdditionalKey(); + } + + @Override + protected void process(Tuple tuple) { + String key = storeMapper.getKeyFromTuple(tuple); + String value = storeMapper.getValueFromTuple(tuple); + + JedisCommands jedisCommand = null; + try { + jedisCommand = getInstance(); + if (dataType == RedisDataTypeDescription.RedisDataType.HASH) { + jedisCommand.hincrBy(additionalKey, key, Long.valueOf(value)); + } else { + throw new IllegalArgumentException("Cannot process such data type for Count: " + dataType); + } + + collector.ack(tuple); + } catch (Exception e) { + this.collector.reportError(e); + this.collector.fail(tuple); + } finally { + returnInstance(jedisCommand); + } + } + + @Override + public void declareOutputFields(OutputFieldsDeclarer declarer) { + + } +} +``` + +### 4.2 CustomRedisCountApp + +```java +/** + * 利用自定义的RedisBolt实现词频统计 + */ +public class CustomRedisCountApp { + + private static final String DATA_SOURCE_SPOUT = "dataSourceSpout"; + private static final String SPLIT_BOLT = "splitBolt"; + private static final String STORE_BOLT = "storeBolt"; + + private static final String REDIS_HOST = "192.168.200.226"; + private static final int REDIS_PORT = 6379; + + public static void main(String[] args) { + TopologyBuilder builder = new TopologyBuilder(); + builder.setSpout(DATA_SOURCE_SPOUT, new DataSourceSpout()); + // split + builder.setBolt(SPLIT_BOLT, new SplitBolt()).shuffleGrouping(DATA_SOURCE_SPOUT); + // save to redis and count + JedisPoolConfig poolConfig = new JedisPoolConfig.Builder() + .setHost(REDIS_HOST).setPort(REDIS_PORT).build(); + RedisStoreMapper storeMapper = new WordCountStoreMapper(); + RedisCountStoreBolt countStoreBolt = new RedisCountStoreBolt(poolConfig, storeMapper); + builder.setBolt(STORE_BOLT, countStoreBolt).shuffleGrouping(SPLIT_BOLT); + + // 如果外部传参cluster则代表线上环境启动,否则代表本地启动 + if (args.length > 0 && args[0].equals("cluster")) { + try { + StormSubmitter.submitTopology("ClusterCustomRedisCountApp", new Config(), builder.createTopology()); + } catch (AlreadyAliveException | InvalidTopologyException | AuthorizationException e) { + e.printStackTrace(); + } + } else { + LocalCluster cluster = new LocalCluster(); + cluster.submitTopology("LocalCustomRedisCountApp", + new Config(), builder.createTopology()); + } + } +} +``` \ No newline at end of file diff --git a/notes/installation/基于Zookeeper搭建Kafka高可用集群.md b/notes/installation/基于Zookeeper搭建Kafka高可用集群.md index e69de29..9fdcad1 100644 --- a/notes/installation/基于Zookeeper搭建Kafka高可用集群.md +++ b/notes/installation/基于Zookeeper搭建Kafka高可用集群.md @@ -0,0 +1,118 @@ +# 基于Zookeeper搭建Kafka高可用集群 + +## 一、Zookeeper集群搭建 + +## 二、Kafka集群搭建 + +### 2.1 下载解压 + +Kafka安装包官方下载地址:http://kafka.apache.org/downloads ,本用例下载的版本为`2.2.0`,下载命令: + +```shell +# 下载 +wget https://www-eu.apache.org/dist/kafka/2.2.0/kafka_2.12-2.2.0.tgz +``` + +这里说明一下kafka安装包的命名规则:以`kafka_2.12-2.2.0.tgz`为例,前面的2.12代表Scala的版本号(Kafka是采用Scala语言开发的),后面的2.2.0代表Kafka的版本号。 + +```shell +# 解压 +tar -xzf kafka_2.12-2.2.0.tgz +``` + +### 2.2 拷贝配置文件 + +进入解压目录的` config`目录下 ,拷贝三份配置文件 + +```shell +# cp server.properties server-1.properties +# cp server.properties server-2.properties +# cp server.properties server-3.properties +``` + +### 2.3 修改配置 + +分别修改三份配置文件中的部分配置,如下: + +server-1.properties: + +```properties +# The id of the broker. 集群中每个节点的唯一标识 +broker.id=0 +# 监听地址 +listeners=PLAINTEXT://hadoop001:9092 +# 日志文件存放位置 +log.dirs=/usr/local/kafka-logs/00 +# Zookeeper连接地址 +zookeeper.connect=hadoop001:2181,hadoop001:2182,hadoop001:2183 +``` + +server-2.properties: + +```properties +broker.id=1 +listeners=PLAINTEXT://hadoop001:9093 +log.dirs=/usr/local/kafka-logs/01 +zookeeper.connect=hadoop001:2181,hadoop001:2182,hadoop001:2183 +``` + +server-3.properties: + +```properties +broker.id=2 +listeners=PLAINTEXT://hadoop001:9094 +log.dirs=/usr/local/kafka-logs/02 +zookeeper.connect=hadoop001:2181,hadoop001:2182,hadoop001:2183 +``` + +### 2.4 启动集群 + +分别指定不同配置文件,启动三个Kafka节点: + +```shell +bin/kafka-server-start.sh config/server-1.properties +bin/kafka-server-start.sh config/server-2.properties +bin/kafka-server-start.sh config/server-3.properties +``` + +启动后使用jps查看进程,此时应该有三个zookeeper进程和三个kafka进程: + +```shell +[root@hadoop001 kafka_2.12-2.2.0]# jps +14288 QuorumPeerMain +18385 Jps +16228 Kafka +17653 Kafka +14374 QuorumPeerMain +16826 Kafka +14446 QuorumPeerMain +``` + +### 2.5 创建测试主题 + +创建测试主题: + +```shell +bin/kafka-topics.sh --create --bootstrap-server hadoop001:9092 --replication-factor 3 --partitions 1 --topic my-replicated-topic +``` + +查看主题信息: + +```shell +bin/kafka-topics.sh --describe --bootstrap-server hadoop001:9092 --topic my-replicated-topic +``` + +![kafka-cluster-shell](D:\BigData-Notes\pictures\kafka-cluster-shell.png) + +还可以进一步创建一个消费者和一个生产者进行测试: + +```shell +# 创建生产者 +bin/kafka-console-producer.sh --broker-list hadoop001:9093 --topic my-replicated-topic +``` + +```shell +# 创建消费者 +bin/kafka-console-consumer.sh --bootstrap-server hadoop001:9094 --from-beginning --topic my-replicated-topic +``` + diff --git a/pictures/jar-with-dependencies.png b/pictures/jar-with-dependencies.png new file mode 100644 index 0000000000000000000000000000000000000000..c1254bf3de717654d9481e4ab5d7b1e4963e0909 GIT binary patch literal 68149 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�BOO_wTz=%Asv$qbE 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�o{Q9CRqpH%g5y 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 G3;sXy9&l*@ literal 0 HcmV?d00001 diff --git a/pictures/kafka-cluster-shell.png b/pictures/kafka-cluster-shell.png new file mode 100644 index 0000000000000000000000000000000000000000..3826dba25f81041cfc2fb2aac5a156364ee77038 GIT binary patch literal 18090 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 literal 0 HcmV?d00001 diff --git a/pictures/storm-abstractRedisBolt.png b/pictures/storm-abstractRedisBolt.png new file mode 100644 index 0000000000000000000000000000000000000000..62c15df414afce04aaf30a6c344efcfb3e4b1de7 GIT binary patch literal 18244 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 F{|BsN+k^lB literal 0 HcmV?d00001 diff --git a/pictures/storm-jar2.png b/pictures/storm-jar2.png new file mode 100644 index 0000000000000000000000000000000000000000..2771741b274f7483a72b710a59dd060aba33c8f1 GIT binary patch literal 21074 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%0A#0>Fch5ctS-UkgN85a?6DxE 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 G#s39^*Dr_w literal 0 HcmV?d00001 diff --git a/pictures/storm-jedicCommands.png b/pictures/storm-jedicCommands.png new file mode 100644 index 0000000000000000000000000000000000000000..5c60e051895390f3d0e4aea4c140d7378a68be35 GIT binary patch literal 5943 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 literal 0 HcmV?d00001