1. hbase sink介绍

如果还不了解flume请查看我写的其他flume下的博客。

接下来的内容主要来自flume官方文档的学习。

顺便也强烈推荐flume 1.6 官方API

hbase的sink主要有以下两种。两种方式都提供和HBASE一样的一致性保证,即行级原子性

1.1 HbaseSink

agent的配置时提供两种序列化模式:

  1. SimpleHbaseEventSerializer: 将整个事件body部分当做完整的一列写入hbase
  2. RegexHbaseEventSerializer: 根据正则表达式将event body拆分到不同的列当中

优点:
安全性较高:支持往secure hbase写数据(hbase可以开启kerberos校验)

缺点:
性能没有后面的那种AsyncHBaseSink高

1.2 AsyncHbaseSink

异步的Sink,可见速度是比前者快的,但是不支持往Secure Hbase写数据。

采用的序列化器是:SimpleAsyncHbaseEventSerializer,也支持将event body分割成多个列,插入到对应KEY的ROW里

2. 配置flume

我们这里hbase没有开启安全相关选项,一般这集群也主要在内网环境。所以我们这里采用AsyncHbaseSink来进行本次操作。source则为kafka。

channel我们也选用kafka channel。之所以选择kafka channel的依据可以参考flume中各类channel分析对比

配置文件如下:

# ------------------- 定义数据流----------------------
# source的名字
agent.sources = kafkaSource
# channels的名字,建议按照type来命名
agent.channels = kafkaChannel
# sink的名字,建议按照目标来命名
agent.sinks = hbaseSink # ---------------------定义source和sink的绑定关系---------------- # 指定source使用的channel名字
agent.sources.kafkaSource.channels = kafkaChannel
# 指定sink需要使用的channel的名字,注意这里是channel
agent.sinks.hbaseSink.channel = kafkaChannel #-------- kafkaSource相关配置-----------------
# 定义消息源类型
agent.sources.kafkaSource.type = org.apache.flume.source.kafka.KafkaSource
# 定义kafka所在zk的地址
agent.sources.kafkaSource.zookeeperConnect = 10.45.9.139:2181
# 配置消费的kafka topic
agent.sources.kafkaSource.topic = my-topic-test
# 配置消费者组的id
agent.sources.kafkaSource.groupId = flume
# 消费超时时间,参照如下写法可以配置其他所有kafka的consumer选项。注意格式从kafka.xxx开始是consumer的配置属性
agent.sources.kafkaSource.kafka.consumer.timeout.ms = 100 #------- kafkaChannel相关配置-------------------------
# channel类型
agent.channels.kafkaChannel.type = org.aprache.flume.channel.kafka.KafkaChannel
# channel存储的事件容量,即队列长度
agent.channels.kafkaChannel.capacity=10000
# 事务容量
agent.channels.kafkaChannel.transactionCapacity=1000
# kafka broker list
agent.channels.kafkaChannel.brokerList=mysql1:9092,mysql4:9092
# 指定topic
agent.channels.topic=flume
# 指定zk地址
agent.channels.kafkaChannel.zookeeperConnect=10.45.9.139:2181
# 指定producer的选项,关键是指定acks的值,保证消息发送的可靠性,retries采用默认的3
agent.channels.kafkaChannel.kafka.producer.acks=all #---------hbaseSink 相关配置------------------
# 指定sink类型。PS:如果使用RegexHbaseEventSerializer只能使用hbase类型
# agent.sinks.hbaseSink.type = hbase
agent.sinks.hbaseSink.type = asynchbase
# 指定hbase中的表名
agent.sinks.hbaseSink.table = student
# 指明column family
agent.sinks.hbaseSink.columnFamily= info
# 使用的serializer
agent.sinks.hbaseSink.serializer=org.apache.flume.sink.hbase.SimpleAsyncHbaseEventSerializer
# 如果需要使用正则处理value可以使用以下的serializer
#agent.sinks.hbaseSink.serializer=org.apache.flume.sink.hbase.RegexHbaseEventSerializer
# 指定正则表达式,这里用的正则是匹配逗号分隔的字符串
#agent.sinks.hbaseSink.serializer.regex= ^([^,]+),([^,]+),([^,]+),([^,]+)$
# 指定在列族中对应的的colName
# agent.sinks.hbaseSink.serializer.colNames=c1,c2,c3 # 指定hbase所用的zk集合
agent.sinks.hbaseSink.zookeeperQuorum = mysql3:2181,mysql4:2181,mysql5:2181

3. 运行测试flume

在$FLUME_HOME/bin下执行以下命令运行。后台会开启一个Application 的Java进程

nohup sh flume-ng agent --conf-file ../conf/flume-conf.properties --name agent -Dflume.root.logger=INFO,console &

然后写个kafka的producer往我们前面定义的my-topic-test中写消息。
producer的代码如下:

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord; import java.util.Properties; /**
* @author Wan Kaiming on 2016/8/1
* @version 1.0
*/
public class MyProducer {
public static void main(String[] args) {
Properties props = new Properties();
//broker地址 这里用域名,记得修改本地的hosts文件
props.put("bootstrap.servers", "mysql1:9092,mysql4:9092");
//消息可靠性语义
props.put("acks", "all");
//请求broker失败进行重试的次数,避免由于请求broker失败造成的消息重复
props.put("retries", 0);
//按批发送,每批的消息数量
props.put("batch.size", 16384);
//防止来不及发送,延迟一点点时间,使得能够批量发送消息
props.put("linger.ms", 1);
//缓冲大小,bytes
props.put("buffer.memory", 33554432);
//key的序列化类
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
//value的序列化类
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); //创建一个Producer对象,加载配置上下文信息
Producer<String, String> producer = new KafkaProducer<String,String>(props); for(int i=0;i<6;i++){
producer.send(new ProducerRecord<String, String>("my-topic-test", "hello", "world"));
} // while(true){
// //调用send方法进行发送。send方法将消息加到缓存,异步发送
// producer.send(new ProducerRecord<String, String>("my-topic", "hello", "world"));
// } producer.close();
}
}

运行完毕后可以去hbase shell中检查下:

总结:可见key全部是由flume自动生成的。发送给kafka的 value值"world"全部成功保存到HBASE

PS:

  1. 最后一行多出来的incRow是Flume的SimpleAsyncHbaseEventSerializer中使用的。用来统计行数的,每次都在最后一行,效果就是一个计数的count。
  2. 这里产生的行的名字是pCol和iCol都是SimpleAsyncHbaseEventSerializer的默认值,其实可以自定义指定

总结:可见,如果需要更加自由的对写入HBASE的数据做自定义,建议需要了解下这个Event序列化类的源码,然后可以自定义序列化类

4. 使用RegexHbaseEventSerializer来处理些HBASE的值

重要提示:使用RegexHbaseEventSerializer不支持最新的hbase1.2.2。请换成hbase-0.98.20-hadoop2-bin.tar.gz,否则可能会报错找不到类。该BUG说明见:Flume 1.6 HBase 1.12 java.lang.NoSuchMethodError

  1. 修改flume的配置文件,改用RegexHbaseEventSerializer,我使用的配置文件如下
# ------------------- 定义数据流----------------------
# source的名字
agent.sources = kafkaSource
# channels的名字,建议按照type来命名
agent.channels = kafkaChannel
# sink的名字,建议按照目标来命名
agent.sinks = hbaseSink # ---------------------定义source和sink的绑定关系---------------- # 指定source使用的channel名字
agent.sources.kafkaSource.channels = kafkaChannel
# 指定sink需要使用的channel的名字,注意这里是channel
agent.sinks.hbaseSink.channel = kafkaChannel #-------- kafkaSource相关配置-----------------
# 定义消息源类型
agent.sources.kafkaSource.type = org.apache.flume.source.kafka.KafkaSource
# 定义kafka所在zk的地址
agent.sources.kafkaSource.zookeeperConnect = 10.45.9.139:2181
# 配置消费的kafka topic
agent.sources.kafkaSource.topic = my-topic-regex
# 配置消费者组的id
agent.sources.kafkaSource.groupId = flume
# 消费超时时间,参照如下写法可以配置其他所有kafka的consumer选项。注意格式从kafka.xxx开始是consumer的配置属性
agent.sources.kafkaSource.kafka.consumer.timeout.ms = 100
#------- kafkaChannel相关配置-------------------------
# channel类型
agent.channels.kafkaChannel.type = org.apache.flume.channel.kafka.KafkaChannel
# channel存储的事件容量,即队列长度
agent.channels.kafkaChannel.capacity=10000
# 事务容量
agent.channels.kafkaChannel.transactionCapacity=1000
# kafka broker list
agent.channels.kafkaChannel.brokerList=mysql1:9092,mysql4:9092
# 指定topic
agent.channels.kafkaChannel.topic=flume-regex-channel
# 指定zk地址
agent.channels.kafkaChannel.zookeeperConnect=10.45.9.139:2181
# 指定producer的选项,关键是指定acks的值,保证消息发送的可靠性,retries采用默认的3
# agent.channels.kafkaChannel.kafka.producer.acks=all #---------hbaseSink 相关配置------------------
# 指定sink类型
# agent.sinks.hbaseSink.type = asynchbase
agent.sinks.hbaseSink.type = hbase
# 指定hbase中的表名
agent.sinks.hbaseSink.table = student
# 指明column family
agent.sinks.hbaseSink.columnFamily = info
# 使用的serializer
# agent.sinks.hbaseSink.serializer=org.apache.flume.sink.hbase.SimpleAsyncHbaseEventSerializer # 如果需要使用正则处理value可以使用以下的serializer
agent.sinks.hbaseSink.serializer= org.apache.flume.sink.hbase.RegexHbaseEventSerializer
# 指定某一列来当主键,而不是用随机生成的key
# agent.sinks.hbaseSink.serializer.rowKeyIndex = 0
# 指定正则表达式,这里用的正则是匹配逗号分隔的字符串
agent.sinks.hbaseSink.serializer.regex=^([^,]+),([^,]+),([^,]+),([^,]+)$
# 指定在列族中对应的的colName
agent.sinks.hbaseSink.serializer.colNames=c1,c2,c3,c4 # 指定hbase所用的zk集合
agent.sinks.hbaseSink.zookeeperQuorum = mysql3:2181,mysql4:2181,mysql5:2181
  1. 修改producer文件,将value值发送"one,two,three,four"可以匹配正则。执行结果如下图:

