Kafka教程一

一、基于Kraft 在宿主机实现Kafka集群3.5.x

# 安装jdk8
root@redis-6:~# apt install openjdk-11-jdk
root@redis-7:~# apt install openjdk-11-jdk
root@redis-8:~# apt install openjdk-11-jdk
# 验证版本
root@redis-6:~# java -version
# 分发kafka的安装文件,三台节点都要执行
root@redis-6:~# cd /apps/
root@redis-6:/apps# wget https://downloads.apache.org/kafka/3.5.1/kafka_2.13-3.5.1.tgz
root@redis-6:/apps# tar xvf kafka_2.13-3.5.1.tgz 
root@redis-6:/apps# ln -sv /apps/kafka_2.13-3.5.1 /apps/kafka

root@redis-7:~# cd /apps/
root@redis-7:/apps# wget https://downloads.apache.org/kafka/3.5.1/kafka_2.13-3.5.1.tgz
root@redis-7:/apps# tar xvf kafka_2.13-3.5.1.tgz 
root@redis-7:/apps# ln -sv /apps/kafka_2.13-3.5.1 /apps/kafka

root@redis-8:~# cd /apps/
root@redis-8:/apps# wget https://downloads.apache.org/kafka/3.5.1/kafka_2.13-3.5.1.tgz
root@redis-8:/apps# tar xvf kafka_2.13-3.5.1.tgz 
root@redis-8:/apps# ln -sv /apps/kafka_2.13-3.5.1 /apps/kafka

# 修改配置文件
root@redis-6:/apps# mkdir /data/kraft-logs -p
root@redis-6:/apps#  grep -v "^$" /apps/kafka/config/kraft/server.properties |grep -v "^#"
process.roles=broker,controller
node.id=101
controller.quorum.voters=101@172.18.10.146:9093,102@172.18.10.147:9093,103@172.18.10.148:9093
listeners=PLAINTEXT://:9092,CONTROLLER://:9093
inter.broker.listener.name=PLAINTEXT
advertised.listeners=PLAINTEXT://172.18.10.146:9092
controller.listener.names=CONTROLLER
listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL
num.network.threads=3
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
log.dirs=/data/kraft-logs
num.partitions=1
num.recovery.threads.per.data.dir=1
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.retention.hours=168
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000

root@redis-7:/apps# mkdir /data/kraft-logs -p
root@redis-7:/apps# grep -v "^$" /apps/kafka/config/kraft/server.properties |grep -v "^#"
process.roles=broker,controller
node.id=102
controller.quorum.voters=101@172.18.10.146:9093,102@172.18.10.147:9093,103@172.18.10.148:9093
listeners=PLAINTEXT://:9092,CONTROLLER://:9093
inter.broker.listener.name=PLAINTEXT
advertised.listeners=PLAINTEXT://172.18.10.147:9092
controller.listener.names=CONTROLLER
listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL
num.network.threads=3
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
log.dirs=/data/kraft-logs
num.partitions=1
num.recovery.threads.per.data.dir=1
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.retention.hours=168
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000

root@redis-8:/apps# mkdir /data/kraft-logs -p
root@redis-8:/apps# grep -v "^$" /apps/kafka/config/kraft/server.properties |grep -v "^#"
process.roles=broker,controller
node.id=103
controller.quorum.voters=101@172.18.10.146:9093,102@172.18.10.147:9093,103@172.18.10.148:9093
listeners=PLAINTEXT://:9092,CONTROLLER://:9093
inter.broker.listener.name=PLAINTEXT
advertised.listeners=PLAINTEXT://172.18.10.148:9092
controller.listener.names=CONTROLLER
listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL
num.network.threads=3
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
log.dirs=/data/kraft-logs
num.partitions=1
num.recovery.threads.per.data.dir=1
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.retention.hours=168
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000

# 初始化数据目录
root@redis-6:/apps# /apps/kafka/bin/kafka-storage.sh random-uuid
9bRuxEShTXyMYPDELhLxfw

# 三台节点都要使用上面生成的唯一集群ID进行格式化数据存储目录
root@redis-6:/apps# /apps/kafka/bin/kafka-storage.sh format -t 9bRuxEShTXyMYPDELhLxfw -c /apps/kafka/config/kraft/server.properties
Formatting /data/kraft-logs with metadata.version 3.5-IV2.
root@redis-7:/apps#  /apps/kafka/bin/kafka-storage.sh format -t 9bRuxEShTXyMYPDELhLxfw -c /apps/kafka/config/kraft/server.properties
Formatting /data/kraft-logs with metadata.version 3.5-IV2.
root@redis-8:~#  /apps/kafka/bin/kafka-storage.sh format -t 9bRuxEShTXyMYPDELhLxfw -c /apps/kafka/config/kraft/server.properties
Formatting /data/kraft-logs with metadata.version 3.5-IV2.

