[TOC]java
若是你是開發, 對搭建kafka集羣沒什麼興趣, 能夠跳過這一章, 直接看明天的內容.
mysql
若是你以爲多瞭解一點沒有什麼壞處的話, 請繼續看下去.
sql
提醒一下, 本章圖多docker
kafka集羣的搭建仍是比較繁瑣的, 雖然只是下載文件,修改配置,但數據比較多.數據庫
基本環境須要3臺zk服務器 和3臺 kafka服務器.apache
看圖json
看上去就比較長, 因此我不用這種方法, 使用docker 來簡化一點流程.bootstrap
算複習瀏覽器
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"]
}複製代碼
docker-compose 已裝好
docker network create --driver bridge --subnet 172.29.0.0/25 \
--gateway 172.29.0.1 elk_zoo
docker network ls複製代碼
配置太長,這裏先放個結構, 源文件稍後會放在博客上.
列出的項目基本都要配置, 重點注意:
請參考配置文件印證.
docker-compose up -d複製代碼
ZooInspector
cd zookeeper/src/contrib/zooinspector/
# 打開失敗,須要驗證複製代碼
docker pull wurstmeister/kafka
docker pull sheepkiller/kafka-manager複製代碼
配置太長,這裏先放個結構, 源文件稍後會放在博客上.
列出的項目基本都要配置, 重點注意:
請參考配置文件印證.
docker-compose up -d複製代碼
使用 kafka-manager 的管理頁面,本機ip加9000端口
搞定收工.
本着對懶惰之神的信仰, 用docker短期搞定了集羣的搭建, 鼓掌.
明天開始命令行實操,敬請期待.
今天的三張圖都比較複雜, 不須要記憶, 對照配置文件理清楚流程便可.
先來一個問題吧, 昨天我搭完了kafka的集羣, 管理工具也裝好了, 一切如截圖所示.
有沒有同窗能看出或猜出該集羣存在的問題呢? 對本身有信心的能夠加我好友私聊, 思路對的話, 我也能夠發個小紅包鼓勵的.
kafa-manager 是一個經常使用的 kafka集羣管理工具, 相似工具還有不少, 也有公司本身開發類型的工具.
當集羣配置好以後, 能夠經過瀏覽器登陸kafa-manager , 並添加集羣管理.
添加完畢後, 會顯示這樣
查看Broker信息
點擊Topic 能夠查看Topic
再點擊能夠進行單條信息的設置
其餘
Preferred Replica ElectionReassign PartitionsConsumers
分別涉及副本選舉, 分區和消費者, 後續講到了再介紹.
由於集羣剛建好, 不少信息會看不到,後面幾篇會結合命令行操做一同展現.
下面記錄一些常見故障,及排查思路:
host 名字不能設置爲127.0.0.1
檢查 默認的topic
__consumer_offsets
使用性能測試腳本:
kafka-producer-perf-test.sh
分析生成報告
檢查 jstack信息 或定位源碼排查
檢查kafka日誌, 檢查GC日誌, 檢查zk日誌和GC日誌, 檢查節點內存監控
最後把報異常的節點下線再回復解決
查看logs發現沒權限, 配置
privileged: true
unset JMX_PORT;bin/kafka-topics.sh ..
比較取巧的一個辦法, 取消掉 kafka-env.sh 腳本定義了JMX_PORT變量.
複製代碼
---
正常狀況下, Kafka都是經過代碼鏈接的.
可是, 偶然你想確認下是Kafka錯了,仍是你的代碼錯了.
或者並無條件及時間搞出一段代碼的時候, 簡單用命令行仍是能夠的.
docker inspect 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複製代碼
docker exec -it zoo1 bash
zkCli.sh
ls /
ls /brokers/ids
# 查看kafka 的節點id
[1, 2, 3]複製代碼
注意, 如下命令所有在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小時複製代碼
副本因子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複製代碼
列表及詳情
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複製代碼
默認標記刪除
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複製代碼
所有命令都手打了一遍, 保證可用.
涉及的命令都比較長, 請把代碼框的命令一次複製上去, 不要考慮換行.
昨天說到命令行操做kafka集羣, 其實有個小小故障的.
在運行生產者吞吐量測試時, 把集羣打掛了.
阿里雲的空間有限,kafka-producer-perf-test.sh 命令短期填滿了全部的磁盤空間.
今天會科普一些kafka的基礎知識. 新手向, 大牛請略過
這個沒什麼說的, 著名的消息中間件.
監控中主要配合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 |
生產者 |
負責消息輸入 |
消費者 |
負責消息輸出 |
補充:
follower做用就是複製數據
在leader掛掉時, 從follower中選出新的leader.
follower做用就是複製數據, 並在leader掛掉 時,從中選出新的leader.
主要有如下4個相關配置文件:
用途 |
文件名 |
---|---|
broker 配置 |
server.properties |
zookeeper 配置 | zookeeper.properties |
消費者配置 |
consumer.properties |
生產者配置 |
producer.properties |
基礎就是基礎. yann也是學完這些基礎的東西, 再次看到時才能鄙視以上內容的. 因此, 加油.
昨天把本身的公衆號發給大佬看, 結果被批評了. 說格式太亂, 看不下去. 而後我就開始進行調整格式之旅, 連着發了幾十個預覽, 感受本身都暈掉了.
因此,今天的內容會有點水, 見諒.
這裏簡單說一下, kafka的集羣原理. 以前就說明過, kafka的集羣是由三臺ZooKeeper, 和三臺kafka的集羣組成的.
想互的關係大約相似下面這張圖:
相互的關係不重要, 只要知道 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. 下面的事情就簡單了:
大體的流程就是以上幾步, 但還會有一些細節, 同時能夠用參數微調.
比方說, leader 不是一收到消息就寫入硬盤的, 會有時間或條數的一個閥值. Partiton在物理上對應一個文件夾, 一個分區的多個副本通常不會分配在同一臺物理機上等. 而是先反饋給應用仍是先保證同步, 消息寫到哪一個分區, 則時靠參數來控制了.
Kafka有一個重要的特性, 保證消息在單個分區內的順序. 緣由就是 Kafka會單獨開闢一塊磁盤空間,順序寫入數據. 分區內會有多組segment文件, 知足條件就寫入磁盤, 寫完就再開新的segment 片斷.
最後說一下消費, 消費者其實也是應用程序. 其實應用是主動到Kafka拉取消息的. 固然也是找 leader 拉取. 鑑於Kafka的強悍性能, 能夠同時加多個消費者, 同時消費者能夠組成消費者組. 同一個消費組者的消費者能夠消費同一topic下不一樣分區的數據.
在分區量充足的時候, 可能有一個消費者消費多個分區的狀況, 但若是消費都多於分區數量, 可能就有消費者什麼事都不作, 躺在一邊待機了.因此,不要讓消費者的數量超過主題分區的數量.
全部權
客戶端崩潰時消息的處理.
日誌壓縮
------
實在抱歉, 感受有些有始無終的感受。 前兩節寫的很詳細, 後面卻草草結束。畢竟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 發佈!
發佈在平臺的文章, 和原文存在格式差別, 閱讀不便請見諒
最新內容歡迎關注公衆號: