我们用Flume采集日志信息后,数据进入Kafka。在Kafka之后的选择我们有很多,最典型的就是Flume-ng------Kafka------Storm。当然也可以是Mongo、Elasticsearch、Hbase等等。不过不管去哪,Kafka的数据默认只存7天(可以配置),7天之后就会自动删除了,所以说数据持久化的问题就来了,数据持久化最好的选择就是进入Hadoop。所以本文介绍如何将Kafka中的数据持久化到hdfs。

我这里只是提供一个思路,而且这个思路跟官网并不一致,由于我们的Kafka数据会同时进Mongo、进Elasticsearch,所以进hdfs并不需要实时同步,只是做个永久保存。所有的一切都源于需求,我们都是根据需求去搞事情。先介绍一下写作背景,本人是在北京某公司给某银行做一个大数据有关的项目,基本上银行内部数据量比较大的信息都存在我们平台,目前是300多台服务器,预计今年会扩容到500台左右。目前正处于项目三期开发阶段,引入了Kafka技术。

我做的是定期把每台Broker上的log文件同步到hdfs上,我使用Linux自带的cron服务实现定时执行一个脚本,通过脚本把log文件同步到hdfs。我们定义的log文件满1G就会重新生成一个文件,所以我们只要把满1G大小的log传到hdfs即可。传上去的时候统一放到制定topic下的指定分区,便于日后恢复数据。这里还有一个小问题就是hdfs是不支持文件的续写和替换的,所以对于已存在的文件是不能传到hdfs的,当然这里已存在的文件也没有必要传上去了,所以我们要写一个判断。简单说就是我们只把每天新生成的数据同步到hdfs。

下面是我写的脚本,是依赖cron服务定时执行的

#!/bin/sh
a=1
b=1
filelistcount=`cat filelist.txt |wc -l`
filenamecount=`find  /tmp/kafka-logs/ -name "*.log" | grep /0 | awk -F '/' '{print $NF}'|wc -l`
echo $filenamecount
while [ $a -le $filenamecount ]
do
    
    filenamelog=`find /tmp/kafka-logs/ -name "*.log" | awk -F '/' '{print $NF}'|sed -n $a"P" `   
    filenameindex=`echo $filenamelog|awk -F '.' '{print $1}'`.index
    topicpatition=`find /tmp/kafka-logs/ -name "*.log"| awk -F '/' '{print $4}'|sed -n $a"P" `
    filesize=`du -ah /tmp/kafka-logs/$topicpatition/$filenamelog|awk -F ' ' '{print $1}'`  
    echo $filesize $topicpatition/$filenamelog and $filenameindex
    echo $filesize
    if test "$filesize" = "684K"
    then
        while [ $b -le $filelistcount ]
        do
           if test "$topicpatition/$filenamelog" =  "`cat filelist.txt |sed -n $b"p"`"
           then    
               echo "$topicpatition/$filename:File exists"
               break
           else
                let b++
           fi
           
        done
        if test "$b" -gt "$filelistcount"
        then
             hdfs dfs -put /tmp/kafka-logs/$topicpatition/$filenamelog  /test/
             hdfs dfs -put /tmp/kafka-logs/$topicpatition/$filenameindex  /test/
             echo "send hdfs"
             echo $topicpatition/$filenamelog >> filelist.txt
        fi
        b=1
    fi
    let a++
    
done

 

这个脚本我还没有写完,不过大体框架已经很清晰了。后期可以根据需求再进行完善。