入門kafka

一、安裝kafka

1、安裝環境組件

1.1、安裝jdk

1.2、安裝zookeeper

kafka使用zookeeper保存集羣的元數據信息和消費者信息。kafka發行版自帶了zookeeper,可以直接從腳本啓動,也可以手動安裝。
在這裏插入圖片描述

1.2.1、單機服務
  - 下載穩定版本[鏈接](https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/stable/) ,我這裏下載的版本號3.5.6
以下操作sudo是爲了防止沒有管理員root權限。
解壓zookeeper
tar -zxvf apache-zookeeper-3.5.6-bin.tar.gz
移到系統用戶目錄下
sudo mv apache-zookeeper-3.5.6-bin /usr/local/zookeeper
創建數據保存目錄
sudo mkdir -p /var/lib/zookeeper
修改zoo.cfg配置文件
cat > /usr/local/zookeeper/conf/zoo.cfg << EOF
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
EOF
設置可執行Java環境如果自己安裝則(假設安裝目錄爲如下/usr/java/jdk文件夾名稱)
export JAVA_HOME=/usr/java/jdk文件夾名稱
如果是系統自己rpm安裝的,則Java -version可以執行。則可以繞過設置JAVA_HOME目錄步驟
sudo /usr/local/zookeeper/bin/zkServer.sh start
  - 效果圖

在這裏插入圖片描述
現在鏈接zookeeper端口,通過發送四字命令srvr來驗證zookeeper是否安裝正確。

假設沒有安裝telnet,則需要brew install telnet,沒有brew的話 則需要安裝下。
telnet localhost 2181

返回結果圖:在這裏插入圖片描述

1.2.2、zookeeper羣組服務

zookeeper集羣被稱爲羣組,zookeeper使用的是一致性協議,所以建議每個羣組裏應該包含奇數個節點,只有當羣組的大多數節點可用狀態,zookeeper才能處理外部請求。如果羣組包含5個節點,可以允許2個節點失效,如果包含3個節點,允許1個節點失效。

  • 那麼羣組節點越多越好麼?當然不是,節點越多在選舉的時候性能越低。所以一般建議不超過7個節點。
  • 羣組需要公共配置,
    • 1、每個服務器需要在數據目錄中創建一個myid文件,用於指明自己的ID號。
    • 2、假設羣組裏面的機器名字zoo1.example.com,zoo2.example.com,zoo3.example.com那麼配置文件可能是這樣的:
      server.X=hostname:peerPort:leaderPort
      X:代表服務器的ID,必須是整數,但是不一定從0開始也不要求是連續的。
      hostname:服務器的機器名或者IP地址
      peerPort:用於節點間通信的TCP端口
      leaderPort:用於首領選舉的TCP端口
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
initLimit=20
syncLimit=5
server.1=zoo1.example.com:2888:3888
server.2=zoo2.example.com:2888:3888
server.3=zoo3.example.com:2888:3888

客戶端只需要通過clientPort就能連接到羣組,但是羣組節點間的通信需要同時用到3個端口(peerPort,leaderPort,clientPort)

1.3、安裝kafka broker

在Java和zookeeper都安裝好的基礎上,可以安裝kafka了。安裝目錄usr/local/kafka,將消息日誌保存在/tmp/kafka-logs目錄下。
在這裏插入圖片描述
下載地址:點擊

解壓文件
tar -zxvf kafka_2.12-2.3.1.tgz
移動到系統用戶目錄下
sudo mv kafka_2.12-2.3.1 /usr/local/kafka
創建存放日誌區
mkdir /tmp/kafka-logs
/usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/server.properties
創建主題wolf
/usr/local/kafka/bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic wolf
查看主題wolf
/usr/local/kafka/bin/kafka-topics.sh --zookeeper localhost:2181 --describe --topic wolf
生產消息
 /usr/local/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic wolf
 消費消息
 /usr/local/kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:2181 --topic wolf --from-beginning
 