# 测试启动kafka

在这里插入图片描述

二、基于Zookeeper在kubernetes环境结合storageclass部署kafka 2.8.x集群

# 部署存储类
[root@k8s-master1 1.storageclasses-dir]# pwd
/root/kafka-1029/kafka-cases-n79/1.storageclasses-dir
[root@k8s-master1 1.storageclasses-dir]# kubectl apply -f 1-rbac.yaml
[root@k8s-master1 1.storageclasses-dir]# kubectl apply -f 2-storageclass.yaml 
[root@k8s-master1 1.storageclasses-dir]# kubectl apply -f 3-nfs-provisioner.yaml

# 部署zookeeper
[root@k8s-master1 kafka-cases-n79]#  kubectl apply -f 2.ZooKeeper-StatefulSet.yaml 
#验证zookeeper svc:
[root@k8s-deployer kafka-cases-n79]# kubectl get pvc -n myserver
NAME                         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
datadir-zk-statefulset-0     Bound    pvc-1ea1f82d-39af-4e1f-9b82-4c84fc7e11cd   10Gi       RWO            managed-nfs-storage   99s
datadir-zk-statefulset-1     Bound    pvc-a1c5bb5e-45b1-4d16-9d49-c23c6d91e193   10Gi       RWO            managed-nfs-storage   99s
datadir-zk-statefulset-2     Bound    pvc-fb1bd0a6-3d7d-4885-89be-206fa314ee89   10Gi       RWO            managed-nfs-storage   99s
myserver-myapp-dynamic-pvc   Bound    pvc-1057c0f3-0451-4318-81e4-791ee2ac5338   500Mi      RWX            managed-nfs-storage   61d
#验证zookeeper pod
[root@k8s-deployer kafka-cases-n79]# kubectl get pod -n myserver
NAME                                        READY   STATUS             RESTARTS        AGE
zk-statefulset-0                            1/1     Running            0               2m27s
zk-statefulset-1                            1/1     Running            0               2m27s
zk-statefulset-2                            1/1     Running            0               2m27s
#验证zookeeper service:
[root@k8s-deployer kafka-cases-n79]# kubectl get svc -n myserver
NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
zk-client-service       NodePort    10.100.173.94   <none>        2181:32181/TCP               107s
# 部署kfka
[root@k8s-master1 kafka-cases-n79]#  kubectl apply -f 3.Kafka-StatefulSet.yaml
[root@k8s-deployer kafka-cases-n79]# kubectl get pod -n myserver
NAME                                        READY   STATUS    RESTARTS          AGE
kafka-statefulset-0                         1/1     Running   0                 3m29s
kafka-statefulset-1                         1/1     Running   0                 2m9s
kafka-statefulset-2                         1/1     Running   0                 67s
zk-statefulset-0                            1/1     Running   0                 13m
zk-statefulset-1                            1/1     Running   0                 13m
zk-statefulset-2                            1/1     Running   0                 13m

# 测试kafka消费

在这里插入图片描述

在这里插入图片描述

三、总结kafka的主要配置

process.roles=broker,controller # =Broker,服务器在KRaft模式中充当 Broker角色;= Controller, 服务器在KRaft模式下充当 Controller角色;= Broker,Controller,服务器在KRaft模式中同时充当 Broker 角色和Controller角色;process.roles 没有设置,那么集群就假定是运行在ZooKeeper模式下。
node.id=101 # 唯一标识
controller.quorum.voters=101@172.31.4.101:9093,102@172.31.4.102:9093,103@172.31.4
.103:9093
listeners=PLAINTEXT://:9092,CONTROLLER://:9093
inter.broker.listener.name=PLAINTEXT
advertised.listeners=PLAINTEXT://172.31.4.101:9092
controller.listener.names=CONTROLLER
listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SSL:SSL,S
ASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL
num.network.threads=3
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
log.dirs=/data/kraft-logs
num.partitions=1
num.recovery.threads.per.data.dir=1
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.retention.hours=168
log.segment.bytes=1073741824
log.retention.check.interval.ms=30000

四、总结kafka topic的分区及副本的作用、基于python脚本验证消息的写入Kafka并从Kafka集群消费

# kafka topic的分区及副本的作用
分区:
	一个topic可以有多个分区,分区可以是tipic的存储分布更加均匀,同是分区处于在不同的节点上,也可以提高kafka的访问吞吐率,实现类似负载均衡的效果。