PS:建议把lfume默认的JVM大小改大点,并且开启JMX方便监控JVM

vi $FLUME_HOME/bin/flume-ng
# set default params
# 若干内容...
JAVA_OPTS="-Xmx1500m -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false "
LD_LIBRARY_PATH=""
# 若干内容...

5. 效率测试

测试按照第四节的配置来进行。生产者代码如下:

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord; import java.util.Date;
import java.util.Properties; /**
* @author Wan Kaiming on 2016/8/1
* @version 1.0
*/
public class MyProducer {
public static void main(String[] args) { //统计时间
System.out.println("程序开始时间戳信息:"+new Date());
final long startTime=System.currentTimeMillis(); Properties props = new Properties();
//broker地址 这里用域名,记得修改本地的hosts文件
props.put("bootstrap.servers", "mysql1:9092,mysql4:9092");
//消息可靠性语义
props.put("acks", "all");
//请求broker失败进行重试的次数,避免由于请求broker失败造成的消息重复
props.put("retries", 3);
//按批发送,每批的消息数量
//props.put("batch.size", 16384);
props.put("batch.size", 16384);
//防止来不及发送,延迟一点点时间,使得能够批量发送消息
props.put("linger.ms", 1);
//缓冲大小,bytes
props.put("buffer.memory", 33554432);
//key的序列化类
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
//value的序列化类
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); //创建一个Producer对象,加载配置上下文信息
Producer<String, String> producer = new KafkaProducer<String,String>(props); for(int i=0;i<1000000;i++){
producer.send(new ProducerRecord<String, String>("my-topic-regex", Integer.toString(i), "one,two,three,four"));
} producer.close(); final long endTime=System.currentTimeMillis();
float excTime=(float)(endTime-startTime)/1000;
System.out.println("执行时间:"+excTime+"s");
System.out.println("当前时间为:"+ new Date());
}
}

测试基本信息:

名称 信息
PC硬件信息 Intel(R) Xeon(R) CPU E7- 4830 @ 2.13GHz,内存4G
JAVA JDK1.8
KAFKA 2台broker(heap size =1200M),1个topic,5个分区,2个复制分区,acks=all
flume 1.60版本,heap size=1.5G,kafkachannel,kafka source,hbase sink。
负载信息 100万条消息,每条消息20byte的样子
hbase 1台master,3台slave,其中1台slave和master在一台机器,版本0.98-hadoop2

测试结果1(kafkachannel=0):

  1. kafka发送消息时间:6.912s
  2. hbase接受完全部消息:4分33s
  3. 延迟时间:4分26s

测试结果2(kafkachannel=all):

  1. kafka发送消息时间:8.25s
  2. hbase接受完全部消息:4分59s
  3. 延迟时间:4分51s

PS: 测试会存在一定误差。因为读取hbase的时候是按照1000条的批大小批量读取的,count完整个HBASE的记录本身也会花很多时间。也就是意味着,实际的延迟时间肯定比我测试的要小。测试1的时候,32.8万条消息,花费时间约为120s,得到吞吐量TPS=2733。该值基本比较准确。

综上,在保证消息可靠性前提下,kafka消息通过flume写hbase的吞吐量TPS基本在3K左右这个数量级。相信经过更多的配置优化、硬件性能提升、增大JVM堆等方式,提升TPS不是问题。

