1、 基础知识

有关RabbitMQ,RocketMQ,Kafka的区别这个网上很多,了解一下区别性能,分清什么场景使用。分布式环境下的消息中间件Kafka做的比较不错,在分布式环境下使用频繁,我也不免其俗钻研一下Kafka的使用。

任何消息队列都遵循AMQP协议,AMQP协议(Advanced Message Queuing Protocol,高级消息队列协议)

AMQP是一个标准开放的应用层的消息中间件(Message Oriented Middleware)协议。AMQP定义了通过网络发送的字节流的数据格式。因此兼容性非常好,任何实现AMQP协议的程序都可以和与AMQP协议兼容的其他程序交互,可以很容易做到跨语言,跨平台。

Kafka是一个分布式的、可分区的、可复制的消息系统。它提供了普通消息系统的功能,但具有自己独特的设计。

我们先看一些基本的概念:

  1. 消费者:(Consumer):从消息队列中请求消息的客户端应用程序
  2. 生产者:(Producer) :向broker发布消息的应用程序
  3. AMQP服务端(broker):用来接收生产者发送的消息并将这些消息路由给服务器中的队列,便于fafka将生产者发送的消息,动态的添加到磁盘并给每一条消息一个偏移量,所以对于Kafka一个broker就是一个应用程序的实例
  4. 主题(Topic):一个主题类似新闻中的体育、娱乐、教育等分类概念,在实际工程中通常一个业务一个主题。
  5. 分区(Partition):一个Topic中的消息数据按照多个分区组织,分区是Kafka消息队列组织的最小单位,一个分区可以看作是一个FIFO( First Input First Output的缩写,先入先出队列)的队列。

Kafka将消息以topic为单位进行归纳,每个broker其实就是一个应用服务器,一个broker中会有很多的topic,每个topic其实就是不同的服务需要消息的消息的聚集地。因为每个topic其实会很大,所以就出现了partition个概念,将每个topic的消息分区存储。

Kafka中的消费者有一个分组的概念,每个consumer属于一个consumer group;反过来说,每个group中可以有多个consumer.发送到Topic的消息,只会被订阅此Topic的每个group中的一个consumer消费(而不是该group下的所有consumer,一定要注意这点)

  • 如果所有的consumer都具有相同的group,这种情况和queue模式很像;消息将会在consumers之间负载均衡.
  • 如果所有的consumer都具有不同的group,那这就是”发布-订阅”;消息将会广播给所有的消费者.

在Kafka中,一个partition中的消息只会被group中的一个consumer消费;每个group中consumer消息消费互相独立;我们可以认为一个group是一个”订阅”者,一个Topic中的每个partions,只会被一个”订阅者”中的一个consumer消费,不过一个consumer可以消费多个partitions中的消息.

分布式环境中,Kafka默认使用zookeeper作为注册中心,Kafka集群几乎不维护任何consumer和producer的信息状态,这些信息都由zookeeper保存,所以consumer和producer非常的轻量级,随时注册和离开都不会对Kafka造成震荡。

producer和consumer通过zookeeper去发现topic,并且通过zookeeper来协调生产和消费的过程。

producer、consumer和broker均采用TCP连接,通信基于NIO实现。Producer和consumer能自动检测broker的增加和减少。

上面图中没有说明partition的组成,partition物理上由多个segment组成,每一个segment 数据文件都有一个索引文件对应。每个partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到partition中。partition中的每个消息都有一个连续的序列号叫做offset,用于partition唯一标识一条消息.

相比传统的消息系统,Kafka可以很好的保证有序性。

传统的队列在服务器上保存有序的消息,如果多个consumers同时从这个服务器消费消息,服务器就会以消息存储的顺序向consumer分发消息。虽然服务器按顺序发布消息,但是消息是被异步的分发到各consumer上,所以当消息到达时可能已经失去了原来的顺序,这意味着并发消费将导致顺序错乱。为了避免故障,这样的消息系统通常使用“专用consumer”的概念,其实就是只允许一个消费者消费消息,当然这就意味着失去了并发性。

