分布式发布订阅消息系统 Kafka

本文介绍了Kafka作为分布式消息系统的特性与工作原理。Kafka通过Flume获取数据,自身用于缓存,Strom处理数据,Redis存储数据。Kafka采用Topic分类消息,Producer发送,Consumer接收,集群依赖Zookeeper管理元数据。其特点包括高吞吐量、数据持久化、易于拓展、消费者状态维护、分区消费和消费者组并行消费。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

现有消息队列(MessageQueue)比较:


网站系统 <-- Flume集群 --> Kafka集群 --> strom集群 --> redis集群

Flume用于获取数据,Kafka用于缓存数据,strom用于处理,redis用于存储。

Kafka类似于JMS中间件,但是设计完全不一样,此外Kafka并不是JMS规范的实现。

Kafka对消息保存时根据Topic进行归类,发送者为Producer,接受者为Consumer。一个Kafka集群由多个Kafka实例(Server)组成,每个Server称为broker。

Kafka集群、Producer和Consumer都依赖于zookeeper保存元数据信息(meta信息),以保证系统可用性。

Kafka特性:

1. 同时为发布和订阅提供高吞吐量(每秒生产25万条数据(50M),每秒处理55万条数据(110M))。

2. 可持久化数据。可持久化到磁盘,所以可用于批量消费,如ETL、实时应用程序,防止数据丢失。

3. 易于向外拓展。所有的Producer、consumer和broker都是分布式的,无需停机即可拓展机器。

4. 消息被处理状态在consumer中维护,而不是Server。

5. Kafka会将topic中的消息进行分区(partition),不同的consumer可以同时消费不同分区的数据(但是若consumer数大于partition数,就会有consumer获取不到数据),提高数据传输速度。一个 topic 可以分为多个 partition,每个 partition 是一个有序的队列。partition 中的每条消息都会被分配一个有序的 id(offset)。

6. Consumer Group 消费者组,可以并行消费Topic中partition的消息


message是通信的基本单位,包含三个属性:

offset  对应类型:long

messageSize 对应类型:int32 

data   message的具体内容


Producer

public class Producer extends Thread {
	private String topic;
	private kafka.javaapi.producer.Producer<Integer, String> producer;
	private Properties props = new Properties();
	public Producer(String topic) { 
		this.topic = topic;
		props.put("serializer.class", "kafka.serializer.StringEncoder");
        props.put("metadata.broker.list", "localhost:9092");
        producer = new kafka.javaapi.producer.Producer<Integer, String>(new ProducerConfig(props));
	}
	@Override
	public void run() {
		int messageNo = 1;
		String messageStr = new String ("Message_" + messageNo);
		System.out.println("Send:"+messageStr);
		producer.send(new KeyedMessage<Integer, String>(topic, messageStr));
		messageNo ++;
		try {
			sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}


Consumer

public class Consumer extends Thread {
	private ConsumerConnector consumer;	//通过properties设置Consumer参数,并且创建了连接器,连接到Kafka
	private String topic;
	public Consumer(String topic) {
		consumer = kafka.consumer.Consumer.createJavaConsumerConnector(createConsumerConfig());
		this.topic = topic;
	}
	private ConsumerConfig createConsumerConfig() {
		Properties props = new Properties();
		props.put("zookeeper.connect", KafkaProperties.zkConnect);
        props.put("group.id", KafkaProperties.groupId);
        props.put("zookeeper.session.timeout.ms", "40000");
        props.put("zookeeper.sync.time.ms", "200");
        props.put("auto.commit.interval.ms", "1000");
        return new ConsumerConfig(props);
	}
	
	@Override
	public void run() {
		//Map用于存topic及具体的partition
		Map<String, Integer> topicCountMap = new HashMap<String, Integer>();
        topicCountMap.put(topic, 1);
        //consumerMap为broker发出来的消息,KafkaSteam为partition中的数据
        Map<String, List<KafkaStream<byte[], byte[]>>> consumerMap = consumer.createMessageStreams(topicCountMap);
        KafkaStream<byte[], byte[]> stream = consumerMap.get(topic).get(0);
        ConsumerIterator<byte[], byte[]> it = stream.iterator();
        while (it.hasNext()) {
            System.out.println("receive:" + new String(it.next().message()));
            try {
                sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
	}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值