使用Kafka的一些簡單介紹: 1集羣 2原理 3 術語

[TOC]java

第一節 Kafka 集羣

承前

若是你是開發, 對搭建kafka集羣沒什麼興趣, 能夠跳過這一章, 直接看明天的內容.
mysql

若是你以爲多瞭解一點沒有什麼壞處的話, 請繼續看下去.
sql

提醒一下, 本章圖多docker

Kafka 集羣搭建

概述

kafka集羣的搭建仍是比較繁瑣的, 雖然只是下載文件,修改配置,但數據比較多.數據庫

基本環境須要3臺zk服務器 和3臺 kafka服務器.apache

操做流程

看圖json

mark

看上去就比較長, 因此我不用這種方法, 使用docker 來簡化一點流程.bootstrap

Kafka 集羣快速搭建

安裝 Docker

算複習瀏覽器

uname -a
yum -y install docker
service docker start
# 或
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh複製代碼

鏡像加速緩存

vi /etc/docker/daemon.json
    {
      "registry-mirrors": ["https://uzoia35z.mirror.aliyuncs.com"]
    }複製代碼

zookeeper集羣

docker-compose 已裝好

新建docker網絡

docker network create --driver bridge --subnet 172.29.0.0/25 \
  --gateway 172.29.0.1  elk_zoo
docker network ls複製代碼

yml 腳本

配置太長,這裏先放個結構, 源文件稍後會放在博客上.

mark

列出的項目基本都要配置, 重點注意:

  • ports: # 端口
  • volumes: # 掛載卷
  • environment: 環境變量
  • networks: 有兩部分, ip 和共有網絡

請參考配置文件印證.

docker-compose up -d複製代碼

驗證

ZooInspector

cd zookeeper/src/contrib/zooinspector/
# 打開失敗,須要驗證複製代碼

Kafka集羣

鏡像

docker pull wurstmeister/kafka
docker pull sheepkiller/kafka-manager複製代碼

yml 腳本

配置太長,這裏先放個結構, 源文件稍後會放在博客上.

mark

​ 列出的項目基本都要配置, 重點注意:

  • ports: # 端口
  • volumes: # 掛載卷
  • environment: 環境變量
  • external_links 外連
  • networks: 有兩部分, ip 和共有網絡

請參考配置文件印證.

docker-compose up -d複製代碼

驗證

mark

使用 kafka-manager 的管理頁面,本機ip加9000端口

mark

搞定收工.

本着對懶惰之神的信仰, 用docker短期搞定了集羣的搭建, 鼓掌.

明天開始命令行實操,敬請期待.

今天的三張圖都比較複雜, 不須要記憶, 對照配置文件理清楚流程便可.

第二節 集羣管理工具

先來一個問題吧, 昨天我搭完了kafka的集羣, 管理工具也裝好了, 一切如截圖所示.

有沒有同窗能看出或猜出該集羣存在的問題呢? 對本身有信心的能夠加我好友私聊, 思路對的話, 我也能夠發個小紅包鼓勵的.

集羣管理工具

概述

kafa-manager 是一個經常使用的 kafka集羣管理工具, 相似工具還有不少, 也有公司本身開發類型的工具.

操做流程

當集羣配置好以後, 能夠經過瀏覽器登陸kafa-manager , 並添加集羣管理.

mark

添加完畢後, 會顯示這樣

查看Broker信息

mark

點擊Topic 能夠查看Topic

mark

再點擊能夠進行單條信息的設置

mark


其餘

Preferred Replica ElectionReassign PartitionsConsumers

分別涉及副本選舉, 分區和消費者, 後續講到了再介紹.

由於集羣剛建好, 不少信息會看不到,後面幾篇會結合命令行操做一同展現.

集羣 Issues

下面記錄一些常見故障,及排查思路:

  1. 單機能夠用, 集羣發送信息失敗

host 名字不能設置爲127.0.0.1

  1. 升級後不能消費信息

檢查 默認的topic

__consumer_offsets

  1. 響應比較慢

使用性能測試腳本:

kafka-producer-perf-test.sh

分析生成報告

檢查 jstack信息 或定位源碼排查

  1. 日誌持續報異常