注意事項zookeeper is not a recognized option

如果執行/usr/local/kafka/bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic wolf --from-beginning
報錯:zookeeper is not a recognized option
更改爲/usr/local/kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:2181 --topic wolf --from-beginning
因爲低版本的kafka的zookeeper命令行替換爲bootstrap-server

效果圖:在這裏插入圖片描述

1.4、broker配置

1.4.1、常規配置
  1. broker.id(每個broker需要維護的標識符,不能重複,最好是根據機器的名字映射好)
  2. port(默認使用配置文件,會監聽9092的端口,修改port參數可以修改爲別的端口,如果使用1024以下的端口,需要使用root權限啓動kafka。)
  3. zookeeper.connect(用於保存broker元數據的地址,比如本地的localhost:2181,最好是列表,防止單個broker故障帶來的不可用服務)
  4. log.dirs(所有消息存儲到磁盤是根據log.dirs指定的,它是一組用逗號分隔的本地文件系統路徑,broker自我調優是根據最少使用原則,把同一個分區的日誌片段保存到同一個路徑下,要注意的是,broker往擁有最少的數目分區的路徑新增分區,而不是往擁有最小的磁盤空間的路徑新增分區)
  5. num.recovery.threads.per.data.dir(假設該數設置8,log.dir=3則一共需要24個線程用於恢復數據主要有三種情況:服務器正常啓動,用於打開每個分區的日誌片段,服務器奔潰後重啓,用於檢查和截斷每個分區的日誌片段,服務器正常關閉,用於關閉日誌片段。)
  6. auto.create.topics.enable(默認情況下,自動創建主題的三種場景:當一個生產者開始往主題寫入消息時候,或者當一個消費者開始從主題讀取消息時候,或者當任意一個客戶端向主題發送元數據請求的時候)
1.4.2、主題的默認配置
  1. num.partitions(默認啓用,指定了新創建的主題包含多少個分區,我們可 以增加主題分區的個數,但是不能減少分區的個數。)
    1.1、如何選定適合自己的分區數可以參考這幾個因素:
    1.1.1、主題需要達到多大的吞吐量,希望每秒寫入100kb還是1GB?
    1.1.2、從單個分區讀取數據的最大吞吐量多少?消費者將數據寫入數據庫的速度不會超過50MB/秒,從分區的讀取速度也就不會超過50MB/秒
    1.1.3、可以通過類似的方法估算生產者向單個分區寫入數據的吞吐量,不過生產者的速度一般比消費者快得多。所以最好爲生產者多估算一些吞吐量
    1.1.4、每個broker包含的分區個數,可用的磁盤空間和網絡帶寬
    1.1.5、如果消息是按照不同的鍵來寫入分區,那麼爲已有的主題新增分區會很困難
    1.1.6、單個broker對分區個數是有限制的,因爲分區越多,佔用的內存越多,完成首領選舉需要的時間越長。
    假設根據以上數據,每秒鐘要從主題寫入和讀取1GB的數據,並且每個消費者每秒鐘可以處理50MB的數據,那麼至少需要20個分區。如果對於這些不能估算,可以分區的大小限制在25GB以內(經驗值)
  2. log.retention.ms
    kafka通常根據時間來決定數據可以被保留多久,默認使用log.retention.hours參數來配置時間,默認值168小時。除此之外,還有其他兩個參數log.retention.minutes和log.retention.ms。如果指定了多個時間參數,系統會優先選擇最小值的那個參數。
    根據時間保留數據和最後修改時間:
    通過檢查磁盤上日誌片段文件的最後修改時間來實現的。一般來說,最後修改時間指的就是日誌片段的關閉時間,也就是文件裏最後一個消息的時間戳。
  3. log.retention.bytes
    3.1、另一種方式通過保留的消息字節數來判斷消息是否過期。它的值通過參數log.retention.bytes來指定,作用在每一個分區上。eg:假設8個分區,並且log.retention.bytes被設爲1GB。那麼這個主題最多可以保留8GB的數據。
    3.2、 log.retention.bytes和log.retention.ms同時指定
    根據字節大小和時間保留數據,同時指定 log.retention.bytes和log.retention.bytes那麼滿足其中一個條件則消息就會被刪除。
  4. log.segment.bytes
    當日志片段大小達到log.segment.bytes指定的上限(默認1GB)時,當前日誌片段就會被關閉,一個新的日誌片段被打開。這個參數越小,就會越頻繁的關閉和分配新文件,從而降低磁盤寫入的整體效率。
    使用時間戳獲取偏移量:
    日誌片段的大小會影響使用時間戳獲取偏移量。日誌片段越小,結果越準確。
  5. log.segment.ms
    指定多長時間之後日誌片段會被關閉。與log.segment.bytes一起合起來使用,也是先滿足哪個然後哪個配置生效
  6. message.max.bytes
    broker通過設置該參數來限制單個消息的大小。默認值是1000 000也就是1MB。這個值是壓縮後的消息體值,對性能有顯著影響。
    在服務端和客戶端之間協調消息大小的配置:
    消費者客戶端可以通過設置fetch.message.max.bytes必須與服務器端設置的消息大小進行協調。如果這個值比message.max.bytes小,那麼消費者就會出現阻塞。