使用flume将kafka数据sink到HBase【转】的更多相关文章

  1. flume 读取kafka 数据

    本文介绍flume读取kafka数据的方法 代码: /************************************************************************* ...

  2. Spark Streaming接收Kafka数据存储到Hbase

    Spark Streaming接收Kafka数据存储到Hbase fly spark hbase kafka 主要参考了这篇文章https://yq.aliyun.com/articles/60712 ...

  3. 使用Flume消费Kafka数据到HDFS

    1.概述 对于数据的转发,Kafka是一个不错的选择.Kafka能够装载数据到消息队列,然后等待其他业务场景去消费这些数据,Kafka的应用接口API非常的丰富,支持各种存储介质,例如HDFS.HBa ...

  4. 大数据平台架构(flume+kafka+hbase+ELK+storm+redis+mysql)

    上次实现了flume+kafka+hbase+ELK:http://www.cnblogs.com/super-d2/p/5486739.html 这次我们可以加上storm: storm-0.9.5 ...

  5. flume+kafka+hbase+ELK

    一.架构方案如下图: 二.各个组件的安装方案如下: 1).zookeeper+kafka http://www.cnblogs.com/super-d2/p/4534323.html 2)hbase ...

  6. 大数据新手之路四:联合使用Flume和Kafka

    Ubuntu16.04+Kafka1.0.0+Flume1.8.0 1.目标 ①使用Flume作为Kafka的Producer: ②使用Kafka作为Flume的Sink: 其实以上两点是同一个事情在 ...

  7. 大数据入门第二十四天——SparkStreaming(二)与flume、kafka整合

    前一篇中数据源采用的是从一个socket中拿数据,有点属于“旁门左道”,正经的是从kafka等消息队列中拿数据! 主要支持的source,由官网得知如下: 获取数据的形式包括推送push和拉取pull ...

  8. 解决Flume向Kafka多分区写数据

    1  问题背景 Flume向kafka发布数据时,发现kafka接收到的数据总是在一个partition中,而我们希望发布来的数据在所有的partition平均分布 2 解决办法 Flume的官方文档 ...

  9. Flume和Kafka完成实时数据的采集

    Flume和Kafka完成实时数据的采集 写在前面 Flume和Kafka在生产环境中,一般都是结合起来使用的.可以使用它们两者结合起来收集实时产生日志信息,这一点是很重要的.如果,你不了解flume ...

随机推荐

  1. Xshell连接Ubuntu失败问题

    转自:https://www.linuxidc.com/Linux/2017-08/146222.htm Xshell是一个安全终端模拟软件,可以进行远程登录.我使用XShell的主要目的是在Wind ...

  2. springmvc是如何和前端页面联系起来的

    springmvc的使用,在controller中通过注解的形式,获取从前端jsp页面传过来的action参数. 方法/步骤   使用springmvc必须在web.xml中配置(Dispatcher ...

  3. ACM经验分享[转]

    明确规则 规则:以最少的时间过题 (这意味着0ms与1000ms是一样的) 了解规则,善用规则 虽然这个题我不会但是AC是没有问题的 --ACRush 大力出奇迹 学会对拍数据,准备好对拍脚本:测试很 ...

  4. fisheye Error occurred during initialization of VM Could not reserve enough space for object heap 问题解决!

    参考文章:https://answers.atlassian.com/questions/9397/not-enough-heap-space-to-run-fisheye fisheye下载好了之后 ...

  5. nfs的优化

    总结和测试了一下自己的经验: NFS中的rsize.wsize rsize.wsize对于NFS的效能有很大的影响.wsize和rsize设定了SERVER和CLIENT之间往来数据块的大小,这两个参 ...

  6. POJ 2230 Watchcow (欧拉回路)

    Watchcow Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5258   Accepted: 2206   Specia ...

  7. HDU 3018 Ant Trip (欧拉回路)

    Ant Trip Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  8. openstack rpc机制

    一.概述: 在openstack项目中,api的调用规则: 跨项目:如nova调用keystone, glance,cinder等,使用rest api(通过相应的python-XXXclient 库 ...

  9. windows Maven3.0 服务器配置搭建

    搭建nexus私服,原因很简单,不必多说,本文重点说下最新版的Maven 3.0.x系列的安装步骤. 最新版的网上中文资料很少,参考后都没成功.最后在官网的英文资料中得到答案,成功搞定. 1.确定我们 ...

  10. 代码管理(三)sourcetree 的使用

    一.SourceTree简介   SourceTree 是 Windows 和Mac OS X 下免费的 Git 和 Hg 客户端,拥有可视化界面,容易上手操作.同时它也是Mercurial和Subv ...