檢查kafka日誌, 檢查GC日誌, 檢查zk日誌和GC日誌, 檢查節點內存監控

最後把報異常的節點下線再回復解決

  1. docker遇到 掛載數據卷無限重啓

查看logs發現沒權限, 配置

privileged: true

  1. docker裏運行kafka命令時提示地址被佔用

unset JMX_PORT;bin/kafka-topics.sh ..


比較取巧的一個辦法, 取消掉 kafka-env.sh 腳本定義了JMX_PORT變量.

複製代碼

---

第三節 使用命令操縱集羣

正常狀況下, Kafka都是經過代碼鏈接的.

可是, 偶然你想確認下是Kafka錯了,仍是你的代碼錯了.

或者並無條件及時間搞出一段代碼的時候, 簡單用命令行仍是能夠的.

docker

docker inspect zookeeper複製代碼

zookeeper

集羣查看

​ 登陸集羣,判斷狀態

docker exec -it zoo1 bash
zkServer.sh status  

ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
Mode: leader
# 注意 Mode: standalone 爲單機複製代碼

配置文件

若是狀態是單機, 檢查如下文件:

vi zoo.cfg    # server.1=zoo1:2888:3888 之類, 多臺
vi myid  # 1或2等  

# 也多是環境變量形式
      ZOO_MY_ID=3 \
      ZOO_SERVERS="server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888"複製代碼

啓動zk集羣

./zkServer.sh start
jps   # QuorumPeerMain複製代碼

kafka查看

docker exec -it zoo1 bash
zkCli.sh
ls /
ls /brokers/ids    

# 查看kafka 的節點id
[1, 2, 3]複製代碼

topic

建立topic

注意, 如下命令所有在kafka的目錄下執行

cd /opt/kafka_2.12-2.3.0/  

unset JMX_PORT;bin/kafka-topics.sh --create --zookeeper zoo1:2181 --replication-factor 1 --partitions 1 --topic test1  

# 加參數 --bootstrap-server localhost:9091 能夠用自帶zk
# --config delete.retention.ms=21600000 日誌保留6小時複製代碼

建立集羣topic

副本因子1, 分區數3, 名字爲test.

unset JMX_PORT;bin/kafka-topics.sh --create --zookeeper zoo1:2181,zoo2:2181,zoo3:2181 --replication-factor 1 --partitions 3 --topic test複製代碼

查看topic

列表及詳情

unset JMX_PORT; bin/kafka-topics.sh --list --zookeeper zoo1:2181,zoo2:2181,zoo3:2181

unset JMX_PORT;bin/kafka-topics.sh --describe --zookeeper zoo1:2181,zoo2:2181,zoo3:2181 --topic __consumer_offsets複製代碼

刪除topic

默認標記刪除

unset JMX_PORT;bin/kafka-topics.sh --delete  --zookeeper zoo1:2181,zoo2:2181,zoo3:2181 --topic test  

#設置 delete.topic.enable=true 真實刪除複製代碼

生產者

發送消息

cat config/server.properties |grep listeners # 獲取監聽地址  

unset JMX_PORT;bin/kafka-console-producer.sh  --broker-list broker1:9091  --topic test2 
# 運行起來後能夠輸入信息複製代碼

吞吐量測試

unset JMX_PORT;bin/kafka-producer-perf-test.sh --num-records 100000 --topic test --producer-props bootstrap.servers=b
roker1:9091,broker2:9092,broker3:9093 --throughput 5000 --record-size 102400 --print-metrics 

# 3501 records sent, 699.2 records/sec (68.28 MB/sec), 413.5 ms avg latency, 1019.0 ms max latency.複製代碼

消費者

接受消息

unset JMX_PORT;bin/kafka-console-consumer.sh  --bootstrap-server  broker1:9091  --topic test2  

# 實時接受, 要從頭接收使用 --from-beginning複製代碼

列出消費者

unset JMX_PORT;bin/kafka-consumer-groups.sh --bootstrap-server broker1:9091 --list
# KafkaManagerOffsetCache
# console-consumer-26390複製代碼

查看分區消息

查看當前分區最新收到的消息

unset JMX_PORT;bin/kafka-console-consumer.sh --bootstrap-server broker1:9091 --topic test2 --offset latest --partition 0複製代碼