1.5、硬件的選擇

1.5.1、磁盤吞吐量

生產者客戶端的性能直接受到服務器端磁盤吞吐量的影響。生產者生產的消息必須被提交給服務器保存,大多數客戶端在發送消息之後會一直等待,直到至少有一個服務器確認消息已經成功提交爲止。磁盤寫入速度越快,生成消息的延遲越低所以取決於硬件磁盤固態硬盤還是機械硬盤。

1.5.2、磁盤容量

磁盤容量是依賴於保留的消息數量如果服務器每天收到1TB的消息,保留7天,那麼就需要7TB,然後再增加其他文件提供至少10%的額外空間。另外還有緩衝區的空間用於應付消息流量的增長和波動。

1.5.3、內存

服務器端的內存是除了磁盤性能外,影響客戶端的性能的主要因素,磁盤性能影響生產者,內存影響消費者。消費者一般是從分區尾部讀取消息,如果有生產者存在,就緊跟在生產者後面。在這種情況下,消費者讀取的消息會直接存放在系統的頁面緩存裏。運行kafka的JVM不需要太大的內存,剩餘的系統內存可以用來做頁面緩存。這裏不建議kafka同其他重要的應用程序部署一起的原因就是這個,他們需要共享頁面緩存會降低kafka的性能。

1.5.4、網絡

網絡的吞吐量決定了kafka能夠處理的最大數據量,磁盤存儲是制約kafka擴展規模的主要因素。kafka支持多個消費者造成流入和流出的網絡流量不平衡。

1.5.5、CPU

客戶端爲了優化網絡和磁盤空間,會對消息進行壓縮,服務器需要對消息進行批量解壓設置偏移量,然後重新進行批量壓縮,再保存到磁盤。這是kafka要求CPU的原因。

1.6、雲端的Kafka

如何選擇kafka,先從要保留的數據大小開始考慮,然後考慮生產者性能,如果要求低延遲,則考慮I/O優化後的固態硬盤,然後再選擇CPU和內存。而選擇的話一般會部署雲端,可以方便擴縮。

1.7、Kafka集羣

使用集羣可以跨服務器進行負載均衡,以及使用複製功能避免因單點故障造成的數據丟失。

1.7.1、評估系統broker部署個數

考慮因素:

  1. 多少磁盤空間來保留數據
  2. 單個broker有多少空間可用
  3. 是否啓用數據複製或者配置的複製係數多少
  4. 集羣處理請求的能力
1.7.2、broker配置
  1. 所有broker都必須配置相同的zookeeper.connect。用於保存元數據的zookeeper羣組和路徑。
  2. 每個broker的broker.id唯一值得設置。
1.7.3、操作系統的調優