在这方面Kafka做的更好,通过分区的概念,Kafka可以在多个consumer组并发的情况下提供较好的有序性和负载均衡。将每个分区分只分发给一个consumer组,这样一个分区就只被这个组的一个consumer消费,就可以顺序的消费这个分区的消息。因为有多个分区,依然可以在多个consumer组之间进行负载均衡。注意consumer组的数量不能多于分区的数量,也就是有多少分区就允许多少并发消费。

Kafka只能保证一个分区之内消息的有序性,在不同的分区之间是不可以的,这已经可以满足大部分应用的需求。如果需要topic中所有消息的有序性,那就只能让这个topic只有一个分区,当然也就只有一个consumer组消费它。

1.1、 message 被分配到 partition 的过程

每一条消息被发送到broker时,会根据paritition规则(有两种基本的策略,一是采用Key Hash算法,一是采用Round Robin算法)选择被存储到哪一个partition。如果partition规则设置的合理,所有消息可以均匀分布到不同的partition里,这样就实现了水平扩展。(如果一个topic对应一个文件,那这个文件所在的机器I/O将会成为这个topic的性能瓶颈,而partition解决了这个问题)。

在发送一条消息时,可以指定这条消息的key,producer根据这个key和partition机制来判断将这条消息发送到哪个parition。paritition机制可以通过指定producer的paritition.class这一参数来指定,该class必须实现Kafka.producer.Partitioner接口。

1.2、 segment文件存储结构

segment file由2大部分组成,分别为index file和data file,这两个文件一一对应,成对出现,后缀”.index”和“.log”分别表示为segment索引文件、数据文件。

segment文件命名规则:partion全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值。数值最大为64位long大小,19位数字字符长度,没有数字用0填充。

文件类似于下面这种形式:

0000000000000000001.index
0000000000000000001.log
0000000000000036581.index
0000000000000036581.log
0000000000000061905.index
0000000000000061905.log

index和data-file的对应关系如下:

index file 存储索引文件,文件中的元数据指向对应数据文件中message的物理偏移地址。

2、 Kafka单机环境搭建

下载Kafka,解压缩

配置环境变量:

export Kafka_HOME=/usr/local/Kafka
export PATH=$PATH:$Kafka_HOME/bin 重启生效
source /etc/profile

Kafka用到了zeekeeper,所以需要先启动zookeeper,没有安装的需要先安装zk,安装好了以后我们可以启动,我们先来实现单机版的Kafka,先启动一个单单例的zk服务,可以在命令的结尾加个&符号,这样就可以启动后离开控制台。

# bin/zookeeper-server-start.sh config/zookeeper.properties &

再启动Kafka:

# bin/Kafka-server-start.sh config/server.properties

创建topic:

# bin/Kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test

创建producer,可以在控制台手动输入消息:

# bin/Kafka-console-producer.sh --broker-list localhost:9092 --topic test 

this is a message

ctrl+c 可以退出发送。

创建consumer:

# bin/Kafka-console-consumer.sh --zookeeper localhost:2181 --topic test --from-beginning

this is a message
会收到刚才的发送的消息

我们的一个简单的单机环境就搭建好了。