吞吐量測試

bin/kafka-consumer-perf-test.sh --topic test --messages 100000 --num-fetch-threads 10 --threads 10 --broker-list broker1:9091,broker2:9092,broker3:9093 --group console-consumer-26390複製代碼

容錯

unset JMX_PORT;bin/kafka-topics.sh --describe --zookeeper zoo1:2181,zoo2:2181,zoo3:2181 --topic test2  

docker stop broker3
# 幹掉一臺broker, 再用上述命令查看, 注意 Leader: -1
  
unset JMX_PORT;bin/kafka-topics.sh --describe --zookeeper zoo1:2181,zoo2:2181,zoo3:2181 --topic test2複製代碼

mark

所有命令都手打了一遍, 保證可用.

涉及的命令都比較長, 請把代碼框的命令一次複製上去, 不要考慮換行.

第四節 Kafka 術語說明

昨天說到命令行操做kafka集羣, 其實有個小小故障的.

在運行生產者吞吐量測試時, 把集羣打掛了.

阿里雲的空間有限,kafka-producer-perf-test.sh 命令短期填滿了全部的磁盤空間.

mark

今天會科普一些kafka的基礎知識. 新手向, 大牛請略過

簡介

  • ​ Kafka是用Scala語言寫的,
  • ​ 官方主頁 kafka.apache.org ,
  • ​ 定義爲分佈式實時流處理平臺,
  • ​ 其性能嚴重依賴磁盤的性能,
  • ​ 消息無狀態, 須要定時或定量刪除.

用途

消息系統

這個沒什麼說的, 著名的消息中間件.

應用監控

監控中主要配合ELK使用.

用戶行爲追蹤

記錄承載用戶多方面的海量信息, 再轉給各類大數據軟件處理, 如Hadoop,Spark,Strom

流處理

收集流數據

這塊是個人空缺, 昨天命令行操做時, 配置文件出了點錯誤, 後面會補上.

持久性日誌

主要應用Kafka的性能特性, 再配合Flume + HDFS, 至關好用.


性能

​ 聽說Kafka千萬級的性能, 我司沒有這麼大的量, 不敢評論. 不過百萬級是公認的.

​ 性能好的緣由是大量使用操做系統頁緩存,不直接參與物理I/O操做. 同時使用追加寫入方式, 避免隨機寫入致使硬盤的性能噩夢.

還以sendfile爲表明的零拷貝技術, 在內核區完成數據拷貝, 避開用戶緩存.

數據保存

如下爲Zookeeper中 Kafka 保存信息的幾個目錄, 能夠適當瞭解. 查看方法:

docker exec -it zoo1 bash
zkCli.sh
ls /
ls /brokers/ids    
...複製代碼

目錄名
用途
brokers
存放集羣和topic信息
controller
存放節點選舉相關信息
admin
存放腳本命令的輸出結果
isrchangenotification 記錄變化的ISR
config
記錄集羣id 和版本號
controller_epoch
記錄 controller版本號, 避免墓碑問題


專用名詞

名稱
用途
broker
指Kafka的服務器
集羣
指多個broker組成的工做單元
消息
最基礎數據單元
批次
指一組消息
副本
消息的冗餘形式
消息模式 消息序列化的方式
提交
更新分區當前位置
主題
mysql 中表格, 對應命令是topic
分區
對應命令是 partition
生產者
負責消息輸入
消費者
負責消息輸出

補充:

  1. 消息定位:
    由tpoic, partition, offset 能夠定位到惟一的一條消息.
  2. 副本分爲 leader replica和follower replica.

follower做用就是複製數據

在leader掛掉時, 從follower中選出新的leader.

follower做用就是複製數據, 並在leader掛掉 時,從中選出新的leader.

  1. topic能夠設置多個分區,其中有多個segment以存放消息

配置文件

主要有如下4個相關配置文件:

用途
文件名
broker 配置
server.properties
zookeeper 配置 zookeeper.properties
消費者配置
consumer.properties
生產者配置
producer.properties


基礎就是基礎. yann也是學完這些基礎的東西, 再次看到時才能鄙視以上內容的. 因此, 加油.