這些參數主要與虛擬內存網絡子系統和用來存儲日誌片段的磁盤掛載點相關,這些參數一般配置在/etc/sysctl.conf文件裏。

  1. 虛擬內存
    對於大多數依賴吞吐量的應用程序,我們應該儘量避免內存交換,內存頁和磁盤之間的交換對kafka影響的性能較大。
    1.1避免內存交換可以不設置任何交換分區。內存交換不是必須的,但是在系統發生災難性錯誤可以提供幫助。進行內存交換可以防止操作系統由於內存不足而突然終止進程。所以我們可以將vm.swappiness參數的值設置小點。比如1.爲什麼不設置爲0,是因爲0意味着在任何情況下都不要發生交換。顯然不合理。
    1.2vm.dirty_background_ratio設爲小於10的值,該值是系統內存的百分比,大部分情況設爲5就可以,如果設爲0的話會促使內核頻繁的刷新頁面,從而降低內核爲底層設備的磁盤寫入提供緩存的能力。
    1.3設置vm.dirty_ratio參數可以增加被內核進行刷新到磁盤之前的髒頁數量,一般會設置60-80,並且開啓kafka的複製功能,避免因系統奔潰造成數據丟失。如何查看髒頁數量。
cat /proc/vmstat | egrep "dirty|writeback"
髒頁數22
nr_dirty 22
nr_writeback 0
nr_writeback_temp 0
nr_dirty_threshold 1434719
nr_dirty_background_threshold 358679
  1. 磁盤
    文件元數據包含3個時間戳:創建時間ctime,最後修改時間mtime,以及最後訪問時間atime。默認情況下每次文件被讀取後更新atime,導致大量的磁盤寫操作。所以可以將其禁用掉。爲掛載點設置noatime參數防止更新atime。不會影響ctime和mtime。
  2. 網絡
    3.1分配給socket讀寫緩存區的內存大小調整,提升網絡傳輸性能
    3.2TCP socket的讀寫緩存區適當增加,參數net.ipv4,tcp_wmem和net.ipv4.tcp_rmem。最大值不能大於net.core.wmem_max和net.core.rmem_max。
    3.3啓用tcp 時間窗net.ipv4.tcp_window_scaling設爲1啓用tcp時間窗擴展,可以提高客戶端傳輸數據的效率,傳輸的數據可以再服務器端進行緩衝。net.ipv4.tcp_max_syn_backlog設爲比默認值1024更大的值,可以接受更多的併發連接。把net.core.netdev_max_backlog設爲比默認值1000更大的值。有助於應對網絡流量的爆發,特別是使用千兆網絡的情況下,允許更多的數據包排隊等待內核處理。

1.8、生產環境的注意事項

1.8.1、垃圾回收器

使用G1配置,由於使用堆內存較頻繁,所以需要設置下面2個參數。
MaxGCPauseMillis:最大垃圾回收默認的停頓時間。
initiatingHeapOccupancyPercent:啓動新一輪垃圾回收前可以使用的堆內存百分比。一般設置爲35-45%也就是說在這之前不會啓動垃圾回收。

1.8.2、數據中心佈局

在爲broker增加新的分區時候,broker無法獲知機架的信息,也就是兩個broker可能是同一個機架也可能是同一個可用區域。爲了防止出現不完整的主節點選舉,可能恢復時候丟失數據,或者分區添加副本的時候副本可能被分配給同一個機架上的broker,他們使用相同的電源和網絡連接,如果機架出現問題,分區就離線,客戶端無法訪問到。

1.8.3、共享zookeeper

kafka集羣共享一個zookeeper羣主,每個集羣使用一個chroot路徑。消費者將會爲每個消費的分區往zookeeper寫入一次偏移量,合力提交間隔時間是1分鐘,因爲剛好是消費者羣組的某個消費者發生失效時候能夠讀取到重複消息的時間。優化點是最好用最新版本kafka將偏移量等信息保存kafka機器上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章