【kafka】源碼分析-ZeroCopy助力kafka實現高吞吐

系列前言

kafka作爲一個處理實時數據和日誌的管道,每秒可以處理幾十萬條消息。其瓶頸自然也在I/O層面,所以其高吞吐背後離不開如下幾個特性:

  • NIO
  • 磁盤順序讀寫
  • Queue數據結構的極致使用
  • 分區提高併發
  • 零拷貝提高效率
  • 異步刷盤
  • 壓縮提高數據傳輸效率

本次我將從kafka的源碼分析其ZeroCopy模塊的細節。

ZeroCopy基礎概念

傳統IO

  • JVM虛擬機發送一個read()操作系統級別的方法
  • 產生一個上下文的切換,從程序所在的用戶空間切換至系統的內核空間
  • 內核空間向磁盤空間請求數據,通過DMA直接內存訪問的方式將數據讀取到內核空間緩衝區
  • 用戶空間是無法直接使用,需要將這份緩衝數據原封不動的拷貝到用戶空間
  • 在用戶空間裏read數據

有兩次上下文的切換,和兩次數據的拷貝。

ZeroCopy是什麼

零拷貝是指計算機操作的過程中,CPU不需要爲數據在內存之間的拷貝消耗資源。而它通常是指計算機在網絡上發送文件時,不需要將文件內容拷貝到用戶空間(User Space)而直接在內核空間(Kernel Space)中傳輸到網絡的方式。

零拷貝技術減少了用戶態與內核態之間的切換,讓拷貝次數降到最低,從而實現高性能。

Java中的ZeroCopy

在Java中的零拷貝實現是在NIO的FileChannel中,其中有個方法

  • transferTo
  • transferFrom

kafka實現

具體使用

在org.apache.kafka.common.record.FileRecords中具體使用到了ZeroCopy。
kafak版本:2.2.0 https://github.com/apache/kafka/blob/trunk/clients/src/main/java/org/apache/kafka/common/record/FileRecords.java

// org.apache.kafka.common.record.FileRecords
    @Override
    public long writeTo(GatheringByteChannel destChannel, long offset, int length) throws IOException {
        long newSize = Math.min(channel.size(), end) - start;
        int oldSize = sizeInBytes();
        if (newSize < oldSize)
            throw new KafkaException(String.format(
                    "Size of FileRecords %s has been truncated during write: old size %d, new size %d",
                    file.getAbsolutePath(), oldSize, newSize));

        long position = start + offset;
        int count = Math.min(length, oldSize);
        final long bytesTransferred;
        if (destChannel instanceof TransportLayer) {
            TransportLayer tl = (TransportLayer) destChannel;
            bytesTransferred = tl.transferFrom(channel, position, count);
        } else {
            bytesTransferred = channel.transferTo(position, count, destChannel);
        }
        return bytesTransferred;
    }

使用場景

  • partition leader到follower的消息同步
  • consumer拉取partition中的消息

後面講具體分析這塊的邏輯。


參考

  • Kafka Zero-Copy 使用分析 https://www.jianshu.com/p/d47de3d6d8ac
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章