<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>Throughput｜林鼎淵 Dean Lin</title>
    <link>https://deanlin.net/tags/throughput/</link>
    <image><url>https://deanlin.net/images/author_hu_aa256fc934e9a932.jpg</url><title>Throughput｜林鼎淵 Dean Lin</title><link>https://deanlin.net/tags/throughput/</link><width>144</width><height>144</height></image>
    <description>林鼎淵（Dean Lin）的部落格：生成式 AI 企業內訓講師、外商資安公司軟體專家、7 本書作者。400 多篇文章用白話分享生成式 AI 實戰、Claude Code 與 Vibe Coding 教學、團隊合作與職場成長。</description>
    <generator>Hugo</generator>
    <language>zh-tw</language>
    <copyright>© 2020–2026 林鼎淵 Dean Lin</copyright>
    <lastBuildDate>Sun, 20 Nov 2022 21:47:34 +0800</lastBuildDate>
    <atom:link href="https://deanlin.net/tags/throughput/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>正在為大數據所苦嗎？帶你了解 Kafka 這個分布式消息串流平台，以及它能解決什麼問題！</title>
      <link>https://deanlin.net/blog/202211/what-is-kafka/</link>
      <pubDate>Sun, 20 Nov 2022 21:47:34 +0800</pubDate>
      <guid>https://deanlin.net/blog/202211/what-is-kafka/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>技術教學</category>
      <description>如果推出的 Web 系統受到市場親睞，那隨著使用者成長，勢必會更高頻率的呼叫 api 與存取資料庫；假使我們沒有設計任何的緩衝機制，那資料庫不堪重負也只是時間問題。 而且隨著公司規模的擴張，接下來可能會有專門的團隊來分析使用者行為，公司高層與投資人會想看具體的業務狀況…</description>
      <media:content url="https://deanlin.net/blog/202211/what-is-kafka/images/what-is-kafka-og_hu_e61e6985506688e1.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>如果推出的 Web 系統受到市場親睞，那隨著使用者成長，勢必會更高頻率的呼叫 api 與存取資料庫；假使我們沒有設計任何的緩衝機制，那資料庫不堪重負也只是時間問題。</p>
<p>而且隨著公司規模的擴張，接下來可能會有專門的團隊來分析使用者行為，公司高層與投資人會想看具體的業務狀況，系統需要建立即時監控系統，甚至要整合外部資源…如果資料串流沒設計好，系統架構就會變成下面這張圖。</p>
<figure class="figure"><img src="https://deanlin.net/blog/202211/what-is-kafka/images/what-is-kafka-01.webp" width="520" height="519" alt="image from link" fetchpriority="high" decoding="async">
  <figcaption>image from <a href="https://web.archive.org/web/20260612105408/https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying" title="原網頁已失效，連到網際網路檔案館的存檔">link</a></figcaption>
</figure>

<p>如果你覺得這個畫面很可怕，那不妨花點時間了解 Kafka 這門技術；本篇文章會帶讀者了解它的精神，以及選擇它的理由。</p>
<p><img src="https://deanlin.net/blog/202211/what-is-kafka/images/what-is-kafka-02.webp" width="1400" height="739" alt="正在為大數據所苦嗎？帶你了解 Kafka 這個分布式消息串流平台，以及它能解決什麼問題！（圖 2）" loading="lazy" decoding="async"></p>
<pre tabindex="0"><code>大綱

一、Kafka 具體能解決哪些問題，為什麼能解決？
二、Kafka 的基礎架構與階層關係
三、Kafka 為什麼吞吐量大？
四、Redis 也能夠處理 Pub/Sub，為什麼要用 Kafka？
</code></pre><blockquote>
<p>本篇文章是筆者揉合許多大神的經驗後，再用自己理解的話語表達出來，相關的資源放在最下方，有興趣的讀者可以參考看看。</p>
</blockquote>
<h2 id="一kafka-具體能解決哪些問題為什麼能解決">一、Kafka 具體能解決哪些問題，為什麼能解決？<a class="h-anchor" href="#%e4%b8%80kafka-%e5%85%b7%e9%ab%94%e8%83%bd%e8%a7%a3%e6%b1%ba%e5%93%aa%e4%ba%9b%e5%95%8f%e9%a1%8c%e7%82%ba%e4%bb%80%e9%ba%bc%e8%83%bd%e8%a7%a3%e6%b1%ba" aria-label="這個段落的連結"></a></h2>
<p><strong><em>Kafka 可以讓資料以合適的時機出現在合適的地方，你可以把它想像成消息隊列（Message queue），生產者（Producer）會往隊列結尾塞東西，消費者（Consumer）從隊列依次拿東西。</em></strong></p>
<p>如果看完上面的解釋還是一頭霧水，相信下面「送包裹」的案例能幫你理解。</p>
<h3 id="困境描述">困境描述：<a class="h-anchor" href="#%e5%9b%b0%e5%a2%83%e6%8f%8f%e8%bf%b0" aria-label="這個段落的連結"></a></h3>
<p>如果住在沒有管理員的公寓，包裹在上班時間送到你家門口，你就只能跟貨運司機說聲抱歉，因為沒人在家只能請他下次再送。</p>
<h3 id="解決方案">解決方案：<a class="h-anchor" href="#%e8%a7%a3%e6%b1%ba%e6%96%b9%e6%a1%88" aria-label="這個段落的連結"></a></h3>
<p>因為不是每個人都住在有管理員幫忙收包裹的大樓，為了解決這個問題，市場提出一個<strong>解決方案：「超商取貨」</strong>；從此以後，貨運司機不用跟你聯繫，把包裹送到超商即可，而你也不用在家裡等司機送貨，自己有時間的時候再去取貨就好。</p>
<p>「Kafka」就是扮演上述解法中「超商」的角色，這個方案的優勢在於：</p>
<ul>
<li><strong>降低耦合性</strong>：如果收貨人不在家，那司機就算送到門口也沒人取貨，因此這趟運送的實際效益為「0」；改成超商取貨後，司機只管把包裹送到指定超商即可，不再依賴收貨人是否在現場。</li>
<li><strong>非同步機制</strong>：就算收貨人在家，司機到樓下後也要等人下來領包裹（有些人還慢吞吞，或提出各種奧客需求），這個等待期間司機也沒辦法繼續送貨，整個流程都被卡住了；但改成超商取貨後，司機把包裹送到超商就可以直接跑下一家，完全不用等待。</li>
<li><strong>避免高峰期</strong>：假使有人趁著雙 11 在不同平台訂貨，會造成送包裹的單位不同；如果他們剛好在同個時間到你家門口，收貨人在面對一堆等待簽收的司機時容易手忙腳亂。而超商取貨時，儘管包裹的數量是一樣的，但你可以舒服的領取。</li>
</ul>
<hr>
<h2 id="二kafka-的基礎架構與階層關係">二、Kafka 的基礎架構與階層關係<a class="h-anchor" href="#%e4%ba%8ckafka-%e7%9a%84%e5%9f%ba%e7%a4%8e%e6%9e%b6%e6%a7%8b%e8%88%87%e9%9a%8e%e5%b1%a4%e9%97%9c%e4%bf%82" aria-label="這個段落的連結"></a></h2>
<p>透過上面的故事，大家應該對 Kafka 消息轉發者（Message broker）的定位更為理解，下面再說明一下它的基礎架構與階層關係：</p>
<pre tabindex="0"><code>[Producer]  [Kafka cluster]                         [Consumer]
              ├── Broker1                           
Producer0-&gt;   │     ├── Topic A
              │     │     ├── Partition0(Leader)  -&gt; Consumer Group A
              │     └── Topic B                         ├── Consumer0
              │           └── Partition0(Follower)      └── Consumer1
              └── Broker2
                    ├── Topic A
                    │     ├── Partition0(Follower)
                    └── Topic B
Producer1-&gt;               └── Partition0(Leader)  -&gt; Consumer Group B
                                                        ├── Consumer0
                                                        └── Consumer1
</code></pre><ul>
<li><strong>Producer</strong>：生產者，為消息的入口。</li>
<li><strong>Kafka cluster</strong>：Kafka 的集群，通常會有多個 Broker。</li>
<li><strong>Broker</strong>：Kafka 的實體，可以把它想像成每個 Broker 對應一台 Server。</li>
<li><strong>Topic</strong>：消息的主題，有點像是資料庫的 Table。</li>
<li><strong>Partition</strong>：Topic 的分區，一個 Topic 可以有多個分區。</li>
<li><strong>Replication</strong>：你在架構上會發現有些 Partition 是 Leader，有些是 Follower，當 Leader 故障時 Follower 就會上位；且 Leader 跟 Follower 會在不同的機器上，避免故障後一起陣亡。</li>
<li><strong>Consumer</strong>：消費者，為消息的出口。</li>
<li><strong>Consumer Group</strong>：可以將多個消費者組成一個消費群組，在 Kafka 的設計中，一個 Partition 的數據只允許消費群組中的某個消費者消費，消費群組中的消費者可以消費同一個 Topic 不同 Partition 的數據。</li>
</ul>
<p>通常狀態下，<strong>一個 Consumer Group 下的 Consumer 數量，建議與 Partition 的數量相同</strong>；下面我們把 Partition 當成一碗飯，Consumer 比喻為一個人，這樣會更好理解為何要這樣設計：</p>
<ul>
<li>可以出現一個人吃多碗飯的情況（但會吃太飽）。</li>
<li>不能出現多個人吃一碗飯的情況（禁止搶飯吃）。</li>
<li>如果人比飯碗多，那就得有人餓著。</li>
<li><strong>一人一碗，剛剛好（理想設計）。</strong></li>
</ul>
<hr>
<h2 id="三kafka-為什麼速度快吞吐量大">三、Kafka 為什麼速度快、吞吐量大？<a class="h-anchor" href="#%e4%b8%89kafka-%e7%82%ba%e4%bb%80%e9%ba%bc%e9%80%9f%e5%ba%a6%e5%bf%ab%e5%90%9e%e5%90%90%e9%87%8f%e5%a4%a7" aria-label="這個段落的連結"></a></h2>
<ul>
<li><strong>順序讀寫</strong>：Kafka 將資料寫到硬碟上，通常我們都會覺得硬碟的讀寫效能不理想；但效能是否理想，是取決於<code>順序讀寫 or 隨機讀寫</code>，無論硬碟還是記憶體都是如此，有時硬碟順序讀寫的效能甚至高於記憶體隨機讀寫。</li>
</ul>
<figure class="figure"><img src="https://deanlin.net/blog/202211/what-is-kafka/images/what-is-kafka-03.webp" width="585" height="322" alt="image from link" loading="lazy" decoding="async">
  <figcaption>image from <a href="https://deliveryimages.acm.org/10.1145/1570000/1563874/jacobs3.jpg">link</a></figcaption>
