kafka學習

kafka是由LinkedIn開發,主要是用來處理Linkedin的大面積活躍數據流處理(activity stream).  此類的數據經常用來反

映網站的一些有用的信息,比如PV,頁面展示給哪些用戶訪問,用戶搜索什麼關鍵字最多,這類信息經常被log到文件

裏,然後線下且週期性的去分析這些數據。現在這種用戶活躍數據已經成爲互聯網公司重要的一部分,所以必須構建

一個更輕量且更精煉的基礎架構。  


活躍數據 使用案列 

分析一下用戶行爲(pageviews),以便我能設計出更好的廣告位。 

快速的統計用戶投票,點擊。

對用戶的搜索關鍵詞進行統計,分析出當前的流行趨勢。

防止用戶對網站進行無限制的抓取數據,以及超限制的使用API,辨別垃圾。 

對網站進行全方位的實時監控,從而得到實時有效的性能數據,並且及時的發成警告。

批量的導入數據到數據倉庫,對數據進行離線分析,從而得到有價值的商業信息。(0.6可以直接將數據導入Hadoop)  

活躍數據的特點 

      高流量的活躍數據是無法確定其大小的,因爲他可能隨時的變化,比如商家可能促銷,節假日打折,突然又冒出

一個跳樓價等等。所有的數據可能是數量級的往上遞增。 傳統日誌分析方式都是需要離線,而且操作起來比較複雜,

根本無法滿足實時的分析。另一方面,現有的消息隊列系統只能達到近似實時的分析,因爲無法消費大量的持久化在

隊列系統上的信息。Kafka的目標就是能夠成爲一個高效的隊列平臺,無論是處理離線的信息還是在線的信息。



kafka是一個消息訂閱和發佈的系統

我們將message的發佈(publish)者稱爲producer,將message的訂閱(subscribe)者稱爲consumer,將中間的存

儲陣列稱作broker。

kafka集羣


核心概念

1.topic  (發佈的消息都存在於某個主題中)
2.partition (topic中的分區,爲了負載均衡)
3.offset (kafka的消費是依靠讀取每個消息的偏移量,並且消費完不立刻銷燬消息,可配置消息的生命週期)
4.consumer group

一個consumer group對於同一條消息只能消費一次

不同consumer group可以共享同一個消息,同樣每個group只能消費一次


kafka僞分佈式搭建

tar -zxvf kafka_2.10-0.8.1.1.tgz

#(啓動自帶的zookeeper)
啓動ZK bin/zookeeper-server-start.sh config/zookeeper.properties

#啓動kafka服務
啓動服務 bin/kafka-server-start.sh config/server.properties

#在地址爲localhost:2181的zookeeper上創建一個主題test,副本因子是1
創建主題 bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test

#查看地址爲localhost:2181的zookeeper上所有主題
查看主題 bin/kafka-topics.sh --list --zookeeper localhost:2181

#查看test主題的詳細信息

bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic test


命令:

創建生產者 bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test

創建消費者 bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic test --from-beginning

在創建生產者的命令行輸入消息,即可在消費者命令行中顯示。


可以在僞分佈下啓動多個kafka服務(broker)

創建多個server.properties文件分別命名,啓動命令kafka-server-start.sh config/server.properties分別使用這幾個

server.properties文件。需要修改每個server.properties中的內容:

1.broker.id

2.port

3.log.dirs

保證每個broker服務的配置項是唯一,分別啓動。


kafka集羣搭建

修改server.properties文件

1.指定唯一的broker.id

2.host.name指定主機ip或者主機名

3.log.dirs指定一個日誌輸出目錄

將kafka配置信息複製到其他節點,分別修改broker.idhost.name

在各節點分別執行kafka-server-start.sh config/server.properties >/del/null 2>&1 &

以後臺進程啓動(&),並且將輸出送到垃圾箱(>/del/null),將錯誤信息也輸送到1的位置(垃圾箱)2>&1 


package com.bigdata.hadoop.kafka;

import java.util.Properties;
import java.util.concurrent.TimeUnit;

import kafka.javaapi.producer.Producer;
import kafka.producer.KeyedMessage;
import kafka.producer.ProducerConfig;
import kafka.serializer.StringEncoder;

//創建生產者,每秒給主題test12發送一個消息
public class KafkaProducer extends Thread{
	
	String topic = "test12";
	String message = "hello world";
	
	@Override
	public void run() {
		Properties originalProps = new Properties();
		originalProps.put("serializer.class", StringEncoder.class.getName());
		originalProps.put("metadata.broker.list", "hadoop4:9092,hadoop5:9092,hadoop6:9092");
		
		Producer<Integer, String> producer = new Producer<Integer, String>(new ProducerConfig(originalProps));
		
		int i = 0;
		while (true) {
			producer.send(new KeyedMessage<Integer, String>(topic, message + i++));
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	public static void main(String[] args) {
		new KafkaProducer().start();
	}
}

package com.bigdata.hadoop.kafka;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import kafka.consumer.Consumer;
import kafka.consumer.ConsumerConfig;
import kafka.consumer.ConsumerIterator;
import kafka.consumer.KafkaStream;
import kafka.javaapi.consumer.ConsumerConnector;

//創建消費者,消費主題test12的消息
public class KafkaConsumer extends Thread{
	
	String topic = "test12";
	String message = "hello world";
	
	@Override
	public void run() {
		Properties originalProps = new Properties();
		originalProps.put("group.id", "group1");
		originalProps.put("zookeeper.connect", "hadoop4:2181");
		//創建消費者連接器
		ConsumerConnector javaConsumerConnector = Consumer.createJavaConsumerConnector(new ConsumerConfig(originalProps));
		
		Map<String, Integer> topicCountMap = new HashMap<String, Integer>();
		topicCountMap.put(topic, 1);//消費topic 每次消費1條
		//獲取指定topic的消息流
		Map<String, List<KafkaStream<byte[], byte[]>>> messageStreams = javaConsumerConnector.createMessageStreams(topicCountMap);
		KafkaStream<byte[], byte[]> stream = messageStreams.get(topic).get(0);
		//迭代消息流中的消息
		ConsumerIterator<byte[], byte[]> iterator = stream.iterator();
		while (iterator.hasNext()) {
			System.err.println(new String(iterator.next().message()));
		}
	}
	
	public static void main(String[] args) {
		new KafkaConsumer().start();
	}
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章