kafkautil:


import java.util.Properties;

import kafka.javaapi.producer.Producer;
import kafka.producer.ProducerConfig; import org.springframework.beans.factory.annotation.Value; public class KafkaUtil { @Value("#{sys['connect']}")
private static String zkConnect ;
@Value("#{sys['metadata.broker.list']}")
private static String brokerList;
@Value("#{sys['request.required.acks']}")
private static String ack; private static Producer<String, String> producer = null; /*static{
Properties p = PropertiesUtil.getProperties("kafka.properties");
zkConnect = (String) p.get("zk.connect");
brokerList = (String) p.get("metadata.broker.list");
ack = (String) p.get("request.required.acks");
topic = (String) p.get("topic.imeidata");
}
*/
public static Producer<String,String> getProducer(){
if(producer == null){
Properties p = PropertiesUtil.getProperties("kafka.properties");
zkConnect = (String) p.get("zk.connect");
brokerList = (String) p.get("metadata.broker.list");
ack = (String) p.get("request.required.acks"); Properties props = new Properties();
props.put("zk.connect", zkConnect);
props.put("metadata.broker.list", brokerList);
props.put("serializer.class", "kafka.serializer.StringEncoder");
props.put("request.required.acks", ack);
props.put("producer.type", "async");//是否同步 sync:同步 async:异步
props.put("partitioner.class", "com.kafka.SendPartitioner");//发送到多个分区进行分布式存储的分区算法类 props.put("request.timeout.ms", "50000");
props.put("queue.buffering.max.ms", "10000");//默认值5000 异步模式下,每隔此时间间隔会将缓冲的消息提交一次
props.put("batch.num.messages", "1000");//默认值200 异步模式下,一次批量提交消息的条数,
//但如果间隔时间超过 queue.buffering.max.ms 的值,不管有没有达到批量提交的设值,都会进行一次提交
ProducerConfig config = new ProducerConfig(props);
producer = new Producer<String, String>(config);
}
return producer;
} }
kafka消息发送类的属性:
1:zk.connect:zk服务端连接地址

2:metadata.broker.list:zk客户端地址
3:serializer.class:kafka消息发送序列化格式

4:request.required.acks:是否确认消息消费机制 它有三个选项:1,0,-1
0,意味着producer永远不会等待一个来自broker的ack,这就是0.7版本的行为。这个选项提供了最低的延迟,但是持久化的保证是最弱的,当server挂掉的时候会丢失一些数据。经测试,每10K消息大约会丢几百条消息。 1,意味着在leader replica已经接收到数据后,producer会得到一个ack。这个选项提供了更好的持久性,因为在server确认请求成功处理后,client才会返回。如果刚写到leader上,还没来得及复制leader就挂了,那么消息才可能会 丢失。

-1,意味着在所有的ISR都接收到数据后,producer才得到一个ack。这个选项提供了最好的持久性,只要还有一个replica存活,那么数据就不会丢失。经测试,100W条消息没有丢消息。

  

5:request.timeout.ms:请求超时
6:producer.type 是否同步 它有两个选项 sync:同步   async:异步  同步模式下,每发送一次消息完毕才会返回 在异步模式下,可以选择异步参数。
7:queue.buffering.max.ms:默认值5000  异步模式下,每隔此时间间隔会将缓冲的消息提交一次
8:batch.num.messages:默认值200  异步模式下,一次批量提交消息的条数,但如果间隔时间超过 queue.buffering.max.ms 的值,不管有没有达到批量提交的设值,都会进行一次提交
9:partitioner.class:自定义分区算法
在一个kafka集群中,每一个节点称为一个broker,所以进入zk通过/ls命令查看根目录有个brokers目录(kafka默认安装配置文件是放在zk根目录,我更喜欢入在自定义目录下),这里保存了当前kafka集群在正在运行的节点名:

只有将所有消息最大限度平均的发送到每个broker上去,才能达到最好的集群效果。那么kafka是通过什么来保证这一点的呢。
 