副本:
	副本是针对一分区而言的,一个分区可以有多个副本。每个分区有一个leader,零或多个follower。Leader处理此分区的所有的读写请求,而follower被动的复制数据。如果leader宕机,其它的一个follower会被推举为新的leader。 一台服务器可能同时是一个分区的leader,另一个分区的follower。 这样可以平衡负载,避免所有的请求都只让一台或者某几台服务器处理。副本可以实现分区数据的备份,提供数据冗余,提高伸缩性。
# 基于python脚本验证消息的写入Kafka并从Kafka集群消费
root@redis-1:~/pydir# cat myserver-KafkaConsumer.py 
#/usr/bin/env python3
#coding=utf-8
#pip3 install --index-url https://mirrors.aliyun.com/pypi/simple/ kafka-python

from kafka import KafkaConsumer

conn = KafkaConsumer('myserver',bootstrap_servers=['172.18.10.146:9092','172.18.10.147:9092','172.18.10.148:9092'])
for message in conn:
    print ("%s:%d:%d: key=%s value=%s" % (message.topic, message.partition,
    message.offset, message.key,message.value))
conn.close()

root@redis-1:~/pydir# cat myserver-KafkaProducer.py 
#/usr/bin/env python3
#coding=utf-8 
#pip3 install --index-url https://mirrors.aliyun.com/pypi/simple/ kafka-python

from kafka import KafkaProducer
#conn = KafkaProducer(bootstrap_servers=['172.18.10.130:9092','172.18.10.130:9092','172.18.10.130:9092'],compression_type='gzip')
conn = KafkaProducer(bootstrap_servers=['172.18.10.146:9092','172.18.10.147:9092','172.18.10.148:9092'],compression_type='gzip')
conn.send('foobar', key=b'foo', value=b'bar')
for i in range(3):
    #msg = "msg%d" % i
    #conn.send('myserver', msg)
    conn.send('myserver',key=b'myserver-key', value=b'msg%d' % i)
    print('topic-->myserver: msg%d发送成功!' % i)
conn.close()

root@redis-1:~/pydir# python3 myserver-KafkaConsumer.py 
root@redis-1:~/pydir# python3 myserver-KafkaProducer.py 

在这里插入图片描述

在这里插入图片描述

五、基于Strimzi Operator部署面向生产环境的Kafka集群

# 创建NS并部署strimzi-cluster-operator
[root@k8s-deployer 20231102]# kubectl create namespace myserver
[root@k8s-deployer 20231102]# kubectl apply -f https://strimzi.io/install/latest?namespace=myserver
[root@k8s-deployer 20231102]# kubectl get pod -n myserver
NAME                                        READY   STATUS             RESTARTS        AGE
strimzi-cluster-operator-95d88f6b5-75pq4    1/1     Running            0               3m26s
# 部署kafka集群
[root@k8s-deployer 20231102]# wget https://strimzi.io/examples/latest/kafka/kafka-persistent-single.yaml --no-check-certificate
[root@k8s-deployer 20231102]#  mv kafka-persistent-single.yaml 1.kafka-persistent-single.yaml
[root@k8s-deployer 7.strimzi-kafka-operator]# vim 1.kafka-persistent-single.yaml 
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
  name: myserver-kafka-cluster
  namespace: myserver #指定目的NS
spec:
  kafka:
    version: 3.5.1
    replicas: 3 #副本数,默认为1
    listeners:
      - name: plain
        port: 9092
        type: internal
        tls: false
      - name: tls
        port: 9093
        type: internal
        tls: true
      - name: external # 增加外部客户端访问用的linstener
        port: 9094 #监听端口
        type: nodeport #指定nodeport类型
        tls: false
        configuration:
          bootstrap:
            nodePort: 31092 # 指定宿主机nodeport端口
    config:
      offsets.topic.replication.factor: 3
      transaction.state.log.replication.factor: 3
      transaction.state.log.min.isr: 3
      default.replication.factor: 1
      min.insync.replicas: 1
      inter.broker.protocol.version: "3.5"
    storage:
      type: jbod
      volumes:
      - id: 0
        type: persistent-claim
        class: nfs-csi 
        size: 100Gi
        deleteClaim: false
  zookeeper:
    replicas: 3
    storage:
      type: persistent-claim
      class: nfs-csi 
      size: 10Gi
      deleteClaim: false
  entityOperator:
    topicOperator: {}
    userOperator: {}