</figure>

<ul>
<li><strong>零拷貝</strong>：從 Producer 到 Broker，Kafka 採用 mmap 的方式把資料持久化到硬碟（從 2 次 CPU 拷貝減為 1 次）；從 Broker 到 Consumer，Kafka 採用 sendFile 的方式發送硬碟資料（零拷貝）。</li>
<li><strong>批量發送</strong>：Producer 在發送消息時，可以等消息到固定數量後再一次發送（假設網路頻寬為 10MB/s，一次傳送 10MB 的消息會比 1KB 的消息分 10,000 次傳送快很多）。</li>
<li><strong>批量壓縮</strong>：有時系統的瓶頸不在 CPU 或是硬碟，而是在網路 IO；針對這個問題，我們可以在批量發送的基礎上，一次對多筆消息進行批量壓縮，以此降低 IO 負擔。</li>
</ul>
<blockquote>
<p>Kafka 的訊息傳送是基於 TCP 協定，擁有比 HTTP 更好的效能，並且比 UDP 更加安全。</p>
</blockquote>
<hr>
<h2 id="四redis-也能處理-pubsub為什麼要用-kafka">四、Redis 也能處理 Pub/Sub，為什麼要用 Kafka？<a class="h-anchor" href="#%e5%9b%9bredis-%e4%b9%9f%e8%83%bd%e8%99%95%e7%90%86-pubsub%e7%82%ba%e4%bb%80%e9%ba%bc%e8%a6%81%e7%94%a8-kafka" aria-label="這個段落的連結"></a></h2>
<p>筆者在網路上看到一個很有趣的<a href="https://zhuanlan.zhihu.com/p/68052232">比喻</a>，在這裡做個分享：</p>
<p>老闆有個好消息要告訴大家，有兩個辦法:</p>
<ol>
<li><strong>到每個座位上挨個兒告訴每個人</strong>。什麼？張三去上廁所了？那張三就只能錯過好消息了！</li>
<li><strong>老闆把消息寫到黑板上，誰想知道就來看一下</strong>。什麼？張三請假了？沒關係，我一周之後才擦掉，總會看見的！什麼？張三請假兩週？那就算了，我反正只保留一周，不然其他好消息沒地方寫了。</li>
</ol>
<p>Redis 用第一種辦法，Kafka 用第二種辦法。</p>
<ul>
<li>Redis 是記憶體資料庫，它提供的 Pub/Sub 是將消息儲存於記憶體中，如果消息不用長久保存，並且消費速度快，那 Redis 很好用。</li>
<li>Kafka 將資料儲存於硬碟上，為消息提供了持久化的服務，這樣的設定對消費者來說很好，他可以按造順序消費，也可以重新消費過去的消息（不過硬碟容量有限，還是會使用「空間 or 時間」作為淘汰策略）。</li>
</ul>
<blockquote>
<p>Redis 也能將資料持久化，但並不是那麼的可靠。</p>
</blockquote>
<hr>
<p>希望這篇文章的內容有讓讀者初步了解 Kafka 的應用，<a href="https://deanlin.net/blog/202211/nodejs-kafka-hands-on/">下一篇文章</a>筆者會帶大家建立 Node.js 專案 ＆ Kafka 環境，透過<a href="https://deanlin.net/blog/202211/nodejs-kafka-hands-on/">具體的實踐</a>來了解 Kafka 的運行邏輯。</p>
<p>參考文件：</p>
<ol>
<li><a href="https://zhuanlan.zhihu.com/p/68052232">再过半小时，你就能明白Kafka的工作原理了</a></li>
<li><a href="https://www.cnblogs.com/smartloli/p/16430041.html">Kafka KRaft模式探索</a></li>
<li><a href="https://blog.csdn.net/liuzhenghui666666/article/details/106467057">Kafka解决了什么问题?(CSDN)</a></li>
<li><a href="https://www.zhihu.com/question/53331259">Kafka解决了什么问题?(知乎)</a></li>
<li><a href="https://kafka.js.org/">KafkaJS</a></li>
</ol>
]]></content:encoded>
    </item>
  </channel>
</rss>