kafka消息类KeyedMessae中有一个方法,参数分别为将要发送消息的队列,和消息KEY,VALUE。通过对KEY的HASH值求broker的个数求模,将会得到broker值,它就是将接收消息的节点。
可以自定义分区实现类,并在属性中指明:
import kafka.producer.Partitioner;
import kafka.utils.VerifiableProperties; public class SendPartitioner implements Partitioner{ public SendPartitioner(VerifiableProperties verifiableProperties) {} @Override
public int partition(Object key, int numPartitions) {
try {
return Math.abs(key.hashCode() % numPartitions);
} catch (Exception e) {
return Math.abs(key.hashCode() % numPartitions);
}
} }
numPartitions 指的是kafka集群节点数,不用显式指定,它可以通过zk实时得到此值。

以上属性大都可以通过kafka的安装配置文件来指定。但一个kafka集群可能并不止服务一个队列或者一个项目。不同的项目具体业务需求不同,所以最好是在各个项目提定具体的参数。

 Storm:

storm与kafka集成有第三方框架,叫做storm-kafka.jar。简而言之,它其实只做了一件事情。就是已经写好了storm的spout,我们只需要编写bolt和提交topology即可实现storm.

它帮我们实现了kafka消费端相对难把握的一件事情,就是偏移量offset的问题。如果你不想每次启动都重头读取kafka消息,尽量避免消息重复消费,那必须要保证良好的偏移量机制。特别是在多个用户组和队列的情况下。

代码:

import com.util.PropertiesUtil;

import storm.kafka.KafkaSpout;
import storm.kafka.SpoutConfig;
import storm.kafka.StringScheme;
import storm.kafka.ZkHosts;
import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.StormSubmitter;
import backtype.storm.spout.SchemeAsMultiScheme;
import backtype.storm.topology.TopologyBuilder; public class Topology { private static String topic;
private static String brokerZkStr;
private static String brokerZkPath;
private static String offset;
private static String app; static{
Properties p = PropertiesUtil.getProperties("storm.properties");
brokerZkStr = (String) p.get("brokerZkStr");
brokerZkPath = (String) p.get("brokerZkPath");
topic = (String) p.get("kafka.topic");
offset = (String) p.get("kafka.offset");
app = (String) p.get("kafka.app"); } public static void main(String[] args) throws InterruptedException {
ZkHosts zk = new ZkHosts(brokerZkStr,brokerZkPath);
SpoutConfig spoutConf = new SpoutConfig(zk, topic,
offset,//偏移量 offset 的根目录
app);//对应一个应用 List<String> zkServices = new ArrayList<>(); for(String str : zk.brokerZkStr.split(",")){
zkServices.add(str.split(":")[0]);
} spoutConf.zkServers = zkServices;
spoutConf.zkPort = 2181;
spoutConf.forceFromStart = false;// true:从头消费 false:从offset处消费
spoutConf.socketTimeoutMs = 60 * 1000;
spoutConf.scheme = new SchemeAsMultiScheme(new StringScheme()); TopologyBuilder builder = new TopologyBuilder();
builder.setSpout("spout", new KafkaSpout(spoutConf),4);
//builder.setSpout("spout", new TestSpout(),5);
builder.setBolt("bolt1", new GetMsgBolt(),4).shuffleGrouping("spout"); Config config = new Config();
config.setDebug(false);
config.setNumWorkers(4);
if(args.length>0){
try {
StormSubmitter.submitTopology(args[0], config, builder.createTopology());
} catch (Exception e) {
e.printStackTrace();
}
}else{
LocalCluster cluster = new LocalCluster();
cluster.submitTopology("MyTopology", config, builder.createTopology());
}
}
}
属性:
1:brokerZkPath kafka集群在zk里的根目录,默认是brokers
2:kafka.offset kafka消息队列偏移量记录在zk中的位置
3:kafka.app 实际上就是kafka.offset的子目录,父级目录规定了kafka集群消息offset的总位置,子目录是具体每个队列或者应用消息的偏移量,避免在多用户组多队列情况下偏移量错乱的情况。