# 创建存储类
[root@k8s-deployer 1.storageclasses-dir]# kubectl apply -f 1-rbac.yaml 
[root@k8s-deployer 1.storageclasses-dir]# kubectl apply -f 2-storageclass.yaml 
[root@k8s-deployer 1.storageclasses-dir]# kubectl apply -f 3-nfs-provisioner.yaml
[root@k8s-deployer 1.storageclasses-dir]# kubectl get sc
NAME                PROVISIONER                                   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-csi (default)   k8s-sigs.io/nfs-subdir-external-provisioner   Retain          Immediate           false                  67s
[root@k8s-deployer 7.strimzi-kafka-operator]# kubectl apply -f 1.kafka-persistent-single.yaml 
kafka.kafka.strimzi.io/myserver-kafka-cluster created
#验证pod,确认zk及kafka分别为running状态
[root@k8s-deployer tmp]#  kubectl get pod  -n myserver

在这里插入图片描述

# 外部访问测试
root@redis-1:~/pydir# cat myserver-KafkaProducer.py 
#/usr/bin/env python3
#coding=utf-8 
#pip3 install --index-url https://mirrors.aliyun.com/pypi/simple/ kafka-python

from kafka import KafkaProducer
#conn = KafkaProducer(bootstrap_servers=['172.18.10.121:9092','172.18.10.121:9092','172.18.10.121:9092'],compression_type='gzip')
conn = KafkaProducer(bootstrap_servers=['172.18.10.146:31092','172.18.10.147:31092','172.18.10.148:31092'],compression_type='gzip')
conn.send('foobar', key=b'foo', value=b'bar')
for i in range(3):
    #msg = "msg%d" % i
    #conn.send('myserver', msg)
    conn.send('myserver',key=b'myserver-key', value=b'msg%d' % i)
    print('topic-->myserver: msg%d发送成功!' % i)
conn.close()
root@redis-1:~/pydir# python3 myserver-KafkaProducer.py
root@redis-1:~/pydir# python3 myserver-KafkaConsumer.py 
topic-->myserver: msg0发送成功!
topic-->myserver: msg1发送成功!
topic-->myserver: msg2发送成功!

六、总结分布式链路追踪的基础功能;

分布式链路跟踪系统是整个分布式系统中跟踪一个用户请求的完整过程,包括数据采集、数据传输、数据存储、数据分析和数据可视化,获取并存储和分享此类跟踪可以让运维清晰了解用户请求与业务系统交互背后的整个调用链的调用关系,因此链路追踪系统是针对业务调试和监控微服务不可或缺的重要系统。

针对dapper的设计要求:
	1)无处不在的部署:任何服务都应该被监控到,任何服务出问题都要做到有据可查。
	2)持续的监控:做到7*24小时全天候监控,任何时候出了问题都要基于监控数据追踪问题根源。
针对dapper的设计目标:
	1)低消耗:dapper跟踪系统对服务的影响应该做到最小,在一些高并发的场合,即使很小的影响也可能会导致服务出现延迟、负载变高或不可用,从而导致业务团队可能会停止dapper系统。
	2)对应用透明:应用程序对dapper系统无感知甚至不知道dapper系统的存在,假如一个跟踪系统必须依赖于应用的开发者配合才能实现跟踪,也即是需要在应用中植入跟踪代码,那么可能会因为代码产生bug或导致应用出问题。
	3)可伸缩性:针对未来众多的服务和大规模业务集群,dapper系统应该能满足未来在性能的压力和功能上的需求。

七、总结SkyWalking的特性、组件及与其它链路追踪系统对比

SkyWalking的特性:
	实现从请求跟踪、指标收集和日志记录的完整信息记录。
	多语言自动探针,支持Java、GO、Python、PHP、NodeJS、LUA、Rust等客户端。
	内置服务网格可观察性,支持从Istio+Envoy Service Mesh收集和分析数据。
	模块化架构,存储、集群管理、使用插件集合都可以进行自由选择。
	支持告警。
	优秀的可视化效果

组件:
	OAP平台(Observability Analysis Platform,可观测性分析平台)或OAP Server,它是一个高度组件化的轻量级分析程序,由兼容各种探针Receiver、流式分析内核和查询内核三部分构成。
	探针:基于无侵入式的收集,并通过HTTP或者gRPC方式发送数据到OAP Server。
	存储实现(Storage Implementors),SkyWalking OAP Server支持多种存储实现并且提供了标准接口,可支持不同的存储后端。
	UI模块(SkyWalking),通过标准的GraphQL(Facebook在2012年开源)协议进行统计数据查询和展示 。

与其它链路追踪系统对比:
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值