第五節 Kafka 集羣工做原理

承前

昨天把本身的公衆號發給大佬看, 結果被批評了. 說格式太亂, 看不下去. 而後我就開始進行調整格式之旅, 連着發了幾十個預覽, 感受本身都暈掉了.

因此,今天的內容會有點水, 見諒.

集羣原理

這裏簡單說一下, kafka的集羣原理. 以前就說明過, kafka的集羣是由三臺ZooKeeper, 和三臺kafka的集羣組成的.

想互的關係大約相似下面這張圖:

mark

相互的關係不重要, 只要知道 ZooKeeper至關於數據庫, Kakka 至關於實例. 雙方個體都足夠強(有三個節點), 組合起來就更強了.

那Kafka爲何要報zk的大腿呢? 實際上是使用zk解決分佈一致性的問題. 三個節點分佈在三臺服務器上, 要保持數據一致, 雖然不少系統是本身維護的, 不過Kafak是叫外援了.

可是, 光有 ZooKeeper 還不夠, 自身也要作至關的努力.

Kafka的集羣主要是經過數據複製和領袖選舉來保證一致性的.

數據複製是指雖然有三個副本, 但只有 leader 對外服務. follower 時刻觀察着 leader 副本的動向, 一但有新的變動, 就果斷拉給本身.

領袖選舉是指若是勞模 leader 不幸掛掉了, 會從 follower 裏面選一個最接近的, 榮升新的 leader.

那怎麼知道, leader 掛掉了呢, 每一個Kafka實例啓動後,都會以會話形式把本身註冊到ZooKeeper服務中, 一但出了問題, 其與ZooKeeper的會話便不能維持下去了,從而超時失效.

就像上班打卡同樣, 一段時間沒打卡了, 就知道 leader 涼了.

補充一個名詞

ISR: leader 節點將會跟蹤與其保持同步的副本列表,該列表稱爲ISR(In-Sync Replica)

工做流程

知道了集羣原理後, 再來看一下工做的流程.

應用程序先鏈接 ZooKeeper 集羣, 獲取Kafka集羣的一些消息. 其中, 最重要的是知道誰是 leader. 下面的事情就簡單了:

  1. 應用程序把消息發送給 leader
  2. leader 將消息寫入本地文件
  3. follower 知道後來同步消息
  4. follower 同步好消息後告訴 leader
  5. leader 收集到全部副的ACK信號後告訴應用程序

大體的流程就是以上幾步, 但還會有一些細節, 同時能夠用參數微調.

比方說, leader 不是一收到消息就寫入硬盤的, 會有時間或條數的一個閥值. Partiton在物理上對應一個文件夾, 一個分區的多個副本通常不會分配在同一臺物理機上等. 而是先反饋給應用仍是先保證同步, 消息寫到哪一個分區, 則時靠參數來控制了.

Kafka有一個重要的特性, 保證消息在單個分區內的順序. 緣由就是 Kafka會單獨開闢一塊磁盤空間,順序寫入數據. 分區內會有多組segment文件, 知足條件就寫入磁盤, 寫完就再開新的segment 片斷.

消費機制

​ 最後說一下消費, 消費者其實也是應用程序. 其實應用是主動到Kafka拉取消息的. 固然也是找 leader 拉取. 鑑於Kafka的強悍性能, 能夠同時加多個消費者, 同時消費者能夠組成消費者組. 同一個消費組者的消費者能夠消費同一topic下不一樣分區的數據.

在分區量充足的時候, 可能有一個消費者消費多個分區的狀況, 但若是消費都多於分區數量, 可能就有消費者什麼事都不作, 躺在一邊待機了.因此,不要讓消費者的數量超過主題分區的數量.

全部權

客戶端崩潰時消息的處理.

  • ​ 消費者組共享接收
  • ​ 全部權轉移 再均衡 rebalance
  • ​ 消費者向broker發送心跳來維持全部權
  • ​ 客戶端拉取數據, 記錄消費

日誌壓縮

  • ​ 針對一個topic的partition
  • ​ 壓縮不會重排序消息
  • ​ 消息的offset是不會變
  • ​ 消息的offset是順序

------

總結