storm集成kafka的更多相关文章

  1. Storm集成Kafka应用的开发

    我们知道storm的作用主要是进行流式计算,对于源源不断的均匀数据流流入处理是非常有效的,而现实生活中大部分场景并不是均匀的数据流,而是时而多时而少的数据流入,这种情况下显然用批量处理是不合适的,如果 ...

  2. storm集成kafka的应用,从kafka读取,写入kafka

    storm集成kafka的应用,从kafka读取,写入kafka by 小闪电 0前言 storm的主要作用是进行流式的实时计算,对于一直产生的数据流处理是非常迅速的,然而大部分数据并不是均匀的数据流 ...

  3. Storm集成Kafka的Trident实现

      原本打算将storm直接与flume直连,发现相应组件支持比较弱,topology任务对应的supervisor也不一定在哪个节点上,只能采用统一的分布式消息服务Kafka.   原本打算将结构设 ...

  4. Storm 学习之路(九)—— Storm集成Kafka

    一.整合说明 Storm官方对Kafka的整合分为两个版本,官方说明文档分别如下: Storm Kafka Integration : 主要是针对0.8.x版本的Kafka提供整合支持: Storm ...

  5. Storm 系列(九)—— Storm 集成 Kafka

    一.整合说明 Storm 官方对 Kafka 的整合分为两个版本,官方说明文档分别如下: Storm Kafka Integration : 主要是针对 0.8.x 版本的 Kafka 提供整合支持: ...

  6. Storm集成Kafka编程模型

    原创文章,转载请注明: 转载自http://www.cnblogs.com/tovin/p/3974417.html 本文主要介绍如何在Storm编程实现与Kafka的集成 一.实现模型 数据流程: ...

  7. 5、Storm集成Kafka

    1.pom文件依赖 <!--storm相关jar --> <dependency> <groupId>org.apache.storm</groupId> ...

  8. Storm应用系列之——集成Kafka

    本文系原创系列,转载请注明. 原帖地址:http://blog.csdn.net/xeseo 前言 在前面Storm系列之——基本概念一文中,提到过Storm的Spout应该是源源不断的取数据,不能间 ...

  9. spark streaming集成kafka

    Kakfa起初是由LinkedIn公司开发的一个分布式的消息系统,后成为Apache的一部分,它使用Scala编写,以可水平扩展和高吞吐率而被广泛使用.目前越来越多的开源分布式处理系统如Clouder ...

随机推荐

  1. 使用NPOI操纵Excle,并输入到客户端

    NPOI下载:http://files.cnblogs.com/files/gosky/NPOI_2.2.0.0.zip 导入以下5个引用: ICSharpCode.SharpZipLib.dll N ...

  2. [leetcode]_Maximum Depth of Binary Tree

    第三道树的题目,我还是不会,我擦,怎么递归算法还是不能很好理解.看来还得好好研究下递归算法. 题目:求一棵树的最大深度. 思路:递归地求取左子树最大深度 和 右子树最大深度,返回较大值即为 整棵树的 ...

  3. 往Android SDCard中读写入数据

    一.用Environment (写) 1.API获取sdcard的路径 File path=Environment.getExternalStorageDirectory(); path=new Fi ...

  4. VMT & DMT

    虚拟方法表和动态方法表 虚拟方法表VMT: 一个虚拟方法表从指针所指地址的负偏移.76 处开始,长度动态分配(由虚拟方法的个数确定).虚拟方法表被分为很多小段,每段占4 个字节,也就是众多指针.每个指 ...

  5. 网页绘制图表 Google Charts with JavaScript #2 ....与ASP.NET网页结合 (ClientScriptManager.RegisterStartupScript 方法)

    此为文章备份,原文出处(我的网站) 网页绘制图表 Google Charts with JavaScript #2 ....与ASP.NET网页结合 (ClientScriptManager.Regi ...

  6. 9.python的布尔类型与流程控制

    布尔类型其实可以算是一种特殊的数字,下面是 help() 函数得到的帮助信息: Help on class bool in module __builtin__: class bool(int) | ...

  7. Python学习教程(learning Python)--2.3.5 Python返回多个值问题

    本节主要学习Python的函数是如何同时返回多个值的问题. 在学习Python的时候惊奇的发现,Python的函数可以同时返回多个值,很有意思. #define function sum def su ...

  8. Oracle 错误代码

    ORA-00001: 违反唯一约束条件 (.) ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 ORA-00019: 超出最大会话许可数 ORA-00020: 超出 ...

  9. 删除字符串第一个byte

    删除字符串第一个byte   一种方式:   char * mag; char buff[1000]; char number; memcpy((char *)msg,buff,len); strnc ...

  10. struct的成员对齐问题-结构体实际大小问题

    struct的成员对齐 注意:为了方便说明,等号左边是每个数据单独所占长度,右边是最终空间大小,以字节为单位. 一.什么时间存在对其问题:(32位机对齐方式是按照4字节对其的,以下所有试验都是在32位 ...