• Kafka 在产品开发中的实践


    问题

    在公司的产品开发中,存在多个团队负责产品的不同子系统,数据从上游进入系统,然后流向下游应用,每个子系统相互独立,是通过数据串在一起,在这种场景下,如果以传统的思维方式,可能是调用下游提供的WebAPI来post数据,也可能是上下游共用相同的数据库,不仅使得上下游耦合紧密,而且难以横向扩展,提高吞吐量,在产品中,我们使用Kafka作为数据总线,在上下游之间传递消息,这样不仅解耦各个子系统,而且可以很容易的扩展kafka集群,使得消息快速的分发和响应,与其他的消息中间件相比(如RabbitMQ等),Kafka相对性能更高,在单机QPS可以达到十万量级甚至更高,而且因为是发布订阅模式,可以实现多播方式,供多个消费者消费,这样如果结合大数据系统,那么一个consumer group对接Hadoop的分析系统,另外一个consumer group对接spark,storm等在线实时系统。通过使用Kafka,解决了子系统间的数据流动瓶颈,在子系统之间,不再需要协商定义调用接口,只需要定义传递的数据协议

    Kafka简介

    Kafka是一个分布式的发布订阅消息系统,通过横向扩展及分区,可以极大的提高吞吐率,消息具有持久化的能力,支持实时与离线处理

    Kafka 拓扑架构

    在kafka中有以下基本概念

    • Topic:主题,指Kafka处理的消息分类,是一个逻辑上的概念
    • Partition:Topic物理上的分区,一个topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)。
    • Message:消息,是通信的基本单位,每个producer可以发布某一个topic的消息。
    • Producers:生产者,推送消息到kafka集群
    • Consumers:消费者,建立到kafka集群的长连接,并拉取消息进行处理
    • Broker:缓存代理,Kafa集群中的一台或多台服务器统称为broker。

    Producer发送消息时必须指定它的Topic,创建topic时,指定分区数量,Topic在逻辑上可以被看作是一个虚拟的queue,可以简单理解为必须指明把这条消息放进某个队列里,而最终消息是在Broker上存储在每个分区中。为了使得Kafka的吞吐率可以线性提高,物理上把Topic常分成多个Partition,每个Partition在物理上对应一个文件夹,该文件夹下存储这个Partition的所有消息和索引文件,一个append log文件,任何发布到此partition的消息都会被追加到log文件的尾部,每条消息在文件中的位置称为offset(偏移量),offset为一个long型的数字,它唯一标记一条消息。

    对于consumer,通常位于group中,在一个group中,可以有多个consumer,但其数量不能多于所消费的topic的分区数量,在一个group中,每个分区的消息至多只能送到一个消费者上,即一个消费者可以消费多个分区,一个分区只能给一个消费者消费,下图显示一个有5个分区的topic,消息存储在2个broker上,每个consumer自己记录在分区(队列)上消费的消息的状态位置offset,kafka集群中的每个server更像以文件方式顺序存储的无状态的日志系统。如果有多个消费组,那便是多播方式

     

    项目架构:

     

    说明

    1. 此处WebAPI和Java Kafka Service部署在同一个server上,因跨进程,使用ICE进行通信,Google Buffer定义协议,需要分别编译为C# 及Java version
    2. producer发送主题消息,用avro定义好消息格式,并序列化后发送出去,并获取offset ack
    3. consumer从分区拉取消息,进行处理

    ICE Slice文件定义如下,然后用ICE sclice2cs及slice2java工具编译此文件,分别生成C#及Java版本的代码文件

    module  InterfaceIce
    {
        sequence<byte> ByteArray;
        interface IPCMessage
        {
            ["ami", "amd"] void Send(ByteArray req, out ByteArray res);
            void printString(string s); 
        };
    };

    Google protobuf 协议文件,分别编译成C#及Java的代码文件,用于对结构化数据做序列号/反序列化

    //request and response exchange package typedef
    syntax = "proto2";
    
    message MyData
    {
        required int32 Id = 1;
        required string Number = 2;
        optional string Name = 3;
        optional int32 Type = 4;
    }

    安全性:

    从0.9版本后,Kafka引入Security,主要包括3部分:身份认证(Authentication),权限控制(Authorization),数据加密(Encryption)。认证机制主要是指配置SSL/SASL,在客户端与服务端连接进行身份认证,而授权是实现消息级别的权限控制,配置客户端的读写topic的操作权限。此外,在clients(producer,consumer)与tools,brokers之间,可以配置SSL对数据加密。

    从WebAPI之后的都是部署在内网,外部无法访问,但即使是内网,也有不同的子系统在使用kafka,只有经过认证和授权的用户才可以使用kafka发布消息及消费消息,上面第2步及第3步,使用的是Kerberos身份认证,ZooKeeper需要启用Kerberos认证模式

    Broker:启动时,读取Broker上的配置文件,发送身份信息给KDC(Authentication Server)认证,只有通过认证才可以加入kafka集群

    Client:Producer(Consumer)启动时需要经过以下步骤

    • 读取producer(Consumer)的配置文件中java.security.auth.login.config的jaas文件地址,jaas.conf的配置文件及keytab的身份信息,发送给KDC(AS)进行身份认证,如果通过则获得TGT
    • producer使用TGT向KDC(Ticket-Granting Server, TGS)请求Kafka服务,KDC验证TGT并向Producer返回SessionKey(会话密钥)和ServiceTicket(服务票据)
    • Producer使用SessionKey和ServiceTicket与Broker建立连接,Broker使用自身的密钥解密ServiceTicket,获得与Producer通信的SessionKey,然后使用SessionKey验证Producer的身份,通过则建立连接,否则拒绝连接

    producer(consumer),在项目配置文件中指定认证文件的路径

    config.properties

    java.security.auth.login.config=D:\tempkafka-jaas.conf

    producer(consumer)kafka-jaas.conf配置文件

    KafkaClient {
         com.sun.security.auth.module.Krb5LoginModule required
         useKeyTab=true
         keyTab="C:/Users/xyz/keytabs/xyz.keytab"
         doNotPrompt=true
         serviceName="kafka" 
         principal="xyz@mycompany.com";
    };  

    keytab 文件创建方法如下,在server上通过ktpass创建好后keytab文件后,保存在kafka producer所在的server上,因为本文是运行在window上的,所以需要将keytab文件保存在路径 C:/Users/{user}/keytabs

    ktpass /princ xyz@mycompany.com /pass mypassword1 /ptype KRB5_NT_PRINCIPAL /crypto All /out xyz.keytab
    cacls xyz.keytab /g xyz@mycompany.com:f 

    扩展阅读:

  • 相关阅读:
    R语言代写模型中的加总偏误与内生性:一种数值模拟方法
    R语言代写NYPD纽约市警察局抢劫者数据分析
    R语言代写使用马尔可夫链Markov Chain, MC来模拟抵押违约
    BZOJ 2600: [Ioi2011]ricehub 双指针+贪心
    BZOJ 4903: [Ctsc2017]吉夫特 数论+dp
    BZOJ 4500: 矩阵 带权并查集
    草稿
    BZOJ 5082: 弗拉格 矩阵乘法
    BZOJ 4764: 弹飞大爷 LCT
    BZOJ 3309: DZY Loves Math 莫比乌斯反演+打表
  • 原文地址:https://www.cnblogs.com/benfly/p/9138876.html
Copyright © 2020-2023  润新知