實在抱歉, 感受有些有始無終的感受。 前兩節寫的很詳細, 後面卻草草結束。畢竟Kafka是一箇中間件, 而不是一個平臺。 再深刻的話, 就須要寫生產架構或敘述業務流程,與初衷不付。畢竟原本打算寫一個簡單的 Kafka科普的。

先打個掛點吧, 有其餘的想法再補充進來。 後面搭 ELK 的時候遇到了再補充一點。

​ 謝謝閱讀。

附 Kafka配置文件:

# 建立網絡:docker network create --driver bridge --subnet 172.69.0.0/25 --gateway 172.69.0.1  kafka_zoo
version: '2'
services:
  broker1:
    image: wurstmeister/kafka
    restart: always
    hostname: broker1
    container_name: broker1
    ports:
      - "9091:9091"
    external_links:
      - zoo1
      - zoo2
      - zoo3
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ADVERTISED_HOST_NAME: broker1
      KAFKA_ADVERTISED_PORT: 9091
      KAFKA_HOST_NAME: broker1
      KAFKA_ZOOKEEPER_CONNECT: zoo1:2181,zoo2:2181,zoo3:2181
      KAFKA_LISTENERS: PLAINTEXT://broker1:9091
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker1:9091
      JMX_PORT: 9988
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - "/root/kafka/broker1/:/kafka"
    networks:
      default:
        ipv4_address: 172.69.0.11
  broker2:
    image: wurstmeister/kafka
    restart: always
    hostname: broker2
    container_name: broker2
    ports:
      - "9092:9092"
    external_links:
      - zoo1
      - zoo2
      - zoo3
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ADVERTISED_HOST_NAME: broker2
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_HOST_NAME: broker2
      KAFKA_ZOOKEEPER_CONNECT: zoo1:2181,zoo2:2181,zoo3:2181
      KAFKA_LISTENERS: PLAINTEXT://broker2:9092
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker2:9092
      JMX_PORT: 9988
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - "/root/kafka/broker2/:/kafka"
    networks:
      default:
        ipv4_address: 172.69.0.12
  broker3:
    image: wurstmeister/kafka
    restart: always
    hostname: broker3
    container_name: broker3
    ports:
      - "9093:9093"
    external_links:
      - zoo1
      - zoo2
      - zoo3
    environment:
      KAFKA_BROKER_ID: 3
      KAFKA_ADVERTISED_HOST_NAME: broker3
      KAFKA_ADVERTISED_PORT: 9093
      KAFKA_HOST_NAME: broker3
      KAFKA_ZOOKEEPER_CONNECT: zoo1:2181,zoo2:2181,zoo3:2181
      KAFKA_LISTENERS: PLAINTEXT://broker3:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker3:9093
      JMX_PORT: 9988
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - "/root/kafka/broker3/:/kafka"
    networks:
      default:
        ipv4_address: 172.69.0.13
  kafka-manager:
    image: sheepkiller/kafka-manager
    restart: always
    container_name: kafa-manager
    hostname: kafka-manager
    ports:
      - "9002:9000"
    links:            # 鏈接本compose文件建立的container
      - broker1
      - broker2
      - broker3
    external_links:   # 鏈接本compose文件之外的container
      - zoo1
      - zoo2
      - zoo3
    environment:
      ZK_HOSTS: zoo1:2181,zoo2:2181,zoo3:2181
      KAFKA_BROKERS: broker1:9091,broker2:9092,broker3:9093
      APPLICATION_SECRET: letmein
      KM_ARGS: -Djava.net.preferIPv4Stack=true
    networks:
      default:
        ipv4_address: 172.69.0.10
networks:
  default:
    external:
      name: kafka_zoo


# mkdir -p /root/kafka/broker1
# mkdir -p /root/kafka/broker2
# mkdir -p /root/kafka/broker3
 
複製代碼

本文由博客一文多發平臺 OpenWrite 發佈!

發佈在平臺的文章, 和原文存在格式差別, 閱讀不便請見諒

最新內容歡迎關注公衆號:
https://user-gold-cdn.xitu.io/2019/11/28/16eb1860db890b3e?w=258&h=258&f=jpeg&s=27767

相關文章
相關標籤/搜索