Kafka基本知识入门(一)的更多相关文章

  1. Linux基础知识入门

    [Linux基础]Linux基础知识入门及常见命令.   前言:最近刚安装了Linux系统, 所以学了一些最基本的操作, 在这里把自己总结的笔记记录在这里. 1,V8:192.168.40.10V1: ...

  2. Oracle 基础知识入门

    前记: 近来项目用到Oracle数据库,大学学了点,后面基本忘记得差不多了,虽然基本语法跟sql 差不多,但是oracle知识是非常多的. 这里简单说点基础知识,希望后面补上更多的关于ORacle知识 ...

  3. Hibernate入门1. Hibernate基础知识入门

    Hibernate入门1. Hibernate基础知识入门 20131127 前言: 之前学习过Spring框架的知识,但是不要以为自己就可以说掌握了Spring框架了.这样一个庞大的Spring架构 ...

  4. Kafka的知识总结

    前言 转自(https://www.cnblogs.com/zhuifeng523/p/12081204.html) Kafka是最初由Linkedin公司开发,是一个分布式.支持分区的(partit ...

  5. kafka安装以及入门

    一.安装 下载最新版kafka,Apache Kafka,然后上传到Linux,我这里有三台机器,192.168.127.129,130,131 . 进入上传目录,解压到/usr/local目录下 - ...

  6. SpringMVC(一) 基础知识+入门案例

    SpringMVC基础知识 1.什么是Springmvc 2.springmvc 框架的原理(必须掌握) 前端控制器.处理器映射器.处理器适配器.视图解析器 3.SpringMVC 入门程序 目的:对 ...

  7. Kafka Streams开发入门(5)

    1. 背景 上一篇演示了split操作算子的用法.今天展示一下split的逆操作:merge.Merge算子的作用是把多股实时消息流合并到一个单一的流中. 2. 功能演示说明 假设我们有多个Kafka ...

  8. Kafka Streams开发入门(4)

    背景 上一篇演示了filter操作算子的用法.今天展示一下如何根据不同的条件谓词(Predicate)将一个消息流实时地进行分流,划分成多个新的消息流,即所谓的流split.有的时候我们想要对消息流中 ...

  9. java学习基础知识入门

    基础入门知识(一) 一.java技术的分类 java按照技术标准和应用场景的不同分为三类,分别是JAVASE.JAVAEE.JAVAME JAVASE : 平台标准版,用于开发部署桌面,服务器以及嵌入 ...

随机推荐

  1. HDU 3338:Kakuro Extension(脑洞大开的网络流)

    http://acm.hdu.edu.cn/showproblem.php?pid=3338 题意:在一个n*m的地图里面,有黑方块和白方块,黑方块可能是“XXXXXXX”或者“YYY/YYY”,这里 ...

  2. kuangbin专题 专题二 搜索进阶 Nightmare Ⅱ HDU - 3085

    题目链接:https://vjudge.net/problem/HDU-3085 题意:有两个鬼和两个人和墙,鬼先走,人再走,鬼每走过的地方都会复制一个新鬼, 但新鬼只能等待旧鬼走完一次行程之后,下一 ...

  3. c++ 二分答案

    c++ 二分答案 问题 使得x^x达到或超过n位数字的最小正整数x是多少?n<=2000000000 分析 对与这种较难求解的问题,我们很难想出较好的解决策略.但是,我们至少知道答案一定在1与2 ...

  4. 解决webpack打包速度慢的解决办法

    技巧1 webpack在打包的时候第一次总是会做很长的准备工作,包括加载插件之类的.在刚接触webpack的时候总是webpack一下-测一下-改一下-再webpack一下,这种方式最后让很多人崩溃了 ...

  5. MyBatis从入门到精通:第一章的pom.xml文件

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...

  6. NOIp 2018 普及&提高组试题答案

    你们考的咋样呢?在评论区说出自己的分数吧!

  7. Linux/Ubuntu正确卸载LXDE

    第一步: sudo apt-get remove lxde 第二步 sudo apt autoremove lxde

  8. 从草图绘制到实施交付:优秀API设计完整流程

    设计好的API是一项繁复的工作,但是优秀的设计是可以通过人为规划实现的,在本文中,我们将研究什么是好的设计以及如何在开发过程中实现它,还将介绍API设计的三个重要阶段:草图绘制,原型设计和交付实施,最 ...

  9. python包-logging-hashlib-openpyxl模块-深浅拷贝-04

    包 包: # 包是一系列模块文件的结合体,表现形式是文件夹,该文件夹内部通常会包含一个__init__.py文件,本质上还是一个模块 包呢,就是前两篇博客中提到的,模块的四种表现形式中的第三种 # 把 ...

  10. SQL Server 设置默认数据库

    STEP 1 调用系统函数 查看SQL Server的当前用户名 SELECT SUSER_NAME(); NOTE : 系统函数的调用跟sql语句执行一样 Paste_Image.png 运行结果 ...