<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Chill Vic’s Architecture Notes]]></title><description><![CDATA[I’m Chill Vic, on the path to systems architecture, using simple, straightforward language to explain complex systems — from databases and system design to operating systems and algorithms.]]></description><link>https://www.chillvic.dev</link><image><url>https://substackcdn.com/image/fetch/$s_!4-yR!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddabf71b-360a-4310-8311-8b9a30fb05e3_722x722.png</url><title>Chill Vic’s Architecture Notes</title><link>https://www.chillvic.dev</link></image><generator>Substack</generator><lastBuildDate>Fri, 16 Oct 2026 10:25:02 GMT</lastBuildDate><atom:link href="https://www.chillvic.dev/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Chill Vic]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[chillvic@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[chillvic@substack.com]]></itunes:email><itunes:name><![CDATA[Chill Vic]]></itunes:name></itunes:owner><itunes:author><![CDATA[Chill Vic]]></itunes:author><googleplay:owner><![CDATA[chillvic@substack.com]]></googleplay:owner><googleplay:email><![CDATA[chillvic@substack.com]]></googleplay:email><googleplay:author><![CDATA[Chill Vic]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Understanding Compiler Optimizations Through CPU Architecture, Part 2: Branch Prediction and Rust Compiler Examples]]></title><description><![CDATA[Why Does the Compiler Optimize with Inlining?]]></description><link>https://www.chillvic.dev/p/understanding-compiler-optimizations</link><guid isPermaLink="false">https://www.chillvic.dev/p/understanding-compiler-optimizations</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Thu, 17 Sep 2026 08:53:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!sQjv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2960696-9dc7-4a1c-a4f5-33843eb767da_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a href="https://open.substack.com/pub/chillvic/p/why-doesnt-compiler-generated-code?r=72gamn&amp;utm_campaign=post-expanded-share&amp;utm_medium=web">In the previous article</a>, we started from the CPU pipeline and looked at superscalar execution, register renaming, out-of-order issue, the ROB, and the store buffer.</p><p>The goal behind these designs is to keep different stations inside the CPU pipeline as full as possible and improve instruction throughput.</p><p>If the pipeline always has ready instructions, the ALU, load units, and store units can keep doing useful work. Conversely, when the CPU does not know what to execute next, some stages in the pipeline start to sit idle.</p><p>By identifying data dependencies, where one instruction needs the result of a previous instruction, superscalar execution and register renaming allow independent instructions to run in parallel. Out-of-order issue also prevents later independent instructions from being blocked by an earlier instruction that is still waiting.</p><p>But for superscalar execution and out-of-order execution to work well, there is an even earlier requirement: Instruction Fetch station must keep fetching new instructions without interruption.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sQjv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2960696-9dc7-4a1c-a4f5-33843eb767da_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sQjv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2960696-9dc7-4a1c-a4f5-33843eb767da_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!sQjv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2960696-9dc7-4a1c-a4f5-33843eb767da_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!sQjv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2960696-9dc7-4a1c-a4f5-33843eb767da_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!sQjv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2960696-9dc7-4a1c-a4f5-33843eb767da_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sQjv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2960696-9dc7-4a1c-a4f5-33843eb767da_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b2960696-9dc7-4a1c-a4f5-33843eb767da_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1839458,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/216111775?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2960696-9dc7-4a1c-a4f5-33843eb767da_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!sQjv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2960696-9dc7-4a1c-a4f5-33843eb767da_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!sQjv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2960696-9dc7-4a1c-a4f5-33843eb767da_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!sQjv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2960696-9dc7-4a1c-a4f5-33843eb767da_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!sQjv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2960696-9dc7-4a1c-a4f5-33843eb767da_1536x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>When Does Instruction Fetch Station Stop?</h1><p>Conceptually, the CPU pipeline can be roughly divided into the <strong>frontend and the backend.</strong></p><p>The frontend is responsible for fetch, decode, rename, and preparing uops.</p><p>The backend is responsible for schedule, execute, memory access, and write back.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OaV6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a2e1df-44bf-4018-aa35-05faae12c6d7_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OaV6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a2e1df-44bf-4018-aa35-05faae12c6d7_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!OaV6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a2e1df-44bf-4018-aa35-05faae12c6d7_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!OaV6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a2e1df-44bf-4018-aa35-05faae12c6d7_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!OaV6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a2e1df-44bf-4018-aa35-05faae12c6d7_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OaV6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a2e1df-44bf-4018-aa35-05faae12c6d7_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/23a2e1df-44bf-4018-aa35-05faae12c6d7_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1590787,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/216111775?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a2e1df-44bf-4018-aa35-05faae12c6d7_1672x941.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OaV6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a2e1df-44bf-4018-aa35-05faae12c6d7_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!OaV6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a2e1df-44bf-4018-aa35-05faae12c6d7_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!OaV6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a2e1df-44bf-4018-aa35-05faae12c6d7_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!OaV6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a2e1df-44bf-4018-aa35-05faae12c6d7_1672x941.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The data dependencies discussed in the <a href="https://open.substack.com/pub/chillvic/p/why-doesnt-compiler-generated-code?r=72gamn&amp;utm_campaign=post-expanded-share&amp;utm_medium=web">previous article</a> mainly affect the backend: if the operands of a uop are not ready, the scheduler cannot send it to an execution unit.</p><div class="callout-block" data-callout="true"><p><strong>But another kind of dependency can block the frontend earlier: control dependency.</strong></p><p><strong>A control dependency means the next program counter is not yet known, so Instruction Fetch does not know where to fetch the next instruction.</strong></p></div><p>Once the frontend stops, the later decode, rename, schedule, and execution units quickly run out of work. Function calls are one common source of such control dependencies.</p><h1>Why Is a Function Call a Control Dependency?</h1><p>Consider this code:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">void f() {
  g();
  x = 1;
}

void h() {
  g();
  y = 2;

}

void g() {
  return;
}</code></pre></div><p>When the CPU executes <code>g()</code> inside f, the call target is usually clear. In other words, the CPU knows where the code for <code>g</code> is. The tricky part is the return.</p><p>From the perspective of the return inside g, if <code>g</code> was called from <code>f</code>, the next instruction should go back to <code>x = 1</code>. If <code>g</code> was called from <code>h</code>, the next instruction should go back to <code>y = 2</code>.</p><p>Therefore, for Instruction Fetch, return is also a control transfer. It needs to know the return address before it can know the next PC and continue fetching.</p><p><strong>While the CPU is waiting, the pipeline frontend may sit idle, so the compiler has a very direct optimization strategy: inline.</strong></p><p>Inlining removes the function call and expands the callee body directly into the caller. For example, the body of g above is very small, so the compiler can expand it into f and h. Once that happens, both the call and return disappear, and the original cross-function control flow becomes a more continuous instruction stream.</p><p>Besides removing the function call, inlining also makes the callee body part of the caller. This lets the compiler continue with optimizations such as constant propagation and dead code elimination. For example:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">fn add_or_sub(x: i32, add: bool) -&gt; i32 {
    if add {
        x + 1
    } else {
        x - 1
    }
}

fn f() -&gt; i32 {
    add_or_sub(10, true)
}</code></pre></div><p>After inlining, the compiler can conceptually see:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">fn f() -&gt; i32 {
    if true {
        10 + 1
    } else {
        10 - 1
    }
}</code></pre></div><p>Because add = true and x = 10 are now known constants, constant propagation plus dead code elimination can simplify the code into:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">fn f() -&gt; i32 {
  11
}</code></pre></div><p><strong>But not every function call can be inlined so easily. Object method calls are a more interesting example.</strong></p><h1>Why Can&#8217;t Object Method Calls Be Inlined Easily?</h1><p>Start with a Rust trait:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">trait Draw {
  fn draw(&amp;self);
}

struct Circle;

struct Square;

impl Draw for Circle {
  fn draw(&amp;self) {}
}

impl Draw for Square {
  fn draw(&amp;self) {}
}</code></pre></div><p>If render is written like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">fn render&lt;T: Draw&gt;(x: &amp;T) {
  x.draw();
}</code></pre></div><p>And called like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">render(&amp;Circle);
render(&amp;Square);</code></pre></div><p>From the perspective of trait abstraction, render seems to only know that x has the Draw capability. It does not seem to know whether x is a Circle or a Square.</p><p>If the method target really had to be determined at runtime, then x.draw() would be an indirect function call, which would make it hard to inline directly.</p><p><strong>But this version of render uses a generic type parameter plus a trait bound. In Rust, this uses static dispatch through generic monomorphization.</strong> </p><p>The compiler generates different versions of the function based on the concrete types actually used:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">render(&amp;Circle); =&gt; render_for_Circle(...) =&gt; x.draw() is Circle::draw

render(&amp;Square); =&gt; render_for_Square(...) =&gt; x.draw() is Square::draw</code></pre></div><p>Once the target becomes clear, the compiler has a chance to inline it. This is one important reason Rust generics use monomorphization: they trade more code generation for static dispatch, direct calls, and more inlining opportunities.</p><p>But Rust traits have another form that cannot be solved through monomorphization.</p><h1>Why Can Rust dyn Trait Be Slower Than Generic Trait?</h1><p>Traits can also be used like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">fn render(x: &amp;dyn Draw) {
  x.draw();
}</code></pre></div><p>Here, dyn Draw means dynamic dispatch.</p><p>render does not know whether the concrete type behind x is Circle or Square. It only knows that x supports Draw.</p><p>This often appears in heterogeneous collections. For example, if an array wants to store values that all implement Draw but may actually be Circle or Square underneath, the concrete element type of Vec still has to be the same. So it is commonly declared as:</p><p><code>Vec&lt;&amp;dyn Draw&gt;</code> or <code>Vec&lt;Box&lt;dyn Draw&gt;&gt;</code></p><p>dyn Draw is an unsized trait object type. It can be roughly understood as another object type whose fields are a data pointer and a vtable pointer:</p><ul><li><p><strong>data pointer:</strong> points to the real object, such as Circle or Square.</p></li><li><p><strong>vtable pointer:</strong> points to a Virtual Method Table. It stores method function pointers and some metadata, and the corresponding method logic is found through a method slot id.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!L2vq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c7cf1b2-a3e1-4f74-a32a-375cc6e86c8e_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!L2vq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c7cf1b2-a3e1-4f74-a32a-375cc6e86c8e_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!L2vq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c7cf1b2-a3e1-4f74-a32a-375cc6e86c8e_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!L2vq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c7cf1b2-a3e1-4f74-a32a-375cc6e86c8e_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!L2vq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c7cf1b2-a3e1-4f74-a32a-375cc6e86c8e_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!L2vq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c7cf1b2-a3e1-4f74-a32a-375cc6e86c8e_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c7cf1b2-a3e1-4f74-a32a-375cc6e86c8e_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1533328,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/216111775?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c7cf1b2-a3e1-4f74-a32a-375cc6e86c8e_1672x941.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!L2vq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c7cf1b2-a3e1-4f74-a32a-375cc6e86c8e_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!L2vq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c7cf1b2-a3e1-4f74-a32a-375cc6e86c8e_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!L2vq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c7cf1b2-a3e1-4f74-a32a-375cc6e86c8e_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!L2vq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c7cf1b2-a3e1-4f74-a32a-375cc6e86c8e_1672x941.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>With dynamic dispatch implemented through the vtable, x.draw() conceptually executes like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">method = x.vtable_ptr[DRAW_SLOT]

method(x.data_ptr)</code></pre></div><p>Because dyn Draw is an unsized object type, it must be passed through a pointer to have a fixed size. Or it can be wrapped in <code>Box&lt;dyn Draw&gt;</code> to provide RAII, so when it leaves scope, the drop metadata in the vtable can correctly drop the concrete object pointed to by the data pointer.</p><p>Therefore, dyn Trait cannot generate <code>render_for_Circle</code> and <code>render_for_Square</code> the way generic <code>T: Trait</code> can. It can only call indirectly through the vtable, and usually cannot be inlined.</p><p>This is one reason dyn Trait can be slower than generic Trait.</p><p>C++ virtual methods are similar. They are usually implemented through a vtable as well. A common optimization technique is CRTP, which uses templates to implement static polymorphism.</p><p>At this point, we can see a pattern:</p><div class="callout-block" data-callout="true"><p><strong>If the compiler knows the call target at compile time, it can use a direct call, and may even inline it. If the target is only known at runtime, the program keeps an indirect call, and the CPU frontend has to deal with the control flow.</strong></p></div><h1>If the Compiler Cannot Remove a Function Call, Can the CPU Optimize It by Itself?</h1><p>Yes. The CPU uses a hardware mechanism to predict return addresses.</p><p>This structure is called the Return Stack Buffer, or RSB. Conceptually, it is like a hardware call stack. When call g happens, the CPU pushes the address after the call into the RSB. When return happens, it pops an address from the RSB and first predicts that the return will go there.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Q6NW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbba2a75f-1342-405e-8ea2-1e61fdb81698_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Q6NW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbba2a75f-1342-405e-8ea2-1e61fdb81698_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!Q6NW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbba2a75f-1342-405e-8ea2-1e61fdb81698_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!Q6NW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbba2a75f-1342-405e-8ea2-1e61fdb81698_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!Q6NW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbba2a75f-1342-405e-8ea2-1e61fdb81698_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Q6NW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbba2a75f-1342-405e-8ea2-1e61fdb81698_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bba2a75f-1342-405e-8ea2-1e61fdb81698_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1503079,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/216111775?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbba2a75f-1342-405e-8ea2-1e61fdb81698_1672x941.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Q6NW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbba2a75f-1342-405e-8ea2-1e61fdb81698_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!Q6NW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbba2a75f-1342-405e-8ea2-1e61fdb81698_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!Q6NW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbba2a75f-1342-405e-8ea2-1e61fdb81698_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!Q6NW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbba2a75f-1342-405e-8ea2-1e61fdb81698_1672x941.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>If the prediction is correct, the CPU can fetch the caller&#8217;s following instructions earlier.</p><p>If the prediction is wrong, the speculative work on the wrong path is flushed, and the CPU fetches again from the correct address. The previous work becomes wasted work.</p><div class="callout-block" data-callout="true"><p><strong>This is part of the CPU frontend&#8217;s branch prediction mechanism. The idea of &#8220;guessing the next PC first&#8221; also appears in other control flows.</strong></p></div><h1>Besides Function Calls, What Other Control Flow Affects the CPU Pipeline?</h1><p>The most common one is if.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">if (x &gt; 0) {
  a();
} else {
  b();
}</code></pre></div><p>Conceptually, it may be compiled into:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">cmp x, 0
jump_if_less_or_equal else_path
call a
jump end
else_path:
call b
end:</code></pre></div><p>For the CPU to know whether the next instruction is on the a path or the b path, it first has to know the result of <code>x &gt; 0</code>. To avoid leaving the pipeline idle, the CPU performs branch prediction and guesses two things:</p><ul><li><p><strong>Direction prediction:</strong> will this branch be taken or not taken?</p></li><li><p><strong>Target prediction:</strong> if it is taken, which address should it jump to?</p></li></ul><p>For example, if <code>jump_if_less_or_equal</code> is taken, it jumps to <code>else_path</code> and needs to know the instruction address of call b. If it is not taken, it does not jump and simply continues to execute the next instruction, call a.</p><p>To avoid wrong guesses, the simplest prediction method is based on past execution behavior. For example, consider a loop branch:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">for (int i = 0; i &lt; 4; i++) {
  work();
}</code></pre></div><p>After compilation:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">loop_start:
work()
i = i + 1
cmp i, 4
jump_if_less loop_start</code></pre></div><p>If the <code>jump_if_less</code> branch is taken, it returns to <code>loop_start</code>. If it is not taken, execution falls through and breaks out of the loop. The simplest predictor can use 1 bit to record branch history:</p><p>The 1st to 3rd times (i: 0 to 2) are all Taken. The 4th time (i: 3) can still be predicted as Taken, so Instruction Fetch can fetch work() without waiting for the <code>jump_if_less</code> result. But on the 5th time (i: 4), if it still predicts Taken, it will be wrong. At this point, the branch history is:</p><p>T T T T N</p><p>When the same loop runs a second time, the previous failure leaves the predictor state at N. The CPU follows the previous state and predicts N, so it gets the first iteration wrong again. The optimization is to use a 2-bit state machine: </p><p>Strongly Taken (ST), Weakly Taken (WT), Weakly Not Taken (WN), and Strongly Not Taken (SN).</p><p>During the first loop, the state sequence is WT ST ST ST WT. When WT sees one wrong prediction, it only moves to WN if it is wrong again, so the second execution of the loop still predicts Taken. The second loop then becomes ST ST ST ST WT. This means only the final round of each loop is mispredicted, reducing repeated loop mispredictions from 2*n+1 to n.</p><p>More advanced CPUs use a loop predictor to remember the taken and not-taken counts of this loop. For example, after observing this loop:</p><p>T T T T N</p><p>The next time, it can predict:</p><p>the first four times are taken, and the fifth time is not taken and exits the loop. If the iteration count is stable, the loop predictor can even correctly predict the final exit. </p><p>But this iteration-count-based predictor is suitable for loops because loop branch behavior has a clear direction: Taken states are usually consecutive. Other control flow, such as if-else, does not necessarily have this property.</p><h1>How Does a Normal if-else Use History for Prediction?</h1><p>A normal if branch often depends on runtime data. For example:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">if (x &gt; 0) {
  a();
} else {
  b();
}</code></pre></div><p>If x comes from a request, the branch result may not have a fixed iteration count. In this case, the predictor uses branch history and patterns.</p><p>A simplified model is:</p><p>The CPU records the recent results of a branch, such as:</p><p>T T N T N</p><p>It uses this history, TTNTN, as a key to look up a predictor table and find the likely next state. Therefore, branch prediction has two tables:</p><ul><li><p><strong>BHT</strong>, Branch History Table, records branch history.</p></li><li><p><strong>PHT</strong>, Pattern History Table, records the likely next state for a given history pattern.</p></li></ul><p><strong>BTB</strong>, Branch Target Buffer, records which instruction address a branch should jump to if it is taken.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZC19!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1396b28c-49e3-42c8-965a-bcd066b7d8eb_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZC19!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1396b28c-49e3-42c8-965a-bcd066b7d8eb_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!ZC19!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1396b28c-49e3-42c8-965a-bcd066b7d8eb_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!ZC19!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1396b28c-49e3-42c8-965a-bcd066b7d8eb_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!ZC19!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1396b28c-49e3-42c8-965a-bcd066b7d8eb_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZC19!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1396b28c-49e3-42c8-965a-bcd066b7d8eb_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1396b28c-49e3-42c8-965a-bcd066b7d8eb_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1472871,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/216111775?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1396b28c-49e3-42c8-965a-bcd066b7d8eb_1672x941.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZC19!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1396b28c-49e3-42c8-965a-bcd066b7d8eb_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!ZC19!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1396b28c-49e3-42c8-965a-bcd066b7d8eb_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!ZC19!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1396b28c-49e3-42c8-965a-bcd066b7d8eb_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!ZC19!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1396b28c-49e3-42c8-965a-bcd066b7d8eb_1672x941.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In real programs, different branches are often correlated. For example:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">if (req.method == POST) {
  ...
}

if (req.body_bytes &gt; 0) {
 ...
}</code></pre></div><p>When `req.method is POST, req.body_bytes &gt; 0 is also more likely to be true. Therefore, the predictor can look not only at a branch&#8217;s own local history, but also at the global history of recent branches. For example, T T N T N can represent the states of the previous five branches. In simple terms:</p><div class="callout-block" data-callout="true"><p><strong>Local history stores how this specific branch behaved in the past, while global history stores what the recent overall control flow looked like.</strong></p></div><p>Modern CPU branch predictors combine many information sources, such as local history and global history, to improve accuracy. But prediction is not free. It requires additional hardware space for RSB, history, and predictor state, and it also requires extra table lookups and selection logic.</p><p>And even if prediction is usually accurate, one wrong guess can turn fetched, decoded, renamed, and even partially executed work on the wrong path into wasted work.</p><p>Therefore, the compiler still needs to optimize control flow.</p><h1>How Does the Compiler Help Control Flow Run Faster?</h1><p>The most direct optimization is similar to inlining a function call away: sometimes the compiler can eliminate a branch jump through branchless transformation.</p><p>For example, suppose x is dynamically determined by a request:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">if (x &gt; 10) {
  count += 1;
}</code></pre></div><p>Conceptually, after compilation this may become:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">cmp x, 10
jump_if_less_or_equal skip
add count, 1
skip:</code></pre></div><p>When <code>jump_if_less_or_equal</code> is hard to predict, the CPU may often put instructions from the wrong path into the pipeline, causing wasted work. In this case, the compiler can transform it into:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">count += (x &gt; 10);</code></pre></div><p>Conceptually, it becomes:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">cmp x, 10
flag = condition ? 1 : 0
add count, flag</code></pre></div><p>Now the <code>jump_if_less_or_equal</code> branch disappears. There is no branch jump to predict. But set flag still depends on the result of cmp x, 10, so the dependency has not disappeared. <strong>It has only changed from a control dependency into a data dependency.</strong> <strong>The instruction stream can now continue forward without a jump and without guessing the next PC.</strong></p><p>The tradeoff is that branchless code often has to prepare the values for both outcomes first, such as 1 and 0, and then select or combine the right one afterward.</p><p>Therefore, branchless code is suitable for small value selection, such as adding 0 or 1 to count, or operations like <code>max(a, b)</code>. But branchless transformation is not universal. For example:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">if (req.is_premium) {
  handle_premium();
} else {
  handle_normal();
}</code></pre></div><p><code>handle_premium</code> and <code>handle_normal</code> may contain complex logic. You would not want to execute both <code>handle_premium</code> and <code>handle_normal</code> first and then choose one result. In this case, besides relying on the CPU predictor, the compiler&#8217;s machine-instruction layout also matters.</p><p>The example above can be arranged in two shapes.</p><p>case A:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">cmp req.is_premium, true
jump_if_false normal
handle_premium
return
normal:
handle_normal
return</code></pre></div><p>case B:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">cmp req.is_premium, true
jump_if_true premium
handle_normal
return
premium:
handle_premium
return</code></pre></div><p>Assume <code>req.is_premium</code> is rare. Then <code>handle_normal</code> is the hot path, and <code>handle_premium</code> is the cold path.</p><p>In case A, the <code>jump_if_false</code> normal branch is frequently taken and jumps to normal. Since instructions are laid out sequentially in the instruction cache, a jump redirect makes the instruction stream less sequential and less continuous, which may reduce instruction locality.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XL7w!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe743bd54-3117-4371-a46b-a6f788691911_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XL7w!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe743bd54-3117-4371-a46b-a6f788691911_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!XL7w!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe743bd54-3117-4371-a46b-a6f788691911_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!XL7w!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe743bd54-3117-4371-a46b-a6f788691911_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!XL7w!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe743bd54-3117-4371-a46b-a6f788691911_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XL7w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe743bd54-3117-4371-a46b-a6f788691911_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e743bd54-3117-4371-a46b-a6f788691911_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1906104,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/216111775?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe743bd54-3117-4371-a46b-a6f788691911_1672x941.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XL7w!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe743bd54-3117-4371-a46b-a6f788691911_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!XL7w!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe743bd54-3117-4371-a46b-a6f788691911_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!XL7w!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe743bd54-3117-4371-a46b-a6f788691911_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!XL7w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe743bd54-3117-4371-a46b-a6f788691911_1672x941.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Therefore, case B is the better layout. jump_if_true premium is usually not taken, so the instruction stream can be fetched sequentially and naturally reach the normal path.</p><div class="callout-block" data-callout="true"><p>This is hot path fall-through optimization. It does not eliminate the branch. It makes the most common path correspond to &#8220;do not jump, just continue executing downward.&#8221;</p></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!s8nW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d4f4594-fb19-4406-a5c1-08819d263cd7_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!s8nW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d4f4594-fb19-4406-a5c1-08819d263cd7_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!s8nW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d4f4594-fb19-4406-a5c1-08819d263cd7_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!s8nW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d4f4594-fb19-4406-a5c1-08819d263cd7_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!s8nW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d4f4594-fb19-4406-a5c1-08819d263cd7_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!s8nW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d4f4594-fb19-4406-a5c1-08819d263cd7_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5d4f4594-fb19-4406-a5c1-08819d263cd7_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1506071,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/216111775?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d4f4594-fb19-4406-a5c1-08819d263cd7_1672x941.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!s8nW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d4f4594-fb19-4406-a5c1-08819d263cd7_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!s8nW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d4f4594-fb19-4406-a5c1-08819d263cd7_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!s8nW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d4f4594-fb19-4406-a5c1-08819d263cd7_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!s8nW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d4f4594-fb19-4406-a5c1-08819d263cd7_1672x941.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>How Does the Compiler Know Which Path Is Hot?</h1><p>The first source is heuristics plus programmer hints. Based on experience, panic paths, throw paths, bounds-check failures, and error paths are usually not triggered often, so they can be marked as cold paths to tell the compiler.</p><p>For Rust&#8217;s unwrap, conceptually it looks like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">#[inline(always)]
pub const fn unwrap(self) -&gt; T {
    match self {
        Some(val) =&gt; val,
        None =&gt; unwrap_failed(),
    }
}

#[cfg_attr(not(panic = &#8220;immediate-abort&#8221;), inline(never))]
#[cold]
#[track_caller]
const fn unwrap_failed() -&gt; ! {
    panic(&#8221;called `Option::unwrap()` on a `None` value&#8221;)
}</code></pre></div><p>The <code>#[cold]</code> attribute tells the compiler that this is a cold path, allowing the compiler to lay out code more appropriately. C++ also has <code>[[likely]]</code> and <code>[[unlikely]]</code>.</p><p>The second source is Profile-Guided Optimization, or PGO. First, an instrumented binary is run with a real workload to collect which branches are common, which functions are hot, and which blocks are cold. Then the program is recompiled using that profile. This is more reliable than manually guessing the hot path because it uses actual execution data.</p><p>For example, Rust can use LLVM PGO. Besides hot path marking, if the profile shows that a dyn Trait is almost always one concrete type, the compiler may optimize that concrete type into a direct dispatch plus inline fast path:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">fn render(x: &amp;dyn Draw) {
    // Original:
    // call x.vtable.draw(x.data)
    // PGO finds that most cases use Circle as the concrete type.

    if likely_is_circle(x) {
        Circle::draw(x.data)   // direct call, possibly inline
    } else {
        x.vtable.draw(x.data)  // fallback dynamic dispatch
    }
}</code></pre></div><h1>Other Interesting Branch-Related Compiler Optimizations</h1><p>The first one is <strong>bounds check elimination</strong>.</p><p>For example:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">sum += slice[i];</code></pre></div><p>This actually contains a condition check: if i is out of bounds, the program has to panic.</p><p>But if the code is:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">for i in 0..slice.len() {
  sum += slice[i];
}</code></pre></div><p>The compiler may be able to prove that i is always between 0 and slice.len(), so it does not need to perform a bounds check every time. It can directly remove that unnecessary branch.</p><p>The second one is <strong>loop unswitching</strong>.</p><p>Suppose we have:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">for (int i = 0; i &lt; n; i++) {
  if (debug) {
    slow_debug(a[i]);
  } else {
    fast(a[i]);
  }
}</code></pre></div><p>If debug does not change throughout the loop, the original code has to check debug every iteration.</p><p>The compiler can transform it into:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">if (debug) {
  for (int i = 0; i &lt; n; i++) {
    slow_debug(a[i]);
  }
} else {
  for (int i = 0; i &lt; n; i++) {
    fast(a[i]);
  }
}</code></pre></div><p>This moves the debug branch from inside the loop to outside the loop. The branch only runs once before entering the loop, reducing the number of branch predictions. The loop body also becomes simpler, making it easier for the compiler to perform loop unrolling.</p><h1>Summary</h1><p>The CPU pipeline can be divided into the frontend (fetch, decode, rename) and the backend (schedule, execute, memory access, write back). The superscalar execution, register renaming, and out-of-order issue discussed in the previous article are mainly about improving backend throughput.</p><p>But backend throughput can only improve if frontend throughput also keeps up. The key issue for backend throughput is data dependency, while the key issue for the frontend is control dependency, such as function calls and if-else.</p><p>From the perspective of CPU architecture, compiler optimization often helps the CPU keep the instruction stream stable. Inlining removes function calls and returns. Rust generics use monomorphization to turn trait method calls into static dispatch, increasing opportunities for direct calls and inlining.</p><p>When a branch cannot be eliminated, the CPU uses branch prediction to guess the next PC. The compiler uses techniques such as branchless transformation, hot path fall-through, cold path marking, PGO, bounds check elimination, and loop unswitching to make control flow easier to predict or less frequent.</p><p>The core idea is simple: the compiler is not just making code shorter. It is reshaping the program into a form that is easier for the CPU pipeline to keep executing.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ct5N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febeeafe3-946b-43a7-9068-c989cebc05d3_1916x821.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ct5N!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febeeafe3-946b-43a7-9068-c989cebc05d3_1916x821.png 424w, https://substackcdn.com/image/fetch/$s_!ct5N!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febeeafe3-946b-43a7-9068-c989cebc05d3_1916x821.png 848w, https://substackcdn.com/image/fetch/$s_!ct5N!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febeeafe3-946b-43a7-9068-c989cebc05d3_1916x821.png 1272w, https://substackcdn.com/image/fetch/$s_!ct5N!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febeeafe3-946b-43a7-9068-c989cebc05d3_1916x821.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ct5N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febeeafe3-946b-43a7-9068-c989cebc05d3_1916x821.png" width="1456" height="624" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ebeeafe3-946b-43a7-9068-c989cebc05d3_1916x821.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:624,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2121334,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/216111775?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febeeafe3-946b-43a7-9068-c989cebc05d3_1916x821.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ct5N!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febeeafe3-946b-43a7-9068-c989cebc05d3_1916x821.png 424w, https://substackcdn.com/image/fetch/$s_!ct5N!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febeeafe3-946b-43a7-9068-c989cebc05d3_1916x821.png 848w, https://substackcdn.com/image/fetch/$s_!ct5N!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febeeafe3-946b-43a7-9068-c989cebc05d3_1916x821.png 1272w, https://substackcdn.com/image/fetch/$s_!ct5N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febeeafe3-946b-43a7-9068-c989cebc05d3_1916x821.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Chill Vic&#8217;s Architecture Notes! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[How to Survive in this AI Age?]]></title><description><![CDATA[A Software Engineer&#8217;s Reflection on Depth, Breadth, and Learning with AI]]></description><link>https://www.chillvic.dev/p/how-to-survive-in-this-ai-age</link><guid isPermaLink="false">https://www.chillvic.dev/p/how-to-survive-in-this-ai-age</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Tue, 15 Sep 2026 09:02:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!0L5W!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf807e5a-98fb-4963-8df3-96fe9b0ffec2_688x1024.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every era of software engineering has had its scarce resource. For a long time, knowledge itself was expensive to acquire. Understanding a new technology could take days of reading documentation, books, and source code. AI has dramatically reduced that cost: today, almost any concept can be explained within seconds.</p><p><strong>But scarcity never disappears. It moves.</strong></p><p>Recently, I spoke with several experienced engineers about what becomes more valuable when knowledge itself is easier to access. One question stood out in our discussions: Should we learn deeply or broadly in the age of AI?</p><p>We generally agreed that breadth of knowledge is becoming increasingly valuable. <strong>But this does not mean that deep expertise is no longer important.</strong></p><div class="callout-block" data-callout="true"><p><em><strong>In fact, breadth and depth reinforce each other, and developing one can naturally contribute to the other.</strong></em></p></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0L5W!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf807e5a-98fb-4963-8df3-96fe9b0ffec2_688x1024.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0L5W!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf807e5a-98fb-4963-8df3-96fe9b0ffec2_688x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0L5W!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf807e5a-98fb-4963-8df3-96fe9b0ffec2_688x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0L5W!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf807e5a-98fb-4963-8df3-96fe9b0ffec2_688x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0L5W!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf807e5a-98fb-4963-8df3-96fe9b0ffec2_688x1024.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0L5W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf807e5a-98fb-4963-8df3-96fe9b0ffec2_688x1024.jpeg" width="688" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/df807e5a-98fb-4963-8df3-96fe9b0ffec2_688x1024.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:688,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:177899,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/215777722?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf807e5a-98fb-4963-8df3-96fe9b0ffec2_688x1024.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0L5W!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf807e5a-98fb-4963-8df3-96fe9b0ffec2_688x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0L5W!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf807e5a-98fb-4963-8df3-96fe9b0ffec2_688x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0L5W!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf807e5a-98fb-4963-8df3-96fe9b0ffec2_688x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0L5W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf807e5a-98fb-4963-8df3-96fe9b0ffec2_688x1024.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Why does breadth matter more in the age of AI?</h1><p>With the rise of agentic AI, a simple prompt can trigger a complex workflow or generate a comprehensive report. However, tasks such as system design, debugging, and product exploration rarely end with a single prompt. They usually require an extended conversation in which you continuously ask questions, evaluate the responses, and decide which direction to explore next.</p><p>This changes the value of knowledge. You may not need deep expertise in every topic, but you need enough familiarity to recognize important concepts when they appear. Once you identify a relevant concept in an AI response, you can formulate a follow-up question and guide the AI toward a potentially useful direction.</p><p>In other words, broad knowledge expands the range of questions you are capable of asking. AI may help you find the answers, but you still need enough knowledge to know which questions are worth asking.</p><p>From my perspective, however, developing breadth is actually more challenging than developing depth. When studying a specific topic in depth, you usually have a relatively clear direction and learning path. Building breadth is different: it requires you to discover and explore fields that you may not even know exist.</p><div class="callout-block" data-callout="true"><p><em><strong>So how can we discover these unknown fields? One possible answer is to start by going deeper into what we already know.</strong></em></p></div><h1>Go Deeper: Ask Why and Explore Alternatives</h1><p><strong>This brings us back to the relationship between depth and breadth</strong>. Diving deeply into one topic naturally exposes you to a range of related concepts. Rather than simply learning what each concept does, however, I believe it is more important to ask three questions: What problem is it trying to solve? What assumptions does the solution make? And what trade-offs does it introduce?</p><p>From there, you can investigate alternative solutions and compare how they approach the same problem. Each alternative may introduce unfamiliar concepts or technologies because different solutions are built around different assumptions and make different trade-offs.</p><p>This creates a natural path from depth to breadth: you begin with one problem, understand one solution deeply, explore its alternatives, and gradually discover adjacent fields along the way.</p><p>Therefore, paradoxically, one of the most effective ways to broaden your knowledge is to start by learning something deeply.</p><div class="callout-block" data-callout="true"><p><em><strong>The next challenge, then, is how to learn deeply and effectively&#8212;and this is where AI can help.</strong></em></p></div><h1>Build Your Reasoning Through Questions, Not Answers</h1><p>Although developing depth can naturally expand the breadth of our knowledge, how we learn deeply matters. Rather than memorizing isolated concepts, I believe we should focus on constructing our own reasoning about a subject. AI makes this process considerably easier.</p><p>Everyone approaches learning with different experiences, prior knowledge, and mental models. As a result, two people may follow entirely different lines of reasoning and still arrive at the same conclusion. What matters is not merely remembering the conclusion, but understanding the chain of questions that leads you there.</p><p>This is where AI becomes particularly valuable. Reasoning can be viewed as an iterative process of asking questions, examining answers, and generating better follow-up questions. With AI, you can continue this process without worrying that a question is too basic or that you are taking up someone else&#8217;s time.</p><p>Repeatedly questioning, digesting, and refining your understanding helps develop two important abilities: <strong>abstraction and mental-model building.</strong> </p><div class="callout-block" data-callout="true"><p><em><strong>Mental models help you understand unfamiliar concepts more quickly by providing a reusable framework for reasoning, while abstraction allows you to transfer ideas from one domain to another.</strong></em></p></div><h1>One of My Mental Models for Understanding New Concepts</h1><p>One mental model I find particularly useful is to start with the simplest, most naive solution whenever I struggle to understand why a technology was designed in a particular way.</p><p>Take MVCC as an example. It is widely used in database systems to support transaction isolation. Instead of simply memorizing how MVCC works, I start with a more fundamental question: <strong>without MVCC, how could we prevent one transaction from reading another transaction&#8217;s uncommitted changes?</strong></p><p>The first step is to <strong>seek alternatives</strong>. I usually start with the simplest possible solution because it is often the easiest one to come up with on my own, without relying on prior knowledge of the actual design. </p><p>For MVCC, the most straightforward alternative is to use locks. This immediately leads to the next step: <strong>examining the trade-offs</strong>. What happens when concurrency increases? Lock contention can become a major bottleneck.</p><p>Following this reasoning helps explain why maintaining multiple versions of data is useful. Rather than forcing readers and writers to compete for access to the same version of a record, MVCC allows them to operate on different versions under appropriate visibility rules.</p><p>The final step is to <strong>build an abstraction</strong>. The idea is no longer limited to MVCC: maintaining different versions or copies of data can reduce coordination and contention between concurrent readers and writers. Once we extract this underlying pattern, we can recognize similar ideas in other domains, such as Read-Copy-Update (RCU) concurrency control in the Linux kernel.</p><p>This gives me a reusable reasoning process: <strong>seek alternatives &#8594; examine trade-offs &#8594; build an abstraction</strong>. AI can accelerate this process by helping me explore each question and alternative, rather than simply giving me the final answer.</p><div class="callout-block" data-callout="true"><p><em><strong>But when it comes to building breadth, this raises another question: how much do we actually need to understand before moving on, and when should we go deeper?</strong></em></p></div><h1>Building Layers into Your Mental Model</h1><p>Once you have developed a mental model for learning unfamiliar concepts, the next step is to give that model different levels of depth. This allows you to build broad knowledge efficiently without feeling the need to master every field you encounter.</p><p>I organize my learning into three layers:</p><p><strong>Layer 1 &#8212; Purpose and intuition:</strong> What is it? What problem does it solve? Why does that problem matter?</p><p><strong>Layer 2 &#8212; Design and trade-offs:</strong> How does the technology solve the problem? What assumptions does it make? What trade-offs does it introduce? What alternatives exist? What does the high-level architecture look like?</p><p><strong>Layer 3 &#8212; Implementation and internals:</strong> How is it actually implemented? How do you debug it? How do you analyze its behavior and internal details?</p><p>Consider learning how an AI model is trained. I might begin with fundamental questions: What is machine learning? How does a machine learn from data? Why are linear algebra and calculus important?</p><p>I can then move toward questions about the solution itself. What would the simplest approach to adjusting a model be? In next-token prediction, what exactly are we trying to optimize? Why do we need more sophisticated architectures?</p><p>From there, I might explore architectural questions: How does a Transformer handle long-range dependencies? How does it differ from CNNs and RNNs, and what limitations of earlier approaches was it designed to address?</p><p>Answering questions at this level gives me a working mental model of the field without requiring deep expertise in every implementation detail. For many adjacent fields, reaching Layer 1 or Layer 2 may already be sufficient. </p><p>If a field later becomes important to my work, I can continue into Layer 3. With a clear understanding of the underlying problem, design choices, and trade-offs, I can develop a deeper learning roadmap much faster and, more importantly, know which questions are worth asking as I explore the implementation details.</p><p>In this way, breadth doesn&#8217;t come at the expense of depth; instead, it provides a foundation that makes deeper learning faster and more focused.</p><p>But as AI continues to reduce the cost of learning, a new bottleneck emerges.</p><div class="callout-block" data-callout="true"><p><em><strong>If knowledge is no longer the scarce resource, what is?</strong></em></p></div><h1>Managing Attention and Anxiety in the Age of AI</h1><p>AI has dramatically lowered the barrier to accessing information and learning new skills. At the same time, however, information overload has become a more serious problem. There is always another concept to learn, another AI response to read, and another direction to explore. This endless stream of information can easily leave us mentally exhausted and anxious. Without the ability to manage our attention and emotions, we may lose ourselves in it&#8212;or simply accept AI-generated answers without questioning them critically.</p><p>This is why effective learning is not just about having the right methodology. In the age of AI, managing our attention and anxiety has become equally important. </p><p>As knowledge becomes increasingly accessible, attention is becoming one of the scarcest resources in learning.</p><p>For me, emotional management begins with awareness. Our emotions influence how we behave and make decisions. Procrastination, for example, is not always caused by a lack of energy or discipline. Sometimes, it comes from emotional resistance to a task, such as anxiety or discomfort. Recognizing what we are feeling and what triggers that feeling is therefore an important first step.</p><div class="callout-block" data-callout="true"><p><em><strong>Understanding what a calm emotional baseline feels like can also improve emotional awareness.</strong> </em></p></div><p>Personally, I periodically practice what is often called a &#8220;dopamine detox,&#8221; such as reducing my phone usage for a period of time. At first, this can be difficult, and I may experience strong urges or discomfort. But once I get through the initial period, I become more aware of what a genuinely calm emotional state feels like and how much it helps me stay focused.</p><p>The value of a dopamine detox, in my experience, is that we can become so accustomed to constant stimulation&#8212;from social media, short-form videos, low-quality AI-generated content, streaming platforms, and other forms of digital entertainment&#8212;that a highly stimulated state starts to feel normal. Over time, this can make sustained concentration more difficult and leave us feeling mentally drained or emotionally low without clearly understanding why.</p><p>However, this doesn&#8217;t mean that we need to eliminate entertainment entirely. Once a dopamine detox helps me establish a calmer baseline, the key is to become more conscious of how much digital stimulation I consume and to recognize changes in my mood and attention.</p><p>When I notice that I&#8217;ve consumed too much low-quality content or become distracted by excessive digital stimulation, I can catch the pattern before getting pulled too deeply into it. I can then step away for a while, reduce the stimulation again, and gradually regain that sense of calm and focus.</p><h1>Conclusion</h1><p>At the beginning, I said that scarcity never disappears&#8212;it moves. I initially thought the challenge in the age of AI was simply finding a better way to learn: balancing breadth and depth, asking better questions, and building stronger mental models.</p><p>But AI has made learning easier than ever. The real scarce resource is becoming our attention and our ability to manage it. Ultimately, learning effectively with AI is not just about knowing how to learn, but also about staying focused, managing our emotions, and thinking critically in a world of unlimited information.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Chill Vic&#8217;s Architecture Notes! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Understanding Compiler Optimizations Through CPU Architecture, Part 1: Superscalar, OoO, and Store Buffer]]></title><description><![CDATA[Why Doesn't Compiler-Generated Code Look Like What You Wrote?]]></description><link>https://www.chillvic.dev/p/why-doesnt-compiler-generated-code</link><guid isPermaLink="false">https://www.chillvic.dev/p/why-doesnt-compiler-generated-code</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Sun, 13 Sep 2026 09:00:38 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!cckT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e91195f-3878-4078-9be6-f0c6c079242c_1024x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The code you write might look like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">a = b + c + d + e</code></pre></div><p>But after compiler optimization, the logic may look more like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">a1 = b + c

a2 = d + e

a = a1 + a2</code></pre></div><p>Originally, this could be written in one line. Why would the compiler split it into more steps? Wouldn&#8217;t more steps make performance worse?</p><p>The goal of this kind of optimization is to improve how efficiently the CPU executes instructions. </p><p><strong>To understand why this helps, we first need to understand how a CPU executes instructions.</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cckT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e91195f-3878-4078-9be6-f0c6c079242c_1024x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cckT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e91195f-3878-4078-9be6-f0c6c079242c_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!cckT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e91195f-3878-4078-9be6-f0c6c079242c_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!cckT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e91195f-3878-4078-9be6-f0c6c079242c_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!cckT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e91195f-3878-4078-9be6-f0c6c079242c_1024x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cckT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e91195f-3878-4078-9be6-f0c6c079242c_1024x1536.png" width="1024" height="1536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8e91195f-3878-4078-9be6-f0c6c079242c_1024x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1536,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1679345,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/215472269?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e91195f-3878-4078-9be6-f0c6c079242c_1024x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cckT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e91195f-3878-4078-9be6-f0c6c079242c_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!cckT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e91195f-3878-4078-9be6-f0c6c079242c_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!cckT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e91195f-3878-4078-9be6-f0c6c079242c_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!cckT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e91195f-3878-4078-9be6-f0c6c079242c_1024x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>How Does a CPU Execute Instructions?</h1><p>The simplest CPU model is made of a control unit, an ALU, registers, and memory.</p><p><strong>The control unit</strong> reads and decodes instructions, and coordinates other hardware units. In modern CPUs, complex instructions may also be decoded into smaller micro-operations, usually called micro-ops or uops.</p><p><strong>The ALU</strong> handles integer arithmetic and logic operations, such as addition, subtraction, multiplication, division, and bit operations.</p><p><strong>Registers</strong> are the fastest storage locations inside the CPU. They hold operands and computation results.</p><p><strong>Memory</strong> can be understood as data outside the CPU core or inside the cache hierarchy, such as L1 cache, L2 cache, and RAM.</p><p>From this, we can see that the control unit and the ALU are different hardware units. They are like two different workstations in a factory. Each can process its own part of the work.</p><p>Assume we have two instructions: A and B.</p><p>If the control unit and ALU were treated as one shared workstation, the flow might look like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">cycle 1: decode A

cycle 2: execute A

cycle 3: decode B

cycle 4: execute B</code></pre></div><p>It takes 4 cycles to finish. But if decode and execute are handled by separate workstations, the flow can become:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">cycle 1: decode A

cycle 2: execute A, while decoding B

cycle 3: execute B</code></pre></div><p>Now it finishes in 3 cycles. This is the core idea of a pipeline: </p><blockquote><p><strong>It does not make a single instruction complete faster, but it overlaps different stages of multiple instructions to improve overall throughput.</strong></p></blockquote><p>If we expand the model a little, a classic pipeline can be simplified into five stages:</p><p><strong>Instruction Fetch &#8594; Decode &#8594; Execute &#8594; Memory &#8594; Write Back</strong></p><p><strong>Instruction Fetch</strong>: fetch instruction, using the program counter to read the instruction from instruction cache</p><p><strong>Decode</strong>: decode the instruction and identify the opcode, source registers, and destination register</p><p><strong>Execute</strong>: use the ALU or another execution unit to perform the operation</p><p><strong>Memory</strong>: load or store data</p><p><strong>Write Back</strong>: write the result back to a register</p><p>Each stage is handled by different hardware logic and has its own workstation. At this point, another question naturally appears:</p><div class="callout-block" data-callout="true"><p><strong>If the CPU already has multiple hardware units, can we add more ALUs so more instructions can execute at the same time?</strong></p></div><h1>Can a CPU Add More Hardware Units to Improve Instruction Throughput?</h1><p>Yes. This is the idea behind <em><strong>superscalar execution</strong></em> inside a single core.</p><p>But first, we need to separate two things: adding more ALUs inside one core is not the same as having a multi-core CPU.</p><p>Multi-core is thread-level parallelism. Different threads or processes can be scheduled onto different cores.</p><p>Multiple ALUs inside one core are for instruction-level parallelism. The CPU tries to execute multiple instructions from the same thread at the same time using different execution units, such as ALUs. </p><blockquote><p><strong>The precondition for instruction-level parallelism is that the instructions being executed in parallel must not depend on each other.</strong></p></blockquote><p>For example:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">x = a + b

y = c + d</code></pre></div><p>These two additions do not depend on each other. In theory, two ALUs can process them at the same time.</p><p>But consider this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">x = a + b

y = x + d</code></pre></div><p>The second instruction needs the value of x produced by the first instruction. They cannot execute at the same time. This is a dependency.</p><p>Therefore, adding more ALUs only provides more execution resources. To make those resources useful, the CPU still needs to solve instruction dependency problems.</p><h1>How Does a CPU Handle Instruction Dependencies?</h1><p>Instruction dependencies can first be divided into <em><strong>false dependencies and true dependencies.</strong></em></p><p>A false dependency means two instructions appear to use the same value, usually the same register, but they are not actually using the same logical value.</p><p>The first case is <strong>WAW</strong>, write after write.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">first write: r1 = a + b

second write: r1 = c + d</code></pre></div><p>Both instructions write to r1. They appear to write to the same variable. If they execute in parallel, the CPU may worry that the final value of r1 will not come from the second write.</p><p>But from the data perspective, these two writes can be treated as two different versions of r1. <strong>This is the problem register renaming solves.</strong></p><p>Registers can be divided into architectural registers and physical registers.</p><p>An architectural register is a logical register number defined by the ISA, or Instruction Set Architecture. The machine instructions generated by the compiler refer to these registers.</p><p>But the CPU internally stores actual data in physical registers, such as p10, p11, and p12. <strong>Register renaming dynamically maps architectural registers to physical registers.</strong></p><p>So the WAW example above can become:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">r1 = a + b maps to physical register p10

r1 = c + d maps to physical register p11</code></pre></div><p>Now the two writes go to different physical registers and do not overwrite each other. If a later instruction reads r1, it maps to p11 and reads the latest value.</p><p>The second kind of false dependency is WAR, write after read.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">first read: r2 = r1 + a

second write: r1 = b + c</code></pre></div><p>The first instruction needs to read the old r1. The second instruction writes a new r1. Without register renaming, the CPU has to worry that the second instruction writes r1 too early and destroys the old value needed by the first instruction.</p><p>Register renaming keeps the old physical register for the first read, while assigning a new physical register for the second write:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">first read: r2 = old r1 in p11 + a

second write: new r1 goes to p12</code></pre></div><p>This way, the second instruction does not destroy the old value required by the first instruction.</p><p>The other kind of dependency cannot be removed. This is a true dependency. <strong>Register renaming is still used to identify it clearly.</strong></p><p>For example, RAW, read after write.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">first write: r1 = a + b

second read: r2 = r1 + c</code></pre></div><p>The second instruction truly needs the new r1 produced by the first instruction. Register renaming cannot remove this dependency. It can only record it clearly:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">first write: p10 = a + b

second read: r2 = p10 + c</code></pre></div><p>In other words, the second instruction must wait until the value in p10 is ready.</p><p>After dependencies are marked, the CPU also needs a scheduler to send decoded uops to different execution units, such as ALUs, memory load units, and memory store units. Therefore, a modern CPU pipeline is more detailed than the classic five-stage model. Conceptually, it looks like this:</p><p><strong>instruction fetch &#8594; decode &#8594; rename &#8594; schedule &#8594; execute &#8594; memory &#8594; write back</strong></p><p>Rename maps architectural registers to physical registers and builds dependency information. The schedule stage uses those dependencies to decide which uops can be issued to execution units.</p><div class="callout-block" data-callout="true"><p>But just because the CPU can do dependency tracking does not mean the compiler can ignore everything. The compiler should still try to generate an instruction stream that is easier to execute in parallel.</p></div><h1>How Does the Compiler Optimize Code to Maximize Instruction Parallelism?</h1><p>One core compiler optimization is to expose instruction-level parallelism. In other words, the compiler tries to make more independent work visible to the CPU.</p><p>The most typical example is loop unrolling.</p><p>Original program:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">for (int i = 0; i &lt; n; i++) {
  sum += a[i];
}</code></pre></div><p>Conceptually, this might become:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">i = 0
loop_start:
load tmp, a[i]
add sum, sum, tmp
add i, i, 1
cmp i, n
branch_if_less loop_start</code></pre></div><p>There are two problems here.</p><p>First, each loop iteration only performs one sum += a[i], and each iteration depends on the previous value of sum. This creates a long dependency chain.</p><p>Second, each iteration processes only one element but still needs one branch. The branch itself has a cost.</p><p>The compiler can unroll the loop:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">for (int i = 0; i &lt; n; i += 4) {
  sum1 += a[i];
  sum2 += a[i + 1];
  sum3 += a[i + 2];
  sum4 += a[i + 3];
}

sum = sum1 + sum2 + sum3 + sum4</code></pre></div><p>Now sum1, sum2, sum3, and sum4 are four relatively independent accumulation chains. The CPU can see more independent adds and loads, and the number of branches is reduced.</p><p>Another example is the expression reassociation from the beginning of the article.</p><p>Original:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">a = b + c + d + e</code></pre></div><p>If evaluated from left to right, it looks like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">t1 = b + c
t2 = t1 + d
a = t2 + e</code></pre></div><p>This is a three-level dependency chain.</p><p>But if it is rewritten as:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">a1 = b + c
a2 = d + e
a = a1 + a2</code></pre></div><p>a1 and a2 can be computed first in parallel. The dependency depth is reduced from three levels to two.</p><p>This is why optimized logic may look like it has more steps. The compiler is not only counting the number of instructions. It is looking at how CPU architecture can execute the instruction stream in parallel.</p><p>But this optimization has limits. For integers, addition can usually be reassociated like this. For floating-point addition, however, rounding error means the association order cannot always be changed freely.</p><div class="callout-block" data-callout="true"><p>Once more instruction-level parallelism is exposed, the CPU has a better chance of keeping multiple execution units busy. But there is another major issue that affects throughput: memory load and store.</p></div><h1>Why Do Memory Load and Store Affect CPU Instruction Throughput?</h1><p>Registers are fast, but memory is much slower. Even when the data is in L1 cache, latency is still higher than a typical ALU operation. If there is a cache miss and the CPU has to go to RAM, the wait is even longer.</p><p>Assume the instruction stream is:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">instruction 1: load x
instruction 2: a = 1 + x
instruction 3: d = e + f</code></pre></div><p>Instruction 2 needs x, so it depends on the load result from instruction 1. If load x has not completed, instruction 2 cannot issue. If the CPU uses in-order issue, then even though instruction 3 does not depend on the previous instructions, it still has to wait for instruction 2 to issue first. It cannot immediately issue to an idle ALU. The result is that instruction 3 also waits behind the memory load, and the pipeline stalls.</p><p>A better order is:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">instruction 1: load x
instruction 2: d = e + f
instruction 3: a = 1 + x</code></pre></div><p>The slow load is issued first. At the same time, instruction 2 can also be issued. After the ALU finishes d = e + f, the load may have returned, and the scheduler can issue instruction 3. The pipeline does not sit idle.</p><p>Compiler optimization can change instruction order, but this is static instruction scheduling. The compiler cannot always know runtime state, such as cache hits and misses, actual memory latency, or whether a dependency will really block execution.</p><p>Therefore, modern high-performance CPUs perform more aggressive scheduling at runtime. This is out-of-order issue.</p><h1>How Does the CPU Schedule Stage Implement Out-of-Order Issue?</h1><p>Out-of-order (OoO) issue does not mean the whole CPU is out of order from beginning to end.</p><p>More precisely, the CPU front end usually still fetches, decodes, and renames in program order, then places uops into a scheduling window. The scheduler then starts issuing instructions out of order to different execution units.</p><p>The scheduler checks each uop:</p><p>- Whether source operands are ready, for example already available in a register</p><p>- Whether the required execution unit is available</p><p>If the operands are ready and the execution unit is available, the uop can be issued. It does not necessarily have to wait for earlier uops to issue first.</p><p>For example:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">instruction 1: load x
instruction 2: a = 1 + x
instruction 3: d = e + f</code></pre></div><p>When load x has not returned yet, instruction 2 cannot execute. But instruction 3 does not depend on x, so the scheduler can issue instruction 3 first.</p><div class="callout-block" data-callout="true"><p>This is the core of OoO issue: from the uops already inside the scheduling window, pick the ready ones and send them to execution units first.</p><p>But this creates a new correctness problem: instructions can execute out of order, but the results observed by the program must not become out of order. Therefore, the CPU needs in-order commit.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.chillvic.dev/subscribe?"><span>Subscribe now</span></a></p><h1>Why Does Out-of-Order (OoO) Issue Need ROB In-Order Commit?</h1><p>Consider this example:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">int x = 0;

int *p = NULL;

int a = *p;

x = 10;</code></pre></div><p>From the program&#8217;s semantics, int a = *p should execute first. Since p is NULL, this line raises an exception. The later x = 10 should not actually happen.</p><p>But in an OoO CPU, store 10 to x does not appear to depend on int a = *p, so it may execute earlier than the load.</p><p>If the store really becomes externally visible first, the exception would happen with an incorrect state: x has become 10. This is similar to a dirty read in a database transaction.</p><p>To solve this problem, the CPU needs a Reorder Buffer (ROB).</p><p>The ROB can be understood as a circular queue ordered by program order. Before instructions enter the OoO backend, they are assigned ROB entries in their original order. After that, they may execute out of order, but when they complete, they update their own ROB entry status.</p><p>Then, on each CPU cycle, the CPU checks from the ROB head:</p><p>- If the head instruction has completed and has no exception, commit it</p><p>- If the next instruction has also completed, keep committing</p><p>- If it reaches an instruction that has not completed or has an exception, stop</p><p>So the purpose of the ROB is not to prevent out-of-order execution. It is to make sure results become official in program order.</p><div class="callout-block" data-callout="true"><p>This is the basis of precise exceptions: when an exception happens, all earlier instructions appear to have completed, and all later instructions appear not to have happened.</p><p><strong>But store has a special problem.</strong></p></div><h1>Can ROB In-Order Commit Prevent Store from Becoming Visible to Other Threads Too Early?</h1><p>Store is different from a normal register write. A normal ALU instruction first writes its result to a physical register. That result is internal state inside the CPU core. But store writes to memory. If a store writes to memory immediately after execution, another thread may see the value before the store commits. <em><strong>A store that has not committed yet is a speculative store.</strong></em></p><p>Return to the previous example:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">int x = 0;

int *p = NULL;

int a = *p;

x = 10;</code></pre></div><p>If x = 10 is issued out of order and really writes to memory first, then even if the CPU later discovers that int a = *p should raise an exception, x may already have been seen by another thread. This breaks precise exception semantics.</p><p>Therefore, a speculative store cannot write directly to memory at execute time. A speculative store is usually split into several pieces:</p><ol><li><p>Compute the store address</p></li><li><p>Prepare the store data</p></li><li><p>Put the address and data into a store buffer or store queue</p></li><li><p>After the store passes ROB commit, allow it to drain into the cache coherence system</p></li></ol><p>This lets the store complete its computation early without blocking the pipeline. But before it is allowed to officially take effect, it does not pollute memory.</p><p>Therefore, the division of responsibility between the ROB and the store buffer is:</p><p><strong>The ROB decides when this store commits.</strong></p><p><strong>The store buffer holds stores that are already prepared but not yet externally visible.</strong></p><p>However, after a store drains into the cache coherence system, cross-core visibility involves mechanisms such as cache line ownership, invalidation, and data propagation. These are usually handled asynchronously. </p><p>The order observed by other threads does not necessarily match the original program order exactly. Which ordering guarantees actually hold depends on the hardware memory model. For example, x86 and ARM provide different ordering guarantees.</p><h1>What Problem Happens If Other Threads Cannot Observe the Correct Data Order?</h1><p>The store buffer is a private write queue for each core. It solves two problems.</p><p>First, a store does not need to wait for cache coherence to complete before the CPU continues running. The store can enter the buffer first and drain into the cache hierarchy later.</p><p>Second, during OoO issue, a store does not pollute memory too early. Only after ROB commit is the store allowed to become externally visible.</p><p>If a later load on the same core wants to read the value that was just stored, it can use store-to-load forwarding to read the new value from its own store buffer.</p><p>For example:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">x = 1
r = x</code></pre></div><p>Even if x = 1 is still in the store buffer, r = x can still read 1.</p><p>But other cores cannot see your store buffer. They can only observe the write after the store has committed through the ROB and drained into cache coherence so the data becomes synchronized.</p><p>When the hardware memory model allows the drain order and cache coherence synchronization order to differ, a multithreaded program can run into this situation:</p><p>Thread A:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">a = 10
b = 10</code></pre></div><p>Thread B:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">if (b == 10) {
  print(a)
}</code></pre></div><p>From Thread A&#8217;s own perspective, the order is fine. But Thread B may see b = 10 first, while print(a) still prints the old value, such as 0.</p><p>Therefore, we need atomic operations to define which orders cannot be broken.</p><h1>How Does Atomic Solve Multithreaded Data Synchronization?</h1><p>For example:</p><p>Thread A:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">a = 10
atomic.Store release b = 10</code></pre></div><p>Thread B:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">if (atomic.Load acquire b == 10) {
  print(a)
}</code></pre></div><p>A release store is like placing a memory fence at a certain line of code. Stores before this fence must become externally visible before the store on this line. A simple way to understand it is that it restricts the order of writes to memory: store 10 to a must be written first, and only then can store 10 to b be written.</p><blockquote><p>More precisely, atomic operations restrict the synchronization behavior of different hardware memory models. Synchronization does not always happen through RAM. Through the cache coherence system, a core may also read data from another core&#8217;s L1 cache. The purpose of atomic is to tell the underlying hardware system the required visibility order, or ordering boundary.</p></blockquote><p>At this point, you may wonder: if atomic store already restricts write ordering, why does Thread B still need atomic.Load?</p><p>That part is no longer about the store buffer. It is related to cache coherence and the invalidation queue. For a full explanation, see my other article on cache coherence and atomic:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;7dae1fd3-4338-4e9e-939e-ef111d777ea2&quot;,&quot;caption&quot;:&quot;Atomic operations are the bedrock of concurrent programming. For instance, a Mutex is often implemented using an atomic Compare-And-Swap (CAS) at its lowest level. While many initially view Atomics as \&quot;CPU-level locks,\&quot; they are actually mechanisms designed to solve memory synchronization issues across multiple CPU cores in a concurrent read/write envir&#8230;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;lg&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;The Core of Concurrent Programming: Atomic Operations are Not Locks&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:427382735,&quot;name&quot;:&quot;Chill Vic&quot;,&quot;bio&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/62c86bcf-ac82-4ce6-97c9-55e972dbfe93_1079x1221.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2026-02-13T22:13:52.436Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!b_rP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.chillvic.dev/p/the-core-of-concurrent-programming&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:187900483,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:3,&quot;comment_count&quot;:0,&quot;publication_id&quot;:7332667,&quot;publication_name&quot;:&quot;Chill Vic&#8217;s Architecture Notes&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!4-yR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddabf71b-360a-4310-8311-8b9a30fb05e3_722x722.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><h1>Summary</h1><p>Starting from the CPU pipeline and moving through superscalar execution, register renaming, OoO issue, ROB, and the store buffer, we can see that compiler optimization is not simply about making code shorter.</p><p>What the compiler really wants is to generate an instruction stream that fits the CPU better: independent instructions should be easier to see, the pipeline should stall less often, and the OoO scheduler should have more ready work to choose from.</p><p>But every layer of freedom introduced by the CPU for performance also creates new correctness problems. OoO needs the ROB to keep commit ordered. The store buffer needs memory ordering to constrain cross-core visibility. In the next article, we can look at another problem that makes the pipeline harder to keep full: branch prediction.</p>]]></content:encoded></item><item><title><![CDATA[Another OOM? Which Go Memory Metric Should You Watch?]]></title><description><![CDATA[Understanding Go Memory Metrics and the Memory Allocator]]></description><link>https://www.chillvic.dev/p/another-oom-which-go-memory-metric</link><guid isPermaLink="false">https://www.chillvic.dev/p/another-oom-which-go-memory-metric</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Wed, 09 Sep 2026 05:00:43 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!8pJ_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8b960b8-a200-41d7-9dbd-65c5f0a829ad_1024x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>An OOM (Out of Memory) kill is a painful incident. Once it happens, the server is killed and restarted, and the only thing left at the scene is a pile of memory metrics.</p><p>But once you start looking at those metrics, the problem often becomes confusing.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Chill Vic&#8217;s Architecture Notes! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>For example:</p><p>- Grafana shows high RSS, but the pprof heap `inuse_space` is much lower.</p><p>- The container is already close to its memory limit, but Go heap metrics still look fine.</p><p>So which memory metric actually decides whether a process gets OOM killed? And if these metrics do not match, how should we interpret them?</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8pJ_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8b960b8-a200-41d7-9dbd-65c5f0a829ad_1024x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8pJ_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8b960b8-a200-41d7-9dbd-65c5f0a829ad_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!8pJ_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8b960b8-a200-41d7-9dbd-65c5f0a829ad_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!8pJ_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8b960b8-a200-41d7-9dbd-65c5f0a829ad_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!8pJ_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8b960b8-a200-41d7-9dbd-65c5f0a829ad_1024x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8pJ_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8b960b8-a200-41d7-9dbd-65c5f0a829ad_1024x1536.png" width="1024" height="1536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b8b960b8-a200-41d7-9dbd-65c5f0a829ad_1024x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1536,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2006356,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/214834149?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8b960b8-a200-41d7-9dbd-65c5f0a829ad_1024x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8pJ_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8b960b8-a200-41d7-9dbd-65c5f0a829ad_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!8pJ_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8b960b8-a200-41d7-9dbd-65c5f0a829ad_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!8pJ_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8b960b8-a200-41d7-9dbd-65c5f0a829ad_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!8pJ_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8b960b8-a200-41d7-9dbd-65c5f0a829ad_1024x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h1>When does an OOM kill happen?</h1><p>When a server runs inside a container, cgroups are used to limit the resources available to that container. For memory, cgroup v2 uses settings such as `memory.max`. If the cgroup&#8217;s memory usage reaches `memory.max` and the kernel cannot reclaim enough memory, the cgroup OOM killer may be invoked.</p><p>The key metric here is not Resident Set Size (RSS), which measures resident physical memory for a process. The key metric is cgroup memory usage. So what is the difference?</p><p>A cgroup is essentially a resource accounting and limiting mechanism for a group of processes.</p><p>For example, memory.current is the cgroup v2 memory usage metric. It means the kernel has charged this amount of physical memory tothis cgroup, which usually corresponds to a specific container in a container runtime. This includes RSS, but it may also include memory used inside the kernel on behalf of that cgroup, such as:</p><p>- file cache created when a process opens or reads files</p><p>- socket buffers and related kernel memory created for TCP connections</p><p>Therefore cgroup memory usage may be higher than RSS. Some of this memory is reclaimable, especially clean file cache. Reclaiming clean file cache is usually safe because the data can be read from disk again after a cache miss. But not all kernel memory is equally reclaimable, so a high cgroup usage number still needs to be investigated.</p><p>In cgroup v2, `memory.high` can also be configured. When cgroup memory usage goes above this threshold, the kernel puts the cgroup under reclaim pressure and may throttle it. Unlike `memory.max`, crossing `memory.high` does not directly invoke the OOM killer.</p><p>In Kubernetes or container environments, cgroup memory metrics are commonly exposed through cAdvisor Prometheus metrics:</p><p>- `container_memory_usage_bytes`:</p><p>  Current cgroup memory usage. In cgroup v2, this roughly corresponds to `memory.current`.</p><p>- `container_spec_memory_limit_bytes`:</p><p>  The container memory hard limit. In cgroup v2, this roughly corresponds to `memory.max`.</p><p>- `container_memory_rss`:</p><p>  RSS for the container&#8217;s processes.</p><p>- `container_memory_cache`:</p><p>  File cache charged to the cgroup.</p><p>- `container_memory_working_set_bytes`:</p><p>  Usually calculated as usage minus `inactive_file`. It is often used as an estimate of memory that is less easily reclaimable. Kubernetes eviction logic also commonly relies on working-set-style memory metrics.</p><p>- `container_oom_events_total`:</p><p>  The number of OOM events observed for the container.</p><p>Once we understand cgroups, we know that memory monitoring needs to look at both user-space process memory, such as RSS, and kernel-accounted memory, such as file cache and socket memory.</p><p>But inside the user-space process, the runtime has its own memory metrics. If we want to locate which function allocated memory, we need runtime profiling. This creates another common question: why does runtime profiling often disagree with RSS?</p><h1>Why can RSS be larger than pprof heap inuse space?</h1><p>In Go, it is tempting to think that the pprof heap profile represents &#8220;the memory used by the program.&#8221; But that is not quite right.</p><p>The pprof heap `inuse_space` view is about live sampled Go heap allocations. In other words, it estimates heap objects that are still live and have not been reclaimed by GC.</p><p>RSS answers a different question:</p><p>How much physical memory is currently resident for this process&#8217;s virtual address space?</p><p>The process may use memory outside live Go heap objects. This includes goroutine stacks, runtime metadata, memory allocated by C code through cgo, memory mapped through system calls, and other non-heap regions.</p><p>Suppose there is no deep recursion, no unusually large stacks, and no cgo. Should RSS then be close to heap `inuse_space`?</p><p>Not necessarily.</p><p>The reason is that when GC reclaims heap objects, Go does not necessarily return that memory to the kernel immediately. It first returns the memory to the Go runtime&#8217;s memory allocator.</p><p>At that point, pprof heap `inuse_space` may go down, but RSS may not. The missing layer is the memory allocator.</p><h1>What problem does a memory allocator solve?</h1><p>Start with a naive design. Suppose every Go object allocation directly asked the kernel for memory:</p><p>new object -&gt; syscall -&gt; OS allocates pages -&gt; return to user space</p><p>This design has two problems.</p><p>First, system calls are expensive. If every small object allocation requires a syscall, allocation-heavy Go programs would spend too much time crossing between user space and kernel space.</p><p>Second, the operating system manages memory at a coarse granularity. A common page size is 4 KB, but a Go object may be only 16 bytes. If every small object occupied its own OS page, memory waste would be enormous.</p><p>To solve these problems, the Go runtime&#8217;s memory allocator first obtains larger chunks of memory from the OS. At that point, RSS may increase. Later, when the program allocates an object, the allocator serves that request from memory it already manages, usually using a size class that is close to the requested object size.</p><p>In simple terms, the memory allocator sits between the kernel and application objects.</p><p>It manages coarse-grained pages, divides them into smaller allocation units for different object sizes, and avoids making a syscall for every `new` object.</p><h1>What do Go heap metrics mean?</h1><p>Once we understand the allocator, Go runtime memory metrics become easier to read:</p><p>- `go_memstats_heap_alloc_bytes`:</p><p>  Bytes of currently live Go heap objects.</p><p>- `go_memstats_heap_inuse_bytes`:</p><p>  Bytes in active heap spans. A span contains multiple slots for objects.</p><p>- `go_memstats_heap_idle_bytes`:</p><p>  Heap memory the runtime has obtained but that is currently in idle spans.</p><p>- `go_memstats_heap_sys_bytes`:</p><p>  Heap memory obtained from the OS. This includes heap address space that may not currently correspond to resident physical memory.</p><p>- `go_memstats_heap_released_bytes`:</p><p>  Idle heap memory that has been released back to the OS and has not yet been reacquired by the runtime.</p><p>- `go_memstats_alloc_bytes_total`:</p><p>  Cumulative heap allocation bytes since process start.</p><p>The difference between `go_memstats_heap_inuse_bytes` and `go_memstats_heap_alloc_bytes` is important.</p><p>`heap_alloc` counts the logical size of live heap objects. `heap_inuse` counts active heap spans. A span contains slots, and those slots are tied to size classes.</p><p>For example, suppose an object is 14 bytes, but the allocator&#8217;s nearest slot size is 16 bytes. `heap_alloc` accounts for the object size, but the allocator needs a 16-byte slot to store it.</p><p>More importantly, `heap_inuse` is the total size of in-use spans. If a span has at least one live object, the span is considered in use. If a span has no live objects, it becomes idle and is counted in `heap_idle`.</p><p>heap_sys = heap_inuse + heap_idle. In theory, this can be closer to RSS than heap_alloc or heap_inuse, but it is still not the same as RSS. In practice, there are gaps: heap_idle may include heap memory that has already been released back to the OS, while heap_sys does not include non-heap memory such as stacks or cgo allocations.</p><h1>With so many metrics, what should we watch during an OOM?</h1><p>When an OOM happens, the first instinct is often to use pprof to find the guilty function.</p><p>pprof is useful because it can attribute memory to call stacks. For Go heap profiles, pprof commonly exposes views such as inuse_space and aloc_space.</p><p>Profiling is based on periodic sampling, so:</p><p>- `inuse_space`:</p><p>  Live sampled heap allocations. The heap profile reports data as of the most recently completed GC, so it is not always a perfectly current snapshot.</p><p>- `alloc_space`:</p><p>  Cumulative sampled heap allocation bytes since process start, including allocations that have already been garbage collected.</p><p>If `inuse_space` is not large, the profile may have missed the critical moment, or the issue may not be live Go heap. The next step is to check whether runtime `heap_alloc` is large.</p><p>If `heap_alloc` is large but pprof does not show a clear culprit, the heap profile may be too stale, too sampled, or collected at the wrong moment. In that case, look at memory trends over time and compare profiles taken before and during the growth.</p><p>If `heap_alloc` is also not large, then inspect the gap between runtime metrics:</p><p>- `heap_inuse - heap_alloc`:</p><p>  This estimates memory dedicated to size classes but not currently holding live objects. It is an upper bound on fragmentation. If this number is large, it may indicate allocator slack or fragmentation inside active spans.</p><p>- `heap_idle - heap_released`:</p><p>  This is idle heap memory that could be returned to the OS but is still retained by the runtime. If this value is large, it may indicate a recent transient heap spike or a runtime return policy tradeoff.</p><p>Finally, compare cgroup memory usage and RSS.</p><p>If RSS is not large but cgroup memory usage is high, the pressure may come from cgroup-accounted kernel memory, such as file cache, socket buffers, or other kernel structures.</p><p>A useful mental model is to split memory metrics into three layers:</p><p>- application layer:</p><p>  Use pprof to identify which call stacks are responsible for live or cumulative Go heap allocations.</p><p>- process and runtime layer:</p><p>  Use RSS and Go runtime metrics to understand the whole process footprint and allocator state.</p><p>- kernel and cgroup layer:</p><p>  Use cgroup metrics to understand what the kernel has charged to the container, including RSS and kernel-accounted memory.</p><p>Once we understand these layers, it becomes clear why the memory allocator matters. A poor allocator design, or a workload pattern that interacts badly with the allocator, can keep RSS high even when live heap is low.</p><p>So what makes a good memory allocator?</p><h1>What challenges does a memory allocator need to solve?</h1><p>A good memory allocator mainly balances three goals:</p><p>- allocation latency:</p><p>  Allocating a new object must be fast and must not burn too much CPU.</p><p>- fragmentation:</p><p>  The allocator should avoid wasting memory in a way that makes free space hard to reuse or return to the OS.</p><p>- return policy:</p><p>  After GC frees objects, the allocator must decide when and how to return memory to the kernel. It needs to balance performance against OOM risk.</p><p>We can use the Go runtime allocator as an example.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.chillvic.dev/subscribe?"><span>Subscribe now</span></a></p><h1>How does the Go memory allocator reduce allocation latency?</h1><p>After the allocator obtains memory from the kernel, it needs data structures to manage that memory. At the same time, Go allocations happen concurrently across goroutines executing on different Ps and OS threads. If every allocation had to contend on one global allocator lock, allocation latency would suffer.</p><p>To avoid this, Go uses a hierarchy of allocator structures. There is per-P allocation cache for fast local allocation, and more global allocator structures are used only when the local cache has no suitable span or when an allocation is large.</p><p>The data structure design matters too. Go divides small object allocation into size classes such as 8 bytes, 16 bytes, 24 bytes, 32 bytes, and so on. Each size class manages slots of a fixed size. For example, allocating a 10-byte object will use a 16-byte slot.</p><p>This narrows the search space and makes allocation faster.</p><p>But how does the allocator find an available slot inside a span?</p><p>At a simplified level, object slots are like array entries, and each slot has an index. A bitmap records which slots are available. For example, in a simplified free bitmap, `11111110` can mean that all slots except index 0 are free.</p><p>Finding a free slot then becomes a bit operation. The allocator can find the lowest set bit:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">idx = 0;

while (free_bitmap &gt; 0) {

    if (free_bitmap &amp; 1 == 1) return idx;

    free_bitmap &gt;&gt;= 1;

    idx++;

}</code></pre></div><p>Real Go internals use `allocBits` and `allocCache`. In Go&#8217;s implementation, `allocCache` stores the complement of `allocBits`, shifted so that the lowest bit corresponds to `freeindex`. This makes it possible to use a count-trailing-zero operation to quickly find the next free slot.</p><p>For explanation, imagine two 8-bit chunks:</p><p>`11111110 11000000`</p><p>Suppose:</p><p>`freeindex = 5`</p><p>`allocCache = 1110110`</p><p>Then allocation works conceptually like this:</p><p>1. Find the lowest available bit in `allocCache`. Suppose the offset is 2.</p><p>2. Add that offset to the base `freeindex`, so the real slot index is `5 + 2 = 7`.</p><p>3. Update `freeindex` and refresh `allocCache` from the next position.</p><p>The real implementation is more subtle, but the core idea is simple: represent slot state compactly and use CPU-friendly bit operations to find the next free object quickly.</p><h1>What fragmentation problems can the Go allocator run into?</h1><p>Fragmentation can be divided into two types: internal fragmentation and external fragmentation.</p><p>Internal fragmentation happens when the object is smaller than the slot allocated for it. For example, if a 17-byte object is placed into a 24-byte slot, the remaining 7 bytes are wasted.</p><p>Size classes make allocation faster and keep different object sizes organized, but the cost is that objects are rounded up to the nearest slot size. This creates controlled internal fragmentation.</p><p>Struct field layout can also make internal fragmentation worse.</p><p>For example:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">type Test struct {
    A int8
    B int32
}</code></pre></div><p>It looks like this struct should be 5 bytes: 1 byte for `A` and 4 bytes for `B`. But on typical architectures, it will be 8 bytes because of struct padding.</p><p>The reason is alignment.</p><p>When the CPU loads data from memory, hardware usually prefers certain alignment boundaries. For example, a 4-byte load is most natural when it starts at an address that is a multiple of 4.</p><p>If an address is 0, 4, 8, or 12, then a 4-byte value is aligned. Aligned access is usually simpler and faster for the CPU.</p><p>In the `Test` struct, padding is inserted after `A` so that `B` starts at an aligned address. Without padding, `B` might cross two machine-word-sized chunks, forcing extra work to assemble the value.</p><p>A better field order can make padding more compact:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">type Bad struct {
    a int8
    b int64
    c int8
}

// 24 bytes on a typical 64-bit platform

type Better struct {
    b int64
    a int8
    c int8
}

// 16 bytes on a typical 64-bit platform</code></pre></div><p>More compact padding can keep an object from growing into the next size class, which reduces internal fragmentation.</p><p>External fragmentation is different. It means free space exists, but it is scattered in a way that makes it difficult to reuse or return to the kernel.</p><p>There are two related cases:</p><p>- Free space across pages may add up to a large amount, but the allocator cannot use it for the allocation it needs.</p><p>- The kernel reclaims memory at page granularity. If a page still contains a few live slots, the whole page cannot be returned.</p><p>Size class segregation helps because objects of very different sizes are not mixed randomly in the same memory region. That avoids arbitrary holes that are hard to reuse.</p><p>But object lifetimes are still unpredictable. Slots are not freed in a neat order. A page may have only a few live objects left, but those live objects keep the entire page from being returned to the kernel.</p><p>One way to solve this is compacting GC. During GC, the runtime can move live objects together so scattered live objects become contiguous. This can make it easier to release whole pages.</p><p>But compacting GC is complex. Moving objects increases GC work, affects pointer handling, and can add CPU overhead. Go currently uses a non-moving GC, so it needs other mechanisms for deciding when and how to return memory to the kernel.</p><h1>How does the Go allocator return memory to the kernel?</h1><p>The Go runtime has a background scavenger. It releases idle heap pages back to the kernel in the background.</p><p>This background process balances two goals:</p><p>- RSS footprint:</p><p>  Keep resident memory lower to reduce OOM risk.</p><p>- allocation latency:</p><p>  Avoid releasing memory so aggressively that the runtime must repeatedly reacquire pages from the OS.</p><p>Therefore, the scavenger is not just a simple time-based trigger or a single-threshold mechanism. It uses runtime policy to balance memory footprint and allocation performance.</p><p>How memory is released also matters. A common system call used for this purpose is `madvise`.</p><p>`madvise` tells the kernel that the program no longer needs the contents of a virtual memory range. The physical memory backing that range may be reclaimed, but the virtual address range remains reserved so the runtime can reuse it later.</p><p>There are two common modes:</p><p>- `MADV_DONTNEED`:</p><p>  The kernel can discard the physical pages promptly, so RSS usually drops faster.</p><p>- `MADV_FREE`:</p><p>  The kernel may lazily reclaim the pages, often only under memory pressure. RSS may stay high for longer.</p><p>The benefit of `MADV_FREE` is that if the allocator reuses the memory before the kernel reclaims it, the reuse may avoid a page fault. That can improve allocation latency.</p><p>Go used `MADV_FREE` by default on Linux starting in Go 1.12, but many users found the resulting RSS behavior confusing and suspected memory leaks(https://go-review.googlesource.com/c/go/+/267100). Starting in Go 1.16, Linux defaults back to `MADV_DONTNEED`, so RSS more closely reflects memory that is still physically resident.</p><p>If you explicitly want the Linux runtime to use `MADV_FREE` instead of `MADV_DONTNEED`, set:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">GODEBUG=madvdontneed=0</code></pre></div><p>This improves some allocation behavior, but RSS will usually drop only when the OS is under memory pressure.</p><p></p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Chill Vic&#8217;s Architecture Notes! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[TPU Explained from the Ground Up, Part 1: Why Is TPU Computing So Cost-Efficient?]]></title><description><![CDATA[From AllReduce to 3D Torus]]></description><link>https://www.chillvic.dev/p/tpu-explained-from-the-ground-up</link><guid isPermaLink="false">https://www.chillvic.dev/p/tpu-explained-from-the-ground-up</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Thu, 09 Jul 2026 09:26:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!EKOi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When training large AI models, a single chip is usually not enough. The dataset and model parameters are too large, and the memory of a single TPU cannot hold everything. Therefore, multiple TPUs need to be organized into a cluster and compute together.</p><p>However, a cluster is not just many machines placed together.</p><p>When multiple machines are running, the first problem to solve is: after each machine finishes computing its own part, how should the results be synchronized?</p><p>If the synchronization cost is too high, it does not matter how fast the chips are. A large amount of time will be stuck in network communication.</p><p>One key reason TPU clusters can be cost-efficient is that they do not rely only on expensive networking equipment to brute-force bandwidth. Instead, they reduce synchronization cost through collective algorithms and network topology design.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EKOi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EKOi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 424w, https://substackcdn.com/image/fetch/$s_!EKOi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 848w, https://substackcdn.com/image/fetch/$s_!EKOi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 1272w, https://substackcdn.com/image/fetch/$s_!EKOi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EKOi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png" width="1456" height="2170" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2170,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EKOi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 424w, https://substackcdn.com/image/fetch/$s_!EKOi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 848w, https://substackcdn.com/image/fetch/$s_!EKOi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 1272w, https://substackcdn.com/image/fetch/$s_!EKOi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>So what exactly is being synchronized inside a TPU cluster?</h1><p>The basic idea of distributed computing is simple: split a large piece of data into many smaller partitions and assign them to different machines for computation.</p><p>For example, in AI training, the input can be split into multiple batch shards, and different TPUs process different batch shards. After each machine finishes computing its own part, the results need to be merged in some way. Otherwise, each machine only knows its own local result, and the cluster does not share a common state.</p><p>When talking about data synchronization in distributed computing, the most intuitive concept is MapReduce.</p><h1>What is MapReduce? Does AI need MapReduce?</h1><p>Let&#8217;s first build the intuition using SQL.</p><p>Assume we want to compute:</p><pre><code><code>select uid, sum(amount)
from orders
group by uid;</code></code></pre><p>When the <code>orders</code> table is very large, MapReduce first partitions the data and distributes it to different machines for local computation. At this stage, each machine may hold partial sums for different <code>uid</code>s. Then the system enters the shuffle phase.</p><p>The purpose of shuffle is to send data with the same <code>uid</code> to the same reducer. Finally, each reducer computes the result for the keys it is responsible for.</p><p>For example:</p><pre><code><code>sum | uid | machine
10  | 1   | 1
20  | 2   | 2
30  | 3   | 3</code></code></pre><p>In other words, in MapReduce, different machines, or reducers, only hold the complete results for the keys they are responsible for.</p><p><strong>AI training is different. It needs AllReduce.</strong></p><p>That means after the reduce step, the result still needs to be broadcast to everyone, so every machine has the aggregated result for all keys.</p><p>That is:</p><pre><code><code>sum       | uid     | machine
10,20,30  | 1,2,3   | 1
10,20,30  | 1,2,3   | 2
10,20,30  | 1,2,3   | 3</code></code></pre><p>Therefore, you can first understand AllReduce as:</p><pre><code><code>MapReduce + broadcast result to all machines</code></code></pre><h1>But why does AI training need AllReduce?</h1><p>An AI model can first be simplified as:</p><pre><code><code>y = w1*x1 + w2*x2 + ... + wN*xN = wT x</code></code></pre><p><code>x</code> is the input, <code>w</code> represents the model weights, and <code>y</code> is the model output. The training objective is to adjust <code>w</code> so that the model output <code>y</code> becomes closer and closer to the correct answer.</p><p>The adjustment process is roughly:</p><ol><li><p>Input <code>x</code> and compute the prediction <code>y</code>.</p></li><li><p>Use a loss function to measure the gap between the prediction and the correct answer.</p></li><li><p>Use differentiation to calculate how much each weight affects the loss. This is the gradient.</p></li><li><p>Use the gradient to update the weights, so the loss becomes smaller in the next iteration.</p></li></ol><p>Note: More precisely, the gradient represents how much the loss changes when a certain weight changes, either increasing or decreasing.</p><p>When there is a large amount of training input data, the input is split into multiple batch shards and assigned to different TPUs. Each TPU holds the same AI model, but processes a different batch shard. Therefore, each TPU computes a different local gradient vector.</p><p>For example, three TPUs may compute:</p><pre><code><code>machine | w1_gradient | w2_gradient | w3_gradient
a       | 1           | 2           | 3
b       | 3           | 2           | 1
c       | 5           | 3           | 1</code></code></pre><p>If each TPU directly uses its own local gradient to update the model, the models on the three TPUs will quickly diverge.</p><p>Therefore, before updating the model, all local gradients need to be aggregated into one global gradient vector, and every TPU needs to receive the same result.</p><p>This is similar to:</p><pre><code><code>select weight_id, avg(gradient_value)
from gradient_vectors
group by weight_id;</code></code></pre><p>Then broadcast the result to all machines.</p><p>That is:</p><pre><code><code>machine | w1_gradient_avg | w2_gradient_avg | w3_gradient_avg
a       | 3               | 2.33            | 1.67
b       | 3               | 2.33            | 1.67
c       | 3               | 2.33            | 1.67</code></code></pre><p>After that, each machine uses the same gradient vector to update its local model, ensuring that all models remain consistent.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.chillvic.dev/subscribe?"><span>Subscribe now</span></a></p><h1>But if every training step needs gradient synchronization, is simple broadcast practical?</h1><p>The most intuitive way to implement AllReduce is all-to-all broadcast:</p><p>Each machine sends its full gradient vector to every other machine, then sums or averages the vectors it receives.</p><p>Assume there are <code>n</code> machines and each gradient vector has size <code>D</code>.</p><p>Each machine needs to receive roughly <code>(n - 1) * D</code> amount of data. If the number of TPUs increases, <code>n</code> becomes larger. If the model becomes larger, the gradient vector size <code>D</code> also becomes larger.</p><p>Therefore, all-to-all communication quickly explodes network bandwidth requirements and increases cost. This is especially problematic because gradient synchronization happens in every training step, so network communication can become the main bottleneck.</p><p>To solve this problem, we need a different AllReduce algorithm: Ring AllReduce.</p><h1>What is Ring AllReduce?</h1><p>Ring AllReduce is a collective communication algorithm.</p><p>Collective communication means that multiple devices perform the same type of communication operation at the same time.</p><p>Ring AllReduce is split into two steps: ReduceScatter and AllGather.</p><p>Assume there are three machines physically connected as a ring:</p><pre><code><code>a -&gt; b -&gt; c -&gt; a</code></code></pre><p>The three machines each compute their own gradient vector:</p><pre><code><code>      w1 w2 w3
a:   [1, 2, 3]
b:   [3, 2, 1]
c:   [5, 3, 1]</code></code></pre><p>ReduceScatter first splits the gradient vector into shards. For example:</p><pre><code><code>[w1, w2, w3] =&gt; [w1], [w2], [w3]</code></code></pre><p>It also defines which machine will finally hold the reduced result for each shard.</p><p>For example:</p><pre><code><code>a is responsible for w1
b is responsible for w2
c is responsible for w3</code></code></pre><p>Then all machines decide which shard should be sent to their neighbor based on the current network topology and the final reducer of each shard. When a neighbor receives a shard, it adds its own local value to the shard, producing a partial sum, and forwards it to the next neighbor.</p><p>The logic is roughly:</p><p><code>a</code> first identifies that the node at distance <code>n - 1</code> is <code>c</code>, and <code>c</code> is responsible for the <code>w3</code> shard. Therefore, <code>a</code> sends its <code>w3</code> value to its neighbor <code>b</code>.</p><p><code>b</code> receives it, adds its own <code>w3</code> value to <code>a</code>&#8217;s <code>w3</code>, and forwards the partial sum to <code>c</code>.</p><p>Finally, <code>c</code> receives <code>a + b</code> for <code>w3</code>, adds its own <code>w3</code>, and obtains the final reduced result for <code>w3</code>, which is <code>3 + 1 + 1 = 5</code>.</p><p>Collective communication means that <code>a</code>, <code>b</code>, and <code>c</code> perform this type of shard transfer at the same time.</p><p>First communication round:</p><pre><code><code>a - w3(a) -&gt; b   w3(a+b)
b - w1(b) -&gt; c   w1(b+c)
c - w2(c) -&gt; a   w2(c+a)</code></code></pre><p>Second communication round:</p><pre><code><code>b - w3(a+b) -&gt; c   w3(a+b+c)
c - w1(b+c) -&gt; a   w1(b+c+a)
a - w2(c+a) -&gt; b   w2(c+a+b)</code></code></pre><p>After ReduceScatter finishes, each machine only holds the reduced shard it is responsible for:</p><pre><code><code>a: w1(b+c+a) = 1 + 3 + 5 = 9
b: w2(c+a+b) = 2 + 2 + 3 = 7
c: w3(b+c+a) = 3 + 1 + 1 = 5</code></code></pre><p>Then AllGather begins. Each machine sends the reduced shard it holds along the ring, so the other machines can receive it.</p><p>First communication round:</p><pre><code><code>a - w1 -&gt; b
b - w2 -&gt; c
c - w3 -&gt; a</code></code></pre><p>Second communication round:</p><pre><code><code>a - w3 -&gt; b
b - w1 -&gt; c
c - w2 -&gt; a</code></code></pre><p>Finally, every machine receives the complete result:</p><pre><code><code>a: [9, 7, 5]
b: [9, 7, 5]
c: [9, 7, 5]</code></code></pre><p>The benefit of Ring AllReduce is that each machine only sends one shard of the gradient vector in each communication round, instead of sending the full vector.</p><p>For <code>n</code> machines and a vector of size <code>D</code>, the per-machine traffic of Ring AllReduce is approximately:</p><pre><code><code>2 * (n - 1) * (D / n)</code></code></pre><p>When <code>n</code> is large, this is approximately close to:</p><pre><code><code>2*D</code></code></pre><p>Compared with all-to-all communication, where each machine receives <code>(n - 1) * D</code>, Ring AllReduce significantly reduces the amount of data each machine needs to handle.</p><p><strong>However, Ring AllReduce still has limitations.</strong></p><p>If all machines use a single global ring, each machine only has two neighbors: the previous node and the next node. Data can only be passed along this fixed ring to the next neighbor. As the number of machines increases, the number of communication rounds also increases.</p><p>In other words, Ring AllReduce reduces the amount of data transferred, but if the topology is only one long ring, the number of communication rounds still limits overall efficiency.</p><h1>So how does TPU reduce the number of communication rounds?</h1><p>Instead of using a single global ring, TPU uses 2D or 3D torus topology.</p><p>For example, a 3D torus allows each machine to have neighbors in three different dimensions: <code>x</code>, <code>y</code>, and <code>z</code>. Each machine can have six neighbors in total. Therefore, in each communication round, messages can be transmitted to multiple neighbors along different dimensions.</p><p>Let&#8217;s use a 2D torus with dimensions <code>x</code> and <code>y</code> as an example to see how having more neighbors can reduce communication rounds.</p><p>Assume there are four machines, and each machine has neighbors in both the <code>x</code> and <code>y</code> directions:</p><pre><code><code>a &#8212;&#8212; b  X-axis
|    |
c &#8212;&#8212; d  X-axis
Y-axis</code></code></pre><p>Note: The diagram looks like a 2D mesh, but it is actually a 2D torus. The difference is that a torus wraps around like a ring. For example, the top row is not simply <code>a - b</code>; it is effectively <code>a - b - a</code>.</p><p>In a single global ring, each machine usually pushes data to only one fixed neighbor in each round.</p><p>But in a 2D torus, a machine can send data along both the <code>x</code> and <code>y</code> dimensions. Assume the gradient vector length is four, and during ReduceScatter:</p><pre><code><code>a is responsible for w1
b is responsible for w2
c is responsible for w3
d is responsible for w4</code></code></pre><p>For <code>a</code> to collect the complete <code>w1</code> result, the process can be:</p><p>First communication round, parallel along the X-axis:</p><pre><code><code>b -&gt; w1(b) -&gt; a   (a+b)
d -&gt; w1(d) -&gt; c   (c+d)
</code></code></pre><p>Second communication round, parallel along the Y-axis:</p><pre><code><code>c -&gt; w1(c+d) -&gt; a   (a+b+d+c)
</code></code></pre><p>With only two communication rounds, <code>a</code> can collect the complete <code>w1</code> result. A single global ring would need three rounds.</p><p>Note: The example only demonstrates the path for <code>w1</code>. In the actual ReduceScatter process, <code>w2</code>, <code>w3</code>, and <code>w4</code> are also being transmitted at the same time along other links.</p><p>A 3D torus provides even more dimensions and neighbors. The collective algorithm can use more parallel paths to transmit data. In a large-scale cluster, this can effectively reduce the number of communication rounds.</p><p>Therefore, the key reason TPU clusters can be cost-efficient is not that they rely on expensive network devices to brute-force bandwidth, but that they reduce synchronization cost through:</p><p>Ring AllReduce, which reduces the amount of data each machine needs to transmit.</p><p>2D / 3D torus topology, which provides more multidimensional neighbors and increases parallel data movement.</p><p>However, topology only explains how TPU chips are connected. To actually run computation on the cluster, we also need the compiler and runtime.</p><h1>How is computation executed over a TPU cluster network topology?</h1><p>We can use Hive as an analogy.</p><p>In the early days, if you wanted to write distributed computation with MapReduce, you had to write mappers and reducers yourself. The MapReduce runtime would distribute different data partitions to different machines and execute your mapper and reducer logic.</p><p>But if you wanted to write a more complex query, such as:</p><pre><code><code>select uid, sum(amount)
from orders
join products on orders.pid = products.id
where products.name = 'XXX'
group by uid;
</code></code></pre><p>Writing mappers and reducers by hand would be very cumbersome. Therefore, Hive provided a higher-level interface: users write SQL, and Hive compiles the SQL into MapReduce stages.</p><p>TPU training has a similar abstraction layer.</p><p>Users write high-level tensor computations in TensorFlow or JAX, such as forward pass, loss computation, backward pass, and optimizer update. However, TPU hardware itself only supports lower-level tensor operations, such as matrix multiplication, reduce, AllReduce, and tensor load/store.</p><p>Therefore, XLA is needed as the compiler. XLA converts the high-level tensor computation graph into HLO, which stands for High Level Optimizer IR. It then optimizes the graph and generates an executable program for TPU.</p><p>Similar to Hive, XLA is not just doing syntax translation. It also performs optimizations such as sharding, operator fusion, device placement, and collective communication planning.</p><p>For example, in distributed TPU training, XLA can arrange collective operations such as ReduceScatter and AllGather based on the device mesh and TPU network topology information.</p><p>Therefore, the essence of TPU design is a co-design of hardware, network, and compiler. It is not merely a standalone accelerator chip.</p><h1>Preview for the next article: </h1><p>Why is TPU computation so fast? Understanding ICI and internal data movement inside a TPU Pod.</p><p>This article focuses on why TPU computation can be cost-efficient.</p><p>The key point is not that a single TPU chip is magically cheap. Instead, TPU clusters reduce the network synchronization cost of each training step through Ring AllReduce, 2D / 3D torus topology, and the collective schedule planned by XLA and the runtime.</p><p>However, this article only covered topology and computation runtime. The next question is: when data is exchanged inside a TPU Pod, how does the system reduce the latency of data movement?</p>]]></content:encoded></item><item><title><![CDATA[Spark 如何打敗 Hadoop Map Reduce？]]></title><description><![CDATA[&#35299;&#26512;&#20998;&#25955;&#24335;&#36939;&#31639;&#26550;&#27083; - DAG&#12289;shuffle &#21040; fault tolerance]]></description><link>https://www.chillvic.dev/p/spark-hadoop-map-reduce</link><guid isPermaLink="false">https://www.chillvic.dev/p/spark-hadoop-map-reduce</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Thu, 04 Jun 2026 00:24:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!x5Eh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F474e8262-098c-4996-8aec-d357a85ae573_1024x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>AI &#26178;&#20195;&#65292;data processing &#35722;&#24471;&#37325;&#35201;&#65292;feature pipeline&#12289;&#36039;&#26009;&#28165;&#27927;&#12289;data ingest &#21040; data warehouse&#65292;&#25110;&#26159;&#22312; lakehouse &#19978;&#36305;&#22823;&#35215;&#27169; batch query&#65292;&#26412;&#36074;&#19978;&#37117;&#22312;&#34389;&#29702;&#21516;&#19968;&#20214;&#20107;&#65306;&#22823;&#37327;&#36039;&#26009;&#35201;&#34987;&#31337;&#23450;&#12289;&#24555;&#36895;&#36681;&#25563;&#25104;&#25105;&#20497;&#38656;&#35201;&#30340;&#27171;&#23376;&#12290;</p><p>&#22312;&#36889;&#20491;&#38936;&#22495;&#35041;&#65292;Spark &#24190;&#20046;&#26159;&#26368;&#37325;&#35201;&#30340;&#22522;&#24314;&#20043;&#19968;&#65292;&#20294; Spark &#21040;&#24213;&#26159;&#20160;&#40636;&#65311;</p><p>&#28858;&#20160;&#40636;&#19981;&#26159;&#23531;&#19968;&#25903; Python script &#23601;&#22909;&#65311;&#28858;&#20160;&#40636;&#26377;&#20102; Hadoop MapReduce &#21644; Hive&#65292;&#24460;&#20358;&#36996;&#38656;&#35201; Spark&#65311;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!x5Eh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F474e8262-098c-4996-8aec-d357a85ae573_1024x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!x5Eh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F474e8262-098c-4996-8aec-d357a85ae573_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!x5Eh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F474e8262-098c-4996-8aec-d357a85ae573_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!x5Eh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F474e8262-098c-4996-8aec-d357a85ae573_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!x5Eh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F474e8262-098c-4996-8aec-d357a85ae573_1024x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!x5Eh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F474e8262-098c-4996-8aec-d357a85ae573_1024x1536.png" width="1024" height="1536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/474e8262-098c-4996-8aec-d357a85ae573_1024x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1536,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3076310,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/200540339?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F474e8262-098c-4996-8aec-d357a85ae573_1024x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!x5Eh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F474e8262-098c-4996-8aec-d357a85ae573_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!x5Eh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F474e8262-098c-4996-8aec-d357a85ae573_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!x5Eh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F474e8262-098c-4996-8aec-d357a85ae573_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!x5Eh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F474e8262-098c-4996-8aec-d357a85ae573_1024x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Spark &#26159;&#20160;&#40636;&#65311;&#28858;&#20160;&#40636; data pipeline &#38656;&#35201;&#23427;&#65311;</h1><p>&#30070;&#36039;&#26009;&#19981;&#22810;&#26178;&#65292;&#24478; A database &#25644;&#21040; B database&#65292;&#25110;&#20570;&#36039;&#26009;&#36681;&#25563;&#65292;&#19968;&#25903; Python script &#23601;&#22816;&#20102;&#65292;&#20294;&#36039;&#26009;&#35722;&#22823;&#24460;&#25110;&#36039;&#26009;&#26032;&#22686;&#36895;&#24230;&#22826;&#24555;&#26178;&#65292;&#19968;&#21488;&#27231;&#22120;&#24448;&#24448;&#19981;&#22816;&#12290;</p><p>&#20363;&#22914; orders table &#30340; insert rate &#24456;&#39640;&#65292;&#35201;&#25226; binlog real-time ingest &#21040; data warehouse&#12290;&#21934;&#19968; Python process &#26371;&#36861;&#19981;&#19978;&#23531;&#20837;&#36895;&#24230;&#65292;&#26371;&#22240;&#28858; memory&#12289;CPU&#12289;I/O &#37117;&#34987;&#21934;&#27231;&#38480;&#21046;&#20303;&#65292;&#28961;&#27861;&#31337;&#23450;&#34389;&#29702;&#12290;</p><p>&#36889;&#26178;&#20505;&#38656;&#35201;&#20998;&#25955;&#24335;&#36939;&#31639;&#12290;</p><p>&#20998;&#25955;&#24335;&#36939;&#31639;&#26680;&#24515;&#26159;&#65306;&#25226;&#36039;&#26009;&#20999;&#25104; partitions&#65292;&#20998;&#32102;&#22810;&#21488;&#27231;&#22120;&#24179;&#34892;&#34389;&#29702;&#65292;&#20687;&#26159; Kafka partition&#12289;database shard&#12289;data lake partition&#65292;&#37117;&#26159;&#25226;&#36039;&#26009;&#20998;&#25955;&#21040;&#19981;&#21516;&#22320;&#26041;&#12290;&#12290;</p><p>&#22240;&#27492; Spark &#19981;&#21482;&#26159;&#12300;&#36305; pipeline &#30340;&#24037;&#20855;&#12301;&#32780;&#26159;&#20998;&#25955;&#24335;&#36939;&#31639; runtime&#65292;&#23427;&#30495;&#27491;&#34389;&#29702;&#30340;&#26159;&#65306;&#30070;&#36039;&#26009;&#35336;&#31639;&#36328;&#36234;&#22810;&#21488;&#27231;&#22120;&#26178;&#65292;runtime &#35201;&#22914;&#20309;&#23433;&#25490;&#35336;&#31639;&#12289;&#20132;&#25563;&#36039;&#26009;&#12289;&#36861;&#36452;&#20381;&#36084;&#65292;&#20006;&#22312;&#27231;&#22120;&#22833;&#25943;&#26178;&#24674;&#24489;&#12290;</p><h1>&#28858;&#20160;&#40636;&#21934;&#32020;&#25226;&#36039;&#26009;&#20998;&#32102;&#22810;&#21488;&#27231;&#22120;&#36996;&#19981;&#22816;&#65311;</h1><p>&#20551;&#35373;&#22519;&#34892;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">select uid, sum(amount)

from orders

group by uid;
</code></pre></div><p>orders &#24456;&#22823;&#65292;&#25152;&#20197;&#36039;&#26009;&#34987;&#20999;&#25104;&#22810;&#20491; partitions&#65292;&#20998;&#25955;&#22312;&#19981;&#21516; executor (i.e machines) &#19978;&#12290;</p><p>&#31532;&#19968;&#27493;&#65292;&#27599;&#21488; executor &#20808;&#34389;&#29702;&#33258;&#24049; partition &#35041;&#30340; records&#65292;&#31639;&#20986;&#23616;&#37096;&#32080;&#26524;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">| executor | partial result |
| --- | --- |
| 1 | `[uid=1, amount=100]`, `[uid=2, amount=200]`, `[uid=3, amount=300]` |
| 2 | `[uid=1, amount=50]`, `[uid=2, amount=250]`, `[uid=3, amount=40]`, `[uid=5, amount=80]` |</code></pre></div><p>&#20294;&#36889;&#19981;&#26159;&#26368;&#32066;&#31572;&#26696;&#65292;&#35201;&#25226;&#19981;&#21516; executor &#30340;&#23616;&#37096;&#32080;&#26524;&#20381;&#29031; uid &#32858;&#21512;&#29554;&#24471; global sum&#12290;</p><p>&#22240;&#27492;&#20998;&#25955;&#24335;&#36939;&#31639; runtime &#20998;&#30332;&#36039;&#26009;&#24460;&#65292;&#36996;&#38656;&#35201;&#23433;&#25490;&#36039;&#26009;&#20132;&#25563;&#65292;&#36889;&#20491;&#12300;&#20381;&#29031; key &#37325;&#26032;&#20998;&#37197;&#36039;&#26009;&#12301;&#30340;&#36942;&#31243;&#65292;&#23601;&#26159; shuffle&#12290;</p><p>&#20363;&#22914;&#65306;</p><p><code>uid=1</code> &#30340;&#36039;&#26009;&#21516;&#26178;&#20986;&#29694;&#22312; executor 1 &#21644; executor 2&#65292;&#35201;&#25226;&#25152;&#26377; <code>uid=1</code> &#30340; partial results &#36865;&#21040;&#21516;&#19968;&#20491; reducer&#12290;</p><p>shuffle &#24460;&#65292;&#36039;&#26009;&#26371;&#35722;&#25104;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| reducer | final result |
| --- | --- |
| 1 | `[uid=1, amount=150]` |
| 2 | `[uid=2, amount=450]` |
| 3 | `[uid=3, amount=340]` |
| 4 | `[uid=5, amount=80]` |</code></pre></div><p>&#32780;&#36889;&#20063;&#26159; MapReduce &#30340;&#22522;&#26412;&#27169;&#22411;&#65306;</p><p><strong>Map&#65306;&#27599;&#21488;&#27231;&#22120;&#20808;&#34389;&#29702;&#33258;&#24049;&#30340;&#36039;&#26009;&#12290;</strong></p><p><strong>Shuffle&#65306;&#20381;&#29031; key &#25226;&#30456;&#38364;&#36039;&#26009;&#36865;&#21040;&#21516;&#19968;&#20491; reducer&#12290;</strong></p><p><strong>Reduce&#65306;&#27599;&#20491; reducer &#23565;&#33258;&#24049;&#36000;&#36012;&#30340; key &#20570;&#32858;&#21512;&#12290;</strong></p><p>Hadoop MapReduce &#20316;&#28858;&#26089;&#26399;&#30693;&#21517;&#30340;&#20998;&#25955;&#24335;&#36939;&#31639; runtime &#33021;&#35731;&#24037;&#31243;&#24107;&#25226;&#19968;&#27573;&#20998;&#25955;&#24335;&#35336;&#31639;&#25286;&#25104;  <code>map -&gt; shuffle -&gt; reduce</code>&#12290;</p><p>&#32780;&#23526;&#29694;&#36039;&#26009;&#20132;&#25563;&#30340;&#38364;&#37749;&#22312;&#26044; runtime &#35201;&#30693;&#36947;&#36039;&#26009;&#30340;&#20381;&#36084;&#38364;&#20418;&#65292;&#21738;&#20123; reduce &#30340; input &#20358;&#33258;&#26044;&#21738;&#20123; map &#30340; output&#65292;&#22240;&#27492; runtime &#22312;&#22519;&#34892;&#35336;&#31639;&#26178;&#65292;&#26371;&#23559;&#35336;&#31639;&#36942;&#31243;&#35722;&#25104; Directed Acyclic Graph (DAG)&#65306;</p><p>groupBy -&gt; sum -&gt; shuffle -&gt; sum</p><p>&#20294;&#35064; MapReduce &#21839;&#38988;&#26159;&#65292;&#38283;&#30332;&#32773;&#35201;&#33258;&#24049;&#23526;&#20316; map object &#21644; reduce object&#65292;&#30070; computation &#35722;&#35079;&#38620;&#65292;&#20363;&#22914;&#65306;</p><p>filter -&gt; join -&gt; aggregate -&gt; sort -&gt; another aggregate</p><p>&#23601;&#26371;&#26377;&#22810;&#20491; MapReduce jobs &#36319;&#23526;&#20316;&#22810;&#20491; map/reduce object&#65292;&#19988; job &#20043;&#38291;&#30340;&#20381;&#36084;&#33287;&#20013;&#38291;&#32080;&#26524;&#37532;&#25509;&#65292;&#38656;&#35201;&#19978;&#23652;&#31995;&#32113;&#25110;&#38283;&#30332;&#32773;&#31649;&#29702;&#12290;</p><p>&#22240;&#27492; Hive &#20986;&#29694;&#20102;&#65306;&#19981;&#29992;&#30452;&#25509;&#23531; map/reduce object&#65292;&#32780;&#26159;&#21487;&#23531; SQL&#12290;</p><p>Hive &#26371;&#25226; SQL &#35299;&#26512;&#25104; query plan&#65292;&#20778;&#21270;&#26597;&#35426;&#65292;&#20877;&#32232;&#35695;&#25104;&#22810;&#20491; MapReduce jobs&#12290;</p><p>&#20363;&#22914; Hive &#32232;&#35695;&#19979;&#38754; query &#26178;&#65292;&#26371;&#20778;&#21270;&#23526;&#38555; map reduce &#30340; group by  &#37007;&#36655;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">select campaign_id, count(*)
from clicks
group by campaign_id;</code></pre></div><p>&#26368;&#26292;&#21147;&#30340;&#20570;&#27861;&#26159; mapper &#25226;&#27599;&#31558;&#36039;&#26009;&#37117; shuffle &#32102; reducer&#65306;</p><p><code>(a, 1), (a, 1), (a, 1), (b, 1), (b, 1)</code></p><p>shuffle &#24460;&#65306;</p><p><code>(a, [1, 1, 1]), (b, [1, 1])</code></p><p>&#20294; <code>count</code> &#26377;&#25976;&#23416;&#20132;&#25563;&#24615;&#33287;&#32080;&#21512;&#24615;&#65292;&#25152;&#20197; mapper &#21487;&#20197;&#20808;&#20570; local partial aggregation&#65306;</p><p><code>(a, 3), (b, 2)</code></p><p>&#20877;&#25226; partial count shuffle &#32102; reducer&#12290;</p><p>&#36889;&#27171;&#21487;&#20197;&#28187;&#23569; shuffle data &#20659;&#36664;&#37327;&#12290;</p><h1>&#26377;&#20102; Hadoop Map Reduce + Hive&#65292;&#28858;&#20309;&#36996;&#38656;&#35201; Spark&#65311;</h1><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.chillvic.dev/subscribe?"><span>Subscribe now</span></a></p><p>Hadoop Map Reduce runtime + Hive &#26377;&#19968;&#20123;&#38480;&#21046;&#65306;</p><h2><strong>&#31532;&#19968;&#20491;&#38480;&#21046;&#65292;DAG &#30340; boundary&#65306;</strong></h2><p>Hadoop Map Reduce runtime &#19968;&#27425;&#21482;&#31649;&#29702;&#19968;&#27573; <code>map -&gt; shuffle -&gt; reduce</code>&#65292;&#24847;&#21619;&#33879; DAG &#35041;&#21482;&#35352;&#37636;&#19968;&#20491; map reduce job &#30340;&#35336;&#31639;&#36942;&#31243;&#65292;&#22914;&#26524;&#26377;&#22810;&#20491; map reduce job&#65292;&#26371;&#26377;&#22810;&#20491;&#19981;&#30456;&#36899;&#30340; DAG&#65306;</p><p>map1 =&gt; shuffle1 =&gt; reduce1 =&gt; DAG1</p><p>map2 =&gt; shuffle2 =&gt; reduce2 =&gt; DAG2</p><p>&#30070; map2 &#36039;&#26009;&#20358;&#33258;&#26044; reduce1&#65292;&#26410;&#36991;&#20813; map2 &#22519;&#34892;&#19968;&#21322; crash &#37325;&#21855;&#65292;&#38656;&#35201;&#25226; reduce1 &#36039;&#26009;&#25345;&#20037;&#21270;&#65292;&#22240;&#28858; runtime &#24478; DAG2 &#30340;&#35282;&#24230;&#20358;&#30475;&#65292;input &#36039;&#26009;&#20358;&#33258;&#26044;&#26576;&#20491; partition &#32780;&#19981;&#26159;&#36879;&#36942;&#35336;&#31639;&#29554;&#24471;&#30340;&#12290;</p><p>&#22240;&#27492; Hadoop Map Reduce runtime &#27599;&#22519;&#34892;&#23436;&#19968;&#20491; job &#26371;&#25226;&#32080;&#26524;&#23531;&#36914; HDFS (&#20998;&#25955;&#24335;&#27284;&#26696;&#31995;&#32113;) &#20013;&#12290; </p><p>&#20363;&#22914;&#65292;filter -&gt; join -&gt; aggregate -&gt; sort -&gt; another aggregate&#65292;&#22312;&#20659;&#32113; Hive on MapReduce &#35041;&#65292;&#21487;&#33021;&#26371;&#35722;&#25104;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">Job1: filter

&#23531;&#22238; HDFS

Job2: join

&#23531;&#22238; HDFS

Job3: aggregate

&#23531;&#22238; HDFS

Job4: sort

&#23531;&#22238; HDFS

Job5: aggregate</code></pre></div><p>&#20786;&#23384;&#20013;&#38291;&#32080;&#26524;&#26371;&#35731;&#25972;&#20491; pipeline &#26356;&#31337;&#23450;&#65292;&#20294; HDFS &#20786;&#23384;&#25104;&#26412;&#19981;&#20302;&#65292;&#26371;&#26377;&#38989;&#22806;&#30340; disk I/O &amp; network I/O&#12290;</p><h2><strong>&#31532;&#20108;&#20491;&#38480;&#21046;&#26159; optimization &#30340;&#26178;&#27231;&#65306;</strong></h2><p>Hive &#22312;&#22519;&#34892;&#21069;&#29986;&#29983; query plan&#12290;&#23427;&#21487;&#20197;&#26681;&#25818;&#35486;&#27861;&#12289;&#35215;&#21063;&#12289;statistics &#20570;&#20778;&#21270;&#65292;&#20063;&#23601;&#26159;&#35498; optimization &#26159;&#22312;&#22519;&#34892;&#21069;&#23436;&#25104;&#65292;&#28961;&#27861;&#26681;&#25818;&#22519;&#34892;&#20013;&#30340;&#36039;&#26009;&#30495;&#23526;&#24773;&#27841; (e.g shuffle size&#12289;partition size&#12289;data skew) &#37325;&#26032;&#35519;&#25972;&#24460;&#38754;&#30340; strategy&#12290;</p><p>&#22240;&#27492; spark &#30340;&#25361;&#25136;&#35722;&#25104;&#65306;</p><p>&#22914;&#20309;&#36991;&#20813;&#27599;&#19968;&#27493;&#37117;&#25226;&#20013;&#38291;&#32080;&#26524;&#23531;&#22238; HDFS&#65292;&#21516;&#26178;&#20445;&#35657; pipeline &#21487;&#38752;&#65311;</p><p>&#22914;&#20309;&#22312;&#22519;&#34892;&#26178;&#26681;&#25818;&#30495;&#23526;&#36039;&#26009;&#37327;&#35519;&#25972; plan&#65311;</p><h1>Spark &#24590;&#40636;&#35299;&#27770; Hadoop Map Reduce + Hive &#30340;&#32570;&#40670;&#65311;</h1><p>&#39318;&#20808; Spark &#30340;&#26680;&#24515;&#24819;&#27861;&#26159;&#20445;&#30041;&#23436;&#25972;&#30340; computation lineage (&#26576;&#20491;&#36039;&#26009;&#32080;&#26524;&#26159;&#24590;&#40636;&#24478;&#28304;&#38957;&#36039;&#26009;&#19968;&#27493;&#19968;&#27493;&#31639;&#20986;&#20358;&#30340;)&#12290;</p><p>&#20363;&#22914;&#65306;</p><p>map1 -&gt; shuffle1 -&gt; reduce1 -&gt; map2 -&gt; shuffle2 -&gt; reduce2</p><p>&#22312; Spark &#35041;&#65292;&#36889;&#19981;&#26159;&#22810;&#20491;&#26039;&#38283;&#30340; MapReduce jobs&#65292;&#32780;&#26159;&#19968;&#26781;&#23436;&#25972;&#30340; dependency graph&#12290;Spark runtime &#30693;&#36947;&#19979;&#28216;&#36039;&#26009;&#20381;&#36084;&#21738;&#20123;&#19978;&#28216; transformation&#65292;&#20063;&#30693;&#36947;&#21738;&#35041;&#38656;&#35201; shuffle&#65292;&#21738;&#35041;&#21487;&#20197;&#30452;&#25509; pipeline&#12290;</p><p>&#22240;&#27492;&#65292;Spark &#19981;&#29992;&#25226;&#20013;&#38291;&#32080;&#26524;&#23531;&#22238; HDFS&#65292;&#20013;&#38291;&#32080;&#26524;&#21487;&#30041;&#22312; executor memory &#25110; local disk&#12290;&#33509;&#26576;&#20491; executor &#25499;&#25481;&#65292;memory &#35041;&#30340;&#36039;&#26009;&#36986;&#22833;&#65292;Spark &#20173;&#21487;&#20381;&#29031; lineage &#24478;&#19978;&#28216; partition &#37325;&#26032;&#35336;&#31639;&#12290;</p><p>&#20063;&#23601;&#26159;&#35498; Spark &#30340; fault tolerance &#19981;&#26159;&#38752;&#27599;&#19968;&#27493;&#37117; materialize &#21040;&#21487;&#38752;&#20786;&#23384;&#65292;&#32780;&#26159;&#38752;&#12300;&#30693;&#36947;&#24590;&#40636;&#37325;&#31639;&#12301;&#12290;</p><p>&#31532;&#20108;&#65292;Spark Runtime &#21407;&#29983;&#25903;&#25588;&#35486;&#27861;&#35299;&#26512;&#32232;&#35695;&#65292;&#20363;&#22914; Spark SQL &#25226; optimization &#21644; runtime execution &#32202;&#23494;&#22320;&#32080;&#21512;&#23526;&#29694; Adaptive Query Execution&#12290;</p><p>&#20363;&#22914;&#22519;&#34892;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;sql&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-sql">select SUM(orders.amount), products.name from orders 
join products on orders.pid = products.id group by products.name;</code></pre></div><p>&#21021;&#22987; Spark &#20272;&#35336; join &#30340; products &#36039;&#26009;&#37327;&#24456;&#22823;&#65292;&#25152;&#20197;&#29992; Sort Merge Join&#65292;&#36991;&#20813;&#24314;&#31435;&#22826;&#22823;&#30340; hash table (OOM risk)&#12290;</p><p>&#20294;&#23526;&#38555;&#22519;&#34892;&#21040; shuffle &#24460;&#65292;Spark &#30332;&#29694;&#26576;&#19968;&#20596;&#36039;&#26009;&#27604;&#38928;&#26399;&#23567;&#24456;&#22810;&#65292;&#27492;&#26178; AQE &#21487;&#25226;&#24460;&#32396; join strategy &#25913;&#25104; Broadcast Hash Join&#65292;&#25110;&#21512;&#20341;&#36942;&#23567;&#30340; shuffle partitions&#65292;&#35731;&#22519;&#34892;&#26356;&#36028;&#36817;&#30495;&#23526;&#36039;&#26009;&#20998;&#24067;&#12290;</p><p>&#31777;&#21934;&#20358;&#35498;&#65292;Spark runtime &#20855;&#20633;&#35299;&#26512;&#32232;&#35695;&#19981;&#21516;&#26597;&#35426;&#35486;&#35328;&#20197;&#21450;&#24314;&#31435;&#23436;&#25972; computation lineage DAG &#30340;&#33021;&#21147;&#12290;</p><p>&#32780;&#38500;&#20102;&#20381;&#29031;&#30495;&#23526;&#36039;&#26009;&#20570; query optimization&#65292;DAG &#30340;&#20839;&#23481;&#20063;&#26371;&#24433;&#38911; Spark runtime &#22519;&#34892;&#30340;&#31574;&#30053;&#12290;</p><h1>Spark DAG &#22914;&#20309;&#24433;&#38911;&#26597;&#35426;&#20778;&#21270;&#65311;</h1><p>&#19968;&#20491;&#20998;&#25955;&#24335;&#26597;&#35426;&#30340;&#25928;&#33021;&#65292;&#24456;&#22823;&#31243;&#24230;&#21462;&#27770;&#26044; shuffle boundary&#12290;</p><p>shuffle &#19981;&#21482;&#26159;&#12300;&#26377;&#32178;&#36335;&#20659;&#36664;&#12301;&#32780;&#24050;&#12290;&#23427;&#36890;&#24120;&#21253;&#21547;&#65306;</p><ul><li><p>records &#20381;&#29031; key&#12289;range &#25110; hash &#34987;&#37325;&#26032;&#20998;&#30332;</p></li><li><p>map side &#23531; shuffle files</p></li><li><p>reduce side &#24478;&#22810;&#20491; map outputs fetch &#33258;&#24049;&#38656;&#35201;&#30340;&#36039;&#26009;</p></li><li><p>&#33509;&#36039;&#26009;&#20670;&#26012;&#65292;&#26576;&#20123; reduce tasks &#21487;&#33021;&#35722;&#25104;&#38263;&#23614;&#29942;&#38968;</p></li></ul><p>&#22240;&#27492; Spark DAG &#19981;&#21482;&#25551;&#36848;&#12300;&#20808;&#20570;&#20160;&#40636;&#12289;&#24460;&#20570;&#20160;&#40636;&#12301;&#26356;&#37325;&#35201;&#30340;&#26159;&#27161;&#35352;&#21738;&#20123; dependency &#26371;&#24418;&#25104; shuffle boundary&#12290;</p><p>&#22312; Spark DAG &#20013;&#65292;&#27599;&#20491; transformation step &#30340; output/input data &#31281;&#20316; Resilient Distributed Dataset (RDD)&#65292;&#19968;&#20491; DAG &#32080;&#27083;&#20013;&#65306;</p><ul><li><p>Node &#26159; RDD</p></li><li><p>Edge &#26159; dependency</p></li></ul><p>dependency &#21448;&#21487;&#20197;&#20998;&#25104; narrow dependency &#21644; wide dependency&#12290;</p><p>Narrow dependency &#25351; parent RDD &#19981;&#29992;&#20381;&#29031; key&#12289;range &#25110; hash &#37325;&#26032;&#20998;&#30332;&#65292;&#36039;&#26009;&#27969;&#21521;&#26159;&#22266;&#23450;&#30340;&#65292;&#36890;&#24120;&#21487;&#20197;&#22312;&#21516;&#19968;&#20491; stage &#20839; pipeline&#12290;</p><p>&#20363;&#22914; `filter&#12289;`map`&#12289;`flatMap`&#12290;</p><p>Wide dependency &#25351;&#30340;&#26159; parent RDD &#38656;&#35201;&#34987;&#37325;&#26032;&#20998;&#37197;&#21040;&#22810;&#20491; child RDD&#65292;&#26371;&#35320;&#30332; shuffle&#65292;&#20063;&#26371;&#24418;&#25104;&#26032;&#30340; stage boundary&#12290;</p><p>&#32780;&#22312; Spark DAG &#26371;&#29992; stage &#26126;&#30906;&#34920;&#26126;&#21738;&#20123; transformation step &#21487;&#22312; pipeline &#23436;&#25104;&#65292;&#20160;&#40636;&#26178;&#20505;&#26371;&#35320;&#30332; shuffle &#20999;&#20986;&#26032; stage&#65292;&#36890;&#24120;&#22312;&#30456;&#21516; stage &#30340; transformation step &#21487;&#20006;&#34892;&#34389;&#29702;&#19981;&#21516; partition&#65292;&#20294;&#36328; stage &#26178;&#65292;&#19979;&#28216; stage &#24517;&#38920;&#31561;&#19978;&#28216; stage &#20840;&#37096;&#23436;&#25104;&#24460;&#25165;&#33021;&#38283;&#22987;&#65306;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oWgt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa28f6d3b-2216-411a-b849-683a0011dae5_898x470.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oWgt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa28f6d3b-2216-411a-b849-683a0011dae5_898x470.png 424w, https://substackcdn.com/image/fetch/$s_!oWgt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa28f6d3b-2216-411a-b849-683a0011dae5_898x470.png 848w, https://substackcdn.com/image/fetch/$s_!oWgt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa28f6d3b-2216-411a-b849-683a0011dae5_898x470.png 1272w, https://substackcdn.com/image/fetch/$s_!oWgt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa28f6d3b-2216-411a-b849-683a0011dae5_898x470.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oWgt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa28f6d3b-2216-411a-b849-683a0011dae5_898x470.png" width="898" height="470" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a28f6d3b-2216-411a-b849-683a0011dae5_898x470.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:470,&quot;width&quot;:898,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:387848,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/200540339?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa28f6d3b-2216-411a-b849-683a0011dae5_898x470.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oWgt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa28f6d3b-2216-411a-b849-683a0011dae5_898x470.png 424w, https://substackcdn.com/image/fetch/$s_!oWgt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa28f6d3b-2216-411a-b849-683a0011dae5_898x470.png 848w, https://substackcdn.com/image/fetch/$s_!oWgt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa28f6d3b-2216-411a-b849-683a0011dae5_898x470.png 1272w, https://substackcdn.com/image/fetch/$s_!oWgt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa28f6d3b-2216-411a-b849-683a0011dae5_898x470.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>&#22238;&#21040;&#36889;&#20491; query&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;sql&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-sql">select uid, sum(amount * 2) as total
from orders
where status = &#8216;SUCCESS&#8217;
group by uid;</code></pre></div><p>&#27010;&#24565;&#19978;&#21487;&#20197;&#29702;&#35299;&#25104;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">RDD1: orders
filter status = SUCCESS

RDD2: successful orders
map to `(uid, amount * 2)`

RDD3: `(uid, value)`
reduceByKey sum
shuffle boundary

RDD4: `(uid, total)`</code></pre></div><p>`RDD1 -&gt; RDD2 -&gt; RDD3` &#26159; narrow dependency&#65292;filter &#21644; map &#21487;&#22312;&#21516;&#19968;&#20491; task &#35041; pipeline &#22519;&#34892;&#12290;&#19981;&#21516; partitions &#21487;&#20998;&#25955;&#21040;&#19981;&#21516; executors &#24179;&#34892;&#34389;&#29702;&#12290;</p><p>`RDD3 -&gt; RDD4` &#26159; wide dependency&#65292;&#22240;&#28858;&#30456;&#21516; `uid` &#30340; records &#20998;&#25955;&#22312;&#19981;&#21516; partitions&#65292;Spark &#24517;&#38920;&#20381;&#29031; `uid` &#37325;&#26032;&#20998;&#30332;&#36039;&#26009;&#65292;&#35731;&#21516;&#19968;&#20491; key &#30340;&#36039;&#26009;&#32858;&#22312;&#19968;&#36215;&#20570; sum&#12290;</p><p>&#36889;&#23601;&#26159;&#28858;&#20160;&#40636; shuffle &#26159; Spark &#25928;&#33021;&#20998;&#26512;&#30340;&#26680;&#24515;&#65292;&#31777;&#21934;&#30340;&#20998;&#39006;&#65306;</p><p>Narrow Dependency: filter / map / flatMap / union</p><p>Wide Dependency: aggregation + group by or reduce by</p><h1>&#38500;&#20102; Aggregation + Group By &#20043;&#22806;&#36996;&#26377;&#21738;&#20123; Query &#26371;&#35320;&#30332; Shuffle&#65311;</h1><p>`GROUP BY` &#26159;&#26368;&#30452;&#35258;&#30340; shuffle &#20363;&#23376;&#65292;&#20294;&#19981;&#26159;&#21807;&#19968;&#65292;&#21478;&#19968;&#20491;&#24120;&#35211;&#20363;&#23376;&#26159; join&#12290;</p><p>&#20551;&#35373;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">select *
from orders o
join users u
on o.uid = u.uid;</code></pre></div><p>&#33509; `users` &#21644; `orders` &#20998;&#25955;&#22312;&#19981;&#21516; partitions&#65292;&#23601;&#21487;&#33021;&#20986;&#29694;&#65306;</p><p>`user uid=1` &#22312; executor A&#12290;</p><p>`order uid=1` &#22312; executor B&#12290;</p><p>executor A &#25214;&#19981;&#21040;&#23565;&#25033; order&#12290;executor B &#25214;&#19981;&#21040;&#23565;&#25033; user&#12290;</p><p>&#22240;&#27492; Spark &#24517;&#38920;&#25226; join key &#30456;&#21516;&#30340; records &#25918;&#21040;&#21516;&#19968;&#20491; partition&#65292;&#25165;&#33021;&#27491;&#30906; join&#65292;&#23601;&#38656;&#35201; shuffle&#12290;</p><p>&#20294; join &#20063;&#26377;&#20778;&#21270;&#27231;&#21046;&#65292;&#33509;&#20854;&#20013;&#19968;&#24373;&#34920;&#24456;&#23567;&#65292;&#20363;&#22914; `users` table &#24456;&#23567;&#65292;Spark &#21487;&#25226;&#25972;&#24373;&#23567;&#34920; broadcast &#21040;&#25152;&#26377; executors&#65292;&#35731;&#27599;&#20491; executor &#37117;&#33021;&#25226;&#33258;&#24049;&#30340; orders partition &#21644; users table join &#36215;&#20358;&#65292;&#19981;&#38656;&#35201;&#25226; orders &#20381;&#29031; `uid` shuffle&#12290;</p><p>&#20063;&#23601;&#26159; Broadcast Join Optimization&#12290;</p><p>&#21478;&#19968;&#20491;&#20363;&#23376;&#26159; global `ORDER BY`&#12290;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;sql&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-sql">select *
from orders
order by amount desc;</code></pre></div><p>&#33509;&#36039;&#26009;&#26159;&#25353;&#29031; timestamp partition&#65292;&#20294;&#35201;&#20381;&#29031; `amount` &#20570;&#20840;&#22495;&#25490;&#24207;&#65292;Spark &#19981;&#33021;&#35731;&#27599;&#21488; executor &#21508;&#25490;&#21508;&#30340;&#12290;&#22240;&#28858; executor A &#25490;&#20986;&#30340;&#31532;&#19968;&#21517;&#65292;&#19981;&#19968;&#23450;&#27604; executor B &#25490;&#20986;&#30340;&#31532;&#19968;&#21517;&#22823;&#65292;&#20063;&#19981;&#21487;&#33021;&#20840;&#37096;&#25918;&#21040;&#19968;&#20491; executor &#25490;&#24207;&#12290;</p><p>&#22240;&#27492;&#20840;&#22495;&#25490;&#24207;&#38656;&#35201;&#37325;&#26032;&#23450;&#32681; partition range&#12290;</p><p>Spark &#21487;&#20808; sampling &#30475; `amount` &#30340;&#20998;&#24067;&#65292;&#27770;&#23450; range boundaries&#65292;&#20363;&#22914;&#65306;</p><ul><li><p>0 &#21040; 50</p></li><li><p>50 &#21040; 100</p></li><li><p>100 &#21040; 200</p></li></ul><p>&#25509;&#33879;&#20381;&#29031; range &#25226; records shuffle &#21040;&#19981;&#21516; partitions&#65292;&#35731;&#27599;&#20491; partition &#36000;&#36012;&#19968;&#27573;&#26377;&#24207;&#31684;&#22285;&#12290;</p><p>&#36889;&#27171;&#23601;&#19981;&#38656;&#35201;&#25226;&#25152;&#26377;&#36039;&#26009;&#22622;&#21040;&#19968;&#21488; executor&#65292;&#20173;&#21487;&#29986;&#29983; global ordering&#12290;</p><p>&#22240;&#27492;&#21487;&#29992;&#19968;&#20491;&#35215;&#21063;&#21028;&#26039; query &#26159;&#21542;&#21487;&#33021;&#35320;&#30332; shuffle&#65306;</p><p>&#21482;&#35201; query &#38656;&#35201;&#25913;&#35722;&#36039;&#26009;&#20998;&#24067;&#65292;&#35731;&#30456;&#21516; key&#12289;join key&#12289;&#25110;&#25490;&#24207; range &#30340; records &#32858;&#22312;&#19968;&#36215;&#65292;&#23601;&#24456;&#21487;&#33021;&#35201; shuffle&#12290;</p><h1>Spark Runtime &#23526;&#38555;&#24590;&#40636;&#31649;&#29702; executor node&#65311;</h1><p>&#30070; Spark runtime &#24314;&#31435;&#36215; DAG&#65292;&#23436;&#25104; query optimization &#36319;&#20999;&#20998; stage &#24460;&#65292;&#19979;&#19968;&#27493;&#26159;&#25226;&#36889;&#20123; computation &#36305;&#36215;&#20358;&#12290;</p><p>&#19968;&#20491; Spark application &#36890;&#24120;&#30001;&#19968;&#20491; driver &#21644;&#22810;&#20491; executors &#32068;&#25104;&#12290;</p><p>Driver &#26159;&#25511;&#21046;&#20013;&#24515;&#12290;&#23427;&#36000;&#36012;&#35299;&#26512; user program&#65292;&#24314;&#31435; DAG&#65292;&#20999; stages&#65292;&#29986;&#29983; tasks&#65292;&#20006;&#36861;&#36452; task &#29376;&#24907;&#12290;</p><p>Executor &#26159;&#22519;&#34892;&#21934;&#20301;&#12290;&#23427;&#36000;&#36012;&#25509;&#25910; driver &#27966;&#30332;&#30340; tasks&#65292;&#22519;&#34892; computation&#65292;&#23384;&#25918; cache / shuffle data&#65292;&#20006;&#22238;&#22577;&#22519;&#34892;&#29376;&#24907;&#12290;</p><p>Driver &#35041;&#26377;&#20841;&#20491;&#26680;&#24515; scheduler&#65306;</p><ul><li><p><strong>DAGScheduler</strong> &#36000;&#36012;&#30475; dependency graph&#65292;&#27770;&#23450; stage &#22914;&#20309;&#20999;&#20998;&#12290;&#36935;&#21040; shuffle dependency&#65292;&#23601;&#26371;&#20999;&#20986;&#26032;&#30340; stage&#12290;</p></li><li><p><strong>TaskScheduler</strong> &#36000;&#36012;&#25226;&#27599;&#20491; stage &#35041;&#30340; tasks &#20998;&#37197;&#32102; executors&#65292;&#20006;&#32771;&#24942; data locality&#12289;executor &#29376;&#24907;&#12289;task retry &#31561;&#21839;&#38988;&#12290;</p></li></ul><p>Spark runtime &#21482;&#31649;&#29702; computation &#21644; tasks &#20998;&#37197;&#65292;&#19981;&#31649;&#29702; executors &#36939;&#34892;&#30340;&#31680;&#40670;&#29376;&#27841;&#65292;&#22240;&#27492;&#38656;&#35201;&#22806;&#37096; cluster manager&#65292;&#20363;&#22914; Kubernetes&#12289;YARN &#25110; Standalone cluster&#12290;</p><p>Cluster manager &#36000;&#36012;&#31649; node &#36039;&#28304;&#65306;&#21738;&#20123; node &#21487;&#20197;&#21855;&#21205; executor&#12289;executor &#26377;&#22810;&#23569; CPU / memory&#12289;node &#25499;&#25481;&#24460;&#36039;&#28304;&#22914;&#20309;&#22238;&#25910;&#12290;</p><p>&#30070;&#21855;&#21205;&#19968;&#20491; Spark application &#26178;&#65306;</p><p>1. cluster manager &#26371;&#24171; Spark &#37197;&#32622; executor resources</p><p>2. &#25509;&#33879; driver &#36879;&#36942; RPC &#25226; serialized task &#30332;&#32102; executor</p><p>3. executor &#22519;&#34892;&#23436;&#24460;&#65292;&#25226; task status&#12289;metrics&#12289;shuffle output metadata &#22238;&#22577;&#32102; driver</p><p>&#19968;&#20491; Spark application &#35041;&#21487;&#26377;&#22810;&#20491; jobs&#12290;</p><p>job &#36890;&#24120;&#30001; action (i.e pipeline &#26368;&#24460;&#30340;output&#34892;&#28858;) &#35320;&#30332;&#65292;&#20363;&#22914; `collect`&#12289;`count`&#12289;`write`&#12290;</p><p>&#20363;&#22914;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">val ordersDF = spark.read.parquet(&#8221;/orders&#8221;)

ordersDF.filter($&#8221;status&#8221; === &#8220;SUCCESS&#8221;).writeTo(...)
ordersDF.filter($&#8221;status&#8221; === &#8220;FAIL&#8221;).writeTo(...)</code></pre></div><p>&#36889;&#35041;&#20841;&#20491; writes &#20998;&#21029;&#23531;&#21040;&#19981;&#21516;&#22320;&#26041;&#65292;&#26371;&#24418;&#25104;&#20841;&#20491; jobs&#65292;&#27599;&#20491; job &#26377;&#33258;&#24049;&#30340; DAG&#12289;stages&#12289;tasks &#21644;&#22519;&#34892;&#29376;&#24907;&#12290;</p><p>&#20877;&#24448;&#19979;&#25286;&#65306;</p><ul><li><p>job &#30001;&#22810;&#20491; stages &#32068;&#25104;&#12290;</p></li><li><p>stage &#30001;&#22810;&#20491; tasks &#32068;&#25104;&#12290;</p></li><li><p>task &#36890;&#24120;&#23565;&#25033;&#26576;&#20491; partition &#30340; computation&#12290;</p></li></ul><p>&#20063;&#23601;&#26159;&#35498; task &#26159; Spark &#20013;&#26368;&#22522;&#30990;&#30340;&#36939;&#31639;&#21934;&#20301;&#65292;&#37027;&#22914;&#26524; task &#22519;&#34892;&#22833;&#25943;&#24590;&#40636;&#36774;&#65311;</p><h1>Executor task &#22519;&#34892;&#22833;&#25943;&#26371;&#24590;&#27171;&#65311;Driver &#22914;&#20309;&#23526;&#29694; Fault Toleration?</h1><p>&#20998;&#25955;&#24335;&#31995;&#32113;&#19968;&#23450;&#26371;&#36935;&#21040; executor &#25499;&#25481;&#12289;task &#22833;&#25943;&#12289;GC pause&#12289;network timeout&#12290;</p><p>Spark &#30340;&#22522;&#26412;&#31574;&#30053;&#26159;&#65306;driver &#36000;&#36012; task attempt retry&#65292;executor &#22238;&#22577; task &#29376;&#24907;&#12290;</p><p>Driver memory &#35041;&#20445;&#23384; DAG&#12289;stage&#12289;task &#29376;&#24907;&#65292;&#20197;&#21450; shuffle map output &#31561; metadata&#65292;&#25152;&#20197; Driver &#30693;&#36947;&#22914;&#20309; retry task&#65292;&#20294;&#26159; Driver &#26377;&#26178;&#26371;&#35492;&#21028; retry &#26178;&#27231;&#12290;</p><p>&#20363;&#22914; executor &#22240;&#28858; OOM&#12289;GC pause &#25110; CPU &#36942;&#36617;&#65292;&#23566;&#33268; heartbeat timeout&#12290;Driver &#21487;&#33021;&#21028;&#23450; task failed&#65292;&#20006;&#22312;&#21478;&#19968;&#20491; executor &#21855;&#21205;&#26032;&#30340; task attempt&#12290;</p><p>&#20294;&#33290;&#30340; task attempt &#19981;&#19968;&#23450;&#30495;&#30340;&#20572;&#27490;&#12290;&#23427;&#21487;&#33021;&#21482;&#26159;&#26283;&#26178;&#27794;&#26377;&#22238;&#25033;&#65292;&#24460;&#20358;&#21448;&#32380;&#32396;&#36305;&#23436;&#12290;</p><p>&#27492;&#26178;&#23601;&#21487;&#33021;&#20986;&#29694;&#65306;</p><p><strong>old task attempt &#36996;&#22312;&#23531; output&#12290;</strong></p><p><strong>new task attempt &#20063;&#22312;&#23531; output&#12290;</strong></p><p>&#20841;&#20491; attempts &#37117;&#20195;&#34920;&#21516;&#19968;&#20491; logical task&#12290;</p><p>&#20551;&#35373;&#36889;&#20841;&#20491; task &#30340; output &#26159; shuffle map output file&#65292;&#27492;&#26178;&#26371;&#23566;&#33268; reduce task &#36319;&#19978;&#28216; fetch shuffle data &#30340;&#26178;&#20505;&#65292;&#25343;&#21040;&#20841;&#20221;&#30456;&#21516;&#36039;&#26009;&#65292;reduce &#32080;&#26524;&#20986;&#37679;&#12290;</p><p>&#22240;&#27492; Spark Driver &#26377; attempt-based output isolation &#27231;&#21046;&#65292;&#27599;&#20491; task attempt &#23531;&#21040;&#33258;&#24049;&#30340; output location &#26178; output file &#36996;&#19981;&#21487;&#35211;&#65292;executor &#26371;&#21521; driver &#36865;&#20986; commit&#65292;&#30456;&#21516;&#35336;&#31639;&#20839;&#23481;&#30340; task &#20849;&#29992;&#19968;&#20491; id&#65292;driver &#21482;&#25509;&#21463;&#20854;&#20013;&#19968;&#20491; successful commit&#65292;executor &#30906;&#35469; commit &#25104;&#21151;&#24460;&#25165;&#25226; output file &#35722;&#25104;&#21487;&#35211;&#12290;</p><h2><strong>&#20294;&#36889;&#21482;&#20445;&#35703; Spark runtime &#33021;&#31649;&#29702;&#30340; output file isolation&#12290;</strong></h2><p>&#33509; task &#30452;&#25509;&#23531;&#22806;&#37096; DB&#12289;&#21628;&#21483;&#22806;&#37096; API&#65292;&#20841;&#20491; task &#26371;&#26377; double write&#65292;&#21363;&#20415;&#26159;&#25104;&#21151; retry &#27794;&#26377;&#20841;&#20491; task&#65292;&#37325;&#26032;&#23531;&#20837;&#20063;&#21487;&#33021;&#25226;&#26576;&#25209;&#36039;&#26009;&#37325;&#23531;&#20841;&#27425;&#12290;</p><p>&#36889;&#26178;&#20505;&#38656;&#35201; external sink &#33258;&#24049;&#25552;&#20379; atomicity&#12290;</p><p>&#20197; Iceberg &#28858;&#20363;&#65292;executor &#23531;&#36039;&#26009;&#21040; Iceberg Table &#26178;&#36039;&#26009;&#26159;&#25918;&#22312;&#19981;&#21487;&#35211;&#30340; parquet file &#35041;&#65292;&#30070; task &#23436;&#25104;&#35201; commit &#26178;&#65292;&#21487;&#36879;&#36942; Driver &#25910;&#38598;&#25152;&#26377;&#20006;&#34892;&#34389;&#29702; task &#30340;&#23436;&#25104;&#29376;&#24907;&#20006;&#36942;&#28670;&#37325;&#35079;&#30340; task&#65292;&#19968;&#27425;&#30332;&#36865; Iceberg commit &#20462;&#25913; table metadata &#24314;&#31435;&#26032;&#30340; snapshot&#65292;&#38500;&#20102;&#30906;&#20445;&#20006;&#34892;&#23531;&#20837;&#30340;&#36039;&#26009;&#26159;&#21407;&#23376;&#24615;&#20043;&#22806;&#65292;&#20063;&#33021;&#36991;&#20813;&#37325;&#35079; task &#30340; files &#34987; commit&#12290;</p><p>&#36889;&#39006;&#35373;&#35336;&#26412;&#36074;&#26159;&#65306;&#36039;&#26009;&#23531;&#20837;&#21487;&#20808;&#30332;&#29983;&#65292;&#20294;&#30495;&#27491;&#35731;&#36039;&#26009;&#12300;&#21487;&#35211;&#12301;&#30340; commit &#24517;&#38920;&#26159; atomic &#30340;&#12290;</p><h2><strong>&#26368;&#24460;&#36996;&#26377;&#26356;&#22806;&#23652;&#30340;&#22833;&#25943;&#65306;driver &#25499;&#25481;&#12290;</strong></h2><p>Driver &#25499;&#25481;&#26178;&#65292;&#25972;&#20491; Spark application &#36890;&#24120;&#23601;&#22833;&#25943;&#20102;&#65292;&#36890;&#24120; Spark &#26371;&#25645;&#37197; Airflow &#36889;&#39006; workflow orchestrator &#31649;&#29702;&#22810;&#20491; Spark applications &#30340;&#22519;&#34892;&#38918;&#24207;&#12289;&#29376;&#24907;&#21644; retry&#12290;</p><p>&#20294; Airflow retry &#26159; application &#23652;&#32026;&#30340; retry&#12290;</p><p>&#22914;&#26524; Spark application crash&#65292;Airflow &#21487;&#33021;&#37325;&#36305;&#25972;&#20491; application&#12290;&#33509;&#36935;&#21040; network partition&#12289;timeout &#35492;&#21028;&#65292;&#29978;&#33267;&#21487;&#33021;&#20986;&#29694; new application &#21644; old application &#37325;&#30090;&#22519;&#34892;&#12290;</p><p>&#36889;&#24050;&#32147;&#19981;&#26159;&#21934;&#19968; Spark driver &#30340; task attempt isolation &#33021;&#34389;&#29702;&#30340;&#31684;&#22285;&#12290;</p><p>&#22240;&#27492;&#22312; production data pipeline &#35041;&#65292;sink &#31471;&#36890;&#24120;&#35201;&#26377; idempotency key &#25110; transactional write&#12290;</p><p>&#24120;&#35211;&#20570;&#27861;&#26159;&#20351;&#29992;&#36039;&#26009;&#20358;&#28304;&#30340;&#21807;&#19968;&#35672;&#21029;&#36039;&#35338;&#20316;&#28858; deduplication key&#65292;&#20363;&#22914; Kafka &#30340; `(topic, partition, offset)`&#65292;&#25110;&#26989;&#21209;&#23652;&#30340; `order_id`&#12289;`transaction_id`&#65292;&#20877;&#25645;&#37197; upsert / merge &#36991;&#20813;&#37325;&#35079;&#23531;&#20837;&#12290;</p><p>&#25152;&#20197; Spark &#30340; fault tolerance &#21487;&#20998;&#25104;&#19977;&#23652;&#65306;</p><ul><li><p>Spark runtime &#20839;&#37096;&#65306;&#38752; lineage&#12289;task retry&#12289;attempt isolation &#24674;&#24489; computation&#12290;</p></li><li><p>Table format / sink&#65306;&#38752; atomic commit&#12289;transaction&#12289;idempotency &#34389;&#29702; external side effect&#12290;</p></li><li><p>Workflow orchestrator&#65306;&#38752; application-level retry &#31649;&#29702;&#25972;&#39636; pipeline&#65292;&#20294;&#20063;&#21487;&#33021;&#24341;&#20837;&#36328; application &#30340;&#37325;&#35079;&#22519;&#34892;&#12290;</p></li></ul><p>Spark &#35299;&#27770;&#30340;&#26159;&#20998;&#25955;&#24335;&#36039;&#26009;&#35336;&#31639; runtime &#30340;&#21839;&#38988;&#65292;&#23427;&#33021;&#35731; computation &#22312; executor &#22833;&#25943;&#26178;&#24674;&#24489;&#65292;&#20063;&#33021;&#36991;&#20813;&#20839;&#37096; output &#34987;&#22810;&#20491; attempts &#27745;&#26579;&#65292;&#20294;&#30070;&#36039;&#26009;&#38626;&#38283; Spark runtime&#65292;&#23531;&#20837;&#22806;&#37096;&#31995;&#32113;&#65292;&#27491;&#30906;&#24615;&#23601;&#19981;&#20877;&#26159; Spark &#21934;&#29544;&#33021;&#20445;&#35657;&#30340;&#65292;&#36889;&#20063;&#26159;&#35373;&#35336; production data pipeline &#26178;&#65292;&#24517;&#38920;&#21516;&#26178;&#29702;&#35299; Spark&#12289;sink table format&#65292;&#20197;&#21450; orchestrator &#30340;&#21407;&#22240;&#12290;</p>]]></content:encoded></item><item><title><![CDATA[淺入淺出 TPU (上集）：為何 TPU 運算那麼便宜？]]></title><description><![CDATA[&#24478; AllReduce &#21040; 3D Torus &#35299;&#26512;]]></description><link>https://www.chillvic.dev/p/tpu-tpu</link><guid isPermaLink="false">https://www.chillvic.dev/p/tpu-tpu</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Tue, 02 Jun 2026 15:15:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!EKOi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>&#35347;&#32244;&#22823;&#22411; AI model &#26178;&#65292;&#21934;&#24373;&#26230;&#29255;&#36890;&#24120;&#19981;&#22816;&#65292;&#22240;&#28858;&#36039;&#26009;&#37327;&#36319;&#27169;&#22411;&#21443;&#25976;&#22826;&#22823;&#65292;&#21934;&#38982; TPU  memory &#26681;&#26412;&#35037;&#19981;&#19979;&#65292;&#22240;&#27492;&#35201;&#25226;&#22810;&#38982; TPU &#32068;&#25104; cluster &#19968;&#36215;&#36939;&#31639;&#12290;</p><p>&#20294; cluster &#19981;&#26159;&#25226;&#24456;&#22810;&#27231;&#22120;&#25918;&#22312;&#19968;&#36215;&#32780;&#24050;&#12290;</p><p>&#30070;&#22810;&#21488;&#27231;&#22120;&#36939;&#34892;&#26178;&#65292;&#39318;&#20808;&#35201;&#35299;&#27770;&#30340;&#21839;&#38988;&#26159;&#65306;&#27599;&#21488;&#27231;&#22120;&#31639;&#23436;&#33258;&#24049;&#30340;&#37096;&#20998;&#24460;&#65292;&#32080;&#26524;&#35201;&#24590;&#40636;&#21516;&#27493;&#65311;</p><p>&#22914;&#26524;&#21516;&#27493;&#25104;&#26412;&#22826;&#39640;&#65292;&#26230;&#29255;&#31639;&#24471;&#20877;&#24555;&#20063;&#27794;&#29992;&#65292;&#22240;&#28858;&#22823;&#37327;&#26178;&#38291;&#26371;&#21345;&#22312; network communication&#12290;</p><p>&#32780; TPU cluster &#20415;&#23452;&#30340;&#38364;&#37749;&#20043;&#19968;&#65292;&#26159;&#19981;&#21934;&#38752;&#26114;&#36020;&#32178;&#36335;&#35373;&#20633;&#30828;&#25744; bandwidth&#65292;&#32780;&#26159;&#36879;&#36942; collective algorithm &#33287; network topology &#35373;&#35336;&#65292;&#38477;&#20302;&#21516;&#27493;&#36039;&#26009;&#30340;&#25104;&#26412;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EKOi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EKOi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 424w, https://substackcdn.com/image/fetch/$s_!EKOi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 848w, https://substackcdn.com/image/fetch/$s_!EKOi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 1272w, https://substackcdn.com/image/fetch/$s_!EKOi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EKOi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png" width="1456" height="2170" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2170,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:7202795,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/200307161?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EKOi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 424w, https://substackcdn.com/image/fetch/$s_!EKOi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 848w, https://substackcdn.com/image/fetch/$s_!EKOi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 1272w, https://substackcdn.com/image/fetch/$s_!EKOi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6a2ca3f-c518-458f-bf78-65d78148d1d0_1696x2528.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h1>&#37027;&#40636; TPU cluster &#21040;&#24213;&#22312;&#21516;&#27493;&#20160;&#40636;&#65311;</h1><p>&#20998;&#25955;&#24335;&#36939;&#31639;&#30340;&#22522;&#26412;&#24819;&#27861;&#24456;&#31777;&#21934;&#65306;&#25226;&#19968;&#22376;&#36039;&#26009;&#20999;&#25104;&#24456;&#22810;&#23567;&#20998;&#21312;&#65292;&#20998;&#32102;&#19981;&#21516; machine &#36939;&#31639;&#12290;</p><p>&#20363;&#22914; AI training &#20013;&#65292;&#21487;&#25226; input &#20999;&#25104;&#22810;&#20221; batch shard&#65292;&#35731;&#19981;&#21516; TPU &#34389;&#29702;&#19981;&#21516; batch shard&#65292;&#27599;&#21488; machine &#31639;&#23436;&#33258;&#24049;&#30340;&#37096;&#20998;&#24460;&#65292;&#35201;&#25226;&#32080;&#26524;&#29992;&#26576;&#31278;&#26041;&#24335;&#21512;&#20341;&#65292;&#21542;&#21063;&#27599;&#21488; machine &#21482;&#30693;&#36947;&#33258;&#24049;&#30340;&#23616;&#37096;&#32080;&#26524;&#65292;&#25972;&#20491; cluster &#27794;&#26377;&#20849;&#21516;&#29376;&#24907;&#12290;</p><p>&#32780;&#35498;&#21040;&#20998;&#25955;&#24335;&#35336;&#31639;&#30340;&#36039;&#26009;&#21516;&#27493;&#65292;&#26368;&#30452;&#35258;&#26371;&#24819;&#21040;&#20998;&#25955;&#24335;&#36039;&#26009;&#35336;&#31639;&#30340; MapReduce&#12290;</p><h1>&#20160;&#40636;&#26159; MapReduce&#65311;AI &#38656;&#35201;&#30340;&#26159; MapReduce &#21966;&#65311; </h1><p>&#20808;&#29992; SQL &#24314;&#31435;&#30452;&#35258;&#12290;</p><p>&#20551;&#35373;&#25105;&#20497;&#35201;&#31639;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">select uid, sum(amount) from orders group by uid;</code></pre></div><p>&#30070; orders &#37327;&#24456;&#22823;&#26178;&#65292;MapReduce &#26371;&#20808;&#25226;&#36039;&#26009; partition &#20998;&#21040;&#19981;&#21516; machine &#20570;&#23616;&#37096;&#35336;&#31639;&#65292;&#27492;&#26178;&#27599;&#20491; machine &#26371;&#26377;&#19981;&#21516; <code>uid</code> &#30340;&#23616;&#37096; sum&#65292;&#25509;&#33879;&#36914;&#20837; shuffle &#12290;</p><p>shuffle &#30340;&#30446;&#30340;&#26159;&#35731;&#30456;&#21516; <code>uid</code> &#30340;&#36039;&#26009;&#34987;&#36865;&#21040;&#21516;&#19968;&#21488; reducer&#65292;&#26368;&#24460;&#27599;&#21488; reducer &#31639;&#20986;&#33258;&#24049;&#36000;&#36012; key &#30340;&#32080;&#26524;&#12290;</p><p>&#20363;&#22914;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:&quot;2a9692c3-b873-4179-adfa-c42401f8b146&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">sum | uid | machine
10  | 1   | 1
20  | 2   | 2
30  | 3   | 3</code></pre></div><p>&#20063;&#23601;&#26159;&#35498;&#65292;MapReduce &#20013;&#19981;&#21516; machine (reducer) &#21482;&#25345;&#26377;&#33258;&#24049;&#36000;&#36012; key &#30340;&#23436;&#25972;&#32080;&#26524;&#12290;</p><p>&#20294; AI &#19981;&#19968;&#27171;&#65292;&#20182;&#38656;&#35201; AllReduce&#65292;&#20063;&#23601;&#26159; reduce &#23436;&#24460;&#65292;&#36996;&#38656;&#35201; broadcast &#32080;&#26524;&#32102;&#22823;&#23478;&#35731;&#27599;&#21488; machine &#37117;&#26377;&#25152;&#26377; key &#30340;&#32858;&#21512;&#32080;&#26524;&#12290;</p><p>&#20063;&#23601;&#26159;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">sum       | uid     | machine
10,20,30  | 1,2,3   | 1
10,20,30  | 1,2,3   | 2
10,20,30  | 1,2,3   | 3</code></pre></div><p>&#22240;&#27492;&#21487;&#20197;&#20808;&#25226; AllReduce &#29702;&#35299;&#25104;&#65306;</p><p><strong>MapReduce + broadcast result to all machines</strong></p><h1>&#20294; AI training &#28858;&#20160;&#40636;&#38656;&#35201; All Reduce&#65311;</h1><p>AI model &#21487;&#20197;&#20808;&#31777;&#21270;&#25104;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">y = w1*x1+w2*x2+...+wN*xN = wTx</code></pre></div><p><code>x</code> &#26159; input&#65292; <code>w</code> &#26159;&#27169;&#22411;&#27402;&#37325;&#65292; <code>y</code> &#26159;&#27169;&#22411;&#36664;&#20986;&#65292;&#35347;&#32244;&#30446;&#27161;&#26159;&#35519;&#25972;  <code>w</code>&#65292;&#35731;&#27169;&#22411;&#36664;&#20986;&#30340;  <code>y</code>  &#36234;&#20358;&#36234;&#25509;&#36817;&#27491;&#30906;&#31572;&#26696;&#12290;</p><p>&#35519;&#25972;&#26041;&#24335;&#22823;&#33268;&#26159;&#65306;</p><p>1. &#36664;&#20837; <code>x</code>&#65292;&#31639;&#20986;&#38928;&#28204;&#20540; <code>y</code></p><p>2. &#29992; <code>loss function</code> &#31639;&#20986;&#38928;&#28204;&#20540;&#36319;&#27491;&#30906;&#31572;&#26696;&#30340;&#24046;&#36317;</p><p>3. &#36879;&#36942;&#24494;&#20998;&#35336;&#31639;&#27599;&#20491; <code>weight</code> &#23565; <code>loss</code> &#30340;&#24433;&#38911;&#31243;&#24230;&#65292;&#20063;&#23601;&#26159; <code>gradient</code></p><p>4. &#29992; <code>gradient</code> &#26356;&#26032; <code>weight</code>&#65292;&#35731;&#19979;&#19968;&#27425; <code>loss</code> &#35722;&#23567;</p><p>note:  &#31934;&#28310;&#22320;&#35498;&#65292;gradient &#26159;&#26576;&#20491; weight &#25913;&#35722;&#26178;&#65292;loss &#35722;&#21205;&#30340;&#31243;&#24230; (&#35722;&#22823;&#22810;&#23569;&#25110;&#35722;&#23567;&#22810;&#23569;&#65289;&#12290;</p><p>&#30070;&#35347;&#32244;&#30340; input data &#24456;&#22810;&#65292;&#26371;&#25226; input &#20999;&#25104;&#22810;&#20221; batch shard &#20998;&#32102;&#19981;&#21516; TPU&#65292;&#27599;&#21488; TPU &#37117;&#26377;&#30456;&#21516;&#30340; AI model&#65292;&#20294;&#34389;&#29702;&#19981;&#21516; batch shard&#65292;&#22240;&#27492;&#26371;&#31639;&#20986;&#19981;&#21516;&#30340; local gradient vector&#12290;</p><p>&#20363;&#22914;&#19977;&#21488; TPU &#21508;&#33258;&#31639;&#20986;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:&quot;fcb9f838-b516-4f8e-a5d5-3b854412825e&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">machine | w1_gradient | w2_gradient | w3_gradient
a       | 1           | 2           | 3
b       | 3           | 2           | 1
c       | 5           | 3           | 1</code></pre></div><p>&#22914;&#26524;&#27599;&#21488; TPU &#30452;&#25509;&#29992;&#33258;&#24049;&#30340; local gradient &#26356;&#26032; model&#65292;&#19977;&#21488; TPU &#30340; model &#24456;&#24555;&#23601;&#26371;&#35722;&#24471;&#19981;&#19968;&#27171;&#12290;</p><p>&#25152;&#20197;&#26356;&#26032; model &#21069;&#65292;&#38656;&#35201;&#25226;&#25152;&#26377; local gradient &#32858;&#21512;&#25104;&#19968;&#20221; global gradient vector&#65292;&#20006;&#35731;&#27599;&#21488; TPU &#37117;&#25343;&#21040;&#30456;&#21516;&#32080;&#26524;&#12290;</p><p>&#39006;&#20284;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:&quot;dae66083-7503-44c6-b29a-eff6f714e8e1&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">
select weight_id, avg(gradient_value)
from gradient_vectors
group by weight_id;</code></pre></div><p>&#24460; broadcast result to all machines&#12290;</p><p>&#20063;&#23601;&#26159;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:&quot;73cc0f34-96f0-4d32-ac6d-80eff7258b08&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">machine | w1_gradient_avg | w2_gradient_avg | w3_gradient_avg
a       | 3      | 2.33   | 1.67
b       | 3      | 2.33   | 1.67
c       | 3      | 2.33   | 1.67</code></pre></div><p>&#38568;&#24460;&#27599;&#21488; machine &#29992;&#30456;&#21516;&#30340; gradient vector &#26356;&#26032;&#21508;&#33258;&#30340; local model &#30906;&#20445;&#22823;&#23478; model &#19968;&#33268;&#12290;</p><h1>&#20294;&#22914;&#26524;&#27599;&#36650; training &#37117;&#35201;&#21516;&#27493; gradient&#65292;broadcast &#20570;&#27861;&#21487;&#34892;&#21966;&#65311;</h1><p>&#23526;&#29694; All Reduce &#26368;&#30452;&#35258;&#20316;&#27861;&#26159; all-to-all broadcast&#65306;</p><p>&#27599;&#21488; machine &#37117;&#25226;&#33258;&#24049;&#23436;&#25972; gradient vector &#20659;&#32102;&#20854;&#20182;&#25152;&#26377; machine&#65292;&#28982;&#24460;&#22312;&#25226;&#25910;&#21040;&#30340; vector &#21152;&#32317;&#25110;&#24179;&#22343;&#12290;</p><p>&#20551;&#35373;&#26377;  <code>n</code> &#21488; machine&#65292;&#27599;&#20221; gradient vector &#22823;&#23567;&#26159;  <code>D</code>&#12290;</p><p>&#37027;&#27599;&#21488; machine &#22823;&#32004;&#35201;&#25509;&#25910; <code>(n - 1) * D &#36039;&#26009;&#37327;&#65292;&#22914;&#26524; TPU &#25976;&#37327;&#35722;&#22823;&#65292;n &#26371;&#35722;&#22823;&#65292;&#22914;&#26524; model &#35722;&#22823;&#65292;gradient vector &#30340;&#22823;&#23567; D &#20063;&#26371;&#35722;&#22823;&#12290;</code></p><p>&#22240;&#27492; all-to-all &#24456;&#24555;&#23601;&#26371;&#35731; network bandwidth &#29190;&#28856;&#65292;&#25104;&#26412;&#35722;&#39640;&#65292;&#23588;&#20854;&#27599;&#36650; training &#37117;&#35201;&#20570;&#19968;&#27425;&#26178;&#65292;network communication &#26371;&#35722;&#25104;&#20027;&#35201;&#29942;&#38968;&#12290;</p><p>&#28858;&#20102;&#35299;&#27770;&#36889;&#20491;&#21839;&#38988;&#65292;&#38656;&#35201;&#25563;&#19968;&#31278; AllReduce algorithm -  Ring AllReduce&#12290;</p><h1>&#20160;&#40636;&#26159; Ring AllReduce&#65311;</h1><p>Ring AllReduce &#26159;&#19968;&#31278; collective communication algorithm&#12290;</p><p>collective communication &#25351;&#30340;&#26159;&#22810;&#20491; device &#21516;&#26178;&#36914;&#34892;&#21516;&#19968;&#39006;&#36890;&#35338;&#25805;&#20316;&#12290;</p><p>Ring AllReduce &#26371;&#25286;&#25104;&#20841;&#27493;&#65306;ReduceScatter + AllGather</p><p>&#20551;&#35373;&#26377;&#19977;&#21488; machine &#22312;&#29289;&#29702;&#23652;&#38754;&#29992;&#32178;&#32218;&#25490;&#25104;&#19968;&#20491; ring&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:&quot;ad506e43-7647-4ff2-8d4f-3f14a2aa516c&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">a -&gt; b -&gt; c -&gt; a</code></pre></div><p>&#19977;&#21488; machine &#21508;&#33258;&#31639;&#20986;&#33258;&#24049;&#30340; gradient vector&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:&quot;9fce67fe-9c63-41a9-8bfc-707134633775&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">      w1 w2 w3
a:   [1, 2, 3]
b:   [3, 2, 1]
c:   [5, 3, 1]</code></pre></div><p>ReduceScatter &#26371;&#20808;&#25226; gradient vector &#20999;&#25104; shard (e.g [w1, w2, w3] =&gt; [w1], [w2], [w3])&#65292;&#20006;&#23450;&#32681;&#27599;&#20491; shard &#26368;&#24460;&#30001;&#21738;&#21488; machine &#25345;&#26377; reduce &#32080;&#26524;&#12290;</p><p>&#20363;&#22914;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:&quot;0bca339f-fd08-44f5-8f8c-8f6e8fba449d&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">a &#36000;&#36012; w1
b &#36000;&#36012; w2
c &#36000;&#36012; w3</code></pre></div><p>&#25509;&#33879;&#25152;&#26377; machine &#26681;&#25818;&#30070;&#21069; network topology &amp; shard &#30340; final reducer&#65292;&#27770;&#23450;&#35201;&#25226;&#21738;&#20491; shard &#20659;&#32102;&#33258;&#24049;&#30340; neighbor&#65292;neighbor &#25910;&#21040;&#24460;&#26371;&#25226; shard &#21152;&#19978;&#33258;&#36523;&#32080;&#26524; (partial sum) &#24448;&#19979;&#19968;&#20491; neighbor &#20659;&#65292;&#20855;&#39636;&#37007;&#36655;&#65306;</p><ol><li><p>a &#20808;&#25214;&#20986;&#36317;&#38626; n-1 &#30340;&#31680;&#40670;&#26159; c&#65292;&#19988; c &#36000;&#36012; w3 &#30340; shard&#65292;&#37027; a &#26371;&#25226;&#20182;&#30340; w3 &#32080;&#26524;&#20659;&#32102;&#20182;&#30340;&#37168;&#23621; (b)</p></li><li><p>b &#25910;&#21040;&#24460;&#25226; a &#30340; w3 &#21152;&#19978;&#33258;&#24049;&#30340; w3 &#24460;&#20659;&#32102; c</p></li><li><p>&#26368;&#24460; c &#26371;&#25910;&#21040; a+b &#30340; w3&#65292;&#21152;&#19978;&#33258;&#24049;&#30340; w3 &#23601;&#33021;&#26371;&#24471;&#26368;&#32066; w3 &#32080;&#26524; (i.e 3+1+3=5)&#12290;</p></li></ol><p>&#32780; collective communication &#20195;&#34920; a &amp; b &amp; c &#21516;&#26178;&#26371;&#36879;&#36942;&#19978;&#38754;&#37007;&#36655;&#20659; shard &#32102;&#23565;&#25033;&#30340;&#37168;&#23621; :</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:&quot;c5d81c06-c25a-46af-a2cb-3c64b7b5c61a&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">first communication round:
a - w3(a) -&gt; b w3(a+b)
b - w1(b) -&gt; c w1(b+c)
c - w2(c) -&gt; a w3(c+a)

second communication round:
b - w3(a+b) -&gt; c w3(a+b+c)
c - w1(b+c) -&gt; a w1(b+c+a)
a - w2(c+a) -&gt; b w2(c+a+b)
</code></pre></div><p>ReduceScatter &#32080;&#26463;&#24460;&#65292;&#27599;&#21488; machine &#21482;&#25345;&#26377;&#33258;&#24049;&#36000;&#36012;&#30340; reduced shard&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:&quot;5e12c9fe-36f2-4503-9ed7-5403588b7a2b&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">a: w1(b+c+a) = 1 + 3 + 5 = 9
b: w2(c+a+b) = 2 + 2 + 3 = 7
c: w3(b+c+a) = 3 + 1 + 1 = 5</code></pre></div><p>&#25509;&#33879;&#36914;&#20837; AllGather&#65292;&#25226;&#27599;&#21488; machine &#25345;&#26377;&#30340; reduced shard &#20877;&#27839;&#33879; ring &#20659;&#32102;&#20854;&#20182;&#20154;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:&quot;6bb47556-efc8-47db-a553-d607e5168fa9&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">first communication round:
a - w1 -&gt; b
b - w2 -&gt; c
c - w3 -&gt; a

second communication round:
a - w3 -&gt; b
b - w1 -&gt; c
c - w2 -&gt; a</code></pre></div><p>&#26368;&#24460;&#27599;&#21488; machine &#37117;&#25343;&#21040;&#23436;&#25972;&#32080;&#26524;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:&quot;da9c8da3-1d76-4e5e-91be-85888aa1d25f&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">a: [9, 7, 5]
b: [9, 7, 5]
c: [9, 7, 5]</code></pre></div><p>Ring AllReduce &#30340;&#22909;&#34389;&#26159;&#65292;&#27599;&#21488; machine &#27599;&#36650;&#21482;&#20659; gradient vector &#30340;&#19968;&#20491; shard&#65292;&#32780;&#19981;&#26159;&#23436;&#25972; vector&#12290;</p><p>&#23565; <code>n</code> &#21488; machine&#12289;vector &#22823;&#23567; <code>D</code> &#20358;&#35498;&#65292;Ring AllReduce &#30340; per-machine traffic &#32004;<code>&#65306;<br>2 * (n-1) * (D/N)</code></p><p>&#30070; <code>n</code> &#24456;&#22823;&#26178;&#65292;&#36889;&#22823;&#32004;&#25509;&#36817; <code>2D</code>&#12290;</p><p>&#30456;&#27604; all-to-all &#30340; <code>(n - 1) * D</code>&#65292;Ring AllReduce &#22823;&#24133;&#38477;&#20302;&#20102;&#27599;&#21488; machine &#35201;&#34389;&#29702;&#30340;&#36039;&#26009;&#37327;&#65292;&#20294; Ring AllReduce &#36996;&#26159;&#26377;&#32570;&#40670;&#30340;&#65306;</p><p>&#33509;&#25152;&#26377; machine &#29992; single global ring &#20018;&#36899;&#65292;&#27599;&#20491; machine &#21482;&#26377;&#21069;&#24460;&#20841;&#20491; neighbor &#65292;&#23566;&#33268;&#36039;&#26009;&#21482;&#33021;&#27839;&#33879;&#22266;&#23450; ring &#20659;&#32102;&#19979;&#19968;&#20491; neighbor&#65292;machine &#25976;&#37327;&#36234;&#22810;&#65292;communication rounds &#36234;&#22810;&#12290;</p><p>&#25563;&#21477;&#35441;&#35498;&#65292;Ring AllReduce &#38477;&#20302;&#20102;&#20659;&#36664;&#37327;&#65292;&#20294;&#22914;&#26524; topology &#21482;&#26377;&#19968;&#26781;&#38263; ring&#65292;communication round &#25976;&#36996;&#26159;&#26371;&#38480;&#21046;&#25972;&#39636;&#25928;&#29575;&#12290;</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.chillvic.dev/subscribe?"><span>Subscribe now</span></a></p><h1>&#37027;&#40636; TPU &#24590;&#40636;&#35299;&#27770; communication round  &#25976;&#37327;&#21839;&#38988;&#65311;</h1><p>&#19981;&#29992; single global ring&#65292;TPU &#25505;&#29992;&#30340;&#26159; 2D / 3D torus&#12290;</p><p>&#20363;&#22914; 3D torus &#35731;&#27599;&#20491; machine &#21487;&#26377;&#19977;&#20491;  (x, y, z) &#19981;&#21516;&#26041;&#21521;&#30340;&#37168;&#23621;&#65292;&#32317;&#20849;6&#20491;&#37168;&#23621;&#65292;&#22240;&#27492;&#27599;&#27425; communication round &#21487;&#24448;&#22810;&#20491; neighbor &#20659;&#36958;&#35338;&#24687;&#12290;</p><p>&#25105;&#20497;&#20808;&#29992; 2D torus (x, y) &#28858;&#20363;&#65292;&#35264;&#23519;&#30070; neighbor &#35722;&#22810;&#26178;&#65292;communication round &#22914;&#20309;&#35722;&#23569;&#12290;</p><p>&#20551;&#35373;&#26377;&#22235;&#21488; machine&#65292;&#27599;&#20491; machine &#26377; (x, y) &#20841;&#20491;&#26041;&#21521;&#30340;&#37168;&#23621;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:&quot;9a042fbb-2bb6-4dc4-afae-cae9116225b5&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">a &#8212;&#8212; b  (X&#36600;&#21521;)
|    |
c &#8212;&#8212; d  (X&#36600;&#21521;)
(Y&#36600;&#21521;)</code></pre></div><p>note: &#19978;&#38754;&#24456;&#20687; 2D mesh &#20294;&#20854;&#23526;&#26159; 2D torus&#65292;&#24046;&#21029;&#22312; torus &#26159;&#19968;&#20491; ring&#65292;&#20063;&#23601;&#26159;&#35498;&#19978;&#38754;&#30340; a - b &#20854;&#23526;&#26159; a - b - a&#12290;</p><p>&#22312; single global ring &#20013;&#65292;&#27599;&#21488; machine &#27599;&#36650;&#36890;&#24120;&#21482;&#33021;&#27839;&#22266;&#23450;&#26041;&#21521;&#25226;&#36039;&#26009;&#25512;&#32102;&#19979;&#19968;&#20491; neighbor&#12290;</p><p>&#20294;&#22312; 2D torus &#20013;&#65292;machine &#21487;&#20197;&#27839; x &amp; y &#20841;&#20491;&#32173;&#24230;&#20659;&#36039;&#26009;&#65292;&#20551;&#35373; gradient vector &#38263;&#24230;&#26159;&#22235; &#19988; ReduceScatter &#36942;&#31243; a &#36000;&#36012; w1&#65292; b &#36000;&#36012; w2&#65292;c &#36000;&#36012; w3&#65292; d &#36000;&#36012; w4&#12290;</p><p>&#37027;&#40636; a &#35201;&#25910;&#38598;&#23436;&#25972;&#30340; w1 &#38656;&#35201;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">first communication round (X&#36600;&#20006;&#34892;)

b -&gt; w1(b) -&gt; a (a+b)

d -&gt; w1(d) -&gt; c (c+d)

second communication round (Y&#36600;&#20006;&#34892;)

c -&gt; w1(c+d) -&gt; a (a+b+d+c)</code></pre></div><p>&#20841;&#20491; communication round &#65292;a &#23601;&#33021;&#25910;&#38598;&#23436; w1&#65292;&#32780; single global ring &#38656;&#35201;&#19977;&#20491; &#12290;</p><p>note: &#19978;&#38754;&#21482;&#31034;&#31684; w1 &#30340;&#36335;&#24465;&#65307;&#23526;&#38555; ReduceScatter &#20013;&#65292;w2&#12289;w3&#12289;w4 &#20063;&#26371;&#21516;&#26178;&#27839;&#20854;&#20182; link &#20659;&#36958; partial sum&#12290;</p><p>&#32780; 3D torus &#25552;&#20379;&#26356;&#22810;&#32173;&#24230;&#30340;&#37168;&#23621;&#65292;collective algorithm &#21487;&#29992;&#26356;&#22810; parallel path &#20659;&#36958;&#36039;&#26009;&#65292;&#22312;&#22823;&#35215;&#27169; cluster &#20013;&#65292;&#36889;&#33021;&#26377;&#25928;&#28187;&#23569; communication round&#12290;</p><p>&#22240;&#27492; TPU cluster &#35722;&#20415;&#23452;&#30340;&#38364;&#37749;&#26159;&#19981;&#20381;&#38752;&#26114;&#36020;&#30340;&#32178;&#36335;&#35373;&#20633;&#30828;&#25744; bandwidth&#65292;&#32780;&#26159;&#36879;&#36942;&#65306;</p><ul><li><p> Ring AllReduce &#38477;&#20302;&#27599;&#21488; machine &#35201;&#20659;&#30340;&#36039;&#26009;&#37327;</p></li><li><p>2D / 3D torus &#25552;&#20379;&#26356;&#22810;&#32173;&#24230;&#37168;&#23621;&#65292;&#25552;&#39640; parallel &#20659;&#36664;&#37327;</p></li></ul><p>&#20294; topology &#21482;&#22238;&#31572; TPU chip &#20043;&#38291;&#24590;&#40636;&#36899;&#65292;&#30495;&#27491;&#22312; cluster &#19978;&#36939;&#31639;&#36996;&#38656;&#35201; compiler &amp; runtime&#12290;</p><h1>&#22914;&#20309;&#22312; TPU Cluster &#32178;&#36335;&#25299;&#27192;&#20013;&#36939;&#31639;&#36039;&#26009;&#65311;</h1><p>&#36889;&#35041;&#21487;&#29992; Hive &#39006;&#27604;&#65292;&#26089;&#26399;&#35201;&#29992; MapReduce &#23531;&#20998;&#25955;&#24335;&#36939;&#31639;&#65292;&#35201;&#33258;&#24049;&#23531; mapper &#21644; reducer&#12290;MapReduce runtime &#26371;&#25226;&#19981;&#21516; partition &#30340;&#36039;&#26009;&#20998;&#25955;&#21040;&#19981;&#21516; machine&#65292;&#22519;&#34892;&#20320;&#30340; mapper / reducer &#37007;&#36655;&#12290;</p><p>&#20294;&#22914;&#26524;&#35201;&#23531;&#35079;&#38620;&#26597;&#35426;&#65292;&#20363;&#22914;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:&quot;f97d55d2-caed-4673-b168-1c53ccf1e816&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">select uid, sum(amount)
from orders
join products on orders.pid = products.id
where products.name = 'XXX' 
group by uid;</code></pre></div><p>&#30452;&#25509;&#25163;&#23531; mapper &#21644; reducer &#26371;&#24456;&#40635;&#29033;&#65292;&#22240;&#27492; Hive &#25552;&#20379;&#19968;&#20491;&#26356;&#39640;&#23652;&#30340;&#20171;&#38754;&#65306;&#20351;&#29992;&#32773;&#23531; SQL&#65292;Hive &#25226; SQL compile &#25104; MapReduce stages&#12290;</p><p>TPU &#35347;&#32244;&#20063;&#26377;&#39006;&#20284;&#30340;&#25277;&#35937;&#23652;&#65292;&#20351;&#29992;&#32773;&#22312; TensorFlow &#25110; JAX &#20013;&#25776;&#23531;&#30340;&#26159;&#39640;&#38542; Tensor Computation&#65292;&#20363;&#22914; Forward Pass&#12289;Loss Computation&#12289;Backward Pass &#33287; Optimizer Update&#65292;&#20294; TPU &#30828;&#39636;&#26412;&#36523;&#21482;&#25903;&#25588;&#20302;&#38542;&#30340; Tensor Operations&#65292;&#20363;&#22914; Matrix Multiplication&#12289;Reduce&#12289;AllReduce&#12289;Load/Store Tensor &#31561;&#12290;</p><p>&#22240;&#27492;&#38656;&#35201; XLA &#20316;&#28858; Compiler&#65292;&#23559;&#39640;&#38542; Tensor Computation Graph &#36681;&#25563;&#25104; HLO&#65288;High Level Optimizer IR&#65289;&#65292;&#20006;&#26368;&#20339;&#21270;&#20006;&#29986;&#29983; TPU Executable Program&#65292;&#33287; Hive &#39006;&#20284;&#65292;XLA &#19981;&#21482;&#26159;&#20570;&#35486;&#27861;&#36681;&#25563;&#65292;&#36996;&#26371;&#36914;&#34892; Sharding&#12289;Operator Fusion&#12289;Device Placement&#12289;Collective Communication Planning &#31561;&#26368;&#20339;&#21270;&#12290;</p><p>&#20363;&#22914;&#65292;&#22312;&#20998;&#25955;&#24335; TPU &#35347;&#32244;&#20013;&#65292;XLA &#26371;&#26681;&#25818; device mesh &#21644; TPU  Network Topology &#36039;&#35338;&#23433;&#25490; Collective Operations&#65288;ReduceScatter&#12289;AllGather&#65289;&#22519;&#34892;&#26041;&#24335;&#12290;</p><p>&#22240;&#27492; TPU &#30340;&#35373;&#35336;&#26412;&#36074;&#19978;&#26159; Hardware&#12289;Network&#12289;Compiler &#19977;&#32773;&#20849;&#21516;&#35373;&#35336;&#65288;Co-design&#65289;&#30340;&#31995;&#32113;&#65292;&#32780;&#19981;&#21482;&#26159;&#21934;&#32020;&#30340;&#21152;&#36895;&#22120;&#30828;&#39636;&#12290;</p><h1>&#19979;&#38598;&#38928;&#21578;&#65306;&#28858;&#20309; TPU &#36939;&#31639;&#37027;&#40636;&#24555;&#65311;ICI &#33287; TPU Pod &#20839;&#37096;&#36039;&#26009;&#35299;&#26512;</h1><p>&#36889;&#31687;&#20808;&#22238;&#31572;&#12300;&#28858;&#20309; TPU &#36939;&#31639;&#37027;&#40636;&#20415;&#23452;&#12301;&#12290;</p><p>&#37325;&#40670;&#19981;&#26159;&#21934;&#38982; TPU chip &#31070;&#22855;&#22320;&#30465;&#37666;&#65292;&#32780;&#26159; TPU cluster &#36879;&#36942; Ring AllReduce&#12289;2D / 3D torus topology&#65292;&#20197;&#21450; XLA / runtime &#30340; collective schedule&#65292;&#38477;&#20302;&#27599;&#36650; training &#30340;&#32178;&#36335;&#21516;&#27493;&#25104;&#26412;&#12290;</p><p>&#20294;&#36889;&#31687;&#21482;&#35611;&#21040; topology &#21644; computation runtime&#65292;&#19979;&#19968;&#20491;&#21839;&#38988;&#26159;&#65306;&#36039;&#26009;&#22312; TPU Pod &#35041;&#20132;&#25563;&#26178;&#65292;&#35201;&#22914;&#20309;&#38477;&#20302; Pod &#25910;&#21040;&#36039;&#26009;&#30340;&#24310;&#36978;&#65311;</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Chill Vic&#8217;s Architecture Notes! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[How to Build a High-Performance TCP Server Part 2 – Is io_uring Always Faster Than epoll? A Deep Dive into System Internals.]]></title><description><![CDATA[From syscall overhead to shared memory queues: understanding the next evolution of Linux I/O]]></description><link>https://www.chillvic.dev/p/how-to-build-a-high-performance-tcp-0c1</link><guid isPermaLink="false">https://www.chillvic.dev/p/how-to-build-a-high-performance-tcp-0c1</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Fri, 27 Mar 2026 05:20:35 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!-qnL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a href="https://chillvic.substack.com/p/tcp-server-ep1-server">As mentioned in the previous episode</a>, Nginx, Redis, and Rust&#8217;s Tokio all utilize non-blocking I/O combined with <code>epoll</code> to develop high-efficiency TCP servers. However, <code>epoll</code> has its drawbacks: when <code>epoll_wait</code> returns a ready connection, you still need to perform additional <code>read</code> or <code>write</code> system calls to move data. With high concurrency, the context switching between user space and kernel space significantly impacts performance.</p><p><code>io_uring</code> is the kernel mechanism designed to solve this. <strong>But how do we read and write data without executing </strong><code>read</code><strong> &amp; </strong><code>write</code><strong> system calls?</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-qnL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-qnL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!-qnL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!-qnL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!-qnL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-qnL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png" width="1024" height="1536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1536,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-qnL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!-qnL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!-qnL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!-qnL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>How to read/write without read &amp; write system calls?</h1><p>When using <code>io_uring</code>, the kernel establishes two queues:</p><ol><li><p><strong>Submission Queue (SQ)</strong>: The user-space process places I/O operation requests (e.g., read, write) into this queue for the kernel to consume.</p></li><li><p><strong>Completion Queue (CQ)</strong>: The kernel places I/O completion notifications into this queue for the user-space process to consume.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cRjA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cRjA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 424w, https://substackcdn.com/image/fetch/$s_!cRjA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 848w, https://substackcdn.com/image/fetch/$s_!cRjA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 1272w, https://substackcdn.com/image/fetch/$s_!cRjA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cRjA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png" width="599" height="373" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:373,&quot;width&quot;:599,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;io_uring &#129425; Explained - Unzip.dev&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="io_uring &#129425; Explained - Unzip.dev" title="io_uring &#129425; Explained - Unzip.dev" srcset="https://substackcdn.com/image/fetch/$s_!cRjA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 424w, https://substackcdn.com/image/fetch/$s_!cRjA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 848w, https://substackcdn.com/image/fetch/$s_!cRjA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 1272w, https://substackcdn.com/image/fetch/$s_!cRjA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Because of this, even blocking I/O becomes asynchronous with <code>io_uring</code>. Operations are encapsulated into entries placed in the SQ, and results are retrieved by consuming CQ entries. An entry contains these primary fields:</p><ul><li><p><strong>fd</strong>: The I/O object (e.g., TCP connection) ID in the kernel.</p></li><li><p><strong>opcode</strong>: An enum for the entry type (e.g., read, write, or accept).</p></li><li><p><strong>data pointer</strong>: A memory pointer where the kernel reads/writes data. Usually, a byte array is initialized in user space and its pointer is passed.</p></li><li><p><strong>user_data</strong>: An identifier for the entry.</p></li></ul><p>When a user-space process receives a &#8220;read complete&#8221; entry from the CQ, it needs to know which byte array to read from. Thus, the <code>user_data</code> in the CQ entry matches the SQ entry. For example, you can cast the pointer of the byte array into an <code>int</code> and store it in <code>user_data</code>:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">// Create SQE (SQ entry)
struct request *req = malloc(sizeof(*req));                                          
sqe-&gt;opcode    = IORING_OP_READ;              
sqe-&gt;fd        = req-&gt;fd;                                                             
sqe-&gt;addr      = (uint64_t)req-&gt;buf;
sqe-&gt;user_data = (uint64_t)req;

// Receive CQE (CQ entry), use user_data to restore the request buffer
struct request *req = (struct request *)cqe-&gt;user_data;</code></pre></div><h1>Does sending entries to SQ &amp; CQ require system calls?</h1><p>While SQ and CQ are kernel objects, the kernel uses <code>mmap</code> to map them into user space, <strong>allowing user-space processes to access them directly without going through system calls.</strong> To explain <code>mmap</code>, we must first mention <strong>Virtual Memory Space</strong>:</p><h3><strong>Virtual Memory Space</strong> </h3><p>Every user-space process has its own <strong>page table</strong> that records accessible memory addresses (e.g., 0x000 ~ 0x3FF represents 1KB). However, these page table addresses are not physical memory locations. The kernel uses a mapping mechanism to map virtual memory addresses to physical ones&#8212;this is <strong>Virtual Memory Mapping</strong> technology.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!btKx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!btKx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 424w, https://substackcdn.com/image/fetch/$s_!btKx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 848w, https://substackcdn.com/image/fetch/$s_!btKx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!btKx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!btKx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg" width="715" height="488" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:488,&quot;width&quot;:715,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;How does the virtual memory map into the RAM?&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="How does the virtual memory map into the RAM?" title="How does the virtual memory map into the RAM?" srcset="https://substackcdn.com/image/fetch/$s_!btKx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 424w, https://substackcdn.com/image/fetch/$s_!btKx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 848w, https://substackcdn.com/image/fetch/$s_!btKx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!btKx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>Page Fault &amp; mmap</strong> </h3><p>The benefit of using Virtual Memory is that when a process executes <code>malloc(1G)</code>, it doesn&#8217;t need 1GB of RAM immediately. Instead, it simply records in the page table that the range 0x00000000 ~ 0x3FFFFFFF is accessible. When the CPU reads a virtual memory address and finds no corresponding physical memory, it triggers a <strong>Page Fault</strong>. Subsequently, the kernel allocates resources and establishes a link based on the actual size used (the minimum unit being 4KB)&#8212;essentially a <strong>lazy load</strong> technique.</p><p>The <code>mmap</code> technique allows a Page Fault to read data from a specified physical memory and establish a link. For instance, by mapping the process&#8217;s virtual memory space 0x000 ~ 0x3FF to the <code>io_uring</code> queue in kernel memory, a CPU read of 0x000 ~ 0x3FF that triggers a Page Fault will directly read the physical memory location of the kernel <code>io_uring</code> queue, rather than being allocated random blank physical memory. </p><p>Consequently, the process can directly access the kernel <code>io_uring</code> queue and send or read entries without through system calls.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Chill Vic&#8217;s Architecture Notes! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>Is there overhead in using queues?</h1><p>Using a doubly linked list as a queue requires locking to handle concurrent push and pop operations safely. <code>io_uring</code> uses a <strong>Ring Buffer</strong> with a fixed-size array and two atomic indices (head and tail) to achieve <strong>lock-less</strong> operations:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!As7t!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!As7t!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 424w, https://substackcdn.com/image/fetch/$s_!As7t!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 848w, https://substackcdn.com/image/fetch/$s_!As7t!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!As7t!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!As7t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg" width="512" height="418" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:418,&quot;width&quot;:512,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Back To Basics: The Ring Buffer &#8211; ShaneKirk.com&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Back To Basics: The Ring Buffer &#8211; ShaneKirk.com" title="Back To Basics: The Ring Buffer &#8211; ShaneKirk.com" srcset="https://substackcdn.com/image/fetch/$s_!As7t!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 424w, https://substackcdn.com/image/fetch/$s_!As7t!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 848w, https://substackcdn.com/image/fetch/$s_!As7t!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!As7t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Example Implementation (Rust):</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">use std::sync::atomic::{AtomicU64, Ordering};                                         
const SIZE: usize = 8; // Must be a power of 2

struct RingBuffer {                                                                                         
    buf: [i64; SIZE],                                                                                      
    head: AtomicU64, // Consumer index                                                                         
    tail: AtomicU64, // Producer index
}                                                                                                           
                                                                                                             
impl RingBuffer {
    fn new() -&gt; Self {
        RingBuffer {                                                                                        
            buf: [0; SIZE],
            head: AtomicU64::new(0),                                                                        
            tail: AtomicU64::new(0),                                                                       
        }
    }

    // Producer side                                                                                          
    fn push(&amp;mut self, val: i64) -&gt; bool {
        let tail = self.tail.load(Ordering::Acquire);                                                       
        let head = self.head.load(Ordering::Acquire);                                                      
                                                                                                            
        if tail - head == SIZE as u64 {
            return false; // Full                                                                           
        }                                                                                                  

        self.buf[(tail &amp; (SIZE as u64 - 1)) as usize] = val;                                                
        self.tail.store(tail + 1, Ordering::Release);
        true                                                                                                
    }                                                                                                      

    // Consumer side
    fn pop(&amp;mut self) -&gt; Option&lt;i64&gt; {
        let head = self.head.load(Ordering::Acquire);
        let tail = self.tail.load(Ordering::Acquire);                                                       
 
        if head == tail {                                                                                   
            return None; // Empty                                                                           
        }

        let val = self.buf[(head &amp; (SIZE as u64 - 1)) as usize];                                            
        self.head.store(head + 1, Ordering::Release);
        Some(val)                                                                                           
    }                                                                                                      
}</code></pre></div><p>Furthermore, arrays are contiguous. For the CPU, a single cache access can fetch the entire structure. Conversely, linked list nodes might be scattered, causing multiple cache misses.</p><h1>Besides queue optimization, what other performance boosts does io_uring offer?</h1><p>Although <code>read</code> &amp; <code>write</code> system calls are gone, <code>io_uring</code> still needs other calls, like <code>io_uring_enter</code> to notify the kernel to process tasks. However, this is still more efficient than <code>epoll</code>:</p><ul><li><p><strong>epoll</strong>: <code>epoll_wait</code> + <code>read</code>/<code>write</code> system calls.</p></li><li><p><strong>io_uring</strong>: <code>io_uring_enter</code> triggers the kernel and waits for CQ entries.</p></li></ul><h3><strong>SQPOLL Mode for Zero I/O System Calls</strong></h3><p>To achieve zero I/O system calls, <code>io_uring</code> supports the <strong>SQPOLL</strong> mode. In this mode, the kernel uses an additional kernel thread to continuously poll the SQ. The user-space process does not need to execute <code>io_uring_enter</code>; it only needs to continuously poll the CQ. The downside is that if there is no data in the CQ, the process will perform many "useless" pulls. Therefore, SQPOLL is suitable for high-intensity, low-latency request scenarios.</p><h3><strong>IOPOLL Mode for Hardware Interrupt Optimization</strong></h3><p>The second optimization concerns hardware interrupts. io_uring still relies on hardware interrupts to signal completion, after which the kernel places the I/O results into the CQ. </p><p>However, hardware interrupts are not free. When the CPU receives an interrupt, it must first execute the interrupt handler. In addition to pausing the current instruction, it also flushes subsequent instructions in the pipeline. After handling the interrupt, execution resumes from the interrupted instruction address, and the following instructions are decoded and refilled into the pipeline.<br><br>If a large number of interrupts arrive in a short period, the CPU repeatedly flushing its pipeline becomes costly. To mitigate this, the kernel uses NAPI to handle network packet interrupts. After receiving the first interrupt, it switches to a polling mode, draining packets from the NIC in batches to avoid a burst of interrupts triggered by incoming traffic.</p><p>However, NAPI is primarily designed for network packet processing. When io_uring is used for file I/O (e.g., databases), a surge of read operations can still generate a large number of interrupts. To address this, io_uring provides the IO_POLL mode, which bypasses interrupts entirely and continuously polls the device for completion events.</p><h1>Real-world Application: PostgreSQL 18</h1><p>Databases perform frequent File I/O. PostgreSQL 18 introduced an async I/O mechanism with two modes:</p><ul><li><p><strong>worker (default)</strong>: Delegates <code>read()</code>/<code>write()</code> to another process. Boosts read-heavy query performance by ~1.5x.</p></li><li><p><strong>io_uring</strong>: Uses <code>io_uring</code> for I/O. Boosts read-heavy performance by <strong>~2.7x</strong>.</p></li></ul><p><em>Note: Since </em><code>io_uring</code><em> is asynchronous, PG warns that </em><code>EXPLAIN ANALYZE</code><em> for I/O timing may become less accurate.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YXgp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YXgp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 424w, https://substackcdn.com/image/fetch/$s_!YXgp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 848w, https://substackcdn.com/image/fetch/$s_!YXgp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 1272w, https://substackcdn.com/image/fetch/$s_!YXgp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YXgp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png" width="1400" height="714" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:714,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;PostgreSQL Async-IO using io_uring | by Sudheer Gajula | Medium&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="PostgreSQL Async-IO using io_uring | by Sudheer Gajula | Medium" title="PostgreSQL Async-IO using io_uring | by Sudheer Gajula | Medium" srcset="https://substackcdn.com/image/fetch/$s_!YXgp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 424w, https://substackcdn.com/image/fetch/$s_!YXgp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 848w, https://substackcdn.com/image/fetch/$s_!YXgp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 1272w, https://substackcdn.com/image/fetch/$s_!YXgp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>ref: https://pganalyze.com/blog/postgres-18-async-io</p><h1>epoll vs. io_uring benchmark - monoio vs. tokio</h1><p>In Rust, the <code>Future</code> abstraction allows swapping runtimes easily. You can refer to the <a href="https://chillvic.substack.com/p/tcp-server-ep1-server">previous article</a> for an introduction to the <code>Future</code> abstraction. <code>monoio</code> is built on <code>io_uring</code>, and its TCP echo server code looks nearly identical to <code>tokio</code>:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">use monoio::{
    io::{AsyncReadRent, AsyncWriteRentExt},
    net::{TcpListener, TcpStream},
};

#[monoio::main(driver = "fusion")]
async fn main() {
    // tracing_subscriber::fmt().with_max_level(tracing::Level::TRACE).init();
    let listener = TcpListener::bind("127.0.0.1:50002").unwrap();
    println!("listening");
    loop {
        let incoming = listener.accept().await;
        match incoming {
            Ok((stream, addr)) =&gt; {
                println!("accepted a connection from {addr}");
                monoio::spawn(echo(stream));
            }
            Err(e) =&gt; {
                println!("accepted connection failed: {e}");
                return;
            }
        }
    }
}

async fn echo(mut stream: TcpStream) -&gt; std::io::Result&lt;()&gt; {
    let mut buf: Vec&lt;u8&gt; = Vec::with_capacity(8 * 1024);
    let mut res;
    loop {
        // read
        (res, buf) = stream.read(buf).await;
        if res? == 0 {
            return Ok(());
        }

        // write all
        (res, buf) = stream.write_all(buf).await;
        res?;

        // clear
        buf.clear();
    }
}
</code></pre></div><p>To evaluate the performance of io_uring and epoll, I built a project called <em><a href="https://github.com/vx416/play_iouring">play_iouring</a></em>, using the monoio and tokio libraries for benchmarking:</p><ul><li><p><strong>TCP echo server</strong>: tested with 10, 100, and 1000 concurrent TCP clients</p></li><li><p><strong>File I/O</strong>: concurrent read/write on 100 files, each with 64 KB per operation</p></li></ul><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">### File I/O (100 files, 64 KiB each)

| Benchmark | monoio | tokio | &#916; |

|---------------|------------|------------|----------------|
| Write (100 files) | ~1.32 ms | ~1.95 ms | monoio ~1.5x faster |
| Read (100 files) | ~693 &#181;s | ~1.87 ms | monoio ~2.7x faster |

  
### TCP Echo

| Benchmark | monoio | tokio | &#916; |
|--------------------|------------|------------|----------|
| 10 clients | ~4.12 ms | ~3.98 ms | ~equal |
| 100 clients | ~26.6 ms | ~27.1 ms | ~equal |
| 1000 clients | ~292 ms | ~330 ms | monoio slightly faster |</code></pre></div><p>File I/O shows a significant improvement. The reason is that Tokio does not use epoll to manage file I/O; instead, it relies on <a href="https://docs.rs/tokio/latest/tokio/fs/index.html">worker threads with blocking I/O</a>. In contrast, Monoio uses io_uring for file operations, which substantially reduces system call overhead. Therefore, file I/O is not a valid comparison between epoll and io_uring.</p><p>For the TCP echo workload, performance is nearly identical. The primary advantage of io_uring lies in reducing system calls, but in the lifecycle of packet read/write, system calls are not the dominant cost. The bottleneck is the kernel&#8217;s network stack (e.g., packet parsing, firewall rules, etc.). With only 1000 concurrent clients, the system call overhead is not significant enough to create a noticeable difference.</p><p>Moreover, under single-machine testing with a large number of concurrent clients, limited CPU cores can skew the results. Therefore, this benchmark mainly demonstrates that epoll and io_uring deliver comparable performance under typical conditions.</p>]]></content:encoded></item><item><title><![CDATA[如何打造高效 TCP Server 下集 - io_uring：為什麼 epoll 還不夠快？]]></title><description><![CDATA[&#24478; syscall &#38283;&#37559;&#21040; shared memory queue&#65292;&#29702;&#35299; Linux I/O &#30340;&#19979;&#19968;&#20491;&#28436;&#36914;]]></description><link>https://www.chillvic.dev/p/tcp-server-ep2-io_uring-epoll</link><guid isPermaLink="false">https://www.chillvic.dev/p/tcp-server-ep2-io_uring-epoll</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Thu, 26 Mar 2026 14:45:15 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!-qnL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a href="https://chillvic.substack.com/p/tcp-server-ep1-server">&#19978;&#38598;&#25552;&#21040;</a>&#65292;Nginx, Redis &amp; Rust tokio &#37117;&#29992; non-blocking I/O &#32080;&#21512; epoll &#38283;&#30332;&#39640;&#25928;&#30340; tcp server (e.g cache server or http server)&#65292;&#20294; epoll &#26377;&#20854;&#32570;&#40670;&#65292;&#30070; epoll_wait &#22238;&#20659;&#21487;&#35712;&#23531;&#30340;&#36899;&#32218;&#26178;&#65292;&#35712;&#23531;&#36039;&#26009;&#20173;&#35201;&#38989;&#22806;&#21628;&#21483; read or write system call&#65292;&#36899;&#32218;&#22810;&#25110;&#35712;&#23531;&#38971;&#32321;&#26178;&#65292;&#36889;&#20123; system call &#22312; user space &#33287; kernel space &#20043;&#38291;&#20999;&#25563;&#30340;&#26178;&#38291;&#26371;&#39023;&#33879;&#24433;&#38911;&#25928;&#33021;&#12290;<br><br>&#32780; io_uring &#23601;&#26159;&#35299;&#27770; epoll &#36889;&#20491;&#21839;&#38988;&#30340;&#21478;&#19968;&#20491; kernel &#27231;&#21046;&#65292;<strong>&#20294;&#19981;&#22519;&#34892; read &amp; write system call &#35201;&#22914;&#20309;&#35712;&#23531;&#36039;&#26009;&#65311;</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-qnL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-qnL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!-qnL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!-qnL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!-qnL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-qnL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png" width="1024" height="1536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1536,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3120212,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/192211419?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-qnL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!-qnL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!-qnL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!-qnL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974a7560-ce34-4fd0-a6cb-bc88e524e8e4_1024x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>&#19981;&#22519;&#34892; read &amp; write system call &#35201;&#22914;&#20309;&#35712;&#23531;&#36039;&#26009;&#65311;</h1><p>&#20351;&#29992; io_uring &#26178;&#65292;kernel &#26371;&#24314;&#31435;&#20841;&#20491; queue&#65306;</p><ul><li><p><strong>Submission Queue (SQ) :</strong> user space process &#23559; I/O &#25805;&#20316; (e.g read, write) &#35531;&#27714;&#25918;&#36914;&#35442; queue &#30001; kernel process &#28040;&#36027;</p></li><li><p><strong>Completion Queue (CQ)&#65306;</strong>kernel process &#23559; I/O &#23436;&#25104;&#36890;&#30693;&#25918;&#20837;&#35442; queue &#30001; user space process &#28040;&#36027;</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cRjA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cRjA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 424w, https://substackcdn.com/image/fetch/$s_!cRjA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 848w, https://substackcdn.com/image/fetch/$s_!cRjA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 1272w, https://substackcdn.com/image/fetch/$s_!cRjA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cRjA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png" width="599" height="373" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:373,&quot;width&quot;:599,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;io_uring &#129425; Explained - Unzip.dev&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="io_uring &#129425; Explained - Unzip.dev" title="io_uring &#129425; Explained - Unzip.dev" srcset="https://substackcdn.com/image/fetch/$s_!cRjA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 424w, https://substackcdn.com/image/fetch/$s_!cRjA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 848w, https://substackcdn.com/image/fetch/$s_!cRjA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 1272w, https://substackcdn.com/image/fetch/$s_!cRjA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa991e713-48d5-4af9-adbc-c28121e50d1d_599x373.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>&#22240;&#27492;&#21363;&#20415;&#26159; blocking I/O &#29992; io_uring &#35712;&#23531;&#20173;&#26159;&#38750;&#21516;&#27493;&#30340;&#65292;&#35712;&#23531;&#25805;&#20316;&#26371;&#34987;&#23553;&#35037;&#25104; entry &#25918;&#36914; SQ &#20013;&#65292;&#36879;&#36942;&#28040;&#36027; CQ entry &#25343;&#21040;&#35712;&#23531;&#32080;&#26524;&#65292;&#35442; entry &#32080;&#27083;&#26377;&#20197;&#19979;&#20027;&#35201; field :</p><ul><li><p>fd (file descriptor) :  I/O object (e.g tpc &#36899;&#32218;) &#22312; kernel &#20013;&#30340; id</p></li><li><p>opcode : &#19981;&#21516; entry &#39006;&#22411;&#30340; enum (e.g read, write or accept)</p></li><li><p>data pointer : kernel &#35712;&#23531;&#36039;&#26009;&#30340;&#35352;&#25014;&#39636;&#25351;&#27161;&#65292;&#36890;&#24120;&#26371;&#22312; user space &#21021;&#22987;&#21270; bytes array &#20006;&#20659;&#35442;&#38499;&#21015;&#25351;&#27161;</p></li><li><p>user_data : &#35442; entry &#30340;&#35672;&#21029;&#34399;</p></li></ul><p>user space process  &#24478; CQ &#25910;&#21040;&#19968;&#20491; read &#23436;&#25104;&#30340; entry &#26178;&#65292;&#38656;&#30693;&#36947;&#21435;&#21738;&#20491; bytes array &#35712;&#36039;&#26009;&#65292;&#22240;&#27492; CQ entry &#20013;&#30340; user_data &#26371;&#36319; SQ entry &#21305;&#37197;&#65292;&#33021;&#24478; user_data &#35672;&#21029;&#34399;&#20013;&#25214;&#21040;&#23565;&#25033;&#30340; bytes array&#65292;&#20363;&#22914;&#25226; bytes array &#30340;&#25351;&#27161;&#35722;&#25104; int &#25918;&#20837; user_data &#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;c&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-c"># &#24314;&#31435; SQE (SQ entry)
struct request *req = malloc(sizeof(*req));                                          
sqe-&gt;opcode    = IORING_OP_READ;              
sqe-&gt;fd        = req-&gt;fd;                                                             
sqe-&gt;addr      = (uint64_t)req-&gt;buf;
sqe-&gt;user_data = (uint64_t)req;

# &#25910;&#21040; CQE (CQ entry)&#65292;&#30452;&#25509;&#29992; user_data &#36996;&#21407; request bytes array &#36039;&#26009;
struct request *req = (struct request *)cqe-&gt;user_data;  </code></pre></div><h1>&#24448; SQ &amp; CQ &#36865; entry &#19981;&#29992; system call &#21966;&#65311;</h1><p>&#38614;&#28982; SQ &amp; CQ &#26159; kernel &#35041;&#30340;&#29289;&#20214;&#65292;&#20294; kernel &#36879;&#36942; mmap system call &#23559; kernel &#30340;&#35352;&#25014;&#39636;&#29289;&#20214;&#33287; user space &#30340;&#35352;&#25014;&#39636;&#29289;&#20214;&#24314;&#31435;&#38364;&#32879;&#65292;&#35201;&#31777;&#21934;&#35498;&#26126; mmap &#25216;&#34899;&#65292;&#39318;&#20808;&#35201;&#25552;&#21040; <strong>virtual memory space</strong> &#27010;&#24565;&#65306;</p><h3>virtual memory space</h3><p>&#27599;&#20491; user space process &#26371;&#26377;&#21508;&#33258;&#30340; page table &#32000;&#37636;&#21487;&#23384;&#21462;&#30340;&#35352;&#25014;&#39636;&#20301;&#32622;&#65292;&#20363;&#22914; 0x000 ~ 0x3FF &#20195;&#34920; 1KB&#65292;&#20294; page table &#35352;&#25014;&#39636;&#20301;&#32622;&#19981;&#26159;&#23526;&#39636;&#35352;&#25014;&#39636;&#20301;&#32622;&#65292;kernel &#26371;&#38989;&#22806;&#36879;&#36942; mapping &#27231;&#21046;&#65292;&#23559; page table &#30340;&#34395;&#25836;&#35352;&#25014;&#39636;&#20301;&#32622;&#26144;&#23556;&#25104;&#23526;&#39636;&#35352;&#25014;&#39636;&#20301;&#32622;&#65292;&#20063;&#23601;&#26159; Virtual Memory Mapping &#25216;&#34899;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!btKx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!btKx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 424w, https://substackcdn.com/image/fetch/$s_!btKx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 848w, https://substackcdn.com/image/fetch/$s_!btKx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!btKx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!btKx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg" width="715" height="488" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:488,&quot;width&quot;:715,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;How does the virtual memory map into the RAM?&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="How does the virtual memory map into the RAM?" title="How does the virtual memory map into the RAM?" srcset="https://substackcdn.com/image/fetch/$s_!btKx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 424w, https://substackcdn.com/image/fetch/$s_!btKx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 848w, https://substackcdn.com/image/fetch/$s_!btKx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!btKx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816d5d0d-527b-452e-98a8-4b12317334ee_715x488.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Page Fault &amp; mmap &#25216;&#34899;</h3><p>&#20351;&#29992; Virtual Memory &#22909;&#34389;&#26159;&#65292;&#30070; process &#22519;&#34892; malloc(1G) &#26178;&#65292;&#19981;&#29992;&#39340;&#19978;&#32102; 1G &#30340; RAM&#65292;&#32780;&#26159;&#20808;&#22312; page table &#32000;&#37636; 0x00000000 ~ 0x3FFFFFFF &#31684;&#22285;&#37117;&#21487;&#23384;&#21462;&#65292;&#30070; CPU &#35712;&#21462; virtual memory &#30340;&#35352;&#25014;&#39636;&#20301;&#32622;&#65292;&#30332;&#29694;&#27794;&#26377;&#23565;&#25033;&#30340;&#23526;&#39636;&#35352;&#25014;&#39636;&#26178;&#26371;&#35320;&#30332; page fault&#65292;&#38568;&#24460;&#20381;&#29031;&#23526;&#38555;&#29992;&#21040;&#30340;&#22823;&#23567; (&#26368;&#23567;&#21934;&#20301;&#28858; 4Kb ) &#21435;&#21521;&#23526;&#39636;&#35352;&#25014;&#39636;&#25343;&#36039;&#28304;&#20006;&#24314;&#31435;&#38364;&#32879;&#65292;&#30456;&#30070;&#26044; lazy load &#25216;&#34899;&#12290;</p><p>&#32780; mmap &#25216;&#34899;&#22312; page fault &#26178;&#21487;&#24478;&#25351;&#23450;&#30340;&#23526;&#39636;&#35352;&#25014;&#39636;&#35712;&#36039;&#26009;&#20006;&#24314;&#31435;&#38364;&#32879;&#65292;&#20363;&#22914;&#23559; process &#30340; virtual memory space 0x000 ~ 0x3FF &#33287; kernel &#35352;&#25014;&#39636;&#20013; io_uring &#30340; queue &#24314;&#31435;&#38364;&#32879;&#65292;CPU &#35712;&#21462; 0x000 ~ 0x3FF &#35320;&#30332; page fault &#26371;&#30452;&#25509;&#35712; kernel io_uring queue &#30340;&#23526;&#39636;&#35352;&#25014;&#39636;&#20301;&#32622;&#65292;&#32780;&#19981;&#26159;&#38568;&#27231;&#20998;&#37197;&#31354;&#30333;&#30340;&#23526;&#39636;&#35352;&#25014;&#39636;&#65292;&#22240;&#27492;&#35442; process &#21487;&#30452;&#25509;&#23384;&#21462;&#21040; kernel io_uring &#30340; queue&#65292;&#19981;&#38656;&#36879;&#36942; system call &#23601;&#33021;&#24448; queue &#36865; entry &#25110;&#35712; entry&#12290;</p><h1>&#20351;&#29992; queue &#19981;&#26371;&#26377;&#38989;&#22806;&#30340;&#25928;&#33021;&#28040;&#32791;&#21966;&#65311;</h1><p>&#20351;&#29992; double linked list &#32080;&#27083;&#30340; queue &#21516;&#26178; push &amp; pop &#38656;&#35201;&#19978;&#37782;&#65292;&#32780; io_uring &#20351;&#29992; ring buffer &#36879;&#36942;&#22266;&#23450;&#22823;&#23567;&#38499;&#21015;&#21152;&#20841;&#20491; atomic value &#30340;&#35712;&#23531; index &#23526;&#29694;&#28961;&#37782;&#30340; push &amp; pop : </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!As7t!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!As7t!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 424w, https://substackcdn.com/image/fetch/$s_!As7t!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 848w, https://substackcdn.com/image/fetch/$s_!As7t!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!As7t!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!As7t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg" width="512" height="418" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:418,&quot;width&quot;:512,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Back To Basics: The Ring Buffer &#8211; ShaneKirk.com&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Back To Basics: The Ring Buffer &#8211; ShaneKirk.com" title="Back To Basics: The Ring Buffer &#8211; ShaneKirk.com" srcset="https://substackcdn.com/image/fetch/$s_!As7t!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 424w, https://substackcdn.com/image/fetch/$s_!As7t!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 848w, https://substackcdn.com/image/fetch/$s_!As7t!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!As7t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996f0ae0-3c77-490d-9991-9e027c8259d2_512x418.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>&#31684;&#20363;&#31243;&#24335;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">use std::sync::atomic::{AtomicU64, Ordering};                                         
const SIZE: usize = 8; // &#24517;&#38920;&#26159; 2 &#30340;&#20906;                                                 

struct RingBuffer {                                                                                         
      buf: [i64; SIZE],                                                                                      
      head: AtomicU64, // consumer &#23531;                                                                         
      tail: AtomicU64, // producer &#23531;
  }                                                                                                           
                                                                                                             
  impl RingBuffer {
      fn new() -&gt; Self {
          RingBuffer {                                                                                        
              buf: [0; SIZE],
              head: AtomicU64::new(0),                                                                        
              tail: AtomicU64::new(0),                                                                       
          }
      }

      // Producer &#31471;                                                                                          
      fn push(&amp;mut self, val: i64) -&gt; bool {
          let tail = self.tail.load(Ordering::Acquire);                                                       
          let head = self.head.load(Ordering::Acquire);                                                      
                                                                                                              
          if tail - head == SIZE as u64 {
              return false; // &#28415;&#20102;                                                                           
          }                                                                                                  

          self.buf[(tail &amp; (SIZE as u64 - 1)) as usize] = val;                                                
          self.tail.store(tail + 1, Ordering::Release);
          true                                                                                                
      }                                                                                                      

      // Consumer &#31471;
      fn pop(&amp;mut self) -&gt; Option&lt;i64&gt; {
          let head = self.head.load(Ordering::Acquire);
          let tail = self.tail.load(Ordering::Acquire);                                                       
   
          if head == tail {                                                                                   
              return None; // &#31354;&#30340;                                                                           
          }

          let val = self.buf[(head &amp; (SIZE as u64 - 1)) as usize];                                            
          self.head.store(head + 1, Ordering::Release);
          Some(val)                                                                                           
      }                                                                                                      
  }</code></pre></div><p>&#19988;&#38499;&#21015;&#26159;&#36899;&#32396;&#35352;&#25014;&#39636;&#31354;&#38291;&#65292;&#23565;&#26044; CPU &#20358;&#35498;&#33021;&#36879;&#36942;&#19968;&#27425; cache &#23384;&#21462;&#25343;&#21040;&#23436;&#25972;&#38499;&#21015;&#36039;&#26009;&#65292;&#30456;&#21453;&#22320; linked list &#31680;&#40670;&#21487;&#33021;&#20998;&#25955;&#22312;&#19981;&#36899;&#32396;&#35352;&#25014;&#39636;&#31354;&#38291;&#65292;CPU &#21487;&#33021;&#26371;&#26377;&#22810;&#27425; cache &#23384;&#21462;&#12290;</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Chill Vic&#8217;s Architecture Notes! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>&#38500;&#20102; queue &#20778;&#21270;&#65292;io_uring &#36996;&#26377;&#21738;&#20123;&#25928;&#33021;&#20778;&#21270;&#65311;</h1><p>&#38614;&#28982;&#27794;&#26377; read &#65286; write system call &#65292;&#20294; io_uring &#20173;&#38656;&#35201;&#20854;&#20182; I/O system call&#65292;&#20363;&#22914;&#25552;&#20132;&#23436;&#25152;&#26377;&#35531;&#27714;&#21040; SQ &#24460;&#65292;&#38656;&#35201;&#22519;&#34892; io_uring_enter system call &#21578;&#30693; kernel &#21487;&#24478; queue &#20013;&#34389;&#29702;&#20219;&#21209;&#65292;&#35442; system call &#26371; blocking &#30452;&#21040; CQ &#26377; entry&#65292;&#19981;&#36942; system call &#20173;&#27604; epoll &#23569;&#65306;</p><ul><li><p><strong>epoll</strong> : epoll_wait &#31561;&#20107;&#20214;&#20197;&#21450; read or write system call</p></li><li><p><strong>io_uring</strong> : io_uring_enter trigger kernel &#20006;&#31561;&#24453; CQ entry</p></li></ul><h3>SQPOLL &#27169;&#24335;&#23526;&#29694; zero I/O system call : </h3><p>&#33509;&#24819;&#23526;&#29694; zero I/O system call&#65292;io_uring &#25903;&#25588; SQPOLL &#27169;&#24335;&#65292;kernel &#26371;&#29992;&#38989;&#22806; kernel thread &#19981;&#26039; polling SQ&#65292;&#32780; user space process &#28961;&#38656;&#22519;&#34892; io_uring_enter &#21482;&#38656;&#35201;&#19981;&#26039; polling CQ &#21363;&#21487;&#65292;&#32570;&#40670;&#26159; CQ &#33509;&#27794;&#36039;&#26009;&#35442; process &#26371;&#26377;&#35377;&#22810;&#28961;&#25928;&#25289;&#21462;&#65292;&#22240;&#27492;  SQPOLL &#36969;&#29992;&#22312;<code>&#35531;&#27714;&#23494;&#38598;&#19988;&#20302;&#24310;&#36978;&#30340;&#22580;&#26223;&#20013;&#12290;</code></p><h3><code>IOPOLL &#27169;&#24335;&#20778;&#21270;&#30828;&#39636;&#20013;&#26039;&#65306;</code></h3><p>&#31532;&#20108;&#20491;&#20778;&#21270;&#26159;&#38364;&#26044;&#30828;&#39636;&#20013;&#26039;&#65292;io_uring &#19968;&#27171;&#36879;&#36942;&#30828;&#39636;&#20013;&#26039;&#35320;&#30332;&#24460;&#65292;kernel &#23559;&#35712;&#23531;&#32080;&#26524;&#25918;&#20837; CQ &#20013;&#65292;&#20294;&#30828;&#39636;&#20013;&#26039;&#19981;&#26159;&#27627;&#28961;&#25104;&#26412;&#65292;CPU &#25910;&#21040;&#20013;&#26039;&#25351;&#20196;&#24460;&#65292;&#35201;&#20808;&#22519;&#34892;&#20013;&#26039;&#25351;&#20196;&#20839;&#23481;&#65292;&#38500;&#20102;&#20572;&#27490;&#30070;&#21069;&#25351;&#20196;&#22806;&#65292;&#36996;&#26371;&#25226;&#22312;&#25351;&#20196; pipeline &#20013;&#30340;&#24460;&#32396;&#25351;&#20196;&#37117;&#31227;&#38500;&#65292;&#20013;&#26039;&#34389;&#29702;&#23436;&#24460;&#65292;&#26371;&#22238;&#21040;&#34987;&#25171;&#26039;&#30340;&#25351;&#20196;&#20301;&#22336;&#65292;&#35299;&#30908;&#24460;&#32396;&#25351;&#20196;&#25918;&#22238; pipeline&#12290;</p><p>&#33509;&#30636;&#38291;&#25910;&#21040;&#22823;&#37327;&#20013;&#26039;&#65292;CPU &#21453;&#35206;&#28165;&#31354; pipeline &#36942;&#31243;&#26159;&#24456;&#28040;&#32791;&#30340;&#65292;&#22240;&#27492; kernel &#20351;&#29992; NAPI (New API for network packet processing) &#25216;&#34899;&#34389;&#29702; network &#23553;&#21253;&#30340;&#20013;&#26039;&#25351;&#20196;&#65292;&#25910;&#21040;&#31532;&#19968;&#20491;&#20013;&#26039;&#24460;&#65292;&#26371;&#20999;&#25563;&#25104; polling &#27169;&#24335;&#65292;&#23559;&#32178;&#21345;&#35041;&#23553;&#21253;&#37117;&#35712;&#20986;&#20358;&#19968;&#27425;&#34389;&#29702;&#65292;&#36991;&#20813;&#30636;&#38291;&#22823;&#37327;&#23553;&#21253;&#35320;&#30332;&#19968;&#22534;&#20013;&#26039;&#12290;</p><p>&#20294; NAPI &#20027;&#35201;&#29992;&#26044;&#32178;&#36335;&#23553;&#21253;&#65292;&#33509;&#23559; io_uring &#29992;&#22312; File I/O (e.g &#36039;&#26009;&#24235;) &#30636;&#38291;&#22823;&#37327;&#35712;&#21462;&#20173;&#26371;&#35320;&#30332;&#19968;&#22534;&#20013;&#26039;&#65292;&#22240;&#27492; io_uring &#25552;&#20379; IO_POLL &#27169;&#24335;&#65292;&#23436;&#20840;&#19981;&#36879;&#36942;&#20013;&#26039;&#32780;&#26159;&#19981;&#26039; polling &#30828;&#39636;&#36039;&#26009;&#12290;</p><h1>io_uring &#30340;&#23526;&#38555;&#25033;&#29992;&#65306;PostgreSQL 18</h1><p>&#36039;&#26009;&#24235;&#31995;&#32113;&#26371;&#23565;&#27284;&#26696;&#26377;&#38971;&#32321;&#30340;&#35712;&#23531; I/O&#65292;&#22240;&#27492; PostgreSQL &#22312; 18 &#29256;&#26412;&#23565; File I/O &#24341;&#20837; async IO &#27231;&#21046;&#65292;&#35442;&#27231;&#21046;&#26377;&#20841;&#20491;&#27169;&#24335; worker (default) &amp; io_uring&#65306;</p><ul><li><p>worker&#65306;&#23559; read() or write() &#25351;&#20196;&#36879;&#36942; queue &#20132;&#30001; PG &#30340;&#21478;&#19968;&#20491; process &#34389;&#29702;&#65292;read heavy query &#25928;&#33021;&#25552;&#21319;&#32004; 1.5 &#20493;&#12290;</p></li><li><p>io_uring&#65306;&#23559; read() or write() &#25351;&#20196;&#25913;&#25104; io_uring &#26041;&#24335;&#34389;&#29702;&#65292;read heavy query  &#25928;&#33021;&#25552;&#21319;&#32004; 2.7 &#20493;&#12290;</p></li></ul><p>&#26377;&#27492;&#21487;&#35211; io_uring &#25928;&#33021;&#25552;&#21319;&#26368;&#22909;&#65292;&#19981;&#36942;&#30001;&#26044; io_uring &#26159;&#30064;&#27493;&#35712;&#23531;&#65292;PG &#25552;&#37266;&#29992; io_uring &#26371;&#23566;&#33268; explain analyze &#23565;&#26044; I/O &#34389;&#29702;&#26178;&#38291;&#35722;&#24471;&#19981;&#31934;&#28310;&#12290;</p><p>ref: https://pganalyze.com/blog/postgres-18-async-io</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YXgp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YXgp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 424w, https://substackcdn.com/image/fetch/$s_!YXgp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 848w, https://substackcdn.com/image/fetch/$s_!YXgp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 1272w, https://substackcdn.com/image/fetch/$s_!YXgp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YXgp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png" width="1400" height="714" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:714,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;PostgreSQL Async-IO using io_uring | by Sudheer Gajula | Medium&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="PostgreSQL Async-IO using io_uring | by Sudheer Gajula | Medium" title="PostgreSQL Async-IO using io_uring | by Sudheer Gajula | Medium" srcset="https://substackcdn.com/image/fetch/$s_!YXgp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 424w, https://substackcdn.com/image/fetch/$s_!YXgp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 848w, https://substackcdn.com/image/fetch/$s_!YXgp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 1272w, https://substackcdn.com/image/fetch/$s_!YXgp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40e042f3-e347-46a4-8248-31737afa20bc_1400x714.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>epoll vs io_uring benchmark - monoio vs tokio</h1><p><a href="https://chillvic.substack.com/p/tcp-server-ep1-server">&#22914;&#19978;&#38598;&#25152;&#35498;</a>&#65292;Rust &#26377; Future &#25277;&#35937;&#21270; async &#25805;&#20316;&#65292;&#22240;&#27492;&#21487;&#20197;&#26367;&#25563;&#19981;&#21516;&#30340;&#24213;&#23652; runtime&#65292;&#23526;&#38555;&#20195;&#30908;&#24190;&#20046;&#19981;&#29992;&#20462;&#25913;&#65292;&#20363;&#22914; monoio &#26159;&#29992; io_uring &#38283;&#30332;&#30340; async runtime&#65292;&#29992; monoio &#38283;&#30332;&#30340; TCP echo server &#33287; tokio &#31243;&#24335;&#24190;&#20046;&#19968;&#27171;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">use monoio::{
    io::{AsyncReadRent, AsyncWriteRentExt},
    net::{TcpListener, TcpStream},
};

#[monoio::main(driver = "fusion")]
async fn main() {
    // tracing_subscriber::fmt().with_max_level(tracing::Level::TRACE).init();
    let listener = TcpListener::bind("127.0.0.1:50002").unwrap();
    println!("listening");
    loop {
        let incoming = listener.accept().await;
        match incoming {
            Ok((stream, addr)) =&gt; {
                println!("accepted a connection from {addr}");
                monoio::spawn(echo(stream));
            }
            Err(e) =&gt; {
                println!("accepted connection failed: {e}");
                return;
            }
        }
    }
}

async fn echo(mut stream: TcpStream) -&gt; std::io::Result&lt;()&gt; {
    let mut buf: Vec&lt;u8&gt; = Vec::with_capacity(8 * 1024);
    let mut res;
    loop {
        // read
        (res, buf) = stream.read(buf).await;
        if res? == 0 {
            return Ok(());
        }

        // write all
        (res, buf) = stream.write_all(buf).await;
        res?;

        // clear
        buf.clear();
    }
}</code></pre></div><p>&#28858;&#20102;&#28204;&#35430; io_uring &amp; epoll &#30340;&#25928;&#33021;&#65292;&#25105;&#23531;&#20102;&#19968;&#20491; <a href="https://github.com/vx416/play_iouring">play_iouring</a> &#23560;&#26696;&#20351;&#29992;  monoio &amp; tokio &#22871;&#20214;&#28204;&#35430;&#65306;</p><ul><li><p>tcp echo server : &#21516;&#26178; 10, 100, 1000 &#20491; tcp client</p></li><li><p>file I/O : &#20341;&#30332;&#35712;&#23531; 100 &#20491;&#27284;&#26696;&#65292;&#27599;&#27425; 64KB</p></li></ul><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">### File I/O (100 files, 64 KiB each)

| Benchmark | monoio | tokio | &#916; |

|---------------|------------|------------|----------------|
| Write (100 files) | ~1.32 ms | ~1.95 ms | monoio ~1.5x faster |
| Read (100 files) | ~693 &#181;s | ~1.87 ms | monoio ~2.7x faster |

  
### TCP Echo

| Benchmark | monoio | tokio | &#916; |
|--------------------|------------|------------|----------|
| 10 clients | ~4.12 ms | ~3.98 ms | ~equal |
| 100 clients | ~26.6 ms | ~27.1 ms | ~equal |
| 1000 clients | ~292 ms | ~330 ms | monoio slightly faster |</code></pre></div><p>File I/O &#26377;&#26126;&#39023;&#30340;&#25552;&#21319;&#65292;&#21407;&#22240;&#26159; tokio &#27794;&#29992; epoll &#31649;&#29702; File I/O &#32780;&#26159; <a href="https://docs.rs/tokio/latest/tokio/fs/index.html">worker thread + blocking I/O</a>&#65292;&#32780; monoio &#26159;&#29992; io_uring &#34389;&#29702; File I/O &#21487;&#22823;&#24133;&#28187;&#23569; system call&#65292;&#22240;&#27492; File I/O &#19981;&#33021;&#30070;&#20316; epoll &#36319; io_uring &#30340;&#27604;&#36611;&#12290;</p><p>&#32780; TCP Echo &#30340;&#25928;&#33021;&#24190;&#20046;&#19968;&#27171;&#65292;io_uring &#35201;&#26377;&#26126;&#39023;&#25928;&#33021;&#25552;&#21319;&#22312;&#26044;&#35299;&#30465;&#22823;&#37327;&#30340; system call&#65292;&#20294;&#23553;&#21253; read write &#29983;&#21629;&#36913;&#26399;&#20013;&#65292;system call &#19981;&#26159;&#26368;&#33457;&#26178;&#38291;&#30340;&#65292;&#32780;&#26159; kernel &#30340; network stack (e.g &#23553;&#21253;&#35299;&#26512;&#65292;firewall rule etc)&#65292;&#22240;&#27492; 1000 clients &#37327;&#36996;&#19981;&#22816;&#21040;&#36896;&#25104;&#39023;&#33879;&#30340; system call delay&#65292;&#20294;&#22823;&#37327; client &#36899;&#32218;&#22312;&#21934;&#27231;&#28204;&#35430;&#26178;&#65292;core &#19981;&#22816;&#19979;&#26371;&#22833;&#28310;&#65292;&#22240;&#27492;&#35442;&#22739;&#28204;&#21482;&#35657;&#26126; epoll &#36319; io_uring &#22312;&#26222;&#36941;&#24773;&#22659;&#19979;&#26377;&#24046;&#19981;&#22810;&#30340;&#24615;&#33021; &#12290;</p>]]></content:encoded></item><item><title><![CDATA[How to Build a High-Performance TCP Server Part 1 - How Can a Single Server Handle Tens of Thousands of Concurrent Connections?]]></title><description><![CDATA[From the C10K Problem to epoll: A Deep Dive into the Performance Secrets of Nginx, Redis, and Rust Tokio]]></description><link>https://www.chillvic.dev/p/how-to-build-a-high-performance-tcp</link><guid isPermaLink="false">https://www.chillvic.dev/p/how-to-build-a-high-performance-tcp</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Tue, 24 Mar 2026 10:37:50 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!AEe4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd884fd-06af-4319-90a6-10f9f5c565fb_1694x2528.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Nginx is renowned as a high-performance proxy server, while Redis stands as the king of caching databases. Both process individual requests with incredible speed because they almost entirely bypass disk I/O, the traditional bottleneck of system performance.</p><p><strong>But what happens when a server is hit by a massive surge of concurrent requests?</strong> </p><p>Let&#8217;s explore how Nginx and Redis manage high-traffic spikes under the hood.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AEe4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd884fd-06af-4319-90a6-10f9f5c565fb_1694x2528.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AEe4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd884fd-06af-4319-90a6-10f9f5c565fb_1694x2528.png 424w, https://substackcdn.com/image/fetch/$s_!AEe4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd884fd-06af-4319-90a6-10f9f5c565fb_1694x2528.png 848w, https://substackcdn.com/image/fetch/$s_!AEe4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd884fd-06af-4319-90a6-10f9f5c565fb_1694x2528.png 1272w, https://substackcdn.com/image/fetch/$s_!AEe4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd884fd-06af-4319-90a6-10f9f5c565fb_1694x2528.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AEe4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd884fd-06af-4319-90a6-10f9f5c565fb_1694x2528.png" width="1456" height="2173" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/efd884fd-06af-4319-90a6-10f9f5c565fb_1694x2528.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2173,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:8020556,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191964110?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd884fd-06af-4319-90a6-10f9f5c565fb_1694x2528.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AEe4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd884fd-06af-4319-90a6-10f9f5c565fb_1694x2528.png 424w, https://substackcdn.com/image/fetch/$s_!AEe4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd884fd-06af-4319-90a6-10f9f5c565fb_1694x2528.png 848w, https://substackcdn.com/image/fetch/$s_!AEe4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd884fd-06af-4319-90a6-10f9f5c565fb_1694x2528.png 1272w, https://substackcdn.com/image/fetch/$s_!AEe4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd884fd-06af-4319-90a6-10f9f5c565fb_1694x2528.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h1><strong>The C10K Problem: Why Do Servers Crash Under High Load?</strong></h1><p>When tens of thousands of client requests flood in simultaneously, even without disk bottlenecks, a server can still fail.</p><p>To return results, a server must establish a TCP connection for every request. A common &#8220;intuitive&#8221; approach is the <strong>Connection-Per-Thread</strong> model. Since each connection must transmit data without blocking others, the server creates one thread for every single connection. This leads to a massive number of threads, causing the CPU to struggle with constant <strong>Context Switching</strong> and exhausting system memory. This is the classic <strong>C10K problem</strong>: how can a single server handle 10,000 concurrent connections efficiently?</p><p>In a TCP server, the <code>accept()</code> system call establishes a connection, while <code>read()</code> and <code>write()</code> handle data. These operations behave differently depending on whether they use <strong>Blocking</strong> or <strong>Non-Blocking I/O</strong>.</p><h3>1. Blocking I/O (Connection-Per-Thread)</h3><p>In Blocking I/O, if a read() call has no data to read, it &#8220;hangs&#8221; (blocks) until data arrives. Similarly, if the kernel&#8217;s write buffer is full, write() blocks until space becomes available. Because a thread is stuck waiting for one connection, it cannot handle others. Therefore, each connection requires its own dedicated thread, leading to the resource exhaustion mentioned above.</p><h3>2. Non-Blocking I/O (One-Thread Polling)</h3><p>In Non-Blocking I/O, <code>read()</code> or <code>write()</code> calls return an error immediately if no data is available or the buffer is full. A single thread can manage multiple connections by cycling through them&#8212;if the first connection has no data, the thread moves to the next without waiting.</p><p>However, this requires a <strong>Polling</strong> loop. The thread must repeatedly check whether each TCP connection is ready for I/O. Each check is a system call. If thousands of connections are idle, the thread wastes massive amounts of CPU cycles making useless system calls.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JrMs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32efb81-5f58-4ec5-8d8f-b9768ae4fdd0_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JrMs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32efb81-5f58-4ec5-8d8f-b9768ae4fdd0_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!JrMs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32efb81-5f58-4ec5-8d8f-b9768ae4fdd0_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!JrMs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32efb81-5f58-4ec5-8d8f-b9768ae4fdd0_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!JrMs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32efb81-5f58-4ec5-8d8f-b9768ae4fdd0_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JrMs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32efb81-5f58-4ec5-8d8f-b9768ae4fdd0_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d32efb81-5f58-4ec5-8d8f-b9768ae4fdd0_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:638826,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191964110?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32efb81-5f58-4ec5-8d8f-b9768ae4fdd0_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JrMs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32efb81-5f58-4ec5-8d8f-b9768ae4fdd0_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!JrMs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32efb81-5f58-4ec5-8d8f-b9768ae4fdd0_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!JrMs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32efb81-5f58-4ec5-8d8f-b9768ae4fdd0_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!JrMs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32efb81-5f58-4ec5-8d8f-b9768ae4fdd0_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Efficient Management: I/O Multiplexing</h1><p>To manage multiple Non-Blocking I/Os efficiently, we look to the Kernel. The Kernel doesn&#8217;t rely on polling; it uses <strong>Hardware Interrupts</strong>. For instance, when a Network Interface Card (NIC) receives a packet, it sends an interrupt signal to the CPU. The CPU pauses its current task, allows the Kernel to read the data into memory, and then notifies the relevant user-space process.</p><p>Since the Kernel can actively notify processes, we can use <strong>I/O Multiplexing</strong>. This allows a user-space process to ask the Kernel to monitor multiple TCP connections at once. The process &#8220;sleeps&#8221; (blocks) on a single system call and only wakes up when at least one connection is ready for I/O.</p><h3><strong>The Evolution: select, poll, and epoll</strong></h3><p>Early Kernel solutions like <code>select</code> used a <strong>bitmap</strong> to track connections. The process would block until a connection became active, at which point the Kernel would update the bitmap. However, <code>select</code> had a limited number of connections it could track, leading to the creation of <code>poll</code>, which used an <strong>array</strong> to remove that limit.</p><p>Despite the improvement, both had two major flaws:</p><ol><li><p>The entire data structure (bitmap or array) had to be copied from user space to kernel space every time.</p></li><li><p>When the process woke up, it had to scan the <em>entire</em> structure to find which specific connection was ready.</p></li></ol><h3><strong>The Superior Mechanism: epoll</strong></h3><p><strong>epoll</strong> is an internal Kernel structure. Instead of passing a bitmap every time, you use <code>epoll_create()</code> to let the Kernel maintain a <strong>Red-Black Tree</strong> and a <strong>Double Linked List</strong>.</p><ul><li><p><strong>Red-Black Tree:</strong> Stores the TCP connections. Adding or removing a connection is <code>O(log n)</code>, making it ideal for frequent changes.</p></li><li><p><strong>Double Linked List (Ready List):</strong> When a connection receives data, the Kernel&#8217;s callback function places it into this list.</p></li></ul><p>When a process calls <code>epoll_wait()</code>, it blocks. Once a connection is ready, the Kernel wakes the process, which simply retrieves the ready connections from the linked list. There is no need to scan thousands of idle connections.</p><p>Since epoll uses a double linked list as a ready queue, it supports two triggering modes:</p><ul><li><p><strong>Level-Triggered (LT):</strong><br>As long as there is unread data on the connection, <code>epoll_wait()</code> will continue to return the file descriptor. In other words, the connection remains in the ready list until all available data has been read.</p></li><li><p><strong>Edge-Triggered (ET):</strong><br>Events are triggered only when the state changes. When new data arrives, the connection is added to the ready list, and once <code>epoll_wait()</code> returns it, it is removed. It will not be added again until new data arrives.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Fuwp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd0784d-58f0-4c01-84e8-6bdd00cbafb8_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Fuwp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd0784d-58f0-4c01-84e8-6bdd00cbafb8_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Fuwp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd0784d-58f0-4c01-84e8-6bdd00cbafb8_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Fuwp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd0784d-58f0-4c01-84e8-6bdd00cbafb8_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Fuwp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd0784d-58f0-4c01-84e8-6bdd00cbafb8_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Fuwp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd0784d-58f0-4c01-84e8-6bdd00cbafb8_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5bd0784d-58f0-4c01-84e8-6bdd00cbafb8_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:835886,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191964110?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd0784d-58f0-4c01-84e8-6bdd00cbafb8_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Fuwp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd0784d-58f0-4c01-84e8-6bdd00cbafb8_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Fuwp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd0784d-58f0-4c01-84e8-6bdd00cbafb8_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Fuwp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd0784d-58f0-4c01-84e8-6bdd00cbafb8_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Fuwp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd0784d-58f0-4c01-84e8-6bdd00cbafb8_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>How Nginx and Redis Use Epoll</h1><p>Both Nginx and Redis typically use a single-threaded event loop (or one per CPU core) to run <code>epoll_wait()</code>. This avoids the complexities of multi-threaded data synchronization. The secret to their speed is that they <strong>never do anything that blocks</strong> the loop.</p><p><strong>The Epoll Loop Workflow:</strong></p><ol><li><p>Call <code>epoll_wait()</code> to find ready I/Os and <code>read()</code> the requests.</p></li><li><p>Process the logic.</p></li><li><p>Call <code>write()</code> to return results. If the kernel send buffer is full, the non-blocking <code>write()</code> returns an error.</p></li><li><p>Instead of waiting, the server moves the data to a temporary <strong>buffer queue</strong>, tells <code>epoll</code> to watch for a &#8220;writable&#8221; event, and moves to the next request.</p></li><li><p>Once the buffer has space, <code>epoll_wait()</code> triggers, and the server finishes the <code>write()</code>.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ny8S!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F407c6e9d-6c89-4c0c-a642-64411612d2f0_1024x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ny8S!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F407c6e9d-6c89-4c0c-a642-64411612d2f0_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!Ny8S!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F407c6e9d-6c89-4c0c-a642-64411612d2f0_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!Ny8S!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F407c6e9d-6c89-4c0c-a642-64411612d2f0_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!Ny8S!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F407c6e9d-6c89-4c0c-a642-64411612d2f0_1024x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ny8S!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F407c6e9d-6c89-4c0c-a642-64411612d2f0_1024x1536.png" width="1024" height="1536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/407c6e9d-6c89-4c0c-a642-64411612d2f0_1024x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1536,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:260021,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191964110?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F407c6e9d-6c89-4c0c-a642-64411612d2f0_1024x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ny8S!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F407c6e9d-6c89-4c0c-a642-64411612d2f0_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!Ny8S!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F407c6e9d-6c89-4c0c-a642-64411612d2f0_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!Ny8S!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F407c6e9d-6c89-4c0c-a642-64411612d2f0_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!Ny8S!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F407c6e9d-6c89-4c0c-a642-64411612d2f0_1024x1536.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>By only executing <code>read</code> or <code>write</code> when the Kernel confirms they are ready, CPU utilization is maximized and memory usage remains low.</p><p>Additionally, as a proxy server, Nginx improves request forwarding throughput by leveraging the kernel&#8217;s <code>SO_REUSEPORT</code> option. </p><p>This allows multiple processes to bind to the same TCP port, with the kernel automatically distributing incoming connections across different server sockets. Each thread (or process) then manages its own set of connections using an independent <code>epoll</code> instance, enabling a concurrent architecture.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zuoC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3eb0dba-1a4f-4b4b-bc6a-32266a14b264_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zuoC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3eb0dba-1a4f-4b4b-bc6a-32266a14b264_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!zuoC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3eb0dba-1a4f-4b4b-bc6a-32266a14b264_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!zuoC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3eb0dba-1a4f-4b4b-bc6a-32266a14b264_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!zuoC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3eb0dba-1a4f-4b4b-bc6a-32266a14b264_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zuoC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3eb0dba-1a4f-4b4b-bc6a-32266a14b264_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e3eb0dba-1a4f-4b4b-bc6a-32266a14b264_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:309910,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191964110?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3eb0dba-1a4f-4b4b-bc6a-32266a14b264_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zuoC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3eb0dba-1a4f-4b4b-bc6a-32266a14b264_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!zuoC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3eb0dba-1a4f-4b4b-bc6a-32266a14b264_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!zuoC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3eb0dba-1a4f-4b4b-bc6a-32266a14b264_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!zuoC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3eb0dba-1a4f-4b4b-bc6a-32266a14b264_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Chill Vic&#8217;s Architecture Notes! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>How to Implement a High-Performance TCP Server using Epoll: A Case Study with Rust's Tokio</h1><p>A common pattern for implementing an <code>epoll</code> loop like Nginx and Redis is the Reactor&#8211;Executor pattern : </p><ul><li><p><strong>Reactor:</strong> Manages event states (via <code>epoll_wait</code>) and wakes up tasks when I/O is ready.</p></li></ul><ul><li><p><strong>Executor:</strong> The core engine that processes the logic (e.g., Redis memory operations or Nginx HTTP parsing).</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Py6a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a407c7-1b1d-4d04-ae10-848d51384103_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Py6a!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a407c7-1b1d-4d04-ae10-848d51384103_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Py6a!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a407c7-1b1d-4d04-ae10-848d51384103_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Py6a!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a407c7-1b1d-4d04-ae10-848d51384103_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Py6a!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a407c7-1b1d-4d04-ae10-848d51384103_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Py6a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a407c7-1b1d-4d04-ae10-848d51384103_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e9a407c7-1b1d-4d04-ae10-848d51384103_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:464059,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191964110?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a407c7-1b1d-4d04-ae10-848d51384103_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Py6a!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a407c7-1b1d-4d04-ae10-848d51384103_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Py6a!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a407c7-1b1d-4d04-ae10-848d51384103_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Py6a!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a407c7-1b1d-4d04-ae10-848d51384103_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Py6a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a407c7-1b1d-4d04-ae10-848d51384103_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In the Rust ecosystem, the event states managed by the reactor are abstracted into the <code>Future</code> trait. This interface represents an asynchronous operation, where calling <code>poll</code> drives the internal logic of the <code>Future</code>. If the data isn't ready, it returns <code>Poll::Pending</code> and registers itself with the Reactor to be woken up later.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bCJo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43766010-c7cc-44bb-8549-d88dac352cfb_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bCJo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43766010-c7cc-44bb-8549-d88dac352cfb_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!bCJo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43766010-c7cc-44bb-8549-d88dac352cfb_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!bCJo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43766010-c7cc-44bb-8549-d88dac352cfb_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!bCJo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43766010-c7cc-44bb-8549-d88dac352cfb_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bCJo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43766010-c7cc-44bb-8549-d88dac352cfb_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/43766010-c7cc-44bb-8549-d88dac352cfb_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1672190,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191964110?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43766010-c7cc-44bb-8549-d88dac352cfb_1024x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bCJo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43766010-c7cc-44bb-8549-d88dac352cfb_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!bCJo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43766010-c7cc-44bb-8549-d88dac352cfb_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!bCJo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43766010-c7cc-44bb-8549-d88dac352cfb_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!bCJo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43766010-c7cc-44bb-8549-d88dac352cfb_1024x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>Example: A Simplified Reactor-Executor</strong></h3><p>First, we define a basic SleepFuture to simulate I/O wait:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">struct SleepFuture {
    deadline: Instant,
}

impl SleepFuture {
    fn new(duration: Duration) -&gt; Self {
        SleepFuture {
            deadline: Instant::now() + duration,
        }
    }
}

impl Future for SleepFuture {
    type Output = ();
    fn poll(self: Pin&lt;&amp;mut Self&gt;, _cx: &amp;mut Context) -&gt; Poll&lt;()&gt; {
        if Instant::now() &gt;= self.deadline {
            Poll::Ready(())
        } else {
            Poll::Pending
        }
    }
}

async fn send_request() -&gt; i32 {
    SleepFuture::new(Duration::from_secs(2)).await;
    1 + 1
}

fn process_response(val: i32) {
    println!("&#34389;&#29702;&#32080;&#26524;: {}", val);
}</code></pre></div><p>Next, we implement the event loop logic for the Reactor and Executor. The Reactor polls futures and sends ready results to the Executor via a channel:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">type BoxFuture = Pin&lt;Box&lt;dyn Future&lt;Output = i32&gt; + Send&gt;&gt;;

fn reactor(futures: Vec&lt;BoxFuture&gt;, tx: mpsc::Sender&lt;i32&gt;) {
    let waker = Waker::noop();
    let mut cx = Context::from_waker(&amp;waker);

    // &#25226;&#27599;&#20491; future &#21253;&#25104; Option&#65292;&#23436;&#25104;&#24460;&#35373;&#28858; None
    let mut tasks: Vec&lt;Option&lt;BoxFuture&gt;&gt; = futures.into_iter().map(Some).collect();
    let total = tasks.len();
    let mut done_count = 0;

    loop {
        for task in tasks.iter_mut() {
            if let Some(fut) = task {
                if let Poll::Ready(val) = fut.as_mut().poll(&amp;mut cx) {
                    tx.send(val).unwrap(); // Ready&#65281;&#19999;&#32102; queue &#35041;&#38754;&#32102; executor
                    *task = None;
                    done_count += 1;
                }
            }
        }

        if done_count &gt;= total {
            break;
        }

        thread::sleep(Duration::from_millis(100)); // &#31777;&#21934;&#30340; polling &#38291;&#38548;
    }
}

fn executor(rx: mpsc::Receiver&lt;i32&gt;, total: usize) -&gt; thread::JoinHandle&lt;()&gt; {
    thread::spawn(move || {
        let mut done = 0;
        while done &lt; total {
            let val = rx.recv().unwrap();
            process_response(val);
            done += 1;
        }
        println!("executor: &#20840;&#37096;&#34389;&#29702;&#23436;&#25104;");
    })
}

fn main() {
    let (tx, rx) = mpsc::channel();

    let futures: Vec&lt;BoxFuture&gt; = vec![
        Box::pin(send_request()),
        Box::pin(send_request()),
    ];
    let total = futures.len();

    // executor worker thread&#65306;&#31561; reactor &#19999;&#32080;&#26524;&#36942;&#20358;&#23601;&#22519;&#34892;
    let handle = executor(rx, total);

    let start = Instant::now();

    // reactor&#65306;poll futures&#65292;ready &#24460;&#36879;&#36942; channel &#19999;&#32102; executor
    reactor(futures, tx);

    handle.join().unwrap();
    println!("&#20840;&#37096;&#23436;&#25104;&#65292;&#32791;&#26178;: {:?}", start.elapsed());
}
</code></pre></div><p>The above code demonstrates the abstraction capability of the <code>Future</code> trait: it encapsulates all operations as asynchronous behaviors and allows developers to define when state transitions occur. </p><p>By combining this with different underlying event loop mechanisms, one can swap out various Reactor&#8211;Executor implementations without modifying the core business logic.</p><h3>Tokio&#8217;s Real-World epoll Implementation</h3><p>With the basic concept of the Reactor-Executor pattern in mind, let&#8217;s look at a simple <strong>TCP Echo Server</strong> implemented with Tokio : </p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">use tokio::net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -&gt; Result&lt;(), Box&lt;dyn std::error::Error&gt;&gt; {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;

    loop {
        let (mut socket, _) = listener.accept().await?;

        tokio::spawn(async move {
            let mut buf = [0; 1024];

            // In a loop, read data from the socket and write the data back.
            loop {
                let n = match socket.read(&amp;mut buf).await {
                    // socket closed
                    Ok(0) =&gt; return,
                    Ok(n) =&gt; n,
                    Err(e) =&gt; {
                        eprintln!("failed to read from socket; err = {:?}", e);
                        return;
                    }
                };

                // Write the data back
                if let Err(e) = socket.write_all(&amp;buf[0..n]).await {
                    eprintln!("failed to write to socket; err = {:?}", e);
                    return;
                }
            }
        });
    }
}</code></pre></div><p>When you use the <code>#[tokio::main]</code> macro, it initializes a <strong>Runtime Object</strong>. The <code>block_on</code> function waits for all future events to complete. Since the primary future is a TCP server handling new connections, the runtime remains active as long as the server is running.</p><p>Under the hood, <code>#[tokio::main]</code> expands to:</p><ol><li><p><code>epoll_create()</code>: Establishes the epoll instance.</p></li><li><p><strong>Thread Pool</strong>: Creates worker threads (Executors).</p></li><li><p><strong>Timer Wheel</strong>: Manages <code>sleep</code> and <code>timeout</code> events.</p></li></ol><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">  fn main() {                                                                                                 
      let runtime = tokio::runtime::Runtime::new().unwrap();                                                                                 
      //  1. epoll_create()     &#8594; create epoll instance
      //  2. create thread pool   &#8594; worker threads                                                              
      //  3. create timer wheel   &#8594; manage sleep/timeout                                                          
                                                                                                              
      runtime.block_on(async {                                                    
          let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap();                                  
          // ...                                                                                              
      });                                                                         
      // block_on start reactor &#30340; event loop                                                                 
  }  </code></pre></div><h3><strong>How Tokio Manages I/O via epoll</strong></h3><p>Tokio&#8217;s Reactor module uses <code>epoll</code> to manage network I/O. When a connection becomes readable, it is pushed into a queue for an Executor to process. </p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust"># Conceptual code example
 impl Reactor {                                                                       
      fn run(&amp;mut self) {                                                             
          loop {                                                                
              let timeout = self.nearest_timer_deadline();                            
              let ready_fds = epoll_wait(self.epoll_fd, timeout);               
                                                                                                              
              for (fd, token) in ready_fds {
                  self.run_queue.push(token.task_id); 
              }                                                                       
          }
      }
  }
</code></pre></div><p>Tokio also wraps TCP connections into Non-Blocking I/O + epoll-registered Futures. When <code>poll</code> is called, it attempts a non-blocking read. If no data is available, it registers the file descriptor with <code>epoll</code> and returns <code>Pending</code>:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust"># Conceptual code example
impl Future for TcpReadFuture {
    fn poll(mut self: Pin&lt;&amp;mut Self&gt;, cx: &amp;mut Context) -&gt; Poll&lt;Vec&lt;u8&gt;&gt; {
        match non_blocking_read(self.fd, &amp;mut self.buf) {
            Ok(data) =&gt; Poll::Ready(data), // Data available, return immediately
            Err(WouldBlock) =&gt; {
                if !self.registered {
                    // Retrieve reactor via thread-local and register to epoll
                    reactor.register(self.fd, Interest::READ, cx.waker().clone());
                    self.registered = true;
                }
                Poll::Pending // Tell the executor: "Not ready, go handle other tasks"
            }
        }
    }
}</code></pre></div><p>When executing an <code>await</code> (e.g., <code>socket.read(&amp;mut buf).await</code>), the compiler generates code conceptually similar to:</p><pre><code># Conceptual code example
loop {
    match future.poll(cx) {
        Poll::Ready(val) =&gt; break val,
        Poll::Pending =&gt; {
            return Poll::Pending;
        }
    }
}</code></pre><p>During the <code>poll</code> call, if the future involves a connection that is not yet ready (e.g., a non-blocking socket), that connection will be registered with <code>epoll</code> (via the runtime&#8217;s reactor) so it can be monitored for readiness.</p><h3><strong>The Role of </strong><code>tokio::spawn</code></h3><p>In Tokio, the executor schedules and polls futures, and it is backed by a pool of worker threads.</p><p>It is important to note that <code>tokio::spawn(async move { ... })</code> does not create a new kernel thread. Instead, it enqueues the async task into the runtime&#8217;s task queue. Worker threads then pick up and execute these tasks by polling their associated futures.</p><p>Each worker thread runs a loop similar to this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;javascript&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-javascript"># Conceptual code example
fn worker_thread(run_queue: Arc&lt;SharedQueue&gt;, tasks: Arc&lt;TaskMap&gt;) {
    loop {
        let task_id = run_queue.pop(); // Blocks if queue is empty
        let task = tasks.get(task_id);
        match task.poll(&amp;mut cx) {
            Poll::Ready(()) =&gt; { tasks.remove(task_id); }
            Poll::Pending   =&gt; { /* Waker is registered, wait for next wake-up */ }
        }
    }
}</code></pre></div><p>Worker threads are configured when the runtime is created:</p><pre><code>#[tokio::main(flavor = &#8220;multi_thread&#8221;, worker_threads = 4)]
async fn main() {
    // your async code
}</code></pre><h3><strong>Nested Future Task</strong></h3><p>In the TCP Echo server above, each task handled by a worker thread is a nested future structure that performs connection read and write operations:</p><ul><li><p><code>spawn</code><strong> Future (ReadLoopFuture)</strong></p><ul><li><p><code>&#9492;&#9472;&#9472; socket.read().await</code> (<strong>TcpReadFuture</strong>)</p><ul><li><p><code>&#9492;&#9472;&#9472; non_blocking_read() &#8594; WouldBlock &#8594; Register epoll</code></p></li></ul></li><li><p><code>&#9492;&#9472;&#9472; socket.write().await</code> (<strong>TcpWriteFuture</strong>)</p><ul><li><p><code>&#9492;&#9472;&#9472; non_blocking_write() &#8594; WouldBlock &#8594; Register epoll</code></p></li></ul></li></ul></li></ul><p>If <code>socket.read()</code> has no data, it is placed in <code>epoll</code> to await notification from the Reactor. The Executor, receiving a <code>Pending</code> status, moves on to the next connection&#8217;s future. Once the Reactor wakes the future, the process continues to the <code>write</code> stage. If the write buffer is full, it returns <code>Pending</code> again, waiting for the next &#8220;writable&#8221; signal from the Reactor.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mONI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc654784f-296a-4886-9b77-9667b03f0ca0_1024x1524.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mONI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc654784f-296a-4886-9b77-9667b03f0ca0_1024x1524.png 424w, https://substackcdn.com/image/fetch/$s_!mONI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc654784f-296a-4886-9b77-9667b03f0ca0_1024x1524.png 848w, https://substackcdn.com/image/fetch/$s_!mONI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc654784f-296a-4886-9b77-9667b03f0ca0_1024x1524.png 1272w, https://substackcdn.com/image/fetch/$s_!mONI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc654784f-296a-4886-9b77-9667b03f0ca0_1024x1524.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mONI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc654784f-296a-4886-9b77-9667b03f0ca0_1024x1524.png" width="1024" height="1524" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c654784f-296a-4886-9b77-9667b03f0ca0_1024x1524.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1524,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1403346,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191964110?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc654784f-296a-4886-9b77-9667b03f0ca0_1024x1524.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!mONI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc654784f-296a-4886-9b77-9667b03f0ca0_1024x1524.png 424w, https://substackcdn.com/image/fetch/$s_!mONI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc654784f-296a-4886-9b77-9667b03f0ca0_1024x1524.png 848w, https://substackcdn.com/image/fetch/$s_!mONI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc654784f-296a-4886-9b77-9667b03f0ca0_1024x1524.png 1272w, https://substackcdn.com/image/fetch/$s_!mONI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc654784f-296a-4886-9b77-9667b03f0ca0_1024x1524.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Finally, the overall Tokio runtime architecture can be summarized as:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5usf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc4ba21-203d-4cf6-9b8f-22117491c458_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5usf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc4ba21-203d-4cf6-9b8f-22117491c458_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!5usf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc4ba21-203d-4cf6-9b8f-22117491c458_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!5usf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc4ba21-203d-4cf6-9b8f-22117491c458_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!5usf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc4ba21-203d-4cf6-9b8f-22117491c458_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5usf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc4ba21-203d-4cf6-9b8f-22117491c458_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2bc4ba21-203d-4cf6-9b8f-22117491c458_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:369390,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191964110?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc4ba21-203d-4cf6-9b8f-22117491c458_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5usf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc4ba21-203d-4cf6-9b8f-22117491c458_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!5usf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc4ba21-203d-4cf6-9b8f-22117491c458_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!5usf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc4ba21-203d-4cf6-9b8f-22117491c458_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!5usf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc4ba21-203d-4cf6-9b8f-22117491c458_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Preview of the next part:</h1><p>Although <code>epoll</code> has been the preferred low-level technology for most high-performance servers, newer async I/O mechanisms have emerged as the kernel has evolved&#8212;most notably <code>io_uring</code>. Rust&#8217;s Tokio ecosystem also has implementations of async runtimes based on <code>io_uring</code>. In the next part, we will examine the performance limitations of <code>epoll</code> and how <code>io_uring</code> addresses them.</p>]]></content:encoded></item><item><title><![CDATA[如何打造高效 TCP Server 上集 - 單台 Server 如何同時處理上萬連線？]]></title><description><![CDATA[&#24478; C10K &#21839;&#38988;&#21040; epoll&#65292;&#28145;&#20837; Nginx&#12289;Redis &#33287; Rust Tokio &#30340;&#39640;&#25928;&#33021;&#31192;&#23494;]]></description><link>https://www.chillvic.dev/p/tcp-server-ep1-server</link><guid isPermaLink="false">https://www.chillvic.dev/p/tcp-server-ep1-server</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Tue, 24 Mar 2026 10:01:02 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!2uJR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49ece0d4-eddf-4da4-ab7a-11d9e1369c51_1694x2528.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Nginx &#26159;&#36681;&#30332;&#35531;&#27714;&#30340;&#39640;&#25928;&#20195;&#29702;&#20282;&#26381;&#22120;&#65292;Redis &#21063;&#26159;&#24555;&#21462;&#36039;&#26009;&#24235;&#30340;&#29579;&#32773;&#65292;&#23427;&#20497;&#22312;&#21934;&#27425;&#35531;&#27714;&#30340;&#34389;&#29702;&#36895;&#24230;&#37117;&#26997;&#24555;&#65292;&#22240;&#28858;&#24190;&#20046;&#23436;&#20840;&#36991;&#38283;&#20102;&#36896;&#25104;&#29942;&#38968;&#30340;&#30828;&#30879; I/O&#12290;</p><p>&#20294;&#22914;&#26524;&#34389;&#29702;&#30636;&#38291;&#22823;&#37327;&#35531;&#27714;&#21602;&#65311;&#35731;&#25105;&#20497;&#28145;&#20837;&#25506;&#31350; Nginx &amp; Redis &#22914;&#20309;&#34389;&#29702;&#30636;&#38291;&#22823;&#27969;&#37327;&#65281;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2uJR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49ece0d4-eddf-4da4-ab7a-11d9e1369c51_1694x2528.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2uJR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49ece0d4-eddf-4da4-ab7a-11d9e1369c51_1694x2528.png 424w, https://substackcdn.com/image/fetch/$s_!2uJR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49ece0d4-eddf-4da4-ab7a-11d9e1369c51_1694x2528.png 848w, https://substackcdn.com/image/fetch/$s_!2uJR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49ece0d4-eddf-4da4-ab7a-11d9e1369c51_1694x2528.png 1272w, https://substackcdn.com/image/fetch/$s_!2uJR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49ece0d4-eddf-4da4-ab7a-11d9e1369c51_1694x2528.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2uJR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49ece0d4-eddf-4da4-ab7a-11d9e1369c51_1694x2528.png" width="1456" height="2173" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/49ece0d4-eddf-4da4-ab7a-11d9e1369c51_1694x2528.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2173,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:8020556,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191958789?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49ece0d4-eddf-4da4-ab7a-11d9e1369c51_1694x2528.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2uJR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49ece0d4-eddf-4da4-ab7a-11d9e1369c51_1694x2528.png 424w, https://substackcdn.com/image/fetch/$s_!2uJR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49ece0d4-eddf-4da4-ab7a-11d9e1369c51_1694x2528.png 848w, https://substackcdn.com/image/fetch/$s_!2uJR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49ece0d4-eddf-4da4-ab7a-11d9e1369c51_1694x2528.png 1272w, https://substackcdn.com/image/fetch/$s_!2uJR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49ece0d4-eddf-4da4-ab7a-11d9e1369c51_1694x2528.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>&#30636;&#38291;&#28263;&#20837;&#19978;&#33836;&#20491; Client &#35531;&#27714;&#65292;&#21363;&#20415;&#27794;&#26377;&#30828;&#30879;&#29942;&#38968;&#65292;Server &#20063;&#26371;&#29190;&#21966;&#65311;</h1><p>&#30636;&#38291;&#28263;&#20837;&#22823;&#37327;&#35531;&#27714;&#26178;&#65292;Server &#35201;&#24314;&#31435;&#22823;&#37327; TCP &#36899;&#32218;&#25509;&#25910;&#35531;&#27714;&#22238;&#20659;&#32080;&#26524;&#65292;&#30001;&#26044;&#27599;&#26781; TCP &#36899;&#32218;&#22312;&#20659;&#36664;&#36942;&#31243;&#20013;&#19981;&#33021;&#20114;&#21345;&#65292;&#22240;&#27492;&#30452;&#35258;&#20570;&#27861;&#26159;&#12300;&#19968;&#26781;&#36899;&#32218;&#32129;&#19968;&#20491; Thread&#12301;&#20358;&#34389;&#29702;&#35531;&#27714;&#20006;&#20659;&#36865;&#32080;&#26524;&#65292;&#27492;&#26178;&#22823;&#37327;&#36899;&#32218;&#24314;&#31435;&#22823;&#37327;&#30340; Thread&#65292;&#36896;&#25104; CPU &#38971;&#32321;&#30340; Context Switch &#20197;&#21450;&#22823;&#37327;&#30340;&#35352;&#25014;&#39636;&#28040;&#32791;&#65292;Server &#36039;&#28304;&#19981;&#22816;&#23601;&#29190;&#20102;&#12290;</p><p><strong>&#32780;&#36889;&#20063;&#34893;&#29983;&#32147;&#20856;&#30340; C10K &#21839;&#38988;&#65292;&#22914;&#20309;&#35731;&#21934;&#21488; Server &#21516;&#26178;&#34389;&#29702; 1 &#33836;&#20491;&#36899;&#32218;&#35531;&#27714;&#65311;</strong></p><p>&#30070; client &#24448; server &#36865;&#35531;&#27714;&#26178;&#65292;TCP server &#30340; accept system call &#26371;&#24314;&#31435;&#19968;&#26781; TCP Connection&#65292;&#20006;&#36879;&#36942; read() &amp; write() system call &#35712;&#23531;&#36039;&#26009;&#65292;&#32780; TCP Connection &#21448;&#20998; Block I/O &#36319; Non-Blocking I/O&#12290; </p><h2><strong>Blocking I/O - Connection Per Thread &#27169;&#24335;</strong></h2><p>Blocking I/O &#22519;&#34892; read() &#26178;&#65292;&#33509;&#27794;&#36039;&#26009;&#21487;&#35712;&#26371;&#21345;&#20303;&#65292;&#30452;&#21040;&#26377;&#36039;&#26009;&#25165; return&#65292;&#21516;&#29702;&#22519;&#34892; write() &#26178;&#65292;&#22914;&#26524; kernel write buffer &#23531;&#28415;&#20102;&#65292;write() &#26371;&#21345;&#20303;&#65292;&#30452;&#21040; kernel buffer &#26377;&#31354;&#38291;&#24460;&#25165;&#26371; return&#12290;</p><p>&#22240;&#27492;&#22810;&#20491; Blocking I/O &#19981;&#33021;&#20849;&#29992; Thread&#65292;&#22240;&#28858;&#30070;&#31532;&#19968;&#20491;&#36899;&#32218;&#30340; read() &#22240;&#28858;&#27794;&#26377;&#36039;&#26009;&#32780;&#21345;&#20303;&#26178;&#65292;&#26371;&#23566;&#33268;&#24460;&#38754;&#36899;&#32218;&#21363;&#20415;&#26377;&#36039;&#26009;&#20063;&#34389;&#29702;&#19981;&#21040;&#65292;&#25152;&#20197; Blocking I/O &#24517;&#38920;&#19968;&#20491;&#36899;&#32218;&#25645;&#37197;&#19968;&#20491; Thread &#21435;&#22519;&#34892;&#21508;&#33258;&#30340; read loop&#12290;</p><h2>Non-Blocking I/O - One Thread Polling &#27169;&#24335;</h2><p>&#32780; Non-Blocking I/O &#22519;&#34892; read() &amp; write() &#26178;&#65292;&#27794;&#36039;&#26009;&#25110;&#19981;&#21487;&#23531;&#26371;&#30452;&#25509; return error&#65292;&#19968;&#20491; Thread &#21487;&#34389;&#29702;&#22810;&#20491; Non-Blocking I/O&#65292;&#21069;&#19968;&#20491;&#36899;&#32218;&#27794;&#36039;&#26009; return error &#24460;&#24448;&#19979;&#19968;&#20491;&#36899;&#32218;&#34389;&#29702;&#65292;&#19981;&#21345;&#20303;&#20219;&#20309;&#20154;&#12290;</p><p>&#20294; Non-Blocking I/O &#23526;&#29694; read loop &#26178;&#65292;&#24517;&#38920;&#19981;&#26039;&#35426;&#21839;&#25152;&#26377; TCP connection &#30906;&#35469;&#26377;&#35504;&#26377;&#36039;&#26009;&#21487;&#35712;&#65292;&#27599;&#27425; read() &#37117;&#26159;&#19968;&#20491; system call&#65292;&#38614;&#28187;&#23569;&#20102; Thread &#25976;&#37327;&#65292;&#20294;&#27599;&#27425;&#37117;&#35201;&#35426;&#21839;&#25152;&#26377;&#36899;&#32218;&#65292;&#26371;&#28040;&#32791;&#22823;&#37327; CPU&#65292;&#19988;&#33509;&#22823;&#37327;&#36899;&#32218;&#37117;&#27794;&#36039;&#26009;&#36996;&#21371;&#21453;&#35206;&#35426;&#21839;&#65292;&#31561;&#26044;&#20570;&#20102;&#35377;&#22810;&#28961;&#25928;&#30340; system call&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Rt2f!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e7442de-e1d8-439c-b292-9dad33f0cef5_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Rt2f!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e7442de-e1d8-439c-b292-9dad33f0cef5_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Rt2f!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e7442de-e1d8-439c-b292-9dad33f0cef5_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Rt2f!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e7442de-e1d8-439c-b292-9dad33f0cef5_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Rt2f!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e7442de-e1d8-439c-b292-9dad33f0cef5_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Rt2f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e7442de-e1d8-439c-b292-9dad33f0cef5_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6e7442de-e1d8-439c-b292-9dad33f0cef5_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:638826,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191958789?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e7442de-e1d8-439c-b292-9dad33f0cef5_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Rt2f!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e7442de-e1d8-439c-b292-9dad33f0cef5_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Rt2f!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e7442de-e1d8-439c-b292-9dad33f0cef5_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Rt2f!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e7442de-e1d8-439c-b292-9dad33f0cef5_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Rt2f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e7442de-e1d8-439c-b292-9dad33f0cef5_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>&#21934;&#32218;&#31243;&#22914;&#20309;&#39640;&#25928;&#22320;&#31649;&#29702;&#22810;&#20491; Non-Blocking I/O &#65311;</h1><p>&#20351;&#29992; Non-Blocking &#30475;&#20284;&#35201;&#36650;&#35426;&#65292;&#20294;&#20854;&#23526; kernel &#22312;&#31649;&#29702;&#22810;&#20491; TCP &#36899;&#32218;&#26178;&#65292;&#19981;&#36879;&#36942;&#36650;&#35426;&#65292;&#32780;&#26159;&#30828;&#39636;&#20013;&#26039;&#35338;&#34399;&#65292;&#20363;&#22914; NIC (&#32178;&#21345;) &#25910;&#21040;&#32178;&#36335;&#23553;&#21253;&#24460;&#65292;&#26371;&#21521; CPU &#30332;&#36865;&#20013;&#26039;&#35338;&#34399;&#65292;&#27492;&#26178; CPU &#26371;&#20572;&#19979;&#25163;&#37002;&#24037;&#20316;&#65292;&#21578;&#35380; Kernel &#26377;&#32202;&#24613;&#20107;&#20214;&#65292;&#38568;&#24460; Kernel &#26371;&#25226;&#23553;&#21253;&#36039;&#26009;&#35712;&#21040;&#35352;&#25014;&#39636;&#20013;&#20006;&#36890;&#30693;&#23565;&#25033;&#30340; user space process&#12290;</p><p>&#31455;&#28982; Kernel &#21487;&#36879;&#36942;&#20013;&#26039;&#35338;&#34399;&#20027;&#21205;&#36890;&#30693;&#65292;&#37027;&#40636; user space process &#23601;&#21487;&#35731; Kernel &#19968;&#27425;&#30435;&#32893;&#22810;&#20491; TCP &#36899;&#32218;&#65292;&#31561;&#20854;&#20013;&#19968;&#20491;&#36899;&#32218;&#26377;&#36039;&#26009;&#21487;&#35712;&#26178;&#22312;&#25226; process &#21914;&#37266;&#65292;&#20063;&#23601;&#26159;&#36879;&#36942;&#19968;&#27425; Blocking &#25805;&#20316;&#30435;&#32893;&#22810;&#20491; Non-Blocking I/O&#65292;&#36991;&#20813; user space process &#35201;&#19981;&#26039;&#36865;&#20986;&#28961;&#25928;&#30340; read()&#65292;&#32780;&#29992;&#19968;&#20491; thread &#36879;&#36942;&#21934;&#19968; system call &#21516;&#26178;&#30435;&#32893;&#22810;&#26781; I/O &#36899;&#32218;&#30340;&#27231;&#21046;&#65292;&#31281;&#28858; I/O &#22810;&#24037;&#65288;I/O Multiplexing&#65289;&#12290;</p><h2>Kernel &#30340; I/O &#22810;&#24037;&#65288;I/O Multiplexing&#65289;&#25216;&#34899; - select &amp; poll</h2><p>&#20363;&#22914;&#26089;&#26399; Kernel &#25552;&#20379; select system call&#65292;&#29992; bitmap &#32080;&#27083;&#31649;&#29702;&#22810;&#20491; Non-Blocking I/O &#20659;&#20837; select&#65292;Kernel &#26371;&#23559; process &#38459;&#22622;&#65292;&#30452;&#21040;&#20219;&#19968;&#36899;&#32218;&#26377;&#36039;&#26009;&#21040;&#36948;&#24460;&#21914;&#37266;&#65292;&#20006;&#35206;&#23531; bitmap &#20839;&#23481;&#65292;&#25226;&#26377;&#36039;&#26009;&#30340;&#36899;&#32218;&#26356;&#26032;&#36914;&#21435;&#65292;&#38568;&#24460;&#34987;&#21914;&#37266;&#30340; process &#35201; scan bitmap &#20839;&#23481;&#25214;&#21040;&#23565;&#25033;&#30340; TCP &#36899;&#32218;&#35712;&#36039;&#26009;&#12290;</p><p>select &#32570;&#40670;&#26159; bitmap &#32080;&#27083;&#38480;&#21046;&#20102;&#30435;&#32893; TCP &#26368;&#22823;&#25976;&#37327;&#65292;&#22240;&#27492; poll system call &#21063;&#23559; bitmap &#32080;&#27083;&#25563;&#25104; array&#65292;&#20294;&#26159; select &amp; poll &#20173;&#26377;&#20849;&#21516;&#30340;&#32570;&#40670;&#65306;</p><ul><li><p>&#29992; user space &#36039;&#26009;&#32080;&#27083;&#31649;&#29702;&#38656;&#35201;&#30435;&#32893;&#30340; TCP &#36899;&#32218;&#65292;&#35201;&#23559;&#35442;&#36039;&#26009;&#32080;&#27083;&#24478; user space &#35079;&#35069;&#21040; kernel space</p></li><li><p>process &#34987;&#21914;&#37266;&#24460;&#65292;&#21363;&#20415;&#21482;&#26377;&#19968;&#26781;&#36899;&#32218;&#21487;&#35712;&#20173;&#35201; scan &#25972;&#20491;&#32080;&#27083; (bitmap or array) &#25165;&#33021;&#25214;&#21040;&#35442;&#36899;&#32218;</p></li></ul><h2>Kernel &#22914;&#20309;&#35373;&#35336;&#20986;&#26356;&#22909;&#30340; I/O &#22810;&#24037;&#27231;&#21046;&#65311;</h2><p>epoll &#26159; kernel &#20839;&#37096;&#31649;&#29702;&#22810;&#26781; non-blocking I/O &#30340;&#32080;&#27083;&#65292;&#22240;&#27492;&#19981;&#29992;&#22312; user space &#21478;&#22806;&#24314;&#31435; bitmap or array &#32080;&#27083;&#65292;&#36879;&#36942; epoll_create() system call&#65292;kernel &#26371;&#24314;&#31435;&#19968;&#38982;&#32005;&#40657;&#27193;&#36319; double linked list&#65292;&#20006;&#29992; epoll_ctl() system call &#23559; TCP &#36899;&#32218;&#25918;&#20837;&#32005;&#40657;&#27193;&#35731; kernel &#31649;&#29702;&#65292;&#32005;&#40657;&#27193;&#26032;&#22686;/&#21034;&#38500;&#36899;&#32218;&#30340;&#26178;&#38291;&#35079;&#38620;&#24230;&#28858; O(log n)&#65292;&#27604;&#38499;&#21015;&#26356;&#36969;&#21512;&#38971;&#32321;&#22686;&#28187;&#36899;&#32218;&#30340;&#22580;&#26223;&#12290; </p><p>user space process &#22519;&#34892; epoll_wait() system call&#65292;kernel &#26371;&#38459;&#22622;&#35442; process&#65292;&#30070;&#25910;&#21040;&#20013;&#26039;&#35338;&#34399;&#20006;&#34389;&#29702;&#23436;&#23553;&#21253;&#24460;&#65292;&#26371;&#36879;&#36942;&#20107;&#20808;&#35387;&#20874;&#30340; callback &#23559;&#23565;&#25033;&#36899;&#32218;&#25918;&#20837; double linked list&#65292;&#38568;&#24460;&#21914;&#37266; process&#65292;process &#30452;&#25509;&#24478; double linked list &#20013;&#29554;&#21462;&#21487;&#35712;&#30340;&#36899;&#32218;&#65292;&#19981;&#29992; scan &#25972;&#20491;&#32080;&#27083;&#12290;</p><p>&#19988;&#26377; double linked list &#32080;&#27083;&#30070;&#20316; queue&#65292;epoll &#33021;&#23526;&#29694;&#20841;&#31278;&#35320;&#30332;&#27169;&#24335;&#65306;</p><ul><li><p>Level-Triggered&#65306;&#30070;&#36899;&#32218;&#36996;&#26377;&#36039;&#26009;&#21487;&#35712;&#65292;epoll_wait() &#23601;&#26371;&#22238;&#20659;&#65292;&#20063;&#23601;&#26159;&#35498;&#27794;&#25226;&#25152;&#26377;&#36039;&#26009;&#35712;&#23436;&#21069;&#65292;&#19981;&#26371;&#24478; double linked list &#20013;&#31227;&#38500;&#12290;</p></li><li><p>Edge-Triggered&#65306;&#29376;&#24907;&#35722;&#21270;&#26178;&#35320;&#30332;&#65292;&#30070;&#26377;&#26032;&#36039;&#26009;&#21040;&#26178;&#65292;&#25918;&#36914; double linked list&#65292;epoll_wait() &#19968;&#22238;&#20659;&#23601;&#31227;&#38500;&#65292;&#30452;&#21040;&#19979;&#27425;&#26377;&#26032;&#36039;&#26009;&#25269;&#36948;&#25165;&#22312;&#25918;&#36914;&#21435;&#12290;</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Q5lA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1da64fa9-6524-4fc7-a78a-2ff17f8a7b7b_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Q5lA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1da64fa9-6524-4fc7-a78a-2ff17f8a7b7b_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Q5lA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1da64fa9-6524-4fc7-a78a-2ff17f8a7b7b_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Q5lA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1da64fa9-6524-4fc7-a78a-2ff17f8a7b7b_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Q5lA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1da64fa9-6524-4fc7-a78a-2ff17f8a7b7b_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Q5lA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1da64fa9-6524-4fc7-a78a-2ff17f8a7b7b_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1da64fa9-6524-4fc7-a78a-2ff17f8a7b7b_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:835886,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191958789?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1da64fa9-6524-4fc7-a78a-2ff17f8a7b7b_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Q5lA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1da64fa9-6524-4fc7-a78a-2ff17f8a7b7b_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Q5lA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1da64fa9-6524-4fc7-a78a-2ff17f8a7b7b_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Q5lA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1da64fa9-6524-4fc7-a78a-2ff17f8a7b7b_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Q5lA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1da64fa9-6524-4fc7-a78a-2ff17f8a7b7b_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Redis &amp; Nginx &#22914;&#20309;&#20351;&#29992; Epoll&#65311;</h1><p>&#20351;&#29992; epoll &#26178;&#65292;&#24120;&#35211;&#27169;&#24335;&#26159;&#29992;&#19968;&#20491; thread &#22519;&#34892; epoll_wait()&#65292;&#36991;&#20813;&#22810;&#32218;&#31243;&#21516;&#26178;&#34389;&#29702;&#30456;&#21516; TCP connection &#23566;&#33268;&#35712;&#21462;&#36039;&#26009;&#34987;&#25130;&#26039;&#65292;&#22240;&#27492;&#21934;&#32218;&#31243;&#30340; epoll loop &#22519;&#34892;&#36942;&#31243;&#23601;&#38656;&#35201;&#36991;&#20813;&#20219;&#20309;&#21487;&#33021;&#30340;&#38459;&#22622;&#12290;</p><p>epoll loop &#36942;&#31243;&#65306;</p><ol><li><p>&#20808;&#36879;&#36942; epoll_wait() &#25214;&#21040;&#21487;&#35712; I/O&#65292;&#28982;&#24460;&#22519;&#34892; read() &#35712;&#35531;&#27714;</p></li><li><p>&#34389;&#29702;&#23436;&#35531;&#27714;&#24460;&#65292;&#22519;&#34892; write() &#65292;&#33509; kernel &#30340; send buffer &#24050;&#28415;&#65292;non-blocking write() &#26371;&#36820;&#22238; error</p></li><li><p>&#25910;&#21040; error &#24460;&#23559;&#36039;&#26009;&#20808;&#23531;&#21040; buffer queue &#20006;&#22519;&#34892; epoll_ctl() &#30435;&#32893;&#35442; I/O &#30340;&#21487;&#23531;&#20107;&#20214;&#65292;&#28982;&#24460;&#22519;&#34892;&#19979;&#19968;&#27425;&#30340; epoll_wait() </p></li><li><p>&#31561;&#21040; send buffer &#26377;&#20301;&#32622;&#65292;epoll_wait() &#22238;&#20659;&#21487;&#23531; I/O&#65292;&#22312;&#23559; buffer queue &#20013;&#30340;&#32080;&#26524;&#23531;&#20837;&#65292;&#32780; write() &#25351;&#20196;&#26371;&#20808;&#23559;&#36039;&#26009;&#23531;&#21040; kernel &#30340; send buffer &#20013;&#65292;&#38568;&#24460;&#22312;&#30064;&#27493;&#23531;&#20837;&#32178;&#21345;&#65292;&#22240;&#27492;&#22519;&#34892;&#24456;&#24555;</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8Q8Q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9747d58-4bc8-472e-9623-b1d389396ac0_1024x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8Q8Q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9747d58-4bc8-472e-9623-b1d389396ac0_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!8Q8Q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9747d58-4bc8-472e-9623-b1d389396ac0_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!8Q8Q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9747d58-4bc8-472e-9623-b1d389396ac0_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!8Q8Q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9747d58-4bc8-472e-9623-b1d389396ac0_1024x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8Q8Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9747d58-4bc8-472e-9623-b1d389396ac0_1024x1536.png" width="1024" height="1536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d9747d58-4bc8-472e-9623-b1d389396ac0_1024x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1536,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:260021,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191958789?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9747d58-4bc8-472e-9623-b1d389396ac0_1024x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8Q8Q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9747d58-4bc8-472e-9623-b1d389396ac0_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!8Q8Q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9747d58-4bc8-472e-9623-b1d389396ac0_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!8Q8Q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9747d58-4bc8-472e-9623-b1d389396ac0_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!8Q8Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9747d58-4bc8-472e-9623-b1d389396ac0_1024x1536.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>&#36879;&#36942;&#19978;&#38754;&#27969;&#31243;&#65292;&#21487;&#30332;&#29694; Nginx &amp; Redis &#30340;&#35373;&#35336;&#37117;&#26159;&#27704;&#36960;&#19981;&#20570;&#26371;&#21345;&#20303;&#30340;&#34892;&#29234; (&#38500;&#20102; epoll_wait)&#65292;&#21482;&#26377;&#22312;&#21487;&#35712;&#25110;&#21487;&#23531;&#30340;&#26178;&#20505;&#25165;&#22519;&#34892; read() &#25110; write()&#65292;&#22240;&#27492; CPU &#20351;&#29992;&#29575;&#36229;&#39640;&#65292;&#27794;&#26377;&#32114;&#27627;&#28010;&#36027;&#65292;Thread &#25976;&#37327;&#20063;&#24456;&#23569;&#65292;&#35352;&#25014;&#39636;&#29992;&#37327;&#19981;&#22823;&#65292;&#36889;&#23601;&#26159;&#28858;&#20160;&#40636; Nginx &amp; Redis &#33021;&#22914;&#27492;&#39640;&#25928;&#34389;&#29702;&#30636;&#38291;&#22823;&#27969;&#37327;&#30340;&#31192;&#35363;&#65281;<br></p><p>&#27492;&#22806; Nginx &#20316;&#28858; proxy server &#28858;&#25552;&#39640;&#35531;&#27714;&#36681;&#30332;&#21534;&#21520;&#37327;&#65292;&#26371;&#36879;&#36942; kernel &#30340; SO_REUSEPORT flag&#65292;&#35731;&#19981;&#21516; process &#30340; tcp server &#30435;&#32893;&#30456;&#21516; port&#65292;kernel &#26371;&#33258;&#21205;&#20998;&#37197;&#36899;&#32218;&#21040;&#19981;&#21516; tcp server socket&#65292;&#32780;&#27599;&#19968;&#20491; thread &#21508;&#33258;&#29992;&#29544;&#31435;&#30340; epoll &#31649;&#29702;&#19981;&#21516;&#36899;&#32218;&#65292;&#23526;&#29694;&#20341;&#30332;&#26550;&#27083;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LwRz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88fe8ea6-13c3-443c-ad76-5c7b8fe0d7c9_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LwRz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88fe8ea6-13c3-443c-ad76-5c7b8fe0d7c9_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!LwRz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88fe8ea6-13c3-443c-ad76-5c7b8fe0d7c9_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!LwRz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88fe8ea6-13c3-443c-ad76-5c7b8fe0d7c9_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!LwRz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88fe8ea6-13c3-443c-ad76-5c7b8fe0d7c9_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LwRz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88fe8ea6-13c3-443c-ad76-5c7b8fe0d7c9_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/88fe8ea6-13c3-443c-ad76-5c7b8fe0d7c9_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:309910,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191958789?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88fe8ea6-13c3-443c-ad76-5c7b8fe0d7c9_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LwRz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88fe8ea6-13c3-443c-ad76-5c7b8fe0d7c9_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!LwRz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88fe8ea6-13c3-443c-ad76-5c7b8fe0d7c9_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!LwRz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88fe8ea6-13c3-443c-ad76-5c7b8fe0d7c9_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!LwRz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88fe8ea6-13c3-443c-ad76-5c7b8fe0d7c9_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Chill Vic&#8217;s Architecture Notes! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>&#22914;&#20309;&#29992; epoll &#23526;&#29694;&#39640;&#25928;&#30340; TCP Server&#65292;&#24050; Rust tokio &#22871;&#20214;&#28858;&#20363;&#65281;</h1><p>&#24120;&#35211;&#23526;&#20316; epoll loop &#30340; design pattern &#28858; reactor executor -  </p><p>reactor &#31649;&#29702;&#20107;&#20214;&#29376;&#24907;&#20006;&#21914;&#37266;&#20107;&#20214;&#65292;&#20363;&#22914; epoll_wait &#30435;&#32893; TCP &#36899;&#32218;&#29376;&#24907;&#65292;&#24478;&#19981;&#21487;&#35712;&#29376;&#24907;&#20006;&#21487;&#35712;&#26178;&#65292;process &#26371;&#34987;&#21914;&#37266;&#24478; queue &#20013;&#29554;&#24471;&#35442;&#36899;&#32218;&#12290;</p><p>executor &#21063;&#26159;&#34389;&#29702;&#35531;&#27714;&#30340;&#26680;&#24515;&#20803;&#20214;&#65292;&#20363;&#22914; redis &#36000;&#36012;&#34389;&#29702;&#35352;&#25014;&#39636;&#36039;&#26009;&#20197;&#21450; nginx &#34389;&#29702; http protocol &#35299;&#26512;&#36681;&#30332;&#31561;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7g-V!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3578309-4a3d-4af8-884e-63c26d63a740_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7g-V!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3578309-4a3d-4af8-884e-63c26d63a740_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!7g-V!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3578309-4a3d-4af8-884e-63c26d63a740_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!7g-V!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3578309-4a3d-4af8-884e-63c26d63a740_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!7g-V!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3578309-4a3d-4af8-884e-63c26d63a740_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7g-V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3578309-4a3d-4af8-884e-63c26d63a740_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e3578309-4a3d-4af8-884e-63c26d63a740_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:464059,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191958789?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3578309-4a3d-4af8-884e-63c26d63a740_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7g-V!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3578309-4a3d-4af8-884e-63c26d63a740_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!7g-V!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3578309-4a3d-4af8-884e-63c26d63a740_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!7g-V!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3578309-4a3d-4af8-884e-63c26d63a740_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!7g-V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3578309-4a3d-4af8-884e-63c26d63a740_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>&#32780;&#22312; Rust &#29983;&#24907;&#31995;&#20013;&#65292;&#23559;&#34987; reactor &#20803;&#20214;&#25152;&#31649;&#29702;&#30340;&#20107;&#20214;&#29376;&#24907;&#65292;&#25277;&#35937;&#21270;&#25104; Future trait&#65292;&#35442;&#20171;&#38754;&#20195;&#34920; async &#25805;&#20316;&#65292;&#36879;&#36942;&#22519;&#34892; poll &#20358;&#23526;&#38555;&#22519;&#34892; Future &#20839;&#37096;&#37007;&#36655;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WOFj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7acd134-7886-4554-a37d-2c26a6bea6ca_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WOFj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7acd134-7886-4554-a37d-2c26a6bea6ca_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!WOFj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7acd134-7886-4554-a37d-2c26a6bea6ca_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!WOFj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7acd134-7886-4554-a37d-2c26a6bea6ca_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!WOFj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7acd134-7886-4554-a37d-2c26a6bea6ca_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WOFj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7acd134-7886-4554-a37d-2c26a6bea6ca_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a7acd134-7886-4554-a37d-2c26a6bea6ca_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1672190,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191958789?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7acd134-7886-4554-a37d-2c26a6bea6ca_1024x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WOFj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7acd134-7886-4554-a37d-2c26a6bea6ca_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!WOFj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7acd134-7886-4554-a37d-2c26a6bea6ca_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!WOFj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7acd134-7886-4554-a37d-2c26a6bea6ca_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!WOFj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7acd134-7886-4554-a37d-2c26a6bea6ca_1024x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>&#20351;&#29992; Rust Future &#38283;&#30332;&#19968;&#20491;&#31777;&#21934;&#30340; reactor &#36319; executor &#27169;&#24335;</h2><p><strong>step 1 - &#23526;&#29694;&#19968;&#20491; time sleep future &#29992;&#20358;&#27169;&#25836;&#35531;&#27714;&#24310;&#36978;</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">struct SleepFuture {
    deadline: Instant,
}

impl SleepFuture {
    fn new(duration: Duration) -&gt; Self {
        SleepFuture {
            deadline: Instant::now() + duration,
        }
    }
}

impl Future for SleepFuture {
    type Output = ();
    fn poll(self: Pin&lt;&amp;mut Self&gt;, _cx: &amp;mut Context) -&gt; Poll&lt;()&gt; {
        if Instant::now() &gt;= self.deadline {
            Poll::Ready(())
        } else {
            Poll::Pending
        }
    }
}

async fn send_request() -&gt; i32 {
    SleepFuture::new(Duration::from_secs(2)).await;
    1 + 1
}

fn process_added_value(val: i32) {
    println!("&#34389;&#29702;&#21152;&#27861;&#32080;&#26524;: {}", val);
}</code></pre></div><p>step 2 - &#23526;&#29694; reactor-executor pattern&#65292;reactor &#36000;&#36012; trigger Ready &#29376;&#24907;&#30340; future &#23559;&#32080;&#26524;&#36879;&#36942; queue &#36865;&#32102; executor &#34389;&#29702;&#65292;executor &#21021;&#22987;&#21270;&#19968;&#20491; thread &#34389;&#29702; queue &#20013;&#30340;&#36039;&#26009;&#12290;<br></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">type BoxFuture = Pin&lt;Box&lt;dyn Future&lt;Output = i32&gt; + Send&gt;&gt;;

fn reactor(futures: Vec&lt;BoxFuture&gt;, tx: mpsc::Sender&lt;i32&gt;) {
    let waker = Waker::noop();
    let mut cx = Context::from_waker(&amp;waker);

    let mut tasks: Vec&lt;Option&lt;BoxFuture&gt;&gt; = futures.into_iter().map(Some).collect();
    let total = tasks.len();
    let mut done_count = 0;

    loop {
        for task in tasks.iter_mut() {
            if let Some(fut) = task {
                if let Poll::Ready(val) = fut.as_mut().poll(&amp;mut cx) {
                    tx.send(val).unwrap(); // Ready&#65281;&#19999;&#32102; executor
                    *task = None;
                    done_count += 1;
                }
            }
        }

        if done_count &gt;= total {
            break;
        }

        thread::sleep(Duration::from_millis(100)); 
    }
}

fn executor(rx: mpsc::Receiver&lt;i32&gt;, total: usize) -&gt; thread::JoinHandle&lt;()&gt; {
    thread::spawn(move || {
        let mut done = 0;
        while done &lt; total {
            let val = rx.recv().unwrap();
            process_added_value(val);
            done += 1;
        }
        println!("executor: &#20840;&#37096;&#34389;&#29702;&#23436;&#25104;");
    })
}</code></pre></div><p>step 3 - &#23436;&#25104; main function &#22519;&#34892;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">fn main() {
    let (tx, rx) = mpsc::channel();
    let futures: Vec&lt;BoxFuture&gt; = vec![Box::pin(send_request()), Box::pin(send_request())];

    let total = futures.len();
    let handle = executor(rx, total);

    let start = Instant::now();
    reactor(futures, tx);
    handle.join().unwrap();
    println!("&#20840;&#37096;&#23436;&#25104;&#65292;&#32791;&#26178;: {:?}", start.elapsed());
}
</code></pre></div><p>&#19978;&#36848;&#20195;&#30908;&#23637;&#31034;&#20102; Future trait &#30340;&#25277;&#35937;&#21270;&#33021;&#21147;&#65292;&#21487;&#25226;&#25152;&#26377;&#25805;&#20316;&#23553;&#35037;&#25104; async &#34892;&#28858;&#65292;&#33258;&#34892;&#23450;&#32681;&#29376;&#24907;&#36681;&#25563;&#26178;&#27231;&#65292;&#25645;&#37197;&#19981;&#21516;&#24213;&#23652;&#30340; event loop &#27231;&#21046;&#65292;&#21487;&#22312;&#19981;&#20462;&#25913;&#26680;&#24515;&#26989;&#21209;&#31243;&#24335;&#26781;&#20214;&#19979;&#65292;&#26367;&#25563;&#19981;&#21516;&#30340; reactor-executor &#30340;&#23526;&#20316;&#12290;</p><h2>Tokio &#30340; epoll &#26550;&#27083;</h2><p>&#32780; tokio &#20316;&#28858; rust &#20013;&#30693;&#21517;&#30340; async runtime&#65292;&#20854;&#24213;&#23652;&#26159;&#29992; epoll &#20358;&#23526;&#29694; reactor-executor&#65292;&#25105;&#20497;&#20358;&#30475;&#19968;&#19979;&#26368;&#31777;&#21934;&#30340; TCP echo server&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">use tokio::net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -&gt; Result&lt;(), Box&lt;dyn std::error::Error&gt;&gt; {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;

    loop {
        let (mut socket, _) = listener.accept().await?;

        tokio::spawn(async move {
            let mut buf = [0; 1024];

            // In a loop, read data from the socket and write the data back.
            loop {
                let n = match socket.read(&amp;mut buf).await {
                    // socket closed
                    Ok(0) =&gt; return,
                    Ok(n) =&gt; n,
                    Err(e) =&gt; {
                        eprintln!("failed to read from socket; err = {:?}", e);
                        return;
                    }
                };

                // Write the data back
                if let Err(e) = socket.write_all(&amp;buf[0..n]).await {
                    eprintln!("failed to write to socket; err = {:?}", e);
                    return;
                }
            }
        });
    }
}</code></pre></div><p><code>#[tokio::main]</code>&#36889;&#20491; macro &#26371;&#21021;&#22987;&#21270;&#19968;&#20491; runtime object&#65292;block_on &#23601;&#26159;&#31561;&#25152;&#26377; future &#20107;&#20214;&#37117;&#34389;&#29702;&#23436;&#65292;&#32780;&#20027;&#35201;&#30340; future &#29289;&#20214;&#26159;&#19968;&#20491; tcp server &#34389;&#29702;&#26032;&#36899;&#32218;&#65292;&#22240;&#27492; TCP server &#27794;&#38364;&#38281; runtime object &#19981;&#26371;&#32080;&#26463;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust"> #[tokio::main] &#23637;&#38283;&#24460;&#65292;&#23526;&#38555;&#19978;&#26159;&#65306;                                                       
  fn main() {                                                                                                 
      let runtime = tokio::runtime::Runtime::new().unwrap();                    
      //  &#20839;&#37096;&#20570;&#20102;&#65306;                                                              
      //  1. epoll_create()     &#8594; &#24314;&#31435; epoll &#23526;&#20363;                                                             
      //  2. &#24314;&#31435; thread pool   &#8594; worker threads                                                              
      //  3. &#24314;&#31435; timer wheel   &#8594; &#31649;&#29702; sleep/timeout                                                          
                                                                                                              
      runtime.block_on(async {                                                    
          let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap();                                  
          // ...                                                                                              
      });                                                                         
      // block_on &#21855;&#21205; reactor &#30340; event loop                                                                 
  }  </code></pre></div><h3>Tokio &#22914;&#20309;&#25226;&#36899;&#32218;&#25918;&#20837; Epoll &#20013;&#65311;</h3><p><code>tokio::net::TcpListener</code> &#36319; <code>tokio::io::{AsyncReadExt, AsyncWriteExt}</code> &#26377;&#21029;&#26044; std &#22871;&#20214;&#20013;&#30340; socket &#29289;&#20214;&#65292;&#23526;&#20316;&#20102; epoll &#29256;&#26412;&#30340; Future&#65292;&#20363;&#22914;&#19979;&#38754;&#31034;&#24847; code : </p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">impl Future for TcpReadFuture {
    type Output = Vec&lt;u8&gt;;

    fn poll(mut self: Pin&lt;&amp;mut Self&gt;, cx: &amp;mut Context) -&gt; Poll&lt;Vec&lt;u8&gt;&gt; {
        match non_blocking_read(self.fd, &amp;mut self.buf) {
            Ok(data) =&gt; Poll::Ready(data), // &#26377;&#36039;&#26009;&#65292;&#30452;&#25509;&#22238;&#20659;
            Err(WouldBlock) =&gt; {
                if !self.registered {
                    reactor.register(self.fd, Interest::READ, cx.waker().clone());
                    self.registered = true;
                }
                Poll::Pending                        
            }
        }
    }
}</code></pre></div><p>&#35712;&#21040;&#36039;&#26009;&#23601;&#22238;&#20659; OK&#65292;&#27794;&#35712;&#21040;&#36879;&#36942; <code>epoll_ctl</code> &#25918;&#21040; epoll &#32080;&#27083;&#20013;&#65292;&#20006;&#22238;&#20659; pending&#65292;&#32780;&#22519;&#34892; <code>await (e.g socket.read(&amp;mut buf).await)</code> &#26178;&#65292;&#32232;&#35695;&#22120;&#26371;&#29986;&#29983; :</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">loop {
    match future.poll(cx) {
        Poll::Ready(val) =&gt; break val,
        Poll::Pending =&gt; {
            return Poll::Pending;
        }
    }
}</code></pre></div><p>&#22519;&#34892; poll &#26178;&#26371;&#23559;&#35442; future &#20013;&#30340; connection &#25918;&#20837; epoll &#20013;&#12290;<br><br>&#26368;&#24460; tokio &#30340; reactor &#27169;&#32068;&#26371;&#22519;&#34892; <code>epoll_wait</code> &#25214;&#21040;&#21487;&#35712;&#36899;&#32218;&#65292;&#25918;&#20837; queue &#20013;&#20132;&#30001;&#19981;&#21516; worker thread &#34389;&#29702;&#12290;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;rust&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-rust">// reactor &#31034;&#24847; code
 impl Reactor {                                                                       
      // Reactor &#29544;&#31435;&#36939;&#20316;&#65292;&#21482;&#36000;&#36012;&#21914;&#37266;
      fn run(&amp;mut self) {                                                             
          loop {                                                                
              let timeout = self.nearest_timer_deadline();                            
              let ready_fds = epoll_wait(self.epoll_fd, timeout);               
                                                                                                              
              for (fd, token) in ready_fds {
                  self.run_queue.push(token.task_id);  // &#19999;&#36914;&#20849;&#20139; queue               
              }                                                                       
          }
      }
  }</code></pre></div><h3>Tokio &#30340; worker thread &#22914;&#20309;&#29986;&#29983;?</h3><p>&#30070; TCP server &#25910;&#21040;&#19968;&#20491;&#36899;&#32218;&#24460;&#22519;&#34892;&#30340; tokio::spawn(async move {...})&#65292;&#35442; spawn &#20006;&#19981;&#26371;&#21021;&#22987;&#21270; kernel thread&#65292;&#32780;&#26159;&#23559;&#36889;&#20491; async future &#29289;&#20214;&#25918;&#36914; worker queue&#65292;&#20132;&#30001;&#19981;&#21516; kernel thread (executor) &#22519;&#34892;&#12290;</p><p>&#27599;&#20491; kernel thread &#26371;&#24478; queue &#20013;&#29554;&#21462; future task &#20006;&#22519;&#34892; poll &#65292;&#27010;&#24565; code &#22914;&#19979;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;javascript&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-javascript"># Conceptual code example
fn worker_thread(run_queue: Arc&lt;SharedQueue&gt;, tasks: Arc&lt;TaskMap&gt;) {
    loop {
        let task_id = run_queue.pop(); // Blocks if queue is empty
        let task = tasks.get(task_id);
        match task.poll(&amp;mut cx) {
            Poll::Ready(()) =&gt; { tasks.remove(task_id); }
            Poll::Pending   =&gt; { /* Waker is registered, wait for next wake-up */ }
        }
    }
}</code></pre></div><p>&#32780; worker thread &#26371;&#22312;&#24314;&#31435; runtime &#30340;&#26178;&#20505;&#25351;&#23450; thread &#25976;&#37327;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">#[tokio::main(flavor = "multi_thread", worker_threads = 4)]
async fn main() {
    // your async code
}</code></pre></div><h3>Nested Future Task</h3><p>&#19978;&#38754; TCP Echo server &#20013;&#65292;worker thread &#34389;&#29702;&#30340;&#27599;&#20491; task &#26159;&#22519;&#34892; connection read &amp; write &#30340; nested future &#32080;&#27083;&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;ba04273a-45b9-4ac4-a106-64197daaf38e&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext"> spawn Future&#65288;ReadLoopFuture&#65289;                                                                           
    &#9492;&#9472;&#9472; socket.read().await&#65288;TcpReadFuture&#65289;                                                                  
          &#9492;&#9472;&#9472; non_blocking_read() &#8594; WouldBlock &#8594; register epoll                                                   
    &#9492;&#9472;&#9472; socket.write().await&#65288;TcpWriteFuture&#65289;                                                                
          &#9492;&#9472;&#9472; non_blocking_write() &#8594; WouldBlock &#8594; register epoll </code></pre></div><p>socket read &#33509;&#27794;&#36039;&#26009;&#65292;&#26371;&#25918;&#21040; epoll &#31561; reactor &#36890;&#30693;&#65292;&#27492;&#26178; executor &#25910;&#21040; socket.read() return &#30340; pending &#29376;&#24907;&#24460;&#26371;&#34389;&#29702;&#19979;&#19968;&#20491;&#36899;&#32218;&#30340; future&#65292;&#31561; reactor &#21914;&#37266;&#35442; future &#24460;&#24448;&#19979;&#34389;&#29702;&#36914;&#34892; write&#65292;&#21516;&#27171;&#33509; write buffer &#28415;&#20102;&#26371;&#22238; pending &#31561; reactor &#20877;&#27425;&#21914;&#37266;&#25165;&#23531;&#20837;&#25104;&#21151;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DeiY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F127dabc6-fbe4-46be-a4c3-68731e3e8c34_1024x1524.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DeiY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F127dabc6-fbe4-46be-a4c3-68731e3e8c34_1024x1524.png 424w, https://substackcdn.com/image/fetch/$s_!DeiY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F127dabc6-fbe4-46be-a4c3-68731e3e8c34_1024x1524.png 848w, https://substackcdn.com/image/fetch/$s_!DeiY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F127dabc6-fbe4-46be-a4c3-68731e3e8c34_1024x1524.png 1272w, https://substackcdn.com/image/fetch/$s_!DeiY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F127dabc6-fbe4-46be-a4c3-68731e3e8c34_1024x1524.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DeiY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F127dabc6-fbe4-46be-a4c3-68731e3e8c34_1024x1524.png" width="1024" height="1524" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/127dabc6-fbe4-46be-a4c3-68731e3e8c34_1024x1524.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1524,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1403346,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191958789?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F127dabc6-fbe4-46be-a4c3-68731e3e8c34_1024x1524.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!DeiY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F127dabc6-fbe4-46be-a4c3-68731e3e8c34_1024x1524.png 424w, https://substackcdn.com/image/fetch/$s_!DeiY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F127dabc6-fbe4-46be-a4c3-68731e3e8c34_1024x1524.png 848w, https://substackcdn.com/image/fetch/$s_!DeiY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F127dabc6-fbe4-46be-a4c3-68731e3e8c34_1024x1524.png 1272w, https://substackcdn.com/image/fetch/$s_!DeiY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F127dabc6-fbe4-46be-a4c3-68731e3e8c34_1024x1524.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>&#26368;&#32066;&#25972;&#20491; tokio runtime &#26550;&#27083;&#28858;&#65306;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!t1Dh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc6ba1b-fe1c-4105-a6e0-01bcd19909b0_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!t1Dh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc6ba1b-fe1c-4105-a6e0-01bcd19909b0_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!t1Dh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc6ba1b-fe1c-4105-a6e0-01bcd19909b0_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!t1Dh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc6ba1b-fe1c-4105-a6e0-01bcd19909b0_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!t1Dh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc6ba1b-fe1c-4105-a6e0-01bcd19909b0_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!t1Dh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc6ba1b-fe1c-4105-a6e0-01bcd19909b0_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bfc6ba1b-fe1c-4105-a6e0-01bcd19909b0_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:369390,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/191958789?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc6ba1b-fe1c-4105-a6e0-01bcd19909b0_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!t1Dh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc6ba1b-fe1c-4105-a6e0-01bcd19909b0_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!t1Dh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc6ba1b-fe1c-4105-a6e0-01bcd19909b0_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!t1Dh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc6ba1b-fe1c-4105-a6e0-01bcd19909b0_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!t1Dh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc6ba1b-fe1c-4105-a6e0-01bcd19909b0_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>&#19979;&#38598;&#38928;&#21578;</h1><p>&#38614;&#28982; epoll &#25552;&#20379;&#26159;&#22823;&#37096;&#20998;&#39640;&#25928; server &#30340;&#24213;&#23652;&#25216;&#34899;&#39318;&#36984;&#65292;&#20294;&#38568;&#33879; kernel &#28436;&#36914;&#65292;&#20840;&#26032;&#30340; async I/O &#34389;&#29702;&#25216;&#34899;&#20063;&#38568;&#33879;&#20986;&#29694;&#65292;&#20063;&#23601;&#26159; io_uring&#65292;&#19988; rust tokio &#20063;&#26377;&#29992; io_uring &#23526;&#29694; async runtime&#65292;&#19979;&#19968;&#38598;&#26371;&#20171;&#32057; epoll &#30340;&#25928;&#33021;&#21839;&#38988;&#65292;&#20197;&#21450; io_uring &#22914;&#20309;&#35299;&#27770;&#65281;</p>]]></content:encoded></item><item><title><![CDATA[How to ACE the "Design a Rate Limiter" system design interview.]]></title><description><![CDATA[Rate Limiter Algorithm Explanation and Use Case Analysis]]></description><link>https://www.chillvic.dev/p/how-to-give-a-full-score-answer-to</link><guid isPermaLink="false">https://www.chillvic.dev/p/how-to-give-a-full-score-answer-to</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Sun, 22 Feb 2026 10:15:25 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!E3zn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2872293-8946-41df-95a5-0bb06364b02b_1696x2528.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Rate limiting is a critical component of system design and a frequently asked topic in technical interviews. To provide a &#8220;100-point&#8221; answer when asked how to implement a rate limiter, you need to go beyond just listing algorithms and demonstrate a deep understanding of their trade-offs, business applications, and distributed system challenges.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!E3zn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2872293-8946-41df-95a5-0bb06364b02b_1696x2528.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!E3zn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2872293-8946-41df-95a5-0bb06364b02b_1696x2528.png 424w, https://substackcdn.com/image/fetch/$s_!E3zn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2872293-8946-41df-95a5-0bb06364b02b_1696x2528.png 848w, https://substackcdn.com/image/fetch/$s_!E3zn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2872293-8946-41df-95a5-0bb06364b02b_1696x2528.png 1272w, https://substackcdn.com/image/fetch/$s_!E3zn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2872293-8946-41df-95a5-0bb06364b02b_1696x2528.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!E3zn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2872293-8946-41df-95a5-0bb06364b02b_1696x2528.png" width="1456" height="2170" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c2872293-8946-41df-95a5-0bb06364b02b_1696x2528.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2170,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:7608568,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/188783999?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2872293-8946-41df-95a5-0bb06364b02b_1696x2528.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!E3zn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2872293-8946-41df-95a5-0bb06364b02b_1696x2528.png 424w, https://substackcdn.com/image/fetch/$s_!E3zn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2872293-8946-41df-95a5-0bb06364b02b_1696x2528.png 848w, https://substackcdn.com/image/fetch/$s_!E3zn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2872293-8946-41df-95a5-0bb06364b02b_1696x2528.png 1272w, https://substackcdn.com/image/fetch/$s_!E3zn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2872293-8946-41df-95a5-0bb06364b02b_1696x2528.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h1>Interviewer: How would you clearly explain the trade-offs and use cases of different rate limiting algorithms?</h1><p>The first step is to categorize rate limiters based on their logic.</p><h2><strong>Time-Window Based Limiters</strong></h2><p>These allow <code>N</code> requests within a specified timeframe. They are generally divided into <strong>Fixed Window</strong> and <strong>Sliding Window</strong>.</p><ul><li><p><strong>Fixed Window:</strong> Requests are counted within fixed time intervals (e.g., 1:00&#8211;1:01, 1:01&#8211;1:02).</p><ul><li><p><strong>Pros:</strong> Extremely simple to implement by mapping timestamps to buckets.</p></li><li><p><strong>Cons:</strong> The &#8220;Boundary Problem.&#8221; A burst of traffic can occur at the junction of two windows. </p><p>For example, if the limit is 100/min, a user could send 100 requests at 1:01:59 and another 100 at 1:02:00, effectively doubling the allowed rate in just two seconds.</p></li></ul></li><li><p><strong>Sliding Window:</strong> This tracks the exact arrival time of each request within the last <code>X</code> seconds.</p><ul><li><p><strong>Implementation:</strong> You can use a <strong>Redis Sorted Set</strong> to store every request timestamp. Before checking the limit, you remove all timestamps older than the current window (<code>current_time</code> - <code>window_size</code>).</p></li><li><p><strong>Trade-off:</strong> While this provides precise control and eliminates boundary bursts, the storage and processing costs are high for high-concurrency traffic.</p></li><li><p><strong>Optimization:</strong> An &#8220;Approximated Sliding Window&#8221; can be used, which divides the window into <code>N</code> smaller buckets. This sacrifices a bit of precision for high efficiency while still smoothing out the boundary spikes of the Fixed Window.</p></li></ul></li></ul><h3><strong>When to use Time-Window Limiters?</strong></h3><p>These are ideal for <strong>Quota Management</strong> where the goal is to limit total resource consumption over time.</p><ul><li><p><strong>Examples:</strong> Limiting a user to 10 SMS messages per hour or 1,000 API calls per day for a subscription tier.</p></li></ul><p><strong>The Downside:</strong> </p><p>If a user exhausts their 120-request-per-minute limit in the first 10 seconds, the server remains idle for the remaining 50 seconds. <strong>While acceptable for resource-intensive APIs</strong> (where waiting is a reasonable business constraint), this &#8220;forced idling&#8221; is detrimental to <strong>Service-Oriented APIs</strong> (e.g., payments or order placement), <strong>where every second of waiting could result in lost transactions or market opportunities.</strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.chillvic.dev/subscribe?"><span>Subscribe now</span></a></p><h2>Usage-Based Limiters: Token Bucket &amp; Leaky Bucket</h2><p>For service-based APIs, the goal is <strong>Traffic Shaping</strong>&#8212;maintaining a stable, continuous flow rather than just enforcing a hard time-range quota.</p><h3><strong>Token Bucket</strong></h3><p>Tokens represent the &#8220;capacity&#8221; to process a request. Tokens are added to the bucket at a fixed <code>refill_rate</code> (e.g., 1 token/sec).</p><ul><li><p><strong>Implementation Detail:</strong> An efficient way to implement this is not through a background thread, but by recording the <code>last_request_arrival_time</code>. When a new request arrives, you calculate the <code>elapsed_time</code>, multiply it by the <code>refill_rate</code> to determine how many tokens to add, and cap it at the bucket&#8217;s maximum capacity.</p></li><li><p><strong>Behavior:</strong> For a limit of 120/min, you could set an initial capacity of 120 tokens and a refill rate of 2/sec. If a user exhausts all 120 tokens in the first second, they don&#8217;t have to wait 50 seconds; they can continue at a steady pace of 2 requests per second as tokens refill.</p></li><li><p><strong>The &#8220;Burst&#8221; Logic:</strong> <strong>The Token Bucket algorithm allows for an initial burst of traffic; however, once a burst occurs, it immediately throttles the rate, converting the traffic into a stable flow.</strong></p></li></ul><h3><strong>Leaky Bucket</strong></h3><p><strong>If your system strictly cannot allow bursts, you should use the Leaky Bucket instead.</strong> Imagine a bucket with a fixed capacity and a hole at the bottom. Requests enter the bucket and are "leaked" (processed) at a constant, predetermined rate.</p><ul><li><p><strong>Implementation Detail:</strong> Rather than a literal queue data structure, an efficient implementation uses time. You maintain a <code>next_free_time</code> variable representing when the next request can be processed:</p><p>Python</p></li></ul><pre><code><code>if request_arrival_time &gt;= next_free_time:
    process_immediately()
    next_free_time = now() + interval
else:
    wait_time = next_free_time - request_arrival_time
    next_free_time += interval
    sleep(wait_time) # or reject if the queue capacity is exceeded</code></code></pre><ul><li><p><strong>Behavior:</strong> With a processing rate of 2/sec (0.5s interval), the Leaky Bucket guarantees that exactly one request is handled every 0.5 seconds, effectively smoothing out any spikes. The bucket&#8217;s &#8220;capacity&#8221; here refers to how many requests can be queued before they are rejected, but it never allows for a simultaneous burst of processing.</p></li></ul><h3><strong>Practical Comparison:</strong></h3><p>In most real-world scenarios, the <strong>Token Bucket</strong> is more practical because it offers better responsiveness by allowing minor bursts. However, the <strong>Leaky Bucket</strong> is essentially a "simplified queue." </p><p>For instance, if an admin triggers 10 heavy report-generation tasks at once, a Leaky Bucket prevents OOM (Out of Memory) by forcing them to be processed sequentially at a safe speed, achieving the benefits of a Queue + Worker setup without the architectural complexity.<br></p><h1>Interviewer: How to Configure Rate Limit Parameters?</h1><p>When an interviewer asks how to set the actual limits, they aren&#8217;t looking for a magic number. They want to see a <strong>Configuration Strategy</strong>:</p><ul><li><p><strong>Identify Dimensions:</strong></p><ul><li><p><strong>Authenticated APIs:</strong> Limit by <code>User ID</code> or <code>API Key</code>.</p></li><li><p><strong>Public APIs:</strong> Limit by <code>IP Address</code>. (Note the caveat: multiple users might share one IP, such as a corporate Wi-Fi, and you must handle proxy headers to get the true client IP).</p></li></ul></li><li><p><strong>Identify Resource Bottlenecks:</strong></p><ul><li><p>Analyze the capacity of your Database, Redis, or third-party services (SMTP, SMS gateways). Know the connection pool limits and the external provider&#8217;s own rate limits.</p></li></ul></li><li><p><strong>Data-Driven Decisions:</strong> * Don&#8217;t guess. Analyze production logs to find <strong>P95 and P99</strong> request rates as a baseline.</p><ul><li><p>Set up real-time monitoring to observe <strong>429 (Too Many Requests)</strong> error rates and system resource utilization to fine-tune the limits dynamically.</p></li></ul></li></ul><h1>Interviewer: How to implement a Distributed Rate Limiter?</h1><p>As systems scale, rate limiting data must be stored in a centralized store, typically <strong>Redis</strong>. The primary challenge here is handling <strong>Race Conditions</strong> under high concurrency.</p><p><strong>The Atomicity Problem:</strong> Even though Redis is single-threaded, a rate-limiting check involves multiple steps: <code>GET counter</code>, <code>CHECK if limit exceeded</code>, and <code>INCR counter</code>. If these are sent as separate commands, Redis cannot guarantee they will be executed as one uninterrupted block. Two different API servers could <code>GET</code> the same counter value, both pass the <code>CHECK</code>, and both increment it, leading to a limit violation.</p><p><strong>The Solution: Lua Scripts</strong> </p><p>To ensure <strong>Atomicity</strong>, you must wrap the logic in a <strong>Lua script</strong> and send it to Redis. Redis executes the entire script as a single, atomic command. During its execution, no other commands can interfere. </p><p>This prevents race conditions entirely and ensures that the &#8220;check-and-set&#8221; logic is thread-safe across the entire distributed cluster.</p>]]></content:encoded></item><item><title><![CDATA[The Core of Concurrent Programming: Atomic Operations are Not Locks]]></title><description><![CDATA[An Analysis of CPU MESI and Atomic Mechanisms]]></description><link>https://www.chillvic.dev/p/the-core-of-concurrent-programming</link><guid isPermaLink="false">https://www.chillvic.dev/p/the-core-of-concurrent-programming</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Fri, 13 Feb 2026 22:13:52 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!b_rP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Atomic operations are the bedrock of concurrent programming. For instance, a Mutex is often implemented using an atomic <strong>Compare-And-Swap (CAS)</strong> at its lowest level. While many initially view Atomics as "CPU-level locks," they are actually mechanisms designed to solve memory synchronization issues across multiple CPU cores in a concurrent read/write environment.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!b_rP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!b_rP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!b_rP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!b_rP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!b_rP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!b_rP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png" width="1024" height="1536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1536,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!b_rP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!b_rP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!b_rP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!b_rP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>The Problem: Why Multi-Core Concurrency Fails</h1><p>Due to physical limitations in hardware circuitry, larger memory capacity results in higher latency. To mitigate this, CPUs use a <strong>Memory Hierarchy</strong> to reduce average access costs.</p><p>Each core uses <strong>Registers</strong> to store data during execution. To avoid hitting the RAM for every variable, cores read data in <strong>Cache Lines (typically 64B)</strong>. These are stored in different cache levels:</p><ul><li><p><strong>L1:</strong> Private to each core.</p></li><li><p><strong>L2:</strong> Mostly private (architecture dependent).</p></li><li><p><strong>L3:</strong> Shared across all cores.</p></li><li><p><strong>RAM:</strong> The final main memory storage.</p></li></ul><p>When a core looks for data, it checks L1 &#8594; L2 &#8594; L3 &#8594; RAM. Once found, the data is filled back up the chain (L3 &#8594; L2 &#8594; L1). If a cache is full, it evicts existing lines to make room.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rqNm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rqNm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!rqNm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!rqNm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!rqNm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rqNm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rqNm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!rqNm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!rqNm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!rqNm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>The <code>x++</code> Race Condition</h3><p>When multiple cores execute <code>x++</code>, the actual instructions are:</p><pre><code>LOAD x &#8594; register
ADD 1
STORE register &#8594; x</code></pre><p>If every STORE had to go straight to RAM, the CPU would be unbearably slow. Instead, modern processors use a per-core store buffer, which temporarily queues writes. These updates are handed off to the cache subsystem, committed into the L1 cache line, and the line is marked dirty. <strong>The data is not written back to RAM (or the lower cache levels such as L3) immediately&#8212;it is propagated only later, typically when the cache line is evicted or a coherence event forces it.</strong></p><p>Because L1 is not shared, two threads on different cores might have their own local copies of the same cache line. They increment their local versions, leading to a <strong>Race Condition</strong> where updates are lost.</p><h1>The Solution: Cache Coherency and MESI</h1><p>To solve this, hardware designers created a <strong>Coherence Interconnect</strong>&#8212;a high-speed pathway for cores to communicate. Rather than constantly sending data, they exchange <strong>Cache Line States</strong> to establish <strong>Ownership and and trigger write-backs</strong>. This is governed by the <strong>MESI Protocol</strong>:</p><ul><li><p><strong>M (Modified):</strong> This core has modified the line; it&#8217;s the only copy, and it&#8217;s &#8220;dirty&#8221; (not yet in RAM).</p></li><li><p><strong>E (Exclusive):</strong> This core is the only one with this line; it matches RAM.</p></li><li><p><strong>S (Shared):</strong> Multiple cores have this line; it matches RAM.</p></li><li><p><strong>I (Invalid):</strong> The data is stale because another core modified it.</p></li></ul><h3>The MESI State Machine</h3><ul><li><p><strong>I &#8594; E/S:</strong> Core reads the latest state.</p></li><li><p><strong>S &#8594; M:</strong> Core gains ownership to write.</p></li><li><p><strong>M &#8594; I:</strong> Core receives a notification that another core modified the line.</p></li><li><p><strong>M &#8594; S:</strong> Core sees another core wants to read; it immediately syncs to L3/RAM and changes to Shared.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VsWl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VsWl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!VsWl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!VsWl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!VsWl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VsWl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!VsWl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!VsWl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!VsWl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!VsWl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>To ensure only one core has ownership at a time, the system uses a <strong>BUS</strong> (or Ring/Mesh interconnect). Cores <strong>Snoop</strong> on the BUS for requests and must return an <strong>ACK</strong> before the BUS processes the next request.</p><h3><strong>The Role of the BUS in Serialization:</strong> </h3><p>The coherence interconnect (the BUS) acts as a bottleneck by design to enforce order. When multiple cores try to write to the same cache line, the BUS serializes these requests, ensuring they are handled one by one.</p><p>For instance, if Core <code>A</code> and Core <code>B</code> simultaneously issue a <code>PrWr</code> (Processor Write) request for cache line <code>X</code> to the BUS:</p><ol><li><p>Through bus <strong>arbitration</strong>, the system <strong>serializes</strong> the requests and handles Core A's operation first.</p></li><li><p>When Core B receives Core A&#8217;s <code>PrWr</code> via snooping, it transitions its own cache line X state to <strong>I (Invalid)</strong>. Once Core A receives ACKs from all cores, it changes its state to <strong>M (Modified)</strong>.</p></li><li><p>Subsequently, when the BUS processes Core B&#8217;s <code>PrWr</code>, Core B finds its state is already <strong>I</strong> and cannot transition directly to <strong>M</strong>. It returns a <strong>NACK</strong> and switches to a <strong>PrRd</strong> (Processor Read) request.</p></li><li><p>Once Core A completes its update and receives Core B&#8217;s <strong>PrRd</strong>, it detects that its own state is <strong>M</strong>, <strong>triggers a write-back</strong> to L3 or RAM, and changes its state to <strong>S (Shared)</strong>. This allows Core B to read the latest data.</p></li><li><p>Finally, Core B issues another <code>PrWr</code> to obtain ownership and executes its update.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hVN_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60092699-5e59-4839-a06e-3c1fe884de5d_2816x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hVN_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60092699-5e59-4839-a06e-3c1fe884de5d_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!hVN_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60092699-5e59-4839-a06e-3c1fe884de5d_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!hVN_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60092699-5e59-4839-a06e-3c1fe884de5d_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!hVN_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60092699-5e59-4839-a06e-3c1fe884de5d_2816x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hVN_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60092699-5e59-4839-a06e-3c1fe884de5d_2816x1536.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/60092699-5e59-4839-a06e-3c1fe884de5d_2816x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5693263,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/187900483?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60092699-5e59-4839-a06e-3c1fe884de5d_2816x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hVN_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60092699-5e59-4839-a06e-3c1fe884de5d_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!hVN_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60092699-5e59-4839-a06e-3c1fe884de5d_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!hVN_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60092699-5e59-4839-a06e-3c1fe884de5d_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!hVN_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60092699-5e59-4839-a06e-3c1fe884de5d_2816x1536.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><blockquote><p><strong>In simple terms, MESI defines the state machine for cache lines, while the centralized BUS serializes the order of state transitions.</strong> <br><br>Through the snooping and ACK mechanisms, multiple cores ensure that at any given point, cache line states are consistent across the system&#8212;preventing two cores from both holding the <strong>M</strong> state for the same cache line simultaneously.</p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.chillvic.dev/subscribe?"><span>Subscribe now</span></a></p><h1>Why MESI Isn&#8217;t Enough: The Need for Atomic Instructions</h1><p>Even with MESI, the <code>x++</code> problem persists because <code>x++</code> is multiple steps. <br><br>The <code>x++</code> operation is composed of three distinct steps:</p><pre><code>LOAD x &#8594; register
ADD 1
STORE register &#8594; x</code></pre><p>This process requires two separate state transitions: <br><br>1. The LOAD triggers an <code>I</code> &#8594; <code>S</code> transition, where the CPU moves <code>x</code> into a register and then performs the ADD. <br>2. Later, the STORE triggers an <code>S</code> &#8594; <code>M</code> transition to write the data back to L1 (and eventually to L3 or RAM when requested).<br></p><p>The problem is that <strong>simultaneous LOADs are perfectly legal</strong> under the MESI protocol. If Core A and Core B both LOAD <code>x</code> into their registers at the same time, they each hold a local copy of the same value. Even though Core B&#8217;s <strong>STORE</strong> will technically wait for Core A to finish its write (due to BUS arbitration), Core B will still perform the <strong>ADD</strong> using the <strong>stale value already sitting in its register</strong>.</p><p>In short, the <strong>Invalid (I)</strong> state transition only affects the cache line; it does <strong>not</strong> affect data that has already been moved into a register. <strong>Once a value is in the register, it is &#8220;locked in&#8221; for that execution cycle.</strong></p><h3>How Atomic Solves the Race: <code>LOCK XADD</code></h3><p>To resolve this, atomic operations transform <code>x++</code> into a specialized instruction, such as LOCK XADD. This instruction forces the entire read-modify-write sequence to act as a single, indivisible state transition.</p><p>For example, when two cores execute <code>loop { atomic.add(&amp;x, 1) }</code>, they both issue a write request (<code>PrWr</code>) to the BUS:</p><ul><li><p>If the BUS arbitrates and processes Core A first, Core A will execute the <strong>entire LOAD &#8594; ADD &#8594; STORE sequence in one go</strong>.</p></li><li><p>Core A will <strong>not return an ACK</strong> to any subsequent requests until all three steps are completed.</p></li></ul><p>This ensures that by the time the BUS handles the next request (from Core B), Core A has already synchronized the updated data to the system. This effectively prevents the possibility of Core A and Core B performing a <strong>simultaneous LOAD</strong> into their registers.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cloi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91508a20-c798-4a4e-a4c4-2d4b8f718696_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cloi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91508a20-c798-4a4e-a4c4-2d4b8f718696_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!cloi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91508a20-c798-4a4e-a4c4-2d4b8f718696_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!cloi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91508a20-c798-4a4e-a4c4-2d4b8f718696_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!cloi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91508a20-c798-4a4e-a4c4-2d4b8f718696_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cloi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91508a20-c798-4a4e-a4c4-2d4b8f718696_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/91508a20-c798-4a4e-a4c4-2d4b8f718696_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:333797,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/187900483?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91508a20-c798-4a4e-a4c4-2d4b8f718696_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cloi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91508a20-c798-4a4e-a4c4-2d4b8f718696_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!cloi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91508a20-c798-4a4e-a4c4-2d4b8f718696_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!cloi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91508a20-c798-4a4e-a4c4-2d4b8f718696_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!cloi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91508a20-c798-4a4e-a4c4-2d4b8f718696_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This atomic mechanism is not limited to <code>x++</code> or <code>x--</code> it is also the foundation for the <strong>CAS (Compare-And-Swap)</strong> operation:</p><pre><code>// Conceptual CAS Logic
LOAD flag  -&gt; register
if flag == 0
   flag  =  1
   STORE register -&gt; flag
   STORE true -&gt; ok
else 
   STORE false -&gt; ok</code></pre><p><strong>CAS is the heart of a Mutex:</strong></p><pre><code>// Conceptual Logic
lock   =&gt; for (!atomic.CAS(&amp;lock, 0, 1)) { /* spin/park */ }
unlock =&gt; atomic.CAS(&amp;lock, 1, 0)</code></pre><h1>Optimization Pitfalls: Store Buffers and Invalidation Queues</h1><p><strong>If Atomics solve the multi-step problem, why do we need atomic.Load and atomic.Store for single-step operations?</strong> </p><p>The answer lies in Performance Optimizations that cause Memory Reordering.</p><p>While MESI ensures cache consistency, the <strong>ACK mechanism</strong> introduces two significant performance bottlenecks (latencies):</p><ul><li><p><strong>Write Latency:</strong> When Core A issues a <code>PrWr</code>, it must wait for ACKs from all other cores (confirming they&#8217;ve invalidated their copies) before it can actually commit the update. During this period, the core is forced to <strong>stall</strong>.</p></li><li><p><strong>Invalidation Latency:</strong> When Core B receives Core A&#8217;s <code>PrWr</code>, it must mark its L1 cache line as <strong>Invalid (I)</strong> before sending the ACK. Even though cache is fast, it is significantly slower than registers. If the cache is busy, Core A stays stalled even longer.</p></li></ul><p>To optimize performance, CPUs implement <strong>Delayed Execution</strong>:</p><p><strong>The Hardware &#8220;Cheats&#8221;: Store Buffers &amp; Invalidation Queues</strong></p><ul><li><p><strong>To solve Write Latency:</strong> Instead of stalling, the core places the write command into a <strong>Store Buffer</strong> (a local queue) and moves on to the next instruction immediately.<br></p><p><em><strong>Example:</strong></em>  a = 1; b = y;</p><pre><code>STORE 1 =&gt; a
LOAD y =&gt; register
STORE register =&gt; b</code></pre><p>For the <code>STORE 1 =&gt; a</code> is buffered while the core proceeds to <code>LOAD y</code>. If <code>y</code> is already in a valid local state (<strong>E</strong> or <strong>S</strong>), the core loads it into a register and then executes <code>STORE register =&gt; b</code> before the original <code>a = 1</code> even receives its ACKs.</p></li><li><p><strong>To solve Invalidation Latency:</strong> When a core receives a <code>PrWr</code> from another core, it doesn&#8217;t invalidate its cache line immediately. Instead, it places the request into an <strong>Invalidation Queue</strong> and sends the ACK instantly to let the sender continue.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BjKx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BjKx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!BjKx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!BjKx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!BjKx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BjKx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BjKx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!BjKx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!BjKx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!BjKx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>The Consequence: Store-Load Reordering</h3><p>These optimizations cause the order of memory operations to &#8220;desync&#8221; from the code&#8217;s intended sequence. Consider this classic scenario:</p><pre><code>x = 0, y = 0, x_res =0, y_res = 0

core A
x = 1 
if y == 0 {
   x_res = 1
}

core B
y = 1
if x == 0 {
   y_res = 1
}</code></pre><p><strong>In a perfectly sequential world, it is impossible for both </strong><code>x_res</code><strong> and </strong><code>y_res</code><strong> to be </strong><code>1</code><strong>. At least one write must "happen" before the other core&#8217;s check.</strong></p><p>However, if both Core A and Core B use <strong>Store Buffers</strong>, they might both buffer their respective writes (<code>x=1</code> and <code>y=1</code>) and execute their loads (<code>if y == 0</code> and <code>if x == 0</code>) before the buffers are flushed. The result? Both cores see <code>0</code> for the variables, and both <code>x_res</code> and <code>y_res</code> become <code>1</code>. This is the <strong>Store-Load Reorder</strong> problem.</p><h1>How Atomics Fix Reordering?</h1><p><code>atomic.Store</code> and <code>atomic.Load</code> solve this by inserting <strong>Memory Barriers</strong> (Fences):</p><h2><code>1. atomic.Store</code> as a Write Barrier</h2><p><code>atomic.Store(&amp;x, 1)</code> essentially tells the CPU: &#8220;You cannot execute any subsequent <code>LOAD</code> instructions until the <strong>Store Buffer</strong> is cleared.&#8221; It forces the core to wait until <code>x = 1</code> receives its ACKs and is committed to the cache.</p><pre><code>x = 0, y = 0, x_res =0, y_res = 0

core A
atomic.Store(&amp;x, 1) 
// barrier: Before loading y into the register, the store operation on x must be completed first.
if y == 0 {
   x_res = 1
}

core B
atomic.Store(&amp;y, 1) 
// barrier: Before loading x into the register, the store operation on y must be completed first.
if x == 0 {
   y_res = 1
}</code></pre><p><strong>However, relying solely on atomic.Store does not prevent the following race condition, as invalidation queue optimizations may delay visibility across cores.</strong></p><ol><li><p><strong>Core A</strong> executes <code>atomic.Store(&amp;x, 1)</code>. The write barrier forces it to clear its <strong>Store Buffer</strong>, ensuring <code>x=1</code> is sent out to the coherence interconnect (BUS) via a <code>PrWr</code> (Processor Write) request.</p></li><li><p><strong>Core B</strong> receives Core A&#8217;s <code>PrWr</code> for <code>x</code>. However, to optimize performance, Core B does <strong>not</strong> immediately mark its local cache line as <strong>I (Invalid)</strong>. Instead, it places the invalidation request into its <strong>Invalidation Queue</strong> and sends back an <strong>ACK</strong> immediately.</p></li><li><p><strong>Core B</strong> then proceeds to its next instruction: <code>if x == 0</code>.</p></li><li><p>Since Core B has not yet processed its <strong>Invalidation Queue</strong>, its local cache still thinks <code>x</code> is valid and contains the value <code>0</code>. Core B reads this <strong>stale value</strong>, leading to <code>y_res=1</code>.</p></li><li><p>The same sequence happens inversely for Core A reading <code>y</code>.</p></li></ol><p><strong>Ultimately, even though the write was &#8220;sent,&#8221; the receiver&#8217;s &#8220;read&#8221; was still stale because the invalidation hadn&#8217;t been applied.</strong></p><h2>2. <code>atomic.Load</code> as a Read Barrier</h2><p>To prevent this, we must use <code>atomic.Load</code>, which acts as a <strong>Read Barrier</strong>. Before the <code>LOAD</code> instruction is executed, it forces the core to check its <strong>Invalidation Queue</strong>.</p><ul><li><p>If the target cache line is pending in the queue, the core <strong>must</strong> process the invalidation first.</p></li><li><p>The core then sees the line is <strong>Invalid (I)</strong> and is forced to fetch the latest value <code>x=1</code> from the interconnect.</p></li></ul><p>By combining <code>atomic.Store</code> and <code>atomic.Load</code>:</p><pre><code>x = 0, y = 0, x_res =0, y_res = 0

core A
atomic.Store(&amp;x, 1) 
if atomic.Load(&amp;y) == 0 {
   x_res = 1
}

core B
atomic.Store(&amp;y, 1) 
if atomic.Load(&amp;x) == 0 {
   y_res = 1
}</code></pre><p>The <strong>Store Buffer</strong> is flushed on the sender's side, and the <strong>Invalidation Queue</strong> is prioritized on the receiver's side. This synchronization ensures that <code>x_res</code> and <code>y_res </code>will <strong>never</strong> both be <code>1</code>.</p><blockquote><p><strong>Technical Note:</strong> While the Invalidation Queue is conceptually a &#8220;queue,&#8221; the hardware implementation often uses status bits/metadata to check for pending invalidations instantly, rather than performing a linear scan.</p></blockquote><h1>Go&#8217;s High-Level Encapsulation Compared to Rust&#8217;s Fine-Grained Memory Ordering Control</h1><h2>Go&#8217;s High-Level Encapsulation</h2><p>Go&#8217;s <code>atomic.Load</code> and <code>atomic.Store</code> provide <strong>Sequential Consistency (SeqCst)</strong>.</p><ul><li><p><code>atomic.Store</code><strong>:</strong> Acts as a <strong>Write Barrier</strong>, forcing the Store Buffer to clear before moving on.</p></li><li><p><code>atomic.Load</code><strong>:</strong> Acts as a <strong>Read Barrier</strong>, forcing the core to process its Invalidation Queue to ensure it sees the most recent state.</p></li></ul><h2>Rust&#8217;s Granular Control</h2><p>While Go keeps it simple, Rust allows you to specify the <strong>Memory Ordering</strong>:</p><h3><strong>Release/Acquire:</strong> </h3><ul><li><p>Release (on Store): Ensures all <strong>previous</strong> writes are visible.</p></li><li><p>Acquire (on Load): Ensures all <strong>subsequent</strong> reads see the latest data.</p></li></ul><p>The Release/Acquire pattern in above scenario does not fully prevent the race condition:</p><pre><code>x = 0, y = 0, x_res =0, y_res = 0

core A
atomic.Store(&amp;x, 1, Release) 
if atomic.Load(&amp;y, Acquire) == 0 {
   x_res = 1
}

core B
atomic.Store(&amp;y, 1, Release) 
if atomic.Load(&amp;x, Acquire) == 0 {
   y_res = 1
}</code></pre><p> Since the Release barrier precedes the STORE to x, the write may remain in the store buffer and be propagated later, while the LOAD of y can still be issued beforehand.</p><h4>Proper Use Case for the Release/Acquire Pattern:</h4><p>Consider the following scenario:</p><pre><code>flag = 0, x = 0
core A
x = 1 
atomic.Store(&amp;flag, 1, Release)

core B
for atomic.Load(&amp;flag, Acquire) { print(x) } // guarentee to print 1</code></pre><p>The Release/Acquire pattern is intended for one-way &#8220;handover&#8221; synchronization.</p><p>Core A performs the data write <code>x = 1</code> and then publishes the update by storing to flag with <code>Release</code> semantics. Core B spins on flag using <code>Acquire</code> semantics; once it observes <code>flag == 1</code>, it is guaranteed to see the preceding write to x.</p><p>Release/Acquire is designed for "Handover" (One-way) synchronization, making them faster but trickier to use than SeqCst.</p><h3><strong>Relaxed</strong>:</h3><p>No barriers at all. It only guarantees that the operation itself is atomic (no torn writes), but provides no guarantees about the order of surrounding instructions.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7Ur4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7Ur4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!7Ur4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!7Ur4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!7Ur4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7Ur4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7Ur4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!7Ur4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!7Ur4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!7Ur4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Example code demonstrating the use of atomic in Go and Rust</h1><h2>Go: Flag Competition &amp; Memory Visibility</h2><p>The following Go code demonstrates two goroutines competing for a flag. Because we use <code>atomic.Store</code> and <code>atomic.Load</code> (which provide <strong>Sequential Consistency</strong> in Go), the program remains stable.</p><pre><code>func main() {
&#9;for i := 0; ; i++ {
&#9;&#9;x, y, r1, r2 := int64(0), int64(0), int64(0), int64(0)
&#9;&#9;wg := sync.WaitGroup{}
&#9;&#9;wg.Add(2)

&#9;&#9;go func() {
&#9;&#9;&#9;defer wg.Done()
&#9;&#9;&#9;atomic.StoreInt64(&amp;x, 1)
&#9;&#9;&#9;if atomic.LoadInt64(&amp;y) == 0 { // if Store-Load reordering occurs, y will read 0
&#9;&#9;&#9;&#9;r1 = 1
&#9;&#9;&#9;}
&#9;&#9;}()

&#9;&#9;go func() {
&#9;&#9;&#9;defer wg.Done()
&#9;&#9;&#9;atomic.StoreInt64(&amp;y, 1)
&#9;&#9;&#9;if atomic.LoadInt64(&amp;x) == 0 { // if Store-Load reordering occurs, x will read 0
&#9;&#9;&#9;&#9;r2 = 1
&#9;&#9;&#9;}
&#9;&#9;}()

&#9;&#9;wg.Wait()
&#9;&#9;if r1 == 1 &amp;&amp; r2 == 1 {
&#9;&#9;&#9;&#9;&#9;&#9;panic(fmt.Sprintf("Observed reordering at iteration %d: r1=%d, r2=%d\n", i, r1, r2))

&#9;&#9;}
&#9;}
}</code></pre><h4>How to Break It:</h4><ol><li><p><strong>Remove </strong><code>atomic.Load</code><strong>:</strong> Change the reader to a simple <code>if flag == 1</code>. Because the <strong>Invalidation Queue</strong> might not be flushed immediately, the reader might see <code>flag == 1</code> but still read a stale <code>x == 0</code> from its own cache. It will likely panic after a short run.</p></li><li><p><strong>Remove both Store and Load:</strong> Use standard assignments (<code>flag = 1</code>). The <strong>Store Buffer</strong> and <strong>Caching</strong> will cause the program to panic almost instantly, as the cores will be completely out of sync regarding the order of operations.</p></li></ol><h2>Rust: Fine-Grained Ordering (Release/Acquire)</h2><p>While Go simplifies things with a single atomic model, Rust allows us to use <strong>Release</strong> and <strong>Acquire</strong> semantics. This is perfect for &#8220;Handover&#8221; scenarios where one thread produces data and another consumes it.</p><h4>Rust Example: Ordered Printing (1-1000)</h4><p>In this example, two threads work in tandem to print numbers. We use <code>Release</code> when writing to the flag to ensure previous memory operations are visible, and <code>Acquire</code> when reading to ensure we see those changes.</p><pre><code><code>use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::thread;

fn main() {
    let n = 1000;
    let i = Arc::new(AtomicUsize::new(1));
    let flag = Arc::new(AtomicBool::new(true));
    let (i_a, flag_a) = (Arc::clone(&amp;i), Arc::clone(&amp;flag));
    let t1 = thread::spawn(move || {
        loop {
            if flag_a.load(Ordering::Acquire) {
                let current: usize = i_a.fetch_add(1,Ordering::Relaxed);
                if current &gt; n {
                    flag_a.store(false, Ordering::Release);
                    break;
                }
                println!("{}", current);
                flag_a.store(false, Ordering::Release);
            }
        }
    });

    let (i_b, flag_b) = (Arc::clone(&amp;i), Arc::clone(&amp;flag));
    let t2 = thread::spawn(move || {
        loop {
            if !flag_b.load(Ordering::Acquire) {
                let current: usize = i_b.fetch_add(1,Ordering::Relaxed);
                if current &gt; n {
                    flag_b.store(true, Ordering::Release);
                    break;
                }
                println!("{}", current);
                flag_b.store(true, Ordering::Release);
            }
        }
    });
    t1.join().unwrap();
    t2.join().unwrap();
}</code></code></pre><h4>Why this works:</h4><ul><li><p><code>Ordering::Release</code><strong>:</strong> On the <code>store</code>, it acts as a gatekeeper. It ensures that every memory operation before this store (like the <code>println!</code> or any data modification) is completed and visible to other cores.</p></li><li><p><code>Ordering::Acquire</code><strong>:</strong> It forces the core to process its Invalidation Queue before the load, ensuring the cache line is fully up-to-date. This allows the core to &#8220;see&#8221; data synchronized by another core&#8217;s Release.</p></li><li><p><strong>Performance:</strong> This is more efficient than the default <code>SeqCst</code> (Sequential Consistency) because it doesn&#8217;t require a total global ordering across all cores&#8212;only a synchronized &#8220;handshake&#8221; between these two specific threads.</p></li></ul>]]></content:encoded></item><item><title><![CDATA[併發程式的核心 - Atomic 不是鎖，那 Atomic 是什麼？]]></title><description><![CDATA[CPU MESI &#20197;&#21450; Memory Ordering &#35299;&#26512;]]></description><link>https://www.chillvic.dev/p/atomic-atomic</link><guid isPermaLink="false">https://www.chillvic.dev/p/atomic-atomic</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Fri, 13 Feb 2026 06:39:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!b_rP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>atomic &#26159;&#20341;&#30332;&#31243;&#24335;&#22522;&#30990;&#65292;&#20363;&#22914; mutex &#24213;&#23652;&#26159;&#29992; atomic Compare And Swap &#23526;&#29694;&#30340;&#65292;&#28982;&#32780;&#22312;&#25105;&#28145;&#20837;&#30740;&#31350;&#37666;&#65292;&#23565; atomic &#35469;&#30693;&#26159; CPU &#23652;&#32026;&#37782;&#65292;&#30740;&#31350;&#30332;&#29694;&#65292;atomic &#26159;&#29992;&#20358;&#35299;&#27770;&#22810;&#26680;&#20341;&#30332;&#35712;&#23531;&#36039;&#26009;&#24773;&#27841;&#19979;&#65292;&#19981;&#21516; cpu core  &#20043;&#38291;&#21516;&#27493;&#35352;&#25014;&#39636;&#36039;&#26009;&#30340;&#27231;&#21046;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!b_rP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!b_rP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!b_rP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!b_rP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!b_rP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!b_rP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png" width="1024" height="1536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1536,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2035465,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/187826606?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!b_rP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!b_rP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!b_rP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!b_rP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b46c0e-9f57-4eb7-9302-33ef832d2932_1024x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>&#29694;&#20195; CPU &#26550;&#27083;&#28858;&#20309;&#65311;&#22914;&#20309;&#36319; RAM &#20132;&#20114;&#65311;</h1><p>&#30001;&#26044;&#21463;&#38480;&#30828;&#39636;&#38651;&#36335;&#30340;&#29289;&#29702;&#38480;&#21046;&#65292;&#35352;&#25014;&#39636;&#23481;&#37327;&#36234;&#22823;&#65292;CPU &#23384;&#21462;&#24310;&#36978;&#36234;&#39640;&#65292;&#22240;&#27492; CPU &#25505;&#29992;&#22810;&#23652;&#35352;&#25014;&#39636;&#38542;&#23652;&#65288;memory hierarchy&#65289;&#20358;&#38477;&#20302;&#24179;&#22343;&#23384;&#21462;&#25104;&#26412;&#12290;</p><p>&#27599;&#20491; core &#22519;&#34892;&#26178;&#26371;&#29992; register &#20786;&#23384;&#36939;&#31639;&#26178;&#29992;&#30340;&#36039;&#26009;&#65292;&#28858;&#36991;&#20813;&#27599;&#22519;&#34892;&#21040;&#19968;&#20491;&#35722;&#25976;&#23601;&#23384;&#21462;&#19968;&#27425;&#35352;&#25014;&#39636;&#65292;core &#24050; cache line (64B) &#28858;&#21934;&#20301;&#24478;&#35352;&#25014;&#39636;&#35712;&#36039;&#26009;&#12290;</p><p>&#35712; cache line &#19981;&#26371;&#25972;&#22376;&#25918;&#21040; register &#20013;&#65292;&#32780;&#26159;&#25918;&#22312;&#19981;&#21516;&#23652;&#32026;&#30340; cache&#65292;&#20363;&#22914; L1, L2, L3 &#36319; RAM&#65306;</p><ul><li><p>L1 &#26159;&#27599;&#20491; core &#31169;&#26377;</p></li><li><p>L2 &#22810;&#25976;&#20063;&#26159; per-core &#31169;&#26377;&#65292;&#37096;&#20998;&#26550;&#27083;&#21487;&#20849;&#20139;</p></li><li><p>L3 &#26159;&#22810; core &#20849;&#20139;&#30340;&#26368;&#24460;&#19968;&#23652;&#24555;&#21462;</p></li><li><p>RAM &#26368;&#32066;&#30340;&#20027;&#35352;&#25014;&#39636;&#23384;&#20786;</p></li></ul><p>&#22823;&#23567;&#26159; RAM &gt; L3 &gt; L2 &gt; L1 &gt; register &#65292;&#23384;&#21462;&#36895;&#24230;&#21063;&#30456;&#21453;&#12290;<br><br>core &#26597;&#36039;&#26009;&#26178;&#65292;&#26371;&#24478; L1 &#38283;&#22987;&#26597;&#65292;miss &#24460;&#25214; L2  -&gt; L3 -&gt; RAM&#65292;&#25214;&#21040;&#36039;&#26009;&#24460;&#26371;&#19968;&#36335;&#22238;&#22635;&#65292;&#25918;&#21040; L3 -&gt; L2 -&gt; L1&#65292;&#22238;&#22635;&#26178;&#35352;&#25014;&#39636;&#19981;&#22816;&#23601;&#26371; evict &#20854;&#20182; cache line &#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rqNm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rqNm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!rqNm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!rqNm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!rqNm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rqNm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:7985507,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/187826606?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rqNm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!rqNm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!rqNm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!rqNm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb171134f-c3b4-4f29-a6f1-83ecbcce1c9d_2816x1536.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>&#22810;&#23652;&#35352;&#25014;&#39636;&#26550;&#27083;&#26371;&#26377;&#20160;&#40636;&#21839;&#38988;&#65311; </h1><p>&#30070;&#27599;&#20491; core &#22519;&#34892; x++ &#23526;&#38555;&#25351;&#20196;&#26159;:</p><pre><code>LOAD x &#8594; register
ADD 1
STORE register &#8594; x</code></pre><p>&#33509;&#27599;&#27425; STORE &#37117;&#23531;&#22238; RAM&#65292;core &#22519;&#34892;&#36895;&#24230;&#26371;&#35722;&#24930;&#65292;&#22240;&#27492; CPU &#35373;&#35336;&#26371;&#23559;&#32080;&#26524;&#20786;&#23384;&#22312;&#21478;&#19968;&#20491;&#30828;&#39636;&#20803;&#20214;&#65292;store buffer&#65292;&#30456;&#30070;&#26044;&#27599;&#20491; core &#21508;&#33258;&#30340; queue&#65292;&#20132;&#30001; cache subsystem &#23559;&#26356;&#26032;&#25552;&#20132;&#21040; L1 cache line &#20006;&#27161;&#35352;&#28858; dirty&#65292;&#30070; cache line eviction &#25110;&#32773;&#25910;&#21040; coherence write back &#20107;&#20214;&#26178;&#23531;&#22238;&#26356;&#20302;&#23652;&#24555;&#21462;&#25110; RAM&#12290;</p><p>&#39006;&#20284;&#26368;&#32066;&#19968;&#33268;&#24615;&#65292;&#20808;&#25552;&#20132;&#21040; L1&#65292;&#20294; L1 &#19981;&#26159;&#20849;&#20139;&#30340;&#65292;&#35201;&#31561; L1 &#28415;&#20102;&#35442; cache line &#34987; evict &#25165;&#26371;&#36880;&#27493;&#23531;&#22238; RAM&#65292;&#26368;&#32066;&#35731;&#20854;&#20182; core &#35712;&#21040;&#26356;&#26032;&#24460;&#36039;&#26009;&#12290;</p><p>&#22240;&#27492;&#30070;&#20841;&#20491; thread &#22312;&#19981;&#21516; core &#22519;&#34892; <code>for loop { x++ }</code> &#65292;&#19981;&#21516; core &#23559;&#36039;&#26009;&#25918;&#21040;&#21508;&#33258;&#30340; L1 cache&#65292;&#36617;&#20837; register &#36939;&#31639;&#65292;&#22519;&#34892;&#23436;&#22312;&#23531;&#22238; L1 cache&#65292;&#24444;&#27492;&#20043;&#38291;&#26377;&#33879;&#30456;&#21516; cache line &#30340;&#19981;&#21516;&#21103;&#26412;&#65292;&#29992;&#21508;&#33258;&#21103;&#26412;&#21453;&#35206;&#22519;&#34892; ++ &#65292;&#26368;&#32066;&#32080;&#26524;&#26371; race condition&#12290;<br></p><h1>CPU &#22810;&#26680;&#26550;&#27083;&#22914;&#20309;&#35299;&#27770; cache line &#36039;&#26009;&#19981;&#21516;&#27493;&#30340;&#21839;&#38988;&#65311;</h1><p>&#35201;&#35299;&#27770;&#19981;&#21516;&#27493;&#21839;&#38988;&#65292;&#39318;&#20808;&#35201;&#24314;&#31435;&#39640;&#25928;&#30340;&#21516;&#27493;&#31649;&#36947;&#65292;&#22810; core &#20043;&#38291;&#22312;&#30828;&#39636;&#35373;&#35336;&#19978;&#26371;&#26377; coherence interconnect &#36890;&#36947;&#20132;&#25563; cache line &#36039;&#35338;&#12290;</p><p>&#35442;&#36890;&#36947;&#20027;&#35201;&#19981;&#26159;&#29992;&#20358;&#20132;&#25563;&#26356;&#26032;&#24460;&#30340; cache line &#20839;&#23481;&#65292;&#22240;&#28858;&#20341;&#30332;&#23531;&#20837;&#30340;&#24773;&#22659;&#20013;&#65292;&#25105;&#20497;&#38656;&#35201;&#30906;&#20445;&#23531;&#20837;&#38918;&#24207;&#65292;&#36319;&#23531;&#20837;&#24460;&#35201;&#31435;&#21051;&#21516;&#27493;&#25165;&#19981;&#26371; race condition&#12290;</p><p>&#22240;&#27492;&#35442;&#36890;&#36947;&#20027;&#35201;&#26159;&#20132;&#25563; cache line &#30340;&#29376;&#24907;&#65292;&#20006;&#29992;&#29376;&#24907;&#34920;&#36948; cache line &#30340; ownership&#65292;&#35442;&#29376;&#24907;&#27231;&#21046;&#31281;&#28858; MESI&#65288;Modified, Exclusive, Shared, Invalid&#65289;&#65306;</p><ul><li><p>M : &#35442; cache line &#34987;&#26412; core &#20462;&#25913;&#65292;&#20294;&#23578;&#26410;&#23531;&#22238;&#26356;&#20302;&#23652; cache &#25110; RAM</p></li><li><p>E : &#35442; cache line &#20677;&#23384;&#22312;&#26044;&#26412; core&#65292;&#20839;&#23481;&#33287; RAM &#19968;&#33268;&#65292;&#23578;&#26410;&#34987;&#20462;&#25913;</p></li><li><p>S : &#35442; cache line &#21487;&#33021;&#23384;&#22312;&#22810;&#20491; core&#65292;&#20839;&#23481;&#33287; RAM &#19968;&#33268;&#65292;&#23578;&#26410;&#34987;&#20462;&#25913;</p></li><li><p>I : &#35442; cache line &#34987;&#20854;&#20182; core &#20462;&#25913;&#65292;&#19981;&#21487;&#20351;&#29992;&#65292;&#20351;&#29992;&#21069;&#36879;&#36942; coherence interconnect &#36319;&#20854;&#20182; core &#25343;&#25110;&#32773;&#21435; L3 or RAM &#25343;</p></li></ul><p>MESI &#26159; cache line &#30340;&#29376;&#24907;&#27231;&#65292;&#23450;&#32681;&#20102; cache line &#29376;&#24907;&#30340;&#20999;&#25563;&#65306;</p><ul><li><p>&#24478;&#12300;&#28961;&#12301;&#21040;&#12300;&#26377;&#12301;(I &#8594; E &#25110; I &#8594; S): core &#35712;&#21462; cache line &#26368;&#26032;&#29376;&#24907;</p></li><li><p>&#24478;&#12300;&#35712;&#12301;&#21040;&#12300;&#23531;&#12301;(S &#8594; M) : core &#29554;&#21462;&#35442; cache line ownership &#20006;&#26356;&#26032;</p></li><li><p>&#24478;&#12300;&#26377;&#12301;&#21040;&#12300;&#28961;&#12301;( M &#8594; I) : core &#25910;&#21040;&#21029;&#20154;&#20462;&#25913;&#35442; cache line &#36890;&#30693;&#65292;&#20462;&#25913;&#29376;&#24907;&#25104; I</p></li><li><p>&#24478;&#12300;&#39634;&#12301;&#21040;&#12300;&#28136;&#12301;( M &#8594; S) : core &#25910;&#21040;&#21029;&#20154;&#35712;&#35442; cache line &#36890;&#30693;&#65292;&#30332;&#29694;&#29376;&#24907;&#27794;&#21516;&#27493;&#21040; L3 or RAM&#65292;&#31435;&#39340;&#21516;&#27493;&#20006;&#25226;&#29376;&#24907;&#35722;&#25104; S&#65292;&#19981;&#26371;&#31561; evict &#25165;&#21516;&#27493;&#36039;&#26009;</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VsWl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VsWl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!VsWl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!VsWl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!VsWl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VsWl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:7869899,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/187826606?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!VsWl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!VsWl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!VsWl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!VsWl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8257c8f-f587-4bfa-8011-e9fc234b5719_2816x1536.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>&#28858;&#30906;&#20445;&#21516;&#19968;&#26178;&#38291;&#21516;&#20491; cache line &#21482;&#26377;&#19968;&#20491; core &#29554;&#24471;&#23531;&#20837; ownership&#65292;coherence interconnect &#36890;&#36947;&#26371;&#26159;&#19968;&#20491; BUS&#65292;&#22810;&#20491; core &#30340;&#23531;&#20837;&#35531;&#27714; (PrWr) &#26371;&#34987; BUS sequential &#30340;&#22519;&#34892;&#65292;&#22810;&#20491; core &#26371;&#30435;&#32893; (snooping) BUS &#30340;&#35531;&#27714;&#65292;&#25910;&#21040;&#22238; ACK&#65292;BUS &#25910;&#21040;&#25152;&#26377; core &#30340; ACK &#25165;&#34389;&#29702;&#19979;&#20491;&#35531;&#27714;&#12290;<br><br>&#20363;&#22914; core A &amp; core B &#21516;&#26178;&#23565; BUS &#30332;&#35531; cache line X &#30340; PrWr&#65292;BUS &#20808;&#34389;&#29702; core A &#30340; PrWr&#65292;&#65306;</p><ol><li><p> &#30070; core B &#25910;&#21040; core A &#30340; PrWr &#26371;&#25226;&#33258;&#24049;&#30340; cache line X &#29376;&#24907;&#25913;&#25104; I&#65292;&#32780; core A &#25910;&#21040;&#22823;&#23478;&#30340; ACK &#26371;&#25226;&#29376;&#24907;&#25913;&#25104; M</p></li><li><p> &#38568;&#24460; BUS &#22312;&#36865;&#20986; core B &#30340; PrWr &#26178;&#65292;core B &#30340;&#29376;&#24907;&#26159; I &#27794;&#36774;&#27861;&#25913;&#25104; M&#65292;&#21482;&#33021; NACK&#65292;&#28982;&#24460;&#25913;&#36865; PrRd</p></li><li><p>&#30070; core A &#23436;&#25104;&#26356;&#26032;&#65292;&#25910;&#21040; core B &#30340; PrRd&#65292;&#30332;&#29694;&#29376;&#24907;&#26159; M&#65292;&#23559;&#36039;&#26009;&#23531;&#22238; L3 or RAM&#65292;&#27492;&#26178; core B &#22312;&#21435;&#35712;&#23601;&#33021;&#25343;&#21040;&#26368;&#26032;&#30340;&#36039;&#26009;</p></li><li><p>&#26368;&#24460; core B &#20877;&#36865;&#19968;&#27425; PrWr &#25343;&#21040; ownership &#24460;&#22519;&#34892;&#26356;&#26032;</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7ILW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba754220-96d0-436d-a76e-4e6f52534627_2816x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7ILW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba754220-96d0-436d-a76e-4e6f52534627_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!7ILW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba754220-96d0-436d-a76e-4e6f52534627_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!7ILW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba754220-96d0-436d-a76e-4e6f52534627_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!7ILW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba754220-96d0-436d-a76e-4e6f52534627_2816x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7ILW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba754220-96d0-436d-a76e-4e6f52534627_2816x1536.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ba754220-96d0-436d-a76e-4e6f52534627_2816x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5693263,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/187826606?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba754220-96d0-436d-a76e-4e6f52534627_2816x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7ILW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba754220-96d0-436d-a76e-4e6f52534627_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!7ILW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba754220-96d0-436d-a76e-4e6f52534627_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!7ILW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba754220-96d0-436d-a76e-4e6f52534627_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!7ILW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba754220-96d0-436d-a76e-4e6f52534627_2816x1536.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>&#31777;&#21934;&#20358;&#35498;&#65292;MESI &#23450;&#32681;&#20102; cache line &#29376;&#24907;&#27231;&#65292;&#20013;&#24515;&#21270; BUS &#30906;&#35469;&#29376;&#24907;&#20999;&#25563;&#38918;&#24207;&#65292;&#22810; core &#36879;&#36942; snooping &#36319; ACK &#27231;&#21046;&#30906;&#20445;&#21516;&#19968;&#26178;&#38291;&#40670;&#65292;&#22823;&#23478;&#23565; cache line &#29376;&#24907;&#26159;&#19968;&#33268;&#30340;&#65292;&#19981;&#26371;&#21516;&#26178;&#20841;&#20491; core &#23565;&#21516;&#20491; cache line &#37117;&#26159;&#65325;&#12290;</p><p>note: &#29694;&#20195; CPU &#26550;&#27083;&#22312; coherence interconnect &#36890;&#36947;&#35373;&#35336;&#26371;&#20778;&#21270;&#25928;&#33021;&#65292;&#20363;&#22914;&#29992; ring bus &#25110; mesh interconnect&#65292;&#37197;&#21512; snoop filter &#25110; directory-based protocol&#12290;</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.chillvic.dev/subscribe?"><span>Subscribe now</span></a></p><h1>&#20294;&#36889;&#27171;&#23601;&#33021;&#35299;&#27770; loop { x++ } &#30340;&#21839;&#38988;&#21966;&#65311;</h1><p>x++ &#25351;&#20196;&#26159;&#65306;</p><pre><code>LOAD x &#8594; register
ADD 1
STORE register &#8594; x</code></pre><p>&#26159;&#20841;&#20491;&#29376;&#24907;&#20999;&#25563;&#65292;LOAD &#23559; I =&gt; S&#65292;&#27492;&#26178; CPU &#23559; x &#25918;&#21040; register&#65292;&#28982;&#24460; ADD 1&#65292;&#22519;&#34892; STORE &#24478; S =&gt; M &#23559;&#36039;&#26009;&#23531;&#22238; L1 &#31561;&#21029;&#20154;&#35201;&#35712;&#26178;&#23531;&#22238; L3 or RAM&#12290;</p><p>&#32780;&#21516;&#26178; LOAD &#26159;&#21512;&#27861;&#30340;&#65292;&#30070; core A &amp; core B &#21516;&#26178;&#25226; x &#25918;&#21040; register&#65292;core A &#20808;&#22519;&#34892; STORE &#25226; +1 &#24460;&#32080;&#26524;&#23531;&#22238;&#65292;core B &#35201;&#22519;&#34892; STORE &#26178;&#65292;&#38614;&#28982;&#26371;&#31561; core A &#22519;&#34892;&#23436;&#65292;&#20294;&#26159;&#26371;&#29992; register &#20013; core A STORE &#21069;&#30340;&#20540; ADD 1 &#65292;&#26368;&#32066;&#20173;&#26371; race condition&#12290;<br></p><p>&#31777;&#21934;&#20358;&#35498;  invalid &#19981;&#34389;&#29702; register &#36039;&#26009;&#20839;&#23481;&#65292;register &#19968;&#20294;&#25918;&#20837;&#23601;&#30906;&#23450;&#20102;&#65292;&#28858;&#35299;&#27770;&#35442;&#21839;&#38988;&#65292;atomic &#21487;&#23559; x++ &#35722;&#25104;&#29305;&#27530;&#25351;&#20196; LOCK XADD&#65292;&#26371;&#25226;&#35712;&#23531;&#25805;&#20316;&#35722;&#25104;&#19968;&#20491;&#29376;&#24907;&#20999;&#25563;&#30906;&#20445;&#20854;&#21407;&#23376;&#24615;&#12290;</p><p>&#20363;&#22914;&#20841;&#20491; core &#21516;&#26178;&#22519;&#34892; loop { atomic.add(&amp;x, 1) }&#65292;core A &amp; core B &#26371;&#21516;&#26178;&#30332;&#20986; PrWr &#35531;&#27714;&#65292;&#30070; core A &#20808;&#22519;&#34892;&#65292;&#20182;&#26371;&#19968;&#27425;&#23436;&#25104; LOAD =&gt; ADD =&gt; STORE&#65292;&#19977;&#27493;&#39519;&#23436;&#25104;&#24460;&#25165;&#22238;&#25033;&#19979;&#20491;&#35531;&#27714;&#30340; ACK&#65292;&#36889;&#27171;&#21487;&#30906;&#20445;&#35442; cache line &#19979;&#20491;&#29376;&#24907;&#20999;&#25563;&#26178;&#65292;core A &#24050;&#21516;&#27493;&#26356;&#26032;&#24460;&#36039;&#26009;&#32102;&#22823;&#23478;&#65292;&#36991;&#20813;&#20102; core A &amp; core B &#21516;&#26178; LOAD x &#21040; register &#30340;&#21487;&#33021;&#12290;<br></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eNbn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d364649-990c-4404-b7a5-fbe8cddd135d_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eNbn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d364649-990c-4404-b7a5-fbe8cddd135d_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!eNbn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d364649-990c-4404-b7a5-fbe8cddd135d_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!eNbn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d364649-990c-4404-b7a5-fbe8cddd135d_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!eNbn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d364649-990c-4404-b7a5-fbe8cddd135d_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eNbn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d364649-990c-4404-b7a5-fbe8cddd135d_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5d364649-990c-4404-b7a5-fbe8cddd135d_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:333797,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/187826606?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d364649-990c-4404-b7a5-fbe8cddd135d_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!eNbn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d364649-990c-4404-b7a5-fbe8cddd135d_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!eNbn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d364649-990c-4404-b7a5-fbe8cddd135d_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!eNbn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d364649-990c-4404-b7a5-fbe8cddd135d_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!eNbn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d364649-990c-4404-b7a5-fbe8cddd135d_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>&#35442;&#21407;&#23376;&#25805;&#20316;&#38500;&#20102; x++ or x-- &#36996;&#21487;&#29992;&#22312; CAS (compare and swap) :</p><pre><code>LOAD flag  -&gt; register
if flag == 0
   flag  =  1
   STORE register -&gt; flag
   STORE true -&gt; ok
else 
   STORE false -&gt; ok</code></pre><p>CAS &#26159; mutex &#30340;&#26680;&#24515;&#65292;&#20363;&#22914; </p><pre><code>lock =&gt; for (atomic.CAS(&amp;lock, 0, 1))
unlock =&gt; (atomic.CAS(&amp;lock, 1, 0))</code></pre><h1>&#31455;&#28982; atomic &#20027;&#35201;&#35299;&#27770;&#22810;&#27493;&#39519;&#30340;&#21407;&#23376;&#24615;&#21839;&#38988;&#65292;&#37027;&#40636;&#20687; go &#30340; atomic.Store &#36319; atomic.Load &#21482;&#26377;&#21934;&#27493;&#39519;&#28858;&#20309;&#38656;&#35201; atomic&#65311;</h1><p>MESI &#23526;&#29694;&#29376;&#24907;&#19968;&#33268;&#65292;&#20294; ACK &#27231;&#21046;&#26371;&#24433;&#38911;&#25928;&#33021;&#65292;&#20027;&#35201;&#26377;&#20841;&#20491;&#24310;&#36978;&#65306;</p><p><strong>&#23531;&#20837;&#24310;&#36978;&#65306;</strong>&#30070; core A &#24819;&#23531;&#36039;&#26009; PrWr &#26178;&#65292;&#24517;&#38920;&#31561;&#25152;&#26377;&#26680;&#24515;&#37117;&#22238;&#20659; ACK&#65288;&#30906;&#35469;&#24050;&#22833;&#25928;&#65289;&#25165;&#33021;&#30495;&#30340;&#26356;&#26032;&#65292;&#36889;&#27573;&#26178;&#38291; core &#21482;&#33021;&#20572;&#19979;&#20358;&#65288;stall&#65289;&#12290;</p><p><strong>&#22833;&#25928;&#24310;&#36978;&#65306;</strong>&#30070; core B &#25910;&#21040; core A &#30340; PrWr &#26178;&#65292;&#23427;&#24517;&#38920;&#23559; L1 &#20013; cache line &#27161;&#35352;&#28858; I &#24460;&#25165;&#22238;&#20659; ACK&#65292;&#24555;&#21462;&#38614;&#24555;&#65292;&#20294;&#34389;&#29702;&#36895;&#24230;&#20173;&#27604; register &#24930;&#24471;&#22810;&#65292;&#33509; cache &#27491;&#22312;&#24537;&#65292;core A &#23601;&#35201;&#31561;&#26356;&#20037;&#12290;</p><p>&#28858;&#20778;&#21270;&#25928;&#33021;&#65292;cpu &#20351;&#29992;&#24310;&#36978;&#22519;&#34892;&#20778;&#21270;&#65306;</p><p>&#35299;&#27770;&#23531;&#20837;&#24310;&#36978;&#65292;core &#19981;&#26371; stall &#32780;&#26159;&#23559;&#35201;&#31561; ack &#30340;&#25351;&#20196;&#25918;&#21040; store buffer &#24460;&#24448;&#19979;&#19968;&#20491;&#25351;&#20196;&#34389;&#29702;&#65292;&#20363;&#22914; :</p><pre><code>a = 1; 
b = y;

STORE 1 =&gt; a
LOAD y =&gt; register
STORE register =&gt; b</code></pre><p>STORE 1 &#35201;&#31561; ACK&#65292;&#20808;&#25918;&#21040; store buffer &#24448;&#19979;&#22519;&#34892; LOAD y&#65292;&#22914;&#26524; y &#30340; cache line &#29376;&#24907;&#26159; E or S &#23601;&#21487;&#30452;&#25509;&#25918;&#21040; register&#65292;&#28982;&#24460;&#20877;&#22238;&#21435;&#22519;&#34892; STORE 1 =&gt; a &#36319; STORE register =&gt; b&#12290;</p><p>&#35299;&#27770;&#22833;&#25928;&#24310;&#36978;&#65292;core &#25910;&#21040;&#21029;&#20154;&#30340; PrWr &#19981;&#26371;&#39340;&#19978;&#21435;&#35352;&#25014;&#39636;&#27161;&#35352; I&#65292;&#32780;&#26159;&#25918;&#21040; invalidation queue &#23601;&#22238; ACK&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BjKx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BjKx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!BjKx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!BjKx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!BjKx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BjKx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6857849,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/187826606?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BjKx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!BjKx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!BjKx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!BjKx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482c6e26-8e3b-43f9-afc3-b1f55dbc17ae_2816x1536.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>&#32780;&#19978;&#36848;&#20841;&#20491;&#20778;&#21270;&#26371;&#24433;&#38911;&#36039;&#26009;&#35712;&#23531;&#30340;&#38918;&#24207;&#22833;&#38728;&#65292;&#20363;&#22914;&#65306;</p><pre><code>x = 0, y = 0, x_res =0, y_res = 0

core A
x = 1 
if y == 0 {
   x_res = 1
}

core B
y = 1
if x == 0 {
   y_res = 1
}</code></pre><p>&#27491;&#24120;&#22519;&#34892;&#38918;&#24207;&#19979;&#65306;</p><ol><li><p>core A &#23531;&#25104;&#21151;</p></li><li><p>core A &#26597;&#35426; y == 0&#65292;&#23531; x_res </p></li><li><p>core B &#23531;&#25104;&#21151;</p></li><li><p>core B &#27298;&#26597; x != 0</p></li></ol><p>&#25110;&#32773; core B &#20808;&#23531;&#25104;&#21151;&#65292;&#21448;&#25110;&#32773; core 1 &amp; core 2 &#37117;&#20808;&#23531;&#25104;&#21151;&#65306;</p><ol><li><p>core A &#23531;&#25104;&#21151;</p></li><li><p>core B &#23531;&#25104;&#21151;</p></li><li><p>core A &#27298;&#26597; y != 0</p></li><li><p>core B &#27298;&#26597; x != 0</p></li></ol><p>&#32317;&#32780;&#35328;&#20043;&#65292;&#19981;&#21487;&#33021;&#21516;&#26178;&#20986;&#29694; x_res &#36319; y_res &#21516;&#26178;&#28858; 1 &#30340;&#24773;&#27841;&#12290;<br><br>&#20294;&#22914;&#26524; core A &amp; core B &#28858;&#20778;&#21270;&#23531;&#20837;&#24310;&#36978;&#65292;&#23559; load y &amp; load x &#25552;&#21069;&#22519;&#34892;&#65292;&#23601;&#21487;&#33021;&#20986;&#29694; x_res &amp; y_res &#21516;&#26178;&#28858; 1 &#30340;&#24773;&#27841;&#65292;&#20063;&#23601;&#26159;&#20439;&#31281;&#30340; Store-Load Reorder &#21839;&#38988;&#12290;</p><h1>go &#30340; atomic.Store &#36319; atomic.Load &#22914;&#20309;&#35299;&#27770; Store-Load Reorder &#21839;&#38988;&#65311;</h1><p></p><p>go &#30340; atomic.Store &#26412;&#36074;&#26159;&#22312; Store &#24460;&#35373;&#32622;&#19968;&#20491; barrier&#65292;&#24375;&#21046; core &#28165;&#31354; store buffer&#65292;&#20363;&#22914; :</p><pre><code>atomic.Store(&amp;x, 1) 
b = y;</code></pre><p>&#38614;&#28982; STORE 1 =&gt; x &#34987;&#25918;&#21040; store buffer&#65292;&#20294;&#22312;&#22519;&#34892; LOAD y &#21069;&#26371;&#24375;&#21046;&#28165;&#31354; store buffer &#20063;&#23601;&#26159;&#31561; STORE 1 &#25910;&#21040; ACK &#20006;&#23436;&#25104;&#26356;&#26032;&#65292;&#30906;&#20445; STORE 1 =&gt; x &#20808;&#34987;&#22519;&#34892;&#12290;</p><p>&#20294;&#21482;&#26377; atomic.Store &#20173;&#19981;&#33021;&#35299;&#27770;&#19979;&#38754;&#21839;&#38988;&#65306;</p><pre><code>x = 0, y = 0, x_res =0, y_res = 0

core A
atomic.Store(&amp;x, 1) 
if y == 0 {
   x_res = 1
}

core B
atomic.Store(&amp;y, 1) 
if x == 0 {
   y_res = 1
}</code></pre><p>&#22240;&#28858; core B &#25910;&#21040; core B &#30340; PrWr&#65292;core B &#19981;&#26371;&#39340;&#19978;&#27161;&#35352; I&#65292;&#32780;&#26159;&#25918;&#21040; invalidation queue&#65292;&#33509; core B &#22519;&#34892; LOAD x &#26178;&#65292;invalidation queue &#36996;&#27794;&#28165;&#31354;&#65292;core B &#23601;&#26371;&#35712;&#21040; core A &#26356;&#26032;&#21069;&#30340;&#20540;&#65292;&#20173;&#21487;&#33021;&#20986;&#29694; x_res &amp; y_res &#37117;&#26159; 1 &#30340;&#24773;&#27841;&#12290;</p><p>&#32780; atomic.Load &#26371;&#22312; LOAD &#20043;&#21069;&#35373;&#32622; barrier &#24375;&#21046;&#27298;&#26597; invalidation queue &#20013;&#26377;&#27794;&#26377;&#35442; cache line&#65292;&#26377;&#30340;&#35441;&#26356;&#26032;&#25104; I &#29376;&#24907;&#65292;&#20006;&#30906;&#20445;&#35712;&#21040;&#26368;&#26032;&#36039;&#26009;&#65292;&#22240;&#27492;&#65306;</p><pre><code>x = 0, y = 0, x_res =0, y_res = 0

core A
atomic.Store(&amp;x, 1) 
if atomic.Load(&amp;y) == 0 {
   x_res = 1
}

core B
atomic.Store(&amp;y, 1) 
if atomic.Load(&amp;x) == 0 {
   y_res = 1
}</code></pre><p>&#23601;&#32085;&#23565;&#19981;&#26371;&#20986;&#29694; x_res &amp; y_res &#21516;&#26178;&#28858; 1 &#30340;&#24773;&#27841;&#12290;</p><p>note: &#38614;&#28982;&#35498; invalidation queue &#31281;&#20316; queue&#65292;&#20294;&#27298;&#26597; cache line &#22312;&#19981;&#22312; invalidation queue &#26412;&#36074;&#19978;&#26159;&#29992;&#29376;&#24907;&#30908;&#65292;&#32780;&#19981;&#26159;&#30495;&#30340; scan queue&#12290;</p><h1>go &#30340; atomic &#36319; rust &#30340; atomic &#20043;&#38291;&#26377;&#20160;&#40636;&#19981;&#19968;&#27171;&#65311;</h1><p>go &#30340; atomic.Load &amp; atomic.Store &#26412;&#36074;&#19978;&#39006;&#20284; SeqCst ordering&#65292;&#20063;&#23601;&#26159;&#22312; STORE &#20043;&#24460;&#65292;LOAD &#20043;&#21069;&#35373;&#19979; barrier&#65292;&#36889;&#27171;&#21487;&#20445;&#35657;&#23531;&#20837;&#26041;&#30340;&#25351;&#20196;&#19981;&#26371;&#34987; reorder&#12290;</p><p>&#20294;&#20687; rust &#26356;&#24213;&#23652;&#30340;&#35486;&#35328;&#23601;&#25903;&#25588;&#20854;&#20182; atomic barrier &#27231;&#21046;&#65292;&#20363;&#22914;  Release/Acquire &#65292;Release &#26159;&#22312; STORE &#20043;&#21069;&#35373;&#32622; barrier&#65292;Acquire &#22312; LOAD &#20043;&#21069;&#35373;&#19979; barrier&#12290;</p><p>&#20363;&#22914;&#19979;&#38754;&#26696;&#20363;&#65306;</p><pre><code>x = 0, y = 0, x_res =0, y_res = 0

core A
atomic.Store(&amp;x, 1, Release) 
if atomic.Load(&amp;y, Acquire) == 0 {
   x_res = 1
}

core B
atomic.Store(&amp;y, 1, Release) 
if atomic.Load(&amp;x, Acquire) == 0 {
   y_res = 1
}</code></pre><p>&#26371; race condition&#65292;&#22240;&#28858; Release &#21482;&#20445;&#35657; STORE 1 =&gt; x &#20043;&#21069;&#28165;&#31354; store buffer&#65292;STORE 1 =&gt; x &#21487;&#34987;&#25918;&#21040; store buffer &#24460;&#23601;&#24448;&#19979;&#22519;&#34892;&#65292;&#26371;&#30332;&#29983; Store-Load Reorder &#30340;&#24773;&#27841;&#12290;</p><p>&#22240;&#27492; Release/Acquire &#21482;&#33021;&#29992;&#22312;&#21934;&#21521;&#20659;&#36664;&#30340;&#24773;&#27841;&#65292;&#20363;&#22914;&#65306;</p><p>core A</p><pre><code>flag = 0, x = 0
core A
x = 1 
atomic.Store(&amp;flag, 1, Release)

core B
for atomic.Load(&amp;flag, Acquire) { print(x) }</code></pre><p>core B &#30340; stdout &#19968;&#23450;&#26159;&#36664;&#20986; 1</p><p>&#26368;&#24460; rust &#36996;&#26377; Relaxed Ordering &#19981;&#35373;&#32622;&#20219;&#20309; barrier &#20294;&#20445;&#35657;&#36889;&#27425;&#25351;&#20196;&#26159;&#21407;&#23376;&#24615;&#30340;&#65292;&#20363;&#22914; atomic.Add(&amp;x, 1, Relaxed)&#12290;<br></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7Ur4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7Ur4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!7Ur4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!7Ur4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!7Ur4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7Ur4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:7470164,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/187826606?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7Ur4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!7Ur4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!7Ur4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!7Ur4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4d9dcaa-790f-442f-869f-1285948a4d45_2816x1536.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><br></p><h1>Go &#33287; Rust &#31684;&#20363;&#20195;&#30908;</h1><p>&#19979;&#38754; go &#20195;&#30908;&#23637;&#31034;&#20841;&#20491; thread &#31478;&#29229; flag &#30340;&#20195;&#30908;&#65306;</p><p> &#30001;&#26044;&#27491;&#30906;&#21152;&#19978; atomic&#65292;&#25152;&#20197;&#19981;&#26371; break&#65292;&#21487;&#20197;&#35430;&#33879;&#20570;&#20197;&#19979;&#35519;&#25972;&#65306;</p><ol><li><p>&#31227;&#38500; atomic.Load&#65292;&#36305;&#19968;&#38499;&#23376;&#24460;&#26377;&#27231;&#26371; break</p></li><li><p>&#31227;&#38500; atomic.Store &amp; atomic.Load &#36305;&#19968;&#19979;&#24460;&#24456;&#24555;&#23601;&#26371; break</p></li></ol><pre><code>func main() {
&#9;for i := 0; ; i++ {
&#9;&#9;x, y, r1, r2 := int64(0), int64(0), int64(0), int64(0)
&#9;&#9;wg := sync.WaitGroup{}
&#9;&#9;wg.Add(2)

&#9;&#9;go func() {
&#9;&#9;&#9;defer wg.Done()
&#9;&#9;&#9;atomic.StoreInt64(&amp;x, 1)
&#9;&#9;&#9;if atomic.LoadInt64(&amp;y) == 0 { // if Store-Load reordering occurs, y will read 0
&#9;&#9;&#9;&#9;r1 = 1
&#9;&#9;&#9;}
&#9;&#9;}()

&#9;&#9;go func() {
&#9;&#9;&#9;defer wg.Done()
&#9;&#9;&#9;atomic.StoreInt64(&amp;y, 1)
&#9;&#9;&#9;if atomic.LoadInt64(&amp;x) == 0 { // if Store-Load reordering occurs, x will read 0
&#9;&#9;&#9;&#9;r2 = 1
&#9;&#9;&#9;}
&#9;&#9;}()

&#9;&#9;wg.Wait()
&#9;&#9;if r1 == 1 &amp;&amp; r2 == 1 {
&#9;&#9;&#9;fmt.Printf("Observed reordering at iteration %d: r1=%d, r2=%d\n", i, r1, r2)
&#9;&#9;&#9;break
&#9;&#9;}
&#9;}
}
</code></pre><p>&#19979;&#38754; rust &#20195;&#30908;&#23637;&#31034;&#19981;&#21516; atomic ordering &#23531;&#27861;&#65306;<br>&#20351;&#29992; Release &amp; Acquire &#23526;&#29694;&#21934;&#21521;&#30340; flag &#20659;&#36664;&#65292;&#29992;&#20841;&#20491; thread &#25353;&#29031;&#38918;&#24207;&#21360;&#20986; 1 ~ 1000</p><pre><code>use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::thread;

fn main() {
    let n = 1000;
    let i = Arc::new(AtomicUsize::new(1));
    let flag = Arc::new(AtomicBool::new(true));
    let (i_a, flag_a) = (Arc::clone(&amp;i), Arc::clone(&amp;flag));
    let t1 = thread::spawn(move || {
        loop {
            if flag_a.load(Ordering::Acquire) {
                let current: usize = i_a.fetch_add(1,Ordering::Relaxed);
                if current &gt; n {
                    flag_a.store(false, Ordering::Release);
                    break;
                }
                println!("{}", current);
                flag_a.store(false, Ordering::Release);
            }
        }
    });

    let (i_b, flag_b) = (Arc::clone(&amp;i), Arc::clone(&amp;flag));
    let t2 = thread::spawn(move || {
        loop {
            if !flag_b.load(Ordering::Acquire) {
                let current: usize = i_b.fetch_add(1,Ordering::Relaxed);
                if current &gt; n {
                    flag_b.store(true, Ordering::Release);
                    break;
                }
                println!("{}", current);
                flag_b.store(true, Ordering::Release);
            }
        }
    });
    t1.join().unwrap();
    t2.join().unwrap();
}</code></pre>]]></content:encoded></item><item><title><![CDATA[Kubernetes Network 是怎麼運作的？下集]]></title><description><![CDATA[&#35299;&#26512; eBPF &#39640;&#25928;&#30340;&#31192;&#23494;]]></description><link>https://www.chillvic.dev/p/kubernetes-network-084</link><guid isPermaLink="false">https://www.chillvic.dev/p/kubernetes-network-084</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Sun, 01 Feb 2026 08:31:28 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!heO9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f9d70d5-d3f5-4783-a153-4d26c56bc11f_1024x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>K8S CNI (Container Network Interface) &#23450;&#32681;&#20102; K8S &#32178;&#36335;&#36890;&#35338;&#38656;&#35201;&#30340; API&#65292;&#19978;&#38598;&#20171;&#32057; CNI &#22914;&#20309;&#23526;&#29694; Pod &#20043;&#38291;&#30340;&#36890;&#35338;&#65292;&#26368;&#24460;&#25552;&#21040;&#20659;&#32113; iptables &#23526;&#29694;&#30340; L4 load balance &#25928;&#33021;&#36611;&#24046;&#65292;&#21487;&#25913;&#29992; IPVS&#65292;&#20294;&#23526;&#21209;&#19978; K8S v1.35 &#24460;&#65292;&#22312; kube-proxy &#20013;&#23559; IPVS &#27161;&#35352;&#28858;&#26820;&#29992;&#65292;&#28858;&#20160;&#40636;&#65311;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!heO9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f9d70d5-d3f5-4783-a153-4d26c56bc11f_1024x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!heO9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f9d70d5-d3f5-4783-a153-4d26c56bc11f_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!heO9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f9d70d5-d3f5-4783-a153-4d26c56bc11f_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!heO9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f9d70d5-d3f5-4783-a153-4d26c56bc11f_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!heO9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f9d70d5-d3f5-4783-a153-4d26c56bc11f_1024x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!heO9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f9d70d5-d3f5-4783-a153-4d26c56bc11f_1024x1536.png" width="1024" height="1536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8f9d70d5-d3f5-4783-a153-4d26c56bc11f_1024x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1536,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2186252,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/186481457?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f9d70d5-d3f5-4783-a153-4d26c56bc11f_1024x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!heO9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f9d70d5-d3f5-4783-a153-4d26c56bc11f_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!heO9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f9d70d5-d3f5-4783-a153-4d26c56bc11f_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!heO9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f9d70d5-d3f5-4783-a153-4d26c56bc11f_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!heO9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f9d70d5-d3f5-4783-a153-4d26c56bc11f_1024x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h1>&#22238;&#39015;&#65292;&#28858;&#20309; IPVS &#26371;&#20986;&#29694;&#65311;</h1><p>K8S &#20013;&#30340; L4 load balance &#21151;&#33021;&#21487;&#23559;&#22810;&#20491;&#36865;&#32102;&#30456;&#21516; service IP &#30340; TCP &#24314;&#31435;&#35531;&#27714;&#65292;&#36865;&#32102;&#19981;&#21516;&#30340; pod IP&#65292;&#20659;&#32113;&#29992;&#27861;&#26159; iptables&#12290;</p><p>iptables &#26159; kernel &#20013; netfilter module &#20839;&#24314;&#30340;&#35215;&#21063;&#31649;&#29702;&#27169;&#32068;&#65292;netfilter &#22312;&#23553;&#21253;&#36942;&#28670;&#36681;&#30332;&#36942;&#31243;&#20013;&#23450;&#32681;&#20102;&#19981;&#21516; hook &#40670;&#65292; iptable &#36000;&#36012;&#20786;&#23384;&#31649;&#29702;&#36889;&#20123; hook &#30340;&#23553;&#21253;&#35215;&#21063;&#65292;&#20363;&#22914;&#26159;&#21542;&#35201; drop&#65292;allow or forward&#12290;</p><p>&#20294; iptable &#28961;&#27861;&#23458;&#35069;&#21270; hook callback&#65292;&#32780;&#26159;&#25552;&#20379;&#26377;&#38480;&#30340; hook &#35215;&#21063;&#37197;&#32622;&#65292;&#22240;&#27492;&#29992; iptable &#23526;&#29694; L4 load balance &#26178;&#65292;&#26371;&#21463;&#38480;&#26044; iptable &#21151;&#33021;&#20197;&#21450;&#20839;&#37096;&#23526;&#20316;&#32780;&#24433;&#38911;&#25928;&#33021;&#12290;</p><p>&#22909;&#22312; netfilter &#21478;&#22806;&#25552;&#20379; nf_register_net_hook() &#33021;&#25554;&#20837;&#23458;&#35069;&#21270;&#30340; callback&#65292;&#32780; IPVS &#23601;&#26159;&#36879;&#36942;&#25554;&#20837;&#23458;&#35069;&#21270; callback &#23526;&#29694;&#39640;&#25928;&#30340; L4 load balance&#12290;</p><p>&#20363;&#22914; iptables &#32570;&#40670;&#26159;&#38656;&#35201; for loop &#22810;&#26781;&#35215;&#21063;&#21152;&#19978;&#27231;&#29575;&#21629;&#20013;&#23526;&#29694; load balance&#65292;&#20294; IPVS &#20316;&#28858;&#29544;&#31435;&#30340; module &#19981;&#21463;&#38480; iptables &#20839;&#37096;&#32080;&#27083;&#65292;&#21487;&#29992; hashmap &#23526;&#29694; O(1) &#30340; load balance&#12290;</p><h1>&#20294;&#28858;&#20309;&#35201;&#26820;&#29992; IPVS&#65311;</h1><p>IPVS &#38614;&#28982;&#26159;&#39640;&#25928; L4 load balance&#65292;&#20294; netfilter &#25972;&#20491;&#27169;&#32068;&#36996;&#26377;&#24456;&#22810;&#21151;&#33021;&#65292;&#20363;&#22914;&#32000;&#37636; service IP &#36319; pod IP &#36681;&#25563;&#30340; NAT &amp; DNAT &amp; conntrack &#21151;&#33021;&#65292;&#22914;&#26524; IPVS &#35201;&#26356;&#23436;&#21892;&#26356;&#39640;&#25928;&#65292;&#23601;&#35201;&#23526;&#29694; netfilter &#27169;&#32068;&#20854;&#20182;&#21151;&#33021;&#12290;</p><p>&#36889;&#26178;&#20986;&#29694;&#19968;&#20491;&#38283;&#30332;&#25225;&#25799;&#65292;&#33287;&#20854;&#33457;&#26178;&#38291;&#23436;&#21892;&#19968;&#20491; plugin &#23450;&#20301;&#30340;&#24037;&#20855;&#65292;&#35731;&#20182;&#26377;&#26356;&#22810;&#21151;&#33021;&#65292;&#19981;&#22914;&#23559;&#21407;&#26412; netfilter &#30340; iptables &#27169;&#32068;&#20462;&#25913;&#25104;&#65292;&#20351;&#29992;&#26356;&#39640;&#25928;&#32080;&#27083;&#31649;&#29702;&#35215;&#21063;&#30340;&#27169;&#32068;&#65292;&#22240;&#27492; netables &#23601;&#35477;&#29983;&#20102;&#65292;&#26368;&#24460; K8S v1.35 &#24460;&#23559; IPVS &#27161;&#27880;&#28858; deprecated&#65292;&#25913;&#32780;&#25512;&#34214;&#29992; netables&#12290;</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.chillvic.dev/subscribe?"><span>Subscribe now</span></a></p><h1>&#26356;&#39640;&#25928;&#30340; CNI &#26550;&#27083;&#65292;eBPF &#25216;&#34899;&#22914;&#20309;&#21152;&#36895; Pod &#20043;&#38291;&#36890;&#35338;&#65311;</h1><p>&#26089;&#26399; K8S Cluster&#65292;CNI &#21482;&#36000;&#36012; Pod &#30340; IP &#20998;&#37197;&#36319; Pod &#20043;&#38291;&#36890;&#35338;&#65292;&#20363;&#22914; Flannel &#36319; kube-proxy &#25645;&#37197;&#65292;&#20294;&#26032;&#33288; CNI (e.g cilium) &#25505;&#29992; eBPF &#25216;&#34899;&#65292;&#19981;&#21482; Pod &#20043;&#38291;&#36890;&#35338;&#26356;&#24555;&#65292;&#29978;&#33267;&#33021;&#26367;&#20195; kube-proxy L4 Load balance &#21151;&#33021;&#12290;</p><p>&#20659;&#32113; Flannel CNI &#25216;&#34899;&#65292;Pod &#20043;&#38291;&#36890;&#35338;&#26371;&#36879;&#36942; overlap &#25216;&#34899;&#65292;&#23559; TCP packet &#23553;&#35037;&#25104; UDP packet&#65292;&#31680;&#40670;&#25509;&#25910;&#24460;&#65292;UDP packet &#26371;&#20808;&#32147;&#36942; kernel &#30340; netfilter &#27169;&#32068; forward &#32102; vxlan device &#65292;&#28982;&#24460; vxlan device &#35299;&#21253;&#24460;&#65292;&#23559; TCP packet &#20877;&#32147;&#36942;&#19968;&#27425; netfilter &#27169;&#32068;&#65292;&#25214;&#21040; veth pair &#24314;&#31435;&#30340;&#34395;&#25836;&#32178;&#21345;&#65292;&#36865;&#32102; container&#65292;&#22240;&#27492;&#26371;&#32147;&#36942;&#20841;&#27425; netfilter&#12290;</p><p>eBPF &#26159;&#21487;&#22312; kernel &#23652;&#25554;&#20837;&#23458;&#35069; hook &#37007;&#36655;&#30340;&#25216;&#34899;&#65292;&#20294;&#25554;&#20837;&#40670;&#19981;&#21463;&#38480;&#26044; netfilter modul&#65292;&#32780;&#26159; kernel &#26377;&#26292;&#38706;&#30340; hook &#40670;&#37117;&#26377;&#27231;&#26371;&#25554;&#20837;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Mb_r!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa50b2a5e-664b-4a4f-ab7c-502df74c874d_1554x1688.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Mb_r!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa50b2a5e-664b-4a4f-ab7c-502df74c874d_1554x1688.png 424w, https://substackcdn.com/image/fetch/$s_!Mb_r!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa50b2a5e-664b-4a4f-ab7c-502df74c874d_1554x1688.png 848w, https://substackcdn.com/image/fetch/$s_!Mb_r!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa50b2a5e-664b-4a4f-ab7c-502df74c874d_1554x1688.png 1272w, https://substackcdn.com/image/fetch/$s_!Mb_r!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa50b2a5e-664b-4a4f-ab7c-502df74c874d_1554x1688.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Mb_r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa50b2a5e-664b-4a4f-ab7c-502df74c874d_1554x1688.png" width="1456" height="1582" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a50b2a5e-664b-4a4f-ab7c-502df74c874d_1554x1688.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1582,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Hello eBPF: A Packet Logger in Pure Java using TC and XDP Hooks (13) -  Mostly nerdlessMostly nerdless&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Hello eBPF: A Packet Logger in Pure Java using TC and XDP Hooks (13) -  Mostly nerdlessMostly nerdless" title="Hello eBPF: A Packet Logger in Pure Java using TC and XDP Hooks (13) -  Mostly nerdlessMostly nerdless" srcset="https://substackcdn.com/image/fetch/$s_!Mb_r!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa50b2a5e-664b-4a4f-ab7c-502df74c874d_1554x1688.png 424w, https://substackcdn.com/image/fetch/$s_!Mb_r!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa50b2a5e-664b-4a4f-ab7c-502df74c874d_1554x1688.png 848w, https://substackcdn.com/image/fetch/$s_!Mb_r!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa50b2a5e-664b-4a4f-ab7c-502df74c874d_1554x1688.png 1272w, https://substackcdn.com/image/fetch/$s_!Mb_r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa50b2a5e-664b-4a4f-ab7c-502df74c874d_1554x1688.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source : https://mostlynerdless.de/wp-content/uploads/2024/08/network_stack-1.png</p><p>&#22240;&#27492; eBPF &#25216;&#34899;&#30340; CNI&#65292;&#21487;&#22312; kernel &#25910;&#21040;&#23553;&#21253;&#65292;&#36914;&#20837; netfilter &#27169;&#32068;&#21069;&#65292;&#25554;&#20837;&#19968;&#20491; hook callback&#65292;&#20358;&#32350;&#25481; netfilter &#30340;&#22519;&#34892;&#65292;&#32780; TC (traffic control) &#26159;&#22312; netfilter &#21069;&#36000;&#36012;&#27969;&#37327;&#25511;&#21046;&#30340;&#27169;&#32068;&#65306;</p><p>TC ingress&#65306;&#31649;&#29702; inbound packet &#30340;&#34389;&#29702;&#36895;&#24230;&#65292;&#26377; rate limit &#27231;&#21046;&#65292;&#36319;&#23565; packet &#25110; socket &#25171;&#27161;&#31844;</p><p>TC egress&#65306;&#25511;&#21046; outbound packet&#65292;&#21487;&#20570;&#21040;&#37325;&#26032;&#32232;&#25490;&#65292;&#20381;&#29031; ingress &#30340;&#27161;&#31844;&#27770;&#23450; priority</p><p>&#33509;&#29992; eBPF &#22312; TC Ingress &#25554;&#20837;&#19968;&#20491; hook&#65292;&#20006;&#23526;&#29694; overlay &#35299;&#21253;&#21152;&#23553;&#21253; forward &#30340;&#21151;&#33021;&#65292;&#23601;&#33021;&#36991;&#20813; netfilter &#22519;&#34892;&#20841;&#27425;&#30340; CPU &#28040;&#32791;&#12290;</p><p>&#20363;&#22914;&#22312; kernel &#20013;&#65292;&#27599;&#20491;&#23553;&#21253;&#37117;&#26159;&#19968;&#22602;&#35352;&#25014;&#39636; (e.g bytes array)&#65292;&#32780; skb &#26159; kernel &#29992;&#20358;&#31649;&#29702;&#23553;&#21253;&#35352;&#25014;&#39636;&#30340;&#32080;&#27083;&#65292;eBPF &#21487;&#36879;&#36942;&#20462;&#25913; skb &#30340;&#35352;&#25014;&#39636;&#36215;&#22987;&#20301;&#32622;&#65292;&#36339;&#36942; overlap header&#23526;&#29694;&#35299;&#21253;&#12290;</p><div class="captioned-image-container"><figure><div class="image-link image2" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iOlf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05b65d30-5806-4f09-9f80-54bf1eb39a10_264x191.png 424w, https://substackcdn.com/image/fetch/$s_!iOlf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05b65d30-5806-4f09-9f80-54bf1eb39a10_264x191.png 848w, https://substackcdn.com/image/fetch/$s_!iOlf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05b65d30-5806-4f09-9f80-54bf1eb39a10_264x191.png 1272w, https://substackcdn.com/image/fetch/$s_!iOlf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05b65d30-5806-4f09-9f80-54bf1eb39a10_264x191.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iOlf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05b65d30-5806-4f09-9f80-54bf1eb39a10_264x191.png" width="264" height="191" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/05b65d30-5806-4f09-9f80-54bf1eb39a10_264x191.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:191,&quot;width&quot;:264,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Linux &#32178;&#36335;&#23376;&#31995;&#32113;sk_buffer &#35443;&#32048;&#20998;&#26512;1. &#23450;&#32681;2. &#27010;&#36848;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Linux &#32178;&#36335;&#23376;&#31995;&#32113;sk_buffer &#35443;&#32048;&#20998;&#26512;1. &#23450;&#32681;2. &#27010;&#36848;" title="Linux &#32178;&#36335;&#23376;&#31995;&#32113;sk_buffer &#35443;&#32048;&#20998;&#26512;1. &#23450;&#32681;2. &#27010;&#36848;" srcset="https://substackcdn.com/image/fetch/$s_!iOlf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05b65d30-5806-4f09-9f80-54bf1eb39a10_264x191.png 424w, https://substackcdn.com/image/fetch/$s_!iOlf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05b65d30-5806-4f09-9f80-54bf1eb39a10_264x191.png 848w, https://substackcdn.com/image/fetch/$s_!iOlf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05b65d30-5806-4f09-9f80-54bf1eb39a10_264x191.png 1272w, https://substackcdn.com/image/fetch/$s_!iOlf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05b65d30-5806-4f09-9f80-54bf1eb39a10_264x191.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></div></figure></div><p>image source : http://jared.web.fc2.com/sk_buffer_analysis.pdf</p><p>&#26368;&#24460;&#36681;&#30332;&#21487;&#36879;&#36942; bpf_redirect &#36889;&#20491; BPF helper&#65292;bpf_redirect &#38656;&#25509;&#25910; ifindex &#21443;&#25976;&#65292; ifindex &#26159;&#32178;&#21345;&#35373;&#20633;&#22312; kernel process &#20013;&#30340; id&#65292;&#36889;&#20491; id &#26371;&#22312; veth pair &#24314;&#31435;&#26159;&#29554;&#24471;&#65292;&#21487;&#34987; CNI control panel &#31649;&#29702;&#65292;&#30070; eBPF  bpf_redirect &#36681;&#30332;&#23553;&#21253;&#24460;&#65292;&#26371;&#22238;&#20659; TC_ACT_REDIRECT&#65292;&#21578;&#35380; TC module &#23553;&#21253;&#34987; redirect&#65292;&#19981;&#29992;&#24448;&#19979;&#32102; netfilter&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MNqF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca8f294-fab8-4f61-8f7a-402dcb58a1b2_1685x946.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MNqF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca8f294-fab8-4f61-8f7a-402dcb58a1b2_1685x946.png 424w, https://substackcdn.com/image/fetch/$s_!MNqF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca8f294-fab8-4f61-8f7a-402dcb58a1b2_1685x946.png 848w, https://substackcdn.com/image/fetch/$s_!MNqF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca8f294-fab8-4f61-8f7a-402dcb58a1b2_1685x946.png 1272w, https://substackcdn.com/image/fetch/$s_!MNqF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca8f294-fab8-4f61-8f7a-402dcb58a1b2_1685x946.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MNqF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca8f294-fab8-4f61-8f7a-402dcb58a1b2_1685x946.png" width="1456" height="817" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4ca8f294-fab8-4f61-8f7a-402dcb58a1b2_1685x946.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:817,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&#35793;] &#22914;&#20309;&#22522;&#20110;Cilium &#21644;eBPF &#25171;&#36896;&#21487;&#24863;&#30693;&#24494;&#26381;&#21153;&#30340;Linux&#65288;InfoQ, 2019&#65289;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="&#35793;] &#22914;&#20309;&#22522;&#20110;Cilium &#21644;eBPF &#25171;&#36896;&#21487;&#24863;&#30693;&#24494;&#26381;&#21153;&#30340;Linux&#65288;InfoQ, 2019&#65289;" title="&#35793;] &#22914;&#20309;&#22522;&#20110;Cilium &#21644;eBPF &#25171;&#36896;&#21487;&#24863;&#30693;&#24494;&#26381;&#21153;&#30340;Linux&#65288;InfoQ, 2019&#65289;" srcset="https://substackcdn.com/image/fetch/$s_!MNqF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca8f294-fab8-4f61-8f7a-402dcb58a1b2_1685x946.png 424w, https://substackcdn.com/image/fetch/$s_!MNqF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca8f294-fab8-4f61-8f7a-402dcb58a1b2_1685x946.png 848w, https://substackcdn.com/image/fetch/$s_!MNqF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca8f294-fab8-4f61-8f7a-402dcb58a1b2_1685x946.png 1272w, https://substackcdn.com/image/fetch/$s_!MNqF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca8f294-fab8-4f61-8f7a-402dcb58a1b2_1685x946.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source : https://arthurchiao.art/blog/how-to-make-linux-microservice-aware-with-cilium-zh/</p><h1>&#32350;&#36942; netfilter &#24460;&#65292;kube-proxy &#23601;&#29992;&#19981;&#21040;&#20102;&#65292;&#24590;&#40636;&#23526;&#29694; service endpoint &#65311;</h1><p>kube-proxy &#26159;&#36879;&#36942; netfilter &#23526;&#29694; service endpoint &#30340; Layer 4 Load balance&#65292;&#19968;&#26086; eBPF CNI &#32350;&#36942; netfilter&#65292;&#23601;&#28961;&#27861;&#29992; kube-proxy&#65292;&#22240;&#27492;&#35201;&#21478;&#22806;&#38283;&#30332; Layer 4 Load balance&#12290;</p><p>eBPF &#23526;&#29694; Layer 4 Load balance &#30340;&#22909;&#34389;&#20043;&#19968;&#26159; conntrack &#21487;&#33258;&#34892;&#31649;&#29702;&#65292;&#30001;&#26044; TCP &#36899;&#32218;&#26159;&#26377;&#29376;&#24907;&#30340;&#65292;&#36899;&#32218;&#20839;&#23553;&#21253;&#38920;&#36865;&#24448;&#21516;&#19968;&#20491; pod IP&#65292;&#20294; client &#21482;&#30475;&#21040; service IP&#65292;&#22240;&#27492; kube-proxy &#36879;&#36942; netfilter conntrack &#27231;&#21046;&#65292;&#20786;&#23384; service IP &#36319; pod IP &#30340;&#36681;&#25563;&#65292;&#32780; netfilter &#30340; conntrack &#19981;&#21482;&#26159; IP &#36681;&#25563;&#65292;&#36996;&#29992;&#26044;&#23526;&#29694;&#26377;&#29376;&#24907;&#30340;&#38450;&#28779;&#29254;&#27231;&#21046;&#65292;&#20363;&#22914;&#19981; DROP &#36899;&#32218;&#24314;&#31435;&#24460;&#30340;&#23553;&#21253;&#65292;&#25152;&#20197; conntrack &#36996;&#26371;&#35352;&#37636;&#38989;&#22806;&#36039;&#35338;&#12290;</p><p>&#20294;&#21934;&#32020; Load balance &#20854;&#23526;&#21487;&#32000;&#37636;&#26356;&#23569;&#30340;&#36039;&#26009;&#65292;&#19988; eBPF &#33258;&#34892;&#31649;&#29702; conntrack &#20063;&#19981;&#26371;&#21463;&#38480; kernel nf_conntrack_max &#21443;&#25976;&#38480;&#21046;&#65292;&#19988;&#33021;&#20778;&#21270; hashmap &#30340;&#20786;&#23384;&#32080;&#27083;&#65292;&#26356;&#39640;&#25928;&#22320;&#20056;&#36617;&#22823;&#37327; TCP &#36899;&#32218;&#12290;</p><h1>&#20160;&#40636;&#26159; service mesh&#65311;&#38750; eBPF service mesh &#26377;&#20160;&#40636;&#25928;&#33021;&#21839;&#38988;&#65311;</h1><p>eBPF &#38614;&#28982;&#23526;&#29694; Layer4 Load Balance&#65292;&#20294;&#35442; Load balance &#20006;&#19981;&#33021;&#29992;&#22312; gRPC &#19978;&#12290;</p><p>K8S &#20839;&#37096;&#26381;&#21209;&#28317;&#36890;&#65292;&#24120;&#35211;&#30340; Layer7 &#21332;&#23450;&#26159; gRPC&#65292;gRPC &#29992; TCP &#38263;&#36899;&#32218;&#65292;&#19968;&#26086;&#36899;&#32218;&#24314;&#31435;&#65292;&#25152;&#26377; gRPC &#35531;&#27714;&#37117;&#26371;&#36865;&#24448;&#21516;&#20491; backend server&#12290;</p><p>&#23526;&#29694; gRPC load balance &#24120;&#35211; solution &#26159; service mesh&#65292;&#27599;&#20491; pod &#25645;&#37197;&#29544;&#31435; proxy &#31281;&#28858; sidecar&#65292;proxy &#24444;&#27492;&#20043;&#38291;&#24314;&#31435; gRPC &#36899;&#32218;&#65292;&#24418;&#25104;&#32178;&#29376;&#38364;&#20418;&#65292;server to server &#28317;&#36890;&#26178;&#65292;client &#35531;&#27714;&#36879;&#36942; proxy &#36865;&#20986;&#65292;&#27492;&#26178; client proxy &#21487;&#27770;&#23450;&#35201;&#36865;&#24448;&#21738;&#20491; server proxy &#23526;&#29694; load balance&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Dr9H!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15306b72-9dc8-4e05-9839-88c2362977f5_808x425.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Dr9H!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15306b72-9dc8-4e05-9839-88c2362977f5_808x425.png 424w, https://substackcdn.com/image/fetch/$s_!Dr9H!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15306b72-9dc8-4e05-9839-88c2362977f5_808x425.png 848w, https://substackcdn.com/image/fetch/$s_!Dr9H!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15306b72-9dc8-4e05-9839-88c2362977f5_808x425.png 1272w, https://substackcdn.com/image/fetch/$s_!Dr9H!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15306b72-9dc8-4e05-9839-88c2362977f5_808x425.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Dr9H!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15306b72-9dc8-4e05-9839-88c2362977f5_808x425.png" width="808" height="425" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/15306b72-9dc8-4e05-9839-88c2362977f5_808x425.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:425,&quot;width&quot;:808,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Service Mesh &#36890;&#35338;&#22522;&#30990;&#32080;&#27083;- .NET | Microsoft Learn&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Service Mesh &#36890;&#35338;&#22522;&#30990;&#32080;&#27083;- .NET | Microsoft Learn" title="Service Mesh &#36890;&#35338;&#22522;&#30990;&#32080;&#27083;- .NET | Microsoft Learn" srcset="https://substackcdn.com/image/fetch/$s_!Dr9H!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15306b72-9dc8-4e05-9839-88c2362977f5_808x425.png 424w, https://substackcdn.com/image/fetch/$s_!Dr9H!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15306b72-9dc8-4e05-9839-88c2362977f5_808x425.png 848w, https://substackcdn.com/image/fetch/$s_!Dr9H!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15306b72-9dc8-4e05-9839-88c2362977f5_808x425.png 1272w, https://substackcdn.com/image/fetch/$s_!Dr9H!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15306b72-9dc8-4e05-9839-88c2362977f5_808x425.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source : https://learn.microsoft.com/zh-tw/dotnet/architecture/cloud-native/service-mesh-communication-infrastructure</p><p>&#22240;&#27492; sidecard proxy &#35201;&#25509;&#25910; pod &#30340; inbound &amp; outbound request&#65292;&#32780;&#38750; eBPF &#30340; service mesh &#26159;&#36879;&#36942; iptables &#20462;&#25913; netfilter &#36335;&#30001;&#35215;&#21063;&#65292;&#25226;&#25152;&#26377; outbound address &#37117;&#20462;&#25913;&#25104; proxy address&#65292;&#35731; pod &#25152;&#26377;&#35531;&#27714;&#37117;&#36879;&#36942; side car proxy &#36865;&#20986;&#12290;</p><p>service mesh &#27794;&#27861;&#29992; iptable &#30340; FORWARD rule &#30452;&#25509;&#36681;&#30332;&#65292;&#22240;&#28858; FORWARD &#26159;&#29992;&#22312;&#19981;&#21516;&#32178;&#36335;&#25509;&#21475;&#65292;&#20294; side car &#36319; server &#26159;&#21516;&#19968;&#20491;&#32178;&#36335;&#25509;&#21475;&#65292;&#25152;&#20197;&#36681;&#30332;&#35201;&#36879;&#36942;&#20462;&#25913; dest address&#12290;</p><p>&#20462;&#25913; dest address &#24460;&#65292;&#36996;&#35201;&#20877;&#32147;&#36942; kernel &#30340; netfilter &#27169;&#32068;&#19968;&#27425;&#65292;&#23553;&#21253;&#25165;&#26371;&#21040; proxy&#65292;&#31561;&#26044;&#35498;  server to server &#36879;&#36942; side car proxy &#28317;&#36890;&#26178;&#65292;&#26371;&#26377;&#20841;&#27425; netfilter &#30340; datapath&#65306;</p><p>1. &#31532;&#19968;&#27425; netfilter &#20462;&#25913; dest address &#21040; proxy </p><p>2. &#31532;&#20108;&#27425; netfilter &#20381;&#29031;&#26032;&#30340; dest address forward &#23553;&#21253;&#32102; proxy</p><p>&#20841;&#27425; netfilter &#20195;&#34920;&#26356;&#22810; CPU &#28040;&#32791;&#65292;&#32780; eBPF &#33021;&#35299;&#27770;&#35442;&#21839;&#38988;&#12290;</p><h1>eBPF &#22914;&#20309;&#23526;&#29694;&#26356;&#39640;&#25928;&#30340; service mesh&#65311;</h1><p>&#39318;&#20808; eBPF &#21487;&#22312; server &#23565;&#22806;&#24314;&#31435; tcp &#36899;&#32218;&#26178;&#65292;&#25876;&#25130;&#24314;&#31435;&#35531;&#27714;&#65292;&#23559; dest address &#20462;&#25913;&#25104; proxy address&#65292;server &#30475;&#20284;&#23565;&#22806;&#24314;&#31435;&#20102; tcp &#36899;&#32218;&#65292;&#23526;&#38555;&#26159;&#33287; side car proxy &#24314;&#31435;&#36899;&#32218;&#65292;&#27492;&#33289;&#36991;&#20813;&#20102;&#36879;&#36942; netfilter &#21435;&#36681;&#30332;&#21040; proxy&#12290;</p><p>&#36899;&#32218;&#24314;&#31435;&#24460;&#65292;&#36991;&#20813; server &#24448; proxy &#36865;&#23553;&#21253;&#26178;&#35201;&#32147;&#36942; netfilter&#65292;eBPF &#26371;&#29992; Sockmap &#32080;&#27083;&#65292;&#23559;&#20841;&#20491;&#19981;&#21516; process (server &amp; proxy) &#22312; kernel &#20013; socket &#29289;&#20214;&#20570;&#38364;&#32879;&#65292;&#30070; server &#36865;&#23553;&#21253;&#20986;&#21435;&#26178;&#65292;&#26371;&#34987; eBPF hook &#25876;&#25130;&#65292;&#30332;&#29694; dest socket &#22312; Sockmap &#26377;&#38364;&#32879;&#65292;&#21487;&#30452;&#25509;&#24448;&#23565;&#25033;&#30340; socket &#36865;&#65292;&#19981;&#38656;&#32147;&#36942; netfilter&#12290;</p><p>&#21407;&#26412;&#27794; eBPF &#30340; service mesh &#65292;side car &#35201;&#25876;&#25130; outbound request &#38656;&#32147;&#36942;&#20841;&#27425; netfilter&#65292;&#26377;&#20102; eBPF &#26159; 0 &#27425;&#65292;&#22240;&#27492;&#25928;&#33021;&#26356;&#22909;&#65292;&#29978;&#33267; eBPF &#19979;&#30340; service mesh &#33021;&#26356;&#22909;&#22320;&#25903;&#25588; per node &#30340; proxy &#26550;&#27083;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!swcx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd313742a-e8a8-4dee-848c-b716d5d522b4_2560x1134.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!swcx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd313742a-e8a8-4dee-848c-b716d5d522b4_2560x1134.png 424w, https://substackcdn.com/image/fetch/$s_!swcx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd313742a-e8a8-4dee-848c-b716d5d522b4_2560x1134.png 848w, https://substackcdn.com/image/fetch/$s_!swcx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd313742a-e8a8-4dee-848c-b716d5d522b4_2560x1134.png 1272w, https://substackcdn.com/image/fetch/$s_!swcx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd313742a-e8a8-4dee-848c-b716d5d522b4_2560x1134.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!swcx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd313742a-e8a8-4dee-848c-b716d5d522b4_2560x1134.png" width="1456" height="645" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d313742a-e8a8-4dee-848c-b716d5d522b4_2560x1134.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:645,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;How eBPF will solve Service Mesh - Goodbye Sidecars&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="How eBPF will solve Service Mesh - Goodbye Sidecars" title="How eBPF will solve Service Mesh - Goodbye Sidecars" srcset="https://substackcdn.com/image/fetch/$s_!swcx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd313742a-e8a8-4dee-848c-b716d5d522b4_2560x1134.png 424w, https://substackcdn.com/image/fetch/$s_!swcx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd313742a-e8a8-4dee-848c-b716d5d522b4_2560x1134.png 848w, https://substackcdn.com/image/fetch/$s_!swcx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd313742a-e8a8-4dee-848c-b716d5d522b4_2560x1134.png 1272w, https://substackcdn.com/image/fetch/$s_!swcx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd313742a-e8a8-4dee-848c-b716d5d522b4_2560x1134.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source : https://isovalent.com/blog/post/2021-12-08-ebpf-servicemesh/</p>]]></content:encoded></item><item><title><![CDATA[Kubernetes Network 是怎麼運作的？上集]]></title><description><![CDATA[&#35299;&#26512; Pod &#20043;&#38291;&#30340;&#32178;&#36335;&#36890;&#35338;&#25216;&#34899;]]></description><link>https://www.chillvic.dev/p/kubernetes-network</link><guid isPermaLink="false">https://www.chillvic.dev/p/kubernetes-network</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Tue, 30 Dec 2025 10:25:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!rkwx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9f1e58-835e-4a31-bcad-2336dedbbe76_1696x2528.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p> K8S CNI (Container Network Interface) &#23450;&#32681;&#20102; K8S &#32178;&#36335;&#36890;&#35338;&#38656;&#35201;&#30340; API&#65292;&#20294;&#24213;&#23652; CNI &#23526;&#20316;&#31350;&#31455;&#26159;&#22914;&#20309;&#23526;&#29694; K8S &#32178;&#36335;&#36890;&#35338;&#30340;&#21602;&#65311;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rkwx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9f1e58-835e-4a31-bcad-2336dedbbe76_1696x2528.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rkwx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9f1e58-835e-4a31-bcad-2336dedbbe76_1696x2528.png 424w, https://substackcdn.com/image/fetch/$s_!rkwx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9f1e58-835e-4a31-bcad-2336dedbbe76_1696x2528.png 848w, https://substackcdn.com/image/fetch/$s_!rkwx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9f1e58-835e-4a31-bcad-2336dedbbe76_1696x2528.png 1272w, https://substackcdn.com/image/fetch/$s_!rkwx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9f1e58-835e-4a31-bcad-2336dedbbe76_1696x2528.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rkwx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9f1e58-835e-4a31-bcad-2336dedbbe76_1696x2528.png" width="1456" height="2170" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4c9f1e58-835e-4a31-bcad-2336dedbbe76_1696x2528.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2170,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5389161,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/182943666?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9f1e58-835e-4a31-bcad-2336dedbbe76_1696x2528.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rkwx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9f1e58-835e-4a31-bcad-2336dedbbe76_1696x2528.png 424w, https://substackcdn.com/image/fetch/$s_!rkwx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9f1e58-835e-4a31-bcad-2336dedbbe76_1696x2528.png 848w, https://substackcdn.com/image/fetch/$s_!rkwx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9f1e58-835e-4a31-bcad-2336dedbbe76_1696x2528.png 1272w, https://substackcdn.com/image/fetch/$s_!rkwx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9f1e58-835e-4a31-bcad-2336dedbbe76_1696x2528.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>&#39318;&#20808;&#65292;&#25105;&#20497;&#20808;&#22238;&#31572;&#19968;&#20491;&#26368;&#22522;&#30990;&#21839;&#38988;&#65306;</p><h1>K8S &#22312;&#32178;&#36335;&#23652;&#35201;&#35299;&#27770;&#20160;&#40636;&#21839;&#38988;&#65311;</h1><p>K8S cluster &#26371;&#26377;&#22810;&#20491; worker node&#65292;&#27599;&#20491; node &#26377;&#22810;&#20491; pod&#65292;&#19968;&#20491; pod &#26159;&#19968;&#20491; container &#26377;&#33258;&#24049;&#30340; network namespace&#65292;&#38548;&#38626;&#20102;&#32178;&#36335;&#21487;&#35222;&#31684;&#22285;&#65292;&#22240;&#27492;&#21021;&#22987;&#26178;&#65292;pod &#20043;&#38291;&#26159;&#30475;&#19981;&#21040;&#24444;&#27492;&#30340;&#65292;&#21363;&#20415;&#36889;&#20123; pod &#37117;&#26159;&#22312;&#21516;&#19968;&#20491; node &#35041;&#38754;&#12290;</p><h2>&#22914;&#20309;&#35731;&#30456;&#21516; Node &#20043;&#38291;&#30340; pod &#33021;&#20114;&#30456;&#20132;&#25563;&#23553;&#21253;&#65311;</h2><p>&#23567;&#26178;&#20505;&#21435;&#26379;&#21451;&#23478;&#29609;&#19990;&#32000;&#24093;&#22283;&#65292;&#21363;&#20415;&#27794;&#26377;&#32178;&#36335;&#65292;&#21482;&#35201;&#38651;&#33126;&#26377;&#32178;&#21345;&#65292;&#36879;&#36942;&#32178;&#32218;&#25509;&#19978;&#20132;&#25563;&#22120;&#65292;&#23601;&#21487;&#22312;&#21312;&#32178;&#30475;&#21040;&#24444;&#27492;&#30340;&#38651;&#33126;&#36899;&#32218;&#23565;&#25136;&#12290;</p><p>&#30456;&#21516;&#27010;&#24565;&#65292;&#21487;&#22312; kernel &#20013;&#24314;&#31435;&#34395;&#25836;&#20132;&#25563;&#22120; (aka linux bridge)&#65292;&#32000;&#37636; IP &amp; Mac address &#30340;&#36681;&#25563;&#65292;&#20006;&#36879;&#36942; veth pair &#23559;&#25152;&#26377; pod &#25509;&#19978;&#34395;&#25836;&#20132;&#25563;&#22120;&#65292;&#32780; veth pair &#39006;&#20284;&#34395;&#25836;&#32178;&#32218;&#65292;&#25509;&#19978;&#30636;&#38291;&#65292;kernel &#26371;&#28858;&#36889;&#20491; namespace &#24314;&#31435;&#34395;&#25836;&#32178;&#36335;&#25509;&#21475;&#65292;&#39006;&#20284;&#34395;&#25836;&#32178;&#21345;&#20006;&#20998;&#37197; Mac Address &#21644;&#32129;&#23450;&#20320;&#25351;&#23450;&#30340; IP &#65292;&#36889;&#27171;&#25152;&#26377; pod &#21487;&#36879;&#36942; linux bridge &#20132;&#25563;&#23553;&#21253;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!f7-g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53538f46-096f-496f-90a4-3156a11e99ca_430x370.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!f7-g!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53538f46-096f-496f-90a4-3156a11e99ca_430x370.png 424w, https://substackcdn.com/image/fetch/$s_!f7-g!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53538f46-096f-496f-90a4-3156a11e99ca_430x370.png 848w, https://substackcdn.com/image/fetch/$s_!f7-g!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53538f46-096f-496f-90a4-3156a11e99ca_430x370.png 1272w, https://substackcdn.com/image/fetch/$s_!f7-g!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53538f46-096f-496f-90a4-3156a11e99ca_430x370.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!f7-g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53538f46-096f-496f-90a4-3156a11e99ca_430x370.png" width="430" height="370" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/53538f46-096f-496f-90a4-3156a11e99ca_430x370.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:370,&quot;width&quot;:430,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Fun with veth-devices, Linux bridges and VLANs in unnamed Linux network  namespaces &#8211; III | Linux-Blog &#8211; Dr. M&#246;nchmeyer / anracon&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Fun with veth-devices, Linux bridges and VLANs in unnamed Linux network  namespaces &#8211; III | Linux-Blog &#8211; Dr. M&#246;nchmeyer / anracon" title="Fun with veth-devices, Linux bridges and VLANs in unnamed Linux network  namespaces &#8211; III | Linux-Blog &#8211; Dr. M&#246;nchmeyer / anracon" srcset="https://substackcdn.com/image/fetch/$s_!f7-g!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53538f46-096f-496f-90a4-3156a11e99ca_430x370.png 424w, https://substackcdn.com/image/fetch/$s_!f7-g!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53538f46-096f-496f-90a4-3156a11e99ca_430x370.png 848w, https://substackcdn.com/image/fetch/$s_!f7-g!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53538f46-096f-496f-90a4-3156a11e99ca_430x370.png 1272w, https://substackcdn.com/image/fetch/$s_!f7-g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53538f46-096f-496f-90a4-3156a11e99ca_430x370.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: https://linux-blog.anracom.com/2017/11/14/fun-with-veth-devices-linux-bridges-and-vlans-in-unnamed-linux-network-namespaces-iii/</p><h2>&#37027;&#40636;&#36328; Node &#20043;&#38291;&#30340; pod &#35201;&#24590;&#40636;&#20132;&#25563;&#23553;&#21253;&#65311;</h2><p>&#30070; destination IP &#19981;&#22312; linux bridge &#20013;&#65292;&#21218;&#24517;&#22312;&#19981;&#21516;&#27231;&#22120;&#19978;&#65292;&#27492;&#26178; pod &#30340; outbound &#23553;&#21253;&#35201;&#36879;&#36942; node &#30340; root kernel &#36865;&#20986;&#65292;&#19988; destination IP &#19981;&#22312;&#26159; pod IP &#32780;&#26159;&#21478;&#19968;&#20491; node IP&#65292;&#36889;&#27171;&#22806;&#37096; layer 3 &#32178;&#36335;&#25165;&#30693;&#36947;&#24590;&#40636;&#36681;&#36865;&#23553;&#21253;&#12290;</p><p>&#20363;&#22914; podA -&gt; podB&#8217;s IP -&gt; nodeA -&gt; nodeB&#8217;s IP -&gt; nodeB -&gt; podB&#8217;s IP -&gt; podB</p><p>&#20294;&#19978;&#38754;&#36889;&#26781;&#36335;&#32147;&#26377;&#20841;&#20491;&#21839;&#38988;&#35201;&#20811;&#26381;&#65306;</p><h3>node B &#25910;&#21040; destination IP &#26159; node IP &#26178;&#65292;&#35201;&#24590;&#30693;&#36947;&#35442;&#23553;&#21253;&#35201;&#32102;&#21738;&#20491; pod&#65311;</h3><p>&#31572;&#26696;&#26159;&#36879;&#36942; overlay <strong>network</strong> &#36319; <strong>tunneling</strong> &#25216;&#34899;&#65306;</p><p><strong>tunneling &#25216;&#34899;</strong>&#26159;&#23553;&#21253;&#30090;&#21152;&#25216;&#34899;&#65292;&#20363;&#22914;&#21407;&#23553;&#21253; destination ip &#26159; podB&#8217;s IP&#65292;&#36879;&#36942; tunneling &#30090;&#21152;&#19968;&#23652;&#65292;&#35731; destination ip &#35722;&#25104; nodeB&#8217;s IP&#65292;&#30070; node B &#25910;&#21040;&#24460;&#31227;&#38500;&#30090;&#21152;&#36039;&#35338;&#65292;&#23601;&#33021;&#35703;&#24471; pod B&#8217;s IP&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Oav7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bb884ce-c33a-4a9c-adbc-8fe3b6acaca2_940x481.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Oav7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bb884ce-c33a-4a9c-adbc-8fe3b6acaca2_940x481.png 424w, https://substackcdn.com/image/fetch/$s_!Oav7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bb884ce-c33a-4a9c-adbc-8fe3b6acaca2_940x481.png 848w, https://substackcdn.com/image/fetch/$s_!Oav7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bb884ce-c33a-4a9c-adbc-8fe3b6acaca2_940x481.png 1272w, https://substackcdn.com/image/fetch/$s_!Oav7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bb884ce-c33a-4a9c-adbc-8fe3b6acaca2_940x481.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Oav7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bb884ce-c33a-4a9c-adbc-8fe3b6acaca2_940x481.png" width="940" height="481" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0bb884ce-c33a-4a9c-adbc-8fe3b6acaca2_940x481.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:481,&quot;width&quot;:940,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;VxLAN vs NVGRE: What's the Difference? - GeeksforGeeks&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="VxLAN vs NVGRE: What's the Difference? - GeeksforGeeks" title="VxLAN vs NVGRE: What's the Difference? - GeeksforGeeks" srcset="https://substackcdn.com/image/fetch/$s_!Oav7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bb884ce-c33a-4a9c-adbc-8fe3b6acaca2_940x481.png 424w, https://substackcdn.com/image/fetch/$s_!Oav7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bb884ce-c33a-4a9c-adbc-8fe3b6acaca2_940x481.png 848w, https://substackcdn.com/image/fetch/$s_!Oav7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bb884ce-c33a-4a9c-adbc-8fe3b6acaca2_940x481.png 1272w, https://substackcdn.com/image/fetch/$s_!Oav7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bb884ce-c33a-4a9c-adbc-8fe3b6acaca2_940x481.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: https://www.geeksforgeeks.org/computer-networks/vxlan-vs-nvgre-whats-the-difference/</p><p>&#32780;&#23526;&#38555;&#30340;&#30090;&#21152;&#36319;&#31227;&#38500;&#26159;&#36879;&#36942; <strong>overlay network</strong>&#65292;&#20363;&#22914; VXLAN &#22312; kernel &#20013;&#36939;&#34892;&#19968;&#20491; UDP service bind &#22312; 4789 port&#65292;&#39006;&#20284;&#19968;&#20491;&#34395;&#25836; router (vxlan device)&#65292;Node A &#36865;&#23553;&#21253;&#26178;&#65292;&#25226; dest IP &#26159; podB&#8217;s IP &#30340; TCP &#23553;&#21253;&#23553;&#35037;&#25104; dest IP &#26159; nodeB&#8217;s IP &#30340; UDP &#23553;&#21253;&#65292;&#36865;&#24448; 4789 port&#65292;VXLAN service &#25910;&#21040;&#24460;&#26371;&#35299;&#26512; UDP &#29554;&#24471;&#32102; podB&#8217;s IP &#30340; TCP &#23553;&#21253;&#65292;&#32780;&#36889;&#20491; UDP network &#26159;&#30090;&#21152;&#22312; TCP network &#19978;&#30340;&#65292;&#25152;&#20197;&#31281;&#28858; overlay network&#12290;</p><h3>node A &#35201;&#24590;&#40636;&#23559; podB&#8217;s IP &#25563;&#25104; nodeB&#8217;s IP&#65311;</h3><p>&#39318;&#20808; K8S &#38656;&#35201;&#20570;&#21040;&#22312;&#27599;&#20491; pod &#21021;&#22987;&#21270;&#26178;&#20998;&#37197;&#19968;&#20491; private IP&#65292;&#19988;&#35442; IP &#36328; Node &#20043;&#38291;&#19981;&#33021;&#30896;&#25758;&#65292;&#22240;&#27492;&#38656;&#35201;&#29544;&#31435;&#30340; control panel server &#36000;&#36012;&#31649;&#29702;&#25152;&#26377; node &#21487;&#29992;&#30340; CIDR (e.g 10.0.0.0/32 )&#12290;</p><p>&#25509;&#33879;&#19968;&#27171;&#36879;&#36942; overlay network&#65292;node A &#23559; dest IP &#26159; podB&#8217;s IP &#30340; TCP &#23553;&#21253;&#36865;&#32102;&#65292;VXLAN &#36889;&#20491;&#34395;&#25836; router (vxlan device)&#65292;VXLAN &#26371;&#36879;&#36942;&#24478; control panel &#29554;&#24471;&#19981;&#21516; Node &#36000;&#36012;&#30340; CIDR &#65292;&#23559;&#23553;&#21253;&#23553;&#35037;&#25104; dest IP &#26159; nodeB&#8217;s IP &#30340; UPD &#23553;&#21253;&#36865;&#20986;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DQa_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31675199-59d2-4ce4-969e-4201e81f60c1_599x299.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DQa_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31675199-59d2-4ce4-969e-4201e81f60c1_599x299.jpeg 424w, https://substackcdn.com/image/fetch/$s_!DQa_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31675199-59d2-4ce4-969e-4201e81f60c1_599x299.jpeg 848w, https://substackcdn.com/image/fetch/$s_!DQa_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31675199-59d2-4ce4-969e-4201e81f60c1_599x299.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!DQa_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31675199-59d2-4ce4-969e-4201e81f60c1_599x299.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DQa_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31675199-59d2-4ce4-969e-4201e81f60c1_599x299.jpeg" width="599" height="299" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/31675199-59d2-4ce4-969e-4201e81f60c1_599x299.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:299,&quot;width&quot;:599,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;ENCOR Training &#187; VXLAN Tutorial&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="ENCOR Training &#187; VXLAN Tutorial" title="ENCOR Training &#187; VXLAN Tutorial" srcset="https://substackcdn.com/image/fetch/$s_!DQa_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31675199-59d2-4ce4-969e-4201e81f60c1_599x299.jpeg 424w, https://substackcdn.com/image/fetch/$s_!DQa_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31675199-59d2-4ce4-969e-4201e81f60c1_599x299.jpeg 848w, https://substackcdn.com/image/fetch/$s_!DQa_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31675199-59d2-4ce4-969e-4201e81f60c1_599x299.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!DQa_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31675199-59d2-4ce4-969e-4201e81f60c1_599x299.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: https://www.digitaltut.com/vxlan-tutorial/2</p><p>&#26377;&#20102;&#35731; Pod &#20043;&#38291;&#28317;&#36890;&#30340;&#33021;&#21147;&#24460;&#65292;&#25509;&#19979;&#20358;&#35201;&#35299;&#27770; Pod IP &#37325;&#21855;&#24460;&#26371;&#19968;&#30452;&#25913;&#35722;&#30340;&#21839;&#38988;&#12290;</p><h1>&#22914;&#20309;&#29992;&#19968;&#20491;&#22266;&#23450; private IP &#36865;&#35531;&#27714;&#21040;&#29305;&#23450;&#30340; Pod&#65311;</h1><p>&#30070; Pod &#26356;&#26032;&#37325;&#21855;&#65292;IP &#37325;&#20998;&#37197;&#26371;&#25913;&#35722;&#65292;&#23565; Client &#31471;&#38750;&#24120;&#19981;&#26041;&#20415;&#65292;&#22240;&#27492; K8S &#25552;&#20379; Service Endpoint&#65292;&#24314;&#31435; Service Endpoint &#26178;&#65292;K8S &#26371;&#20998;&#37197;&#19968;&#20491; IP&#65292;&#20006;&#36879;&#36942; label selector &#25214;&#21040;&#35201;&#32129;&#23450;&#30340; pod&#65292;&#23559;&#36865;&#24448;&#35442; service IP &#30340;&#35531;&#27714; forward &#21040; pod &#20013;&#65292;&#21482;&#35201; service &#19981;&#37325;&#24314;&#65292;pod &#19981;&#26039;&#37325;&#21855;&#37117;&#19981;&#24433;&#38911; client &#29992; service IP &#36865;&#35531;&#27714;&#21040; pod&#12290;</p><p>&#32780;&#23559;&#30456;&#21516; service IP &#35531;&#27714;&#36681;&#30332;&#32102;&#19981;&#21516; pod &#30340;&#21151;&#33021;&#65292;&#26412;&#36074;&#19978;&#20006;&#19981;&#26159; Pod &#20043;&#38291;&#30340;&#32178;&#36335;&#36890;&#35338;&#65292;&#32780;&#26159;&#19968;&#20491; Layer4 Load Balance&#65292;&#22240;&#27492;&#20659;&#32113; CNI &#20363;&#22914; Flannel &#19981;&#36000;&#36012;&#36681;&#30332;&#65292;&#21482;&#36000;&#36012; Pod &#20043;&#38291;&#30340; Layer 3 &#36890;&#35338;&#12290;</p><p>&#22240;&#27492; Layer4 Load Balance &#26159;&#30001; kube-proxy &#19968;&#20491; K8S &#26550;&#27083;&#20013;&#30340;&#26680;&#24515;&#27169;&#32068;&#23526;&#29694;&#30340;&#12290;</p><p></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.chillvic.dev/subscribe?"><span>Subscribe now</span></a></p><h1>kube-proxy &#22914;&#20309;&#23559; destination IP &#26159; service IP &#30340;&#23553;&#21253; forward &#32102; pod &#21602;&#65311;</h1><p>&#26089;&#26399;&#29256;&#26412;&#26159;&#29992; iptable&#65292;iptable &#26159;&#20351;&#29992; kernel netfilter module &#30340;&#32178;&#36335;&#23553;&#21253;&#35215;&#21063;&#31649;&#29702;&#24037;&#20855;&#65292;netfilter &#22312; kernel &#20013;&#36000;&#36012;&#23553;&#21253;&#35299;&#26512; &amp; &#36899;&#32218;&#36861;&#36452;&#65292;&#20854;&#25552;&#20379;&#22312;&#35299;&#26512;&#21069;&#36319;&#35299;&#26512;&#24460;&#25554;&#20837; hook &#21151;&#33021;&#65292;&#20363;&#22914; layer 3 &#35299;&#26512;&#24460;&#65292;&#25554;&#20837;&#19968;&#20491;&#38459;&#25803;&#29305;&#23450; ip &#30340; hook &#23601;&#33021;&#23526;&#29694;&#38450;&#28779;&#29254;&#21151;&#33021;&#65292;&#32780;&#36889;&#23601;&#26159; iptable &#26368;&#37325;&#35201;&#30340;&#21151;&#33021;&#20043;&#19968;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PBqt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989c95d5-6a6e-4e55-b3c2-192c0320ca27_979x774.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PBqt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989c95d5-6a6e-4e55-b3c2-192c0320ca27_979x774.png 424w, https://substackcdn.com/image/fetch/$s_!PBqt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989c95d5-6a6e-4e55-b3c2-192c0320ca27_979x774.png 848w, https://substackcdn.com/image/fetch/$s_!PBqt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989c95d5-6a6e-4e55-b3c2-192c0320ca27_979x774.png 1272w, https://substackcdn.com/image/fetch/$s_!PBqt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989c95d5-6a6e-4e55-b3c2-192c0320ca27_979x774.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PBqt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989c95d5-6a6e-4e55-b3c2-192c0320ca27_979x774.png" width="979" height="774" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/989c95d5-6a6e-4e55-b3c2-192c0320ca27_979x774.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:774,&quot;width&quot;:979,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&#36830;&#25509;&#36319;&#36394;&#65288;conntrack&#65289;&#65306;&#21407;&#29702;&#12289;&#24212;&#29992;&#21450;Linux &#20869;&#26680;&#23454;&#29616;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="&#36830;&#25509;&#36319;&#36394;&#65288;conntrack&#65289;&#65306;&#21407;&#29702;&#12289;&#24212;&#29992;&#21450;Linux &#20869;&#26680;&#23454;&#29616;" title="&#36830;&#25509;&#36319;&#36394;&#65288;conntrack&#65289;&#65306;&#21407;&#29702;&#12289;&#24212;&#29992;&#21450;Linux &#20869;&#26680;&#23454;&#29616;" srcset="https://substackcdn.com/image/fetch/$s_!PBqt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989c95d5-6a6e-4e55-b3c2-192c0320ca27_979x774.png 424w, https://substackcdn.com/image/fetch/$s_!PBqt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989c95d5-6a6e-4e55-b3c2-192c0320ca27_979x774.png 848w, https://substackcdn.com/image/fetch/$s_!PBqt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989c95d5-6a6e-4e55-b3c2-192c0320ca27_979x774.png 1272w, https://substackcdn.com/image/fetch/$s_!PBqt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989c95d5-6a6e-4e55-b3c2-192c0320ca27_979x774.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source : https://arthurchiao.art/blog/conntrack-design-and-implementation-zh/</p><p>iptable &#21487;&#22312;&#19981;&#21516;&#26178;&#38291;&#40670;&#24314;&#31435;&#19981;&#21516;&#21151;&#33021;&#30340;&#35215;&#21063;&#65306;</p><ul><li><p>PREROUTING&#65306;kernel layer 3 &#35299;&#21253;&#24460;&#65292;&#36914;&#20837; routing &#35215;&#21063;&#21069;</p></li><li><p>INPUT&#65306;&#22519;&#34892;&#23436; routing &#35215;&#21063;&#65292;&#30332;&#29694;&#26159;&#33258;&#24049;&#30340;&#23553;&#21253;&#65292;&#34389;&#29702;&#36889;&#20491;&#23553;&#21253;&#21069;</p></li><li><p>FORWARD&#65306;&#22519;&#34892;&#23436; routing &#35215;&#21063;&#65292;&#30332;&#29694;&#19981;&#26159;&#33258;&#24049;&#30340;&#65292;forward &#20986;&#21435;&#32102;&#20854;&#20182;&#20154;&#21069;</p></li><li><p>OUTPUT&#65306;user space process &#36865;&#23553;&#21253;&#32102; kernel&#65292;&#22519;&#34892; routing &#20043;&#21069;</p></li><li><p>POSTROUTING &#65306;&#23436;&#25104; routing decision&#65292;&#30906;&#23450;&#32178;&#36335;&#20986;&#21475;&#20171;&#38754;&#24460;&#65292;&#36865;&#20986;&#23553;&#21253;&#20043;&#21069;</p></li></ul><p>&#24120;&#35211;&#38450;&#28779;&#29254;&#26159;&#22312; INPUT &#21152;&#19978;&#29305;&#23450; IP DROP &#35215;&#21063;&#65292;&#21487;&#25803; inbound request&#65292;&#22312; OUTPUT &#21152;&#19978; DROP &#25803; outbound request&#12290;</p><p>&#30070;&#23553;&#21253;&#32147;&#36942; VXLAN &#35299;&#21253;&#29554;&#24471; dest service IP &#30340; TCP &#23553;&#21253;&#26178;&#65292;&#21487;&#24314;&#31435; PREROUTING &#35215;&#21063;&#65292;&#23559; service IP &#20462;&#25913;&#25104; pod IP &#20358;&#23526;&#29694;&#23553;&#21253;&#36681;&#30332;&#65292;&#30070;&#19968;&#20491; service IP &#32972;&#24460;&#26377;&#22810;&#20491; pod &#26178;&#65292;&#26371;&#24314;&#31435;&#22810;&#26781;&#35215;&#21063;&#65292;&#36879;&#36942;&#35373;&#23450; probability &#23526;&#29694; load balancing&#65292;&#20363;&#22914;&#26377;&#19977;&#20491; pod&#65292;&#26371;&#24314;&#31435;&#19977;&#20491; PREROUTING &#35215;&#21063;&#65292;&#30001;&#26044;&#35215;&#21063;&#26159;&#19968;&#26781;&#26781;&#38918;&#24207;&#22519;&#34892;&#30340;&#65292;&#25152;&#20197;&#31532;&#19968;&#26781;&#22519;&#34892;&#25104;&#21151;&#27231;&#29575; 33%&#65292;&#31532;&#20108;&#26781; 50%&#65292;&#31532;&#19977;&#26781; 100&#65285;&#65292;&#23601;&#33021;&#22312;&#27231;&#29575;&#19978;&#35731;&#35531;&#27714;&#24179;&#22343;&#36865;&#24448;&#19977;&#20491;&#19981;&#21516; pod&#12290;</p><p>&#20462;&#25913; dest IP &#24460;&#36914;&#20837; routing &#36865;&#24448; bridge &#36681;&#30332;&#32102; pod &#25110;&#32773;&#32102; vxlan device &#36865;&#24448;&#20854;&#20182; node&#12290;</p><h1>&#38500;&#20102;&#20462;&#25913; destination IP &#20043;&#22806;&#65292;&#28858;&#20309;&#36996;&#35201;&#20462;&#25913; source IP&#65311;</h1><p>pod &#25910;&#21040; request &#24460;&#65292;&#36865;&#20986; response &#26178;&#26371;&#38656;&#35201;&#23559; source IP &#24478; pod IP &#36996;&#21407;&#25104; service IP&#65292;&#20294;&#26159;&#28858;&#20309;&#65311;</p><p>&#21407;&#22240;&#22312;&#26044; TCP &#24314;&#31435;&#26159;&#26377;&#29376;&#24907;&#30340;&#65292;&#26371;&#36879;&#36942; (src_ip, src_port, dest_ip, dest_port, protocol) &#32068;&#25104;&#36899;&#32218; ID&#65292;&#32000;&#37636;&#35442;&#36899;&#32218;&#20013;&#23553;&#21253;&#25509;&#25910;&#29376;&#27841;&#65292;&#26377;&#27794;&#26377;&#36986;&#28431;&#65292;&#35201;&#19981;&#35201; retry&#65292;client &#24314;&#31435; TCP &#26178;&#26159;&#29992; service IP &#28858; dest_ip&#65292;&#22914;&#26524; response &#30340; src_ip &#19981;&#26159; service IP &#22312; client kernel &#20013;&#26371;&#28961;&#27861;&#21305;&#37197;&#35442;&#23553;&#21253;&#23660;&#26044;&#21738;&#20491; TPC &#36899;&#32218;&#32780;&#34987;&#19999;&#26820;&#65292;&#22240;&#27492;&#38656;&#35201;&#20462;&#25913; response &#30340; src_ip&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kcxX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99fdf41-b0cb-408f-bf86-0207a5b69b31_700x365.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kcxX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99fdf41-b0cb-408f-bf86-0207a5b69b31_700x365.jpeg 424w, https://substackcdn.com/image/fetch/$s_!kcxX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99fdf41-b0cb-408f-bf86-0207a5b69b31_700x365.jpeg 848w, https://substackcdn.com/image/fetch/$s_!kcxX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99fdf41-b0cb-408f-bf86-0207a5b69b31_700x365.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!kcxX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99fdf41-b0cb-408f-bf86-0207a5b69b31_700x365.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kcxX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99fdf41-b0cb-408f-bf86-0207a5b69b31_700x365.jpeg" width="700" height="365" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c99fdf41-b0cb-408f-bf86-0207a5b69b31_700x365.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:365,&quot;width&quot;:700,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Napatech blog - What is a flow?&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Napatech blog - What is a flow?" title="Napatech blog - What is a flow?" srcset="https://substackcdn.com/image/fetch/$s_!kcxX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99fdf41-b0cb-408f-bf86-0207a5b69b31_700x365.jpeg 424w, https://substackcdn.com/image/fetch/$s_!kcxX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99fdf41-b0cb-408f-bf86-0207a5b69b31_700x365.jpeg 848w, https://substackcdn.com/image/fetch/$s_!kcxX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99fdf41-b0cb-408f-bf86-0207a5b69b31_700x365.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!kcxX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99fdf41-b0cb-408f-bf86-0207a5b69b31_700x365.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: https://www.napatech.com/what-is-a-flow/</p><p>&#20294;&#19981;&#26159;&#25152;&#26377; response &#30340; src_ip &#37117;&#35201;&#25913;&#65292;&#20551;&#35373; pod A &#24448; pod B &#24314;&#31435;&#20841;&#26781; TCP connections&#65292;src_port &#26371;&#38568;&#27231;&#20998;&#37197;&#65306;</p><ul><li><p>conn_1 &#20351;&#29992; service IP &#65292;id &#28858; (src_ip, src_port_1, service_ip, dest_port, protocol)</p></li><li><p>conn_2 &#30452;&#25509;&#29992; pod IP&#65292;id &#28858; (src_ip, src_port_2, pod_ip, dest_port, protocol)</p></li></ul><p>&#37027;&#21482;&#26377; conn_1 &#30340; response src_ip &#35201;&#24478; service_ip &#25913;&#25104; pod_ip&#65292;conn_2 &#21063;&#35201;&#20445;&#30041;&#65292;&#35201;&#20570;&#21040;&#36889;&#20214;&#20107;&#24773;&#65292;&#23601;&#38656;&#35201;&#32000;&#37636;&#27599;&#20491;&#21407;&#22987; connection &#30340; id&#65292;&#20063;&#23601;&#26159; netfilter conntrack &#21151;&#33021;&#12290;</p><p>conntrack &#21487;&#29992; connection id &#32000;&#37636;&#32147;&#36942; netfilter &#24314;&#31435;&#30340; TCP &#36899;&#32218;&#65292;&#20197;&#21450;&#36681;&#25563;&#34920;&#65292;&#26377;&#20102; conntrack &#21487;&#20197;&#36942;&#28670;&#20986; conn_2 &#27794;&#26377;&#36681;&#25563;&#36942;&#65292;&#19981;&#38656;&#35201;&#20462;&#25913;&#65292;&#32780; conn_1 &#26377;&#36681;&#25563;&#36942;&#65292;&#38656;&#36996;&#21407; src_ip &#28858; service IP&#12290;</p><h1>&#20351;&#29992; iptable &#26377;&#20160;&#40636;&#32570;&#40670;&#65311;</h1><p>iptable &#20027;&#35201;&#26159;&#38450;&#28779;&#29254;&#21151;&#33021;&#65292;&#20294; K8S service IP &#30906;&#26159; forward + load balancer&#65292;&#22240;&#27492;&#20351;&#29992; iptable &#26377;&#20841;&#20491;&#32570;&#40670;&#65306;</p><ul><li><p>&#25928;&#33021;&#24046;&#65306;iptable &#38656;&#35201; for loop &#25152;&#26377;&#35215;&#21063;&#65292;&#30452;&#21040;&#31532;&#19968;&#20491;&#35215;&#21063;&#21629;&#20013;&#24460;&#25165; break&#65292;&#22914;&#26524; service &#24456;&#22810;&#65292;pod &#24456;&#22810;&#65292;&#25928;&#33021;&#26371;&#24456;&#24046;</p></li><li><p>load balancer&#65306;&#21482;&#33021;&#29992;&#27231;&#29575;&#23526;&#20316;&#65292;&#27794;&#26377;&#30906;&#23450;&#65292;&#23458;&#35069;&#21270;&#31243;&#24230;&#20302;&#65292;&#20363;&#22914;&#19981;&#33021;&#29992; Round Robin</p></li></ul><p>&#32780; <strong>IPVS</strong> &#26159; Linux kernel &#36879;&#36942; netfilter hook &#23526;&#20316;&#30340; L4 Load Balancer &#27169;&#32068;&#65292;&#23433;&#35037; ipvsadm &#24037;&#20855;&#24460;&#65292;&#21487;&#30452;&#25509;&#24448; IPVS &#24314;&#31435; routing table&#65292;&#26159;&#19968;&#20491; hashmap &#32080;&#27083;&#65292;O(1) &#26597;&#25214;&#25928;&#33021;&#26356;&#22909;&#65292;&#19988;&#25903;&#25588;&#22810;&#31278; load balance &#31574;&#30053;&#65292;&#20363;&#22914; Round Robin or Least Connections&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OXiC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3295978d-5000-4eeb-9870-8bd643199f00_1024x576.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OXiC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3295978d-5000-4eeb-9870-8bd643199f00_1024x576.jpeg 424w, https://substackcdn.com/image/fetch/$s_!OXiC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3295978d-5000-4eeb-9870-8bd643199f00_1024x576.jpeg 848w, https://substackcdn.com/image/fetch/$s_!OXiC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3295978d-5000-4eeb-9870-8bd643199f00_1024x576.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!OXiC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3295978d-5000-4eeb-9870-8bd643199f00_1024x576.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OXiC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3295978d-5000-4eeb-9870-8bd643199f00_1024x576.jpeg" width="1024" height="576" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3295978d-5000-4eeb-9870-8bd643199f00_1024x576.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:576,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;IPTables vs IPVS in kubernetes&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="IPTables vs IPVS in kubernetes" title="IPTables vs IPVS in kubernetes" srcset="https://substackcdn.com/image/fetch/$s_!OXiC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3295978d-5000-4eeb-9870-8bd643199f00_1024x576.jpeg 424w, https://substackcdn.com/image/fetch/$s_!OXiC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3295978d-5000-4eeb-9870-8bd643199f00_1024x576.jpeg 848w, https://substackcdn.com/image/fetch/$s_!OXiC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3295978d-5000-4eeb-9870-8bd643199f00_1024x576.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!OXiC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3295978d-5000-4eeb-9870-8bd643199f00_1024x576.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: https://www.linkedin.com/pulse/iptables-vs-ipvs-kubernetes-vivek-grover/</p><p>&#26377;&#20102; IPVS &amp; ipvsadm &#20043;&#24460;&#65292;&#20173;&#38656;&#35201;&#19968;&#20491; process &#21435;&#30435;&#32893; control panel &#30340; pod &amp; service &#35722;&#21270;&#36890;&#30693;&#65292;&#26377;&#26032;&#30340; pod &#24314;&#31435;&#38656;&#35201;&#32129;&#23450; service IP&#65292;&#23601;&#35201;&#36879;&#36942; ipvsadm &#20462;&#25913; routing table&#65292;&#32780;&#36889;&#20491; process &#23601;&#26159; kube-proxy&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6hbj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb62ead6-818b-42ab-8cab-1cf5c3bd9a82_827x451.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6hbj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb62ead6-818b-42ab-8cab-1cf5c3bd9a82_827x451.png 424w, https://substackcdn.com/image/fetch/$s_!6hbj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb62ead6-818b-42ab-8cab-1cf5c3bd9a82_827x451.png 848w, https://substackcdn.com/image/fetch/$s_!6hbj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb62ead6-818b-42ab-8cab-1cf5c3bd9a82_827x451.png 1272w, https://substackcdn.com/image/fetch/$s_!6hbj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb62ead6-818b-42ab-8cab-1cf5c3bd9a82_827x451.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6hbj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb62ead6-818b-42ab-8cab-1cf5c3bd9a82_827x451.png" width="827" height="451" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cb62ead6-818b-42ab-8cab-1cf5c3bd9a82_827x451.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:451,&quot;width&quot;:827,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:137998,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/182943666?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb62ead6-818b-42ab-8cab-1cf5c3bd9a82_827x451.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6hbj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb62ead6-818b-42ab-8cab-1cf5c3bd9a82_827x451.png 424w, https://substackcdn.com/image/fetch/$s_!6hbj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb62ead6-818b-42ab-8cab-1cf5c3bd9a82_827x451.png 848w, https://substackcdn.com/image/fetch/$s_!6hbj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb62ead6-818b-42ab-8cab-1cf5c3bd9a82_827x451.png 1272w, https://substackcdn.com/image/fetch/$s_!6hbj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb62ead6-818b-42ab-8cab-1cf5c3bd9a82_827x451.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source : https://www.alibabacloud.com/blog/improving-kubernetes-service-network-performance-with-socket-ebpf_599446</p><h1>&#19979;&#38598;&#38928;&#21578;</h1><p>&#20351;&#29992; IPVS &#23526;&#29694; L4 load balancer &#25928;&#33021;&#24050;&#32147;&#19981;&#37679;&#20102;&#65292;&#20294;&#22909;&#36996;&#35201;&#26356;&#22909;&#65292;&#22312;&#20043;&#21069; cloudflare &#25991;&#31456;&#20013;&#25552;&#21040;&#65292;ebpf &#20063;&#21487;&#23526;&#29694; L4 load balancer&#65292;&#19979;&#38598;&#23601;&#20358;&#35498;&#35498;&#65292;ebpf &#30340; load balancer &#26356;&#22909;&#22312;&#21738;&#35041;&#12290;</p><p>&#27492;&#22806;&#65292;&#38614;&#28982;&#26377; L4 load balancer&#65292;&#20294;&#26159;&#35201;&#23526;&#29694; grpc load balancing &#36890;&#24120;&#38656;&#35201;&#25645;&#37197; service mesh + sidecar&#65292;&#28858;&#20160;&#40636;&#21482;&#26377; sidecar &#33021;&#35299;&#27770; grpc load balancing&#65292;&#32780; ebpf &#21448;&#24590;&#40636;&#35731; sidecar &#25928;&#33021;&#22823;&#24133;&#25552;&#21319;&#65292;&#26371;&#19968;&#36215;&#22312;&#19979;&#38598;&#35498;&#26126;&#65281;</p>]]></content:encoded></item><item><title><![CDATA[CDN is More Than Just Cache: Breaking Down Cloudflare’s Architecture by OSI 7 Layers]]></title><description><![CDATA[Analysis of the Technology Stack: BGP, Anycast, Unimog, QUIC, and Pingora]]></description><link>https://www.chillvic.dev/p/cdn-is-more-than-just-cache-breaking</link><guid isPermaLink="false">https://www.chillvic.dev/p/cdn-is-more-than-just-cache-breaking</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Mon, 22 Dec 2025 02:32:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!XS-x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18948c6b-c297-4ecd-9a95-2b8cf3143ae5_1024x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Cloudflare, a dominant force in the CDN market, provides far more than simple caching. it integrates WAF, DDoS protection, and even allows engineers to execute JavaScript at the edge via Cloudflare Workers. It has effectively become one of the most critical infrastructures of the modern internet.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XS-x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18948c6b-c297-4ecd-9a95-2b8cf3143ae5_1024x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XS-x!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18948c6b-c297-4ecd-9a95-2b8cf3143ae5_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!XS-x!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18948c6b-c297-4ecd-9a95-2b8cf3143ae5_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!XS-x!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18948c6b-c297-4ecd-9a95-2b8cf3143ae5_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!XS-x!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18948c6b-c297-4ecd-9a95-2b8cf3143ae5_1024x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XS-x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18948c6b-c297-4ecd-9a95-2b8cf3143ae5_1024x1536.png" width="1024" height="1536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/18948c6b-c297-4ecd-9a95-2b8cf3143ae5_1024x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1536,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3483183,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/182281728?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18948c6b-c297-4ecd-9a95-2b8cf3143ae5_1024x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XS-x!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18948c6b-c297-4ecd-9a95-2b8cf3143ae5_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!XS-x!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18948c6b-c297-4ecd-9a95-2b8cf3143ae5_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!XS-x!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18948c6b-c297-4ecd-9a95-2b8cf3143ae5_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!XS-x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18948c6b-c297-4ecd-9a95-2b8cf3143ae5_1024x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>What does the architecture of such a vital infrastructure look like? Let&#8217;s explore through the following deep dive:</p><h1>How to Map a Single Domain to Global Edge Proxies?</h1><p>The primary function of a CDN is to route requests to the nearest edge proxy based on the user's location.</p><p>Typically, one domain maps to one public IP. <strong>Geo DNS</strong> supports mapping the same domain to different public IPs based on geography. During a recursive DNS query, the Geo DNS server identifies the client&#8217;s location via their IP and returns the corresponding regional public IP.</p><p><strong>However, this method has flaws:</strong></p><ol><li><p><strong>Latency:</strong> If the Geo DNS server is in the US, the query might travel a long distance just to find a public IP.</p></li><li><p><strong>DNS Caching:</strong> DNS has TTL (Time to Live) values. If a public IP needs to be replaced due to a failure, it takes time for the change to propagate globally, preventing instant failover.</p></li></ol><p>To solve this, Cloudflare uses <strong>Anycast</strong> technology to map a single public IP to physical machines in multiple locations simultaneously.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TIFm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TIFm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 424w, https://substackcdn.com/image/fetch/$s_!TIFm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 848w, https://substackcdn.com/image/fetch/$s_!TIFm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 1272w, https://substackcdn.com/image/fetch/$s_!TIFm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TIFm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png" width="797" height="442" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:442,&quot;width&quot;:797,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TIFm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 424w, https://substackcdn.com/image/fetch/$s_!TIFm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 848w, https://substackcdn.com/image/fetch/$s_!TIFm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 1272w, https://substackcdn.com/image/fetch/$s_!TIFm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: https://blog.cloudflare.com/unimog-cloudflares-edge-load-balancer/</p><h1>How Does Anycast Map One IP to Multiple Locations?</h1><p>Networks are divided into LANs and WANs. Within a region, an <strong>Autonomous System (AS) </strong>(e.g., an ISP) manages a specific network range (e.g., 36.224.0.0/13) . When packets enter the WAN to travel between ASs, <strong>they use the Border Gateway Protocol (BGP) to exchange routing information (a.k.a, IP Prefixes).</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hKER!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hKER!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 424w, https://substackcdn.com/image/fetch/$s_!hKER!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 848w, https://substackcdn.com/image/fetch/$s_!hKER!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!hKER!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hKER!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg" width="800" height="615" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:615,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hKER!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 424w, https://substackcdn.com/image/fetch/$s_!hKER!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 848w, https://substackcdn.com/image/fetch/$s_!hKER!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!hKER!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://www.cloudns.net/blog/understanding-bgp-a-comprehensive-guide-for-beginners/">https://www.cloudns.net/blog/understanding-bgp-a-comprehensive-guide-for-beginners/</a></p><p>For example, an ISP in Taiwan uses BGP to announce to an ISP in Japan that it is responsible for a specific IP range (e.g., <strong>36.224.0.0/13</strong>). When a Japanese user sends a request to an IP within that range (e.g., <strong>36.224.1.1</strong>), the Japanese ISP's routing table directs the packet to Taiwan&#8217;s border router. That border router then forwards the request to the final destination server within the local network.</p><p><strong>Anycast</strong> registers the same IP Prefix with different ASs via multiple border routers. Because different border routers maintain different routing tables, the same public IP will be forwarded to different locations depending on the source AS.</p><p><strong>Cloudflare leverages its status as an independent AS to register IP prefixes at the edge of various networks globally. This ensures that a Taiwan-based request reaches a Taiwan edge proxy via a local border router, minimizing latency by keeping traffic local.</strong></p><p>BGP is a Layer 3 protocol, meaning forwarding doesn&#8217;t require deep packet inspection, leading to high performance and availability. If a Japan data center fails, BGP automatically finds the next best path (e.g., to Taiwan) for that same IP.</p><h1>Is Anycast + BGP the Perfect Solution?</h1><p>Not quite. BGP routing isn&#8217;t based on geographic distance or RTT (Round Trip Time); it&#8217;s based on <strong>AS Path cost</strong>, which is largely determined by administrative policies.</p><p>For example, ASs may charge each other for transit. Network administrators can set the <strong>BGP path cost</strong> based on peering costs rather than geographic distance. To mitigate this, Cloudflare establishes direct peering with ASs to ensure <strong>Local AS Path</strong> priority.<br><br>Note: You can refer to the detailed BGP routing rules <strong><a href="https://networklessons.com/bgp/bgp-attributes-and-path-selection">here</a></strong>.<br><br>Additionally, BGP suffers from <strong>Hijacking</strong>. A hacker can announce the same IP Prefix to other ASs with a lower &#8220;cost,&#8221; diverting legitimate Cloudflare traffic to their own servers.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VxRG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VxRG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 424w, https://substackcdn.com/image/fetch/$s_!VxRG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 848w, https://substackcdn.com/image/fetch/$s_!VxRG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 1272w, https://substackcdn.com/image/fetch/$s_!VxRG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VxRG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png" width="800" height="416" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:416,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VxRG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 424w, https://substackcdn.com/image/fetch/$s_!VxRG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 848w, https://substackcdn.com/image/fetch/$s_!VxRG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 1272w, https://substackcdn.com/image/fetch/$s_!VxRG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://blog.cloudflare.com/bgp-hijack-detection/">https://blog.cloudflare.com/bgp-hijack-detection/</a></p><p><strong>The solution is to verify AS identity during registration (similar to HTTPS certificates)</strong>, though not all ISPs implement this yet. You can use https://isbgpsafeyet.com/ to check whether your ISP has implemented a verification process.</p><p>Additionally, the nature of <strong>Anycast</strong> allows multiple proxy servers in the same region to share the same public IP. <strong>This can lead to the following issue: TCP packets belonging to the same connection might be routed to different servers.</strong></p><p>Once a client establishes a TCP connection with a server, the server&#8217;s kernel stores the <strong>TCP connection ID (src_ip, src_port, dest_ip, dest_port)</strong> and its <strong>corresponding state</strong> (such as which packets have been received and the expected sequence number of the next packet) in memory to ensure packet ordering. <strong>If a packet from that same TCP connection is sent to a different server that lacks the specific connection state, that server will close the connection.</strong></p><h1>How to Solve TCP Instability in Anycast</h1><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.chillvic.dev/subscribe?"><span>Subscribe now</span></a></p><p>The network path for a packet is:</p><ol><li><p><strong>Client</strong> &#8594; ISP Gateway &#8594; BGP Selection &#8594; <strong>Border Gateway</strong></p></li><li><p><strong>Border Gateway</strong> &#8594; <strong>NAT</strong> (Public IP to Private IP)</p></li><li><p><strong>NAT</strong> &#8594; Private Network <strong>Edge Proxy</strong></p></li></ol><p>Layer 2 Gateways use <strong>ECMP (Equal-Cost Multi-Path)</strong> to hash a connection's "4-tuple" (Source/Dest IP and Port) to ensure packets from the same connection go to the same proxy. </p><p>However, when edge proxies are added or removed, the <strong>ECMP algorithm</strong> becomes inconsistent, and it cannot distribute traffic based on the actual <strong>workload</strong> of each proxy.</p><p>Therefore, Cloudflare developed the <strong>Unimog Layer 4 Load Balancer</strong> using <strong>XDP (<a href="https://open.substack.com/pub/chillvic/p/observability-without-the-surgery?utm_campaign=post-expanded-share&amp;utm_medium=post%20viewer">eBPF</a>)</strong>, <strong>granting every proxy server the ability to forward packets</strong>. eBPF allows the implementation of a control plane within a user-space process, providing high flexibility&#8212;for instance, <strong>using <a href="https://github.com/kkdai/maglev">Meglev hashing</a> and monitoring proxy workload to dynamically adjust routing.</strong></p><p>Furthermore, because the proxies themselves possess forwarding capabilities, <strong>NAT</strong> redirection is no longer required. Instead, the proxy can use <strong>IP Tunneling</strong> to encapsulate the packet, modifying the destination IP to a private IP before sending it out.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gGs7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gGs7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 424w, https://substackcdn.com/image/fetch/$s_!gGs7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 848w, https://substackcdn.com/image/fetch/$s_!gGs7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 1272w, https://substackcdn.com/image/fetch/$s_!gGs7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gGs7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png" width="757" height="406" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d44ef998-1e71-4875-a561-8c984b442c35_757x406.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:406,&quot;width&quot;:757,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!gGs7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 424w, https://substackcdn.com/image/fetch/$s_!gGs7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 848w, https://substackcdn.com/image/fetch/$s_!gGs7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 1272w, https://substackcdn.com/image/fetch/$s_!gGs7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://blog.cloudflare.com/unimog-cloudflares-edge-load-balancer/">https://blog.cloudflare.com/unimog-cloudflares-edge-load-balancer/</a></p><p>In addition to the Layer 4 Load Balancer, Cloudflare utilizes another key technology at Layer 4: <strong>QUIC</strong>!</p><h1><strong>What is QUIC, and What Problems Does it Solve?</strong></h1><p>QUIC is a Layer 4 protocol built on UDP, used in HTTP/3 to solve performance bottlenecks in TCP:</p><h3><strong>Head-of-Line (HoL) Blocking:</strong> </h3><p>HTTP/2 resolves the Layer 7 <strong>Head-of-Line (HoL) Blocking</strong> issues found in HTTP/1. It allows multiple requests to be sent simultaneously over a single TCP connection without waiting for the response of the current request. Once the application layer receives the response packets for different requests, it uses <strong>stream IDs</strong> to reassemble them into the complete payload.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4qid!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4qid!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 424w, https://substackcdn.com/image/fetch/$s_!4qid!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 848w, https://substackcdn.com/image/fetch/$s_!4qid!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 1272w, https://substackcdn.com/image/fetch/$s_!4qid!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4qid!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png" width="625" height="618" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:618,&quot;width&quot;:625,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4qid!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 424w, https://substackcdn.com/image/fetch/$s_!4qid!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 848w, https://substackcdn.com/image/fetch/$s_!4qid!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 1272w, https://substackcdn.com/image/fetch/$s_!4qid!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://juejin.cn/post/6844903984524705800">https://juejin.cn/post/6844903984524705800</a></p><p>However, <strong>Head-of-Line Blocking also exists at Layer 4. From TCP&#8217;s perspective, it cannot distinguish between packets belonging to different requests</strong>; it treats them as part of the same connection and insists on receiving them in strict order. </p><p>If a single packet from &#8220;Response A&#8221; is lost, the kernel will not deliver the payload of &#8220;Response B&#8221; to the user-space process&#8212;even if all of Response B&#8217;s packets have arrived safely&#8212;until that missing packet is retransmitted and received.</p><p><strong>QUIC&#8217;s solution is to move the stream ID logic from Layer 7 down to</strong> <strong>Layer 4</strong>. This ensures that while packets within a single stream must remain ordered, different streams are independent of one another. Furthermore, because HTTP/3 allows the application layer (e.g., the browser) to parse and reassemble payloads, <strong>QUIC removes the need for the kernel to maintain packet ordering for multiple streams, thereby reducing the complexity of kernel memory management.</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uGTS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uGTS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 424w, https://substackcdn.com/image/fetch/$s_!uGTS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 848w, https://substackcdn.com/image/fetch/$s_!uGTS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 1272w, https://substackcdn.com/image/fetch/$s_!uGTS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uGTS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png" width="800" height="457" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b14cec7d-3d3d-4666-a04d-d48742377551_800x457.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:457,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uGTS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 424w, https://substackcdn.com/image/fetch/$s_!uGTS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 848w, https://substackcdn.com/image/fetch/$s_!uGTS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 1272w, https://substackcdn.com/image/fetch/$s_!uGTS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://www.researchgate.net/figure/The-head-of-line-blocking-problem-and-the-stream-based-solution_fig1_344551663">https://www.researchgate.net/figure/The-head-of-line-blocking-problem-and-the-stream-based-solution_fig1_344551663</a></p><h3><strong>Connection Establishment Requires a Handshake</strong></h3><p>Before transmitting data, <strong>TCP</strong> requires a handshake process:</p><ol><li><p>Client<code> SYN</code> &#8594; Server<code> </code></p></li><li><p>Server<code> SYN-ACK</code> &#8594; Client </p></li><li><p>Client<code> ACK</code> &#8594; Server</p></li></ol><p>Only then can data transmission begin. </p><p>In contrast, <strong>QUIC</strong> allows the client to send data along with the very first <code>SYN</code> packet, effectively enabling <strong>0-RTT</strong> (Zero Round-Trip Time) data transmission.</p><p>However, when <strong>TLS</strong> is supported, it typically requires <strong>1-RTT</strong>. This is achieved, for example, through the <strong>Diffie&#8211;Hellman algorithm</strong>:</p><ol><li><p><strong>Client</strong> &#8594; sends <code>Public Key</code> &#8594; <strong>Server</strong>.</p></li><li><p><strong>Server</strong> uses its <code>Private Key</code> + <code>Client&#8217;s Public Key</code> to calculate a <strong>Shared Secret</strong>.</p></li><li><p><strong>Server</strong> &#8594; sends a <code>Session Ticket</code> (i.e., the encrypted shared secret) + <code>Server&#8217;s Public Key</code> &#8594; <strong>Client</strong>.</p></li></ol><p>Finally, the <strong>Client</strong> uses its own <code>Private Key</code> + <code>Server&#8217;s Public Key</code> to calculate the same <strong>Shared Secret</strong>. The client then encrypts its request using this secret and sends it to the server along with the session ticket.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Y-v-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Y-v-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 424w, https://substackcdn.com/image/fetch/$s_!Y-v-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 848w, https://substackcdn.com/image/fetch/$s_!Y-v-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 1272w, https://substackcdn.com/image/fetch/$s_!Y-v-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Y-v-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png" width="800" height="419" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:419,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Y-v-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 424w, https://substackcdn.com/image/fetch/$s_!Y-v-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 848w, https://substackcdn.com/image/fetch/$s_!Y-v-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 1272w, https://substackcdn.com/image/fetch/$s_!Y-v-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://vocal.com/voip/quic/">https://vocal.com/voip/quic/</a></p><p>Furthermore, <strong>session tickets</strong> can be stored on the client&#8217;s local disk, allowing them to be reused after a disconnection. Upon reconnecting, there is no need to exchange public keys or recalculate a shared secret; data can be sent immediately, achieving <strong>true 0-RTT</strong>. </p><p>However, this poses a risk of <strong>Replay Attacks</strong>. To mitigate this, the server-side periodically rotates the encryption keys used to generate session tickets, sets a short TTL (Time to Live) for the tickets, and only allows <strong>GET requests</strong> to utilize 0-RTT.</p><p>Beyond performance optimization, QUIC implements its own <strong>retransmission and flow control mechanisms</strong>. For example, if the server&#8217;s memory buffer is full, it will signal the client to stop sending data; similarly, if the RTT (Round-Trip Time) becomes too high, it will instruct the client to pause new transmissions until all missing packets are received.</p><p>Traditional TCP lacks the concept of &#8220;streams.&#8221; For the same packet, even if it is retransmitted, the sequence number remains identical. This leads to <strong>ACK ambiguity</strong>, where the server cannot distinguish whether an incoming ACK is for the original packet or the retransmitted one, <strong>making RTT calculations imprecise.</strong></p><p>In contrast, QUIC&#8217;s ordering is determined by the <strong>stream</strong>, and each stream has its own independent sequence. Packet IDs, however, increment globally (across all streams). <strong>This allows the system to distinguish whether an ACK is for a retransmission or the original packet, leading to more accurate RTT measurements and more reliable flow control.</strong></p><p>Additionally, because QUIC&#8217;s retransmission and flow control are implemented in <strong>user space</strong> (while the kernel simply sees UDP), it offers much greater flexibility. It can be tailored to specific business requirements&#8212;for instance, in streaming scenarios where retransmission requirements are lower but strict flow control is essential.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AMcy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AMcy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 424w, https://substackcdn.com/image/fetch/$s_!AMcy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 848w, https://substackcdn.com/image/fetch/$s_!AMcy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 1272w, https://substackcdn.com/image/fetch/$s_!AMcy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AMcy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png" width="800" height="357" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:357,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AMcy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 424w, https://substackcdn.com/image/fetch/$s_!AMcy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 848w, https://substackcdn.com/image/fetch/$s_!AMcy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 1272w, https://substackcdn.com/image/fetch/$s_!AMcy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://datatracker.ietf.org/meeting/98/materials/slides-98-edu-sessf-quic-tutorial-00.pdf">https://datatracker.ietf.org/meeting/98/materials/slides-98-edu-sessf-quic-tutorial-00.pdf</a></p><h1>Beyond performance optimization, what other benefits does Cloudflare gain from using QUIC?</h1><p>Cloudflare implemented QUIC in Rust (via the <a href="https://github.com/cloudflare/quiche">quiche</a> library) and identified key advantages and challenges during implementation:</p><h3><strong>Benefit &#8212; Connection Migration</strong></h3><p>A TCP connection is identified by a 4-tuple: <code>(src_ip, src_port, dest_ip, dest_port)</code>. Once a user switches networks and changes their source IP (e.g., moving from 5G to Wi-Fi), the connection must be re-established.</p><p>In contrast, <strong>QUIC</strong> uses a <strong>Connection ID (CID)</strong>, which is a random number stored on the client side. As long as the CID remains the same, the state can be recognized even if the user switches networks.</p><p>As mentioned in the Anycast architecture earlier, standard routers at Layer 3 use <strong>ECMP</strong> to decide routes based on the 4-tuple hash. When a user&#8217;s source IP changes, the same CID would typically be forwarded to a different server. However, by adding <strong>CID-based forwarding</strong> to the <strong>Unimog Layer 4 load balancer</strong>, Cloudflare enables users to switch networks without dropping their connection.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!d-QA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!d-QA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 424w, https://substackcdn.com/image/fetch/$s_!d-QA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 848w, https://substackcdn.com/image/fetch/$s_!d-QA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!d-QA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!d-QA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg" width="800" height="580" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:580,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!d-QA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 424w, https://substackcdn.com/image/fetch/$s_!d-QA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 848w, https://substackcdn.com/image/fetch/$s_!d-QA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!d-QA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: https://zhuanlan.zhihu.com/p/311221111</p><h3><strong>Challenge &#8212; Reflection Attacks</strong></h3><p>Since QUIC is built on <strong>UDP</strong>, it is susceptible to <strong>reflection attacks</strong>, a common UDP exploit. Hackers forge the victim&#8217;s IP and send massive requests to a server, causing the server to flood the victim&#8217;s network with large volumes of data.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!x2rJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!x2rJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 424w, https://substackcdn.com/image/fetch/$s_!x2rJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 848w, https://substackcdn.com/image/fetch/$s_!x2rJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 1272w, https://substackcdn.com/image/fetch/$s_!x2rJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!x2rJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png" width="800" height="402" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:402,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!x2rJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 424w, https://substackcdn.com/image/fetch/$s_!x2rJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 848w, https://substackcdn.com/image/fetch/$s_!x2rJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 1272w, https://substackcdn.com/image/fetch/$s_!x2rJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://docs.aws.amazon.com/whitepapers/latest/aws-best-practices-ddos-resiliency/udp-reflection-attacks.html">https://docs.aws.amazon.com/whitepapers/latest/aws-best-practices-ddos-resiliency/udp-reflection-attacks.html</a></p><p>For instance, QUIC&#8217;s TLS handshake requires sending certificates and public keys to the client&#8212;a significant amount of data. A hacker could repeatedly send TLS requests to force the server to bombard the victim with these large payloads.</p><p>TCP avoids this problem by using a small-data handshake; it only sends certificates after receiving a <code>Client ACK</code>. If a hacker forges an IP, they won&#8217;t receive the <code>SYN-ACK</code> and thus cannot return the <code>Client ACK</code>.</p><p>The fundamental solution for QUIC remains a handshake where the server sends an encrypted token to the client and requires it to be returned. However, this method sacrifices the <strong>0-RTT</strong> feature. Consequently, Cloudflare is exploring alternatives like <strong>ECDSA certificates</strong> or <strong>certificate compression</strong> to reduce the payload size.</p><p>In addition to implementing QUIC in Rust, Cloudflare also developed its own proxy server, <strong><a href="https://github.com/cloudflare/pingora">Pingora</a></strong>, to replace Nginx.</p><h1>Why Did Cloudflare Replace Nginx with Pingora?</h1><p>Nginx follows a <strong>process-based</strong> architecture, <strong>utilizing the </strong><code>SO_REUSEPORT</code><strong> socket system call to allow multiple processes to bind to the same port.</strong> The kernel then distributes sockets to these processes based on a hash of the 4-tuple: <code>(src_ip, src_port, dest_ip, dest_port)</code>.</p><p>The downside of a process-based model is that implementing <strong>shared memory</strong> is complex and restrictive. For example, connections from the proxy to the <strong>origin server</strong> cannot be shared across processes. Furthermore, since Nginx is written in C, it carries inherent risks of memory leaks.</p><p>Cloudflare developed <strong>Pingora</strong>, a <strong>thread-based</strong> proxy written in <strong>Rust</strong>. While it retains an architecture similar to Nginx&#8212;<strong>with multiple kernel threads binding to the same port and each thread having its own independent </strong><code>epoll</code><strong> instance&#8212;it allows for the sharing of TCP connection information to origin servers across threads.</strong> Additionally, for scenarios involving exceptionally large payloads or file transfers, Pingora utilizes <strong>zero-copy</strong> techniques. This prevents the CPU overhead caused by copying massive amounts of data from kernel space to user space.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zJVi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zJVi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!zJVi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!zJVi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!zJVi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zJVi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg" width="800" height="800" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:800,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zJVi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!zJVi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!zJVi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!zJVi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://www.linkedin.com/posts/pal-arnab_what-is-pingora-pingora-is-a-new-http-proxy-activity-7106102391397113856-B8rJ/">https://www.linkedin.com/posts/pal-arnab_what-is-pingora-pingora-is-a-new-http-proxy-activity-7106102391397113856-B8rJ/</a></p><p>Moreover, Nginx carries significant <strong>developmental baggage</strong>. <strong>For instance, it often uses Lua scripts for feature extension, but Lua&#8217;s weak typing makes it difficult to maintain and results in lower performance.</strong> Nginx is also modularly built with many overlapping features; even unused modules can impact overall performance. Benchmark results show that Pingora delivers higher throughput, consumes less CPU, and offers greater stability compared to Nginx.</p><h1><strong>How Does Cloudflare Defend Against DDoS?</strong></h1><p>Anycast is inherently more resilient to DDoS attacks than Geo DNS. <strong>When a hacker resolves a domain to an IP and launches an attack, the requests are distributed to different locations via BGP, providing Layer 3 traffic shedding.</strong></p><p>Other <strong>Layer 3 DDoS defense mechanisms include</strong> <strong>Unicast Reverse Path Forwarding (uRPF)</strong>. In a DDoS attack, hackers often forge the source IP to avoid receiving server responses (and to hide their identity). Layer 3 checks the routing table to see if a valid path exists back to that source IP; if not, the source IP is considered forged, and the packet is dropped.</p><p>At <strong>Layer</strong> 4, <strong>SYN Flood</strong> <strong>is a common DDoS attack</strong>. During a TCP handshake, the client sends the first <code>SYN</code> packet. Upon receiving it, the server records the TCP state (source IP, port, initial sequence number, etc.) in the kernel and returns a <code>SYN-ACK</code>. <strong>A SYN flood sends a massive volume of </strong><code>SYN</code><strong> packets to exhaust the kernel&#8217;s memory by filling it with these states.</strong></p><p>One solution for SYN floods is <strong>SYN Cookies</strong>. Instead of storing the state in memory, the server encodes the state into a number used as the initial sequence number in the <code>SYN-ACK</code>. When the client responds with a <code>CLIENT-ACK</code> (where <code>seq = initial sequence number + 1</code>), the server verifies the connection, decodes the state, and only then allocates memory for the connection.</p><p>Additionally, Cloudflare uses <strong>eBPF</strong> to insert hooks at the kernel level. These hooks monitor <strong>PPS (Packets Per Second)</strong> and <strong>BPS (Bits Per Second)</strong> to dynamically adjust Layer 4 rate-limiting strategies.</p><p>Finally, Layer 7 rate limiting is not merely rule-based. Through <strong>Bot Management</strong>, Cloudflare shares attack data across its global proxies. By analyzing behavioral patterns, if an attack is detected in the US, the relevant data is synchronized to Japan, allowing Japanese proxies to block the same bot preemptively.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wLus!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wLus!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 424w, https://substackcdn.com/image/fetch/$s_!wLus!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 848w, https://substackcdn.com/image/fetch/$s_!wLus!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 1272w, https://substackcdn.com/image/fetch/$s_!wLus!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wLus!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png" width="800" height="439" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/52269e1c-7abe-477b-a450-003a88d5262a_800x439.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:439,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wLus!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 424w, https://substackcdn.com/image/fetch/$s_!wLus!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 848w, https://substackcdn.com/image/fetch/$s_!wLus!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 1272w, https://substackcdn.com/image/fetch/$s_!wLus!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://blog.cloudflare.com/cloudflare-bot-management-machine-learning-and-more/">https://blog.cloudflare.com/cloudflare-bot-management-machine-learning-and-more/</a></p><h1><strong>Conclusion</strong></h1><p>What Cloudflare built is not just a CDN. It is a globally distributed system where routing policy, kernel behavior, transport protocols, and application logic are tightly coupled.</p><p>Once you see this, tools like <a href="https://open.substack.com/pub/chillvic/p/observability-without-the-surgery?utm_campaign=post-expanded-share&amp;utm_medium=web">eBPF</a> stop being &#8220;advanced tricks.&#8221; They are no longer optional observability tools &#8212; they become inevitable building blocks.</p><p>After reading this article, Cloudflare&#8217;s incident reports will no longer feel mysterious. You&#8217;ll start recognizing the real constraints and trade-offs behind those failures.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lbc_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74189db0-96aa-4f64-853f-3ee217305aeb_3663x7565.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lbc_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74189db0-96aa-4f64-853f-3ee217305aeb_3663x7565.png 424w, https://substackcdn.com/image/fetch/$s_!lbc_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74189db0-96aa-4f64-853f-3ee217305aeb_3663x7565.png 848w, https://substackcdn.com/image/fetch/$s_!lbc_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74189db0-96aa-4f64-853f-3ee217305aeb_3663x7565.png 1272w, https://substackcdn.com/image/fetch/$s_!lbc_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74189db0-96aa-4f64-853f-3ee217305aeb_3663x7565.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lbc_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74189db0-96aa-4f64-853f-3ee217305aeb_3663x7565.png" width="1456" height="3007" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/74189db0-96aa-4f64-853f-3ee217305aeb_3663x7565.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:3007,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1004733,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/182281728?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74189db0-96aa-4f64-853f-3ee217305aeb_3663x7565.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lbc_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74189db0-96aa-4f64-853f-3ee217305aeb_3663x7565.png 424w, https://substackcdn.com/image/fetch/$s_!lbc_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74189db0-96aa-4f64-853f-3ee217305aeb_3663x7565.png 848w, https://substackcdn.com/image/fetch/$s_!lbc_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74189db0-96aa-4f64-853f-3ee217305aeb_3663x7565.png 1272w, https://substackcdn.com/image/fetch/$s_!lbc_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74189db0-96aa-4f64-853f-3ee217305aeb_3663x7565.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1><strong>References</strong></h1><p><a href="https://blog.cloudflare.com/unimog-cloudflares-edge-load-balancer/">https://blog.cloudflare.com/unimog-cloudflares-edge-load-balancer/</a><br><a href="https://blog.cloudflare.com/the-road-to-quic/">https://blog.cloudflare.com/the-road-to-quic/</a><br><a href="https://blog.cloudflare.com/how-we-built-pingora-the-proxy-that-connects-cloudflare-to-the-internet/https://www.cloudflare.com/ru-ru/learning/dns/what-is-anycast-dns/">https://blog.cloudflare.com/how-we-built-pingora-the-proxy-that-connects-cloudflare-to-the-internet/https://www.cloudflare.com/ru-ru/learning/dns/what-is-anycast-dns/</a><br><a href="https://blog.cloudflare.com/async-quic-and-http-3-made-easy-tokio-quiche-is-now-open-source/">https://blog.cloudflare.com/async-quic-and-http-3-made-easy-tokio-quiche-is-now-open-source/</a><br><a href="https://medium.com/codavel-blog/quic-vs-tcp-tls-and-why-quic-is-not-the-next-big-thing-d4ef59143efd">https://medium.com/codavel-blog/quic-vs-tcp-tls-and-why-quic-is-not-the-next-big-thing-d4ef59143efd</a></p>]]></content:encoded></item><item><title><![CDATA[CDN 絕對不只是 Cache — 從 OSI 7 層解析 Cloudflare 架構]]></title><description><![CDATA[BGP & anycast & unimog & QUIC & pingora &#25216;&#34899;&#26855;&#35299;&#26512;]]></description><link>https://www.chillvic.dev/p/cdn-cache-osi-7-cloudflare</link><guid isPermaLink="false">https://www.chillvic.dev/p/cdn-cache-osi-7-cloudflare</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Mon, 22 Dec 2025 01:46:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!uxTK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ce076e-2e69-4bb2-af9e-4ce87fe97f3b_1024x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Cloudflare &#20316;&#28858; CDN &#38712;&#20027;&#19981;&#21482;&#25552;&#20379; cache&#65292;&#36996;&#20860;&#39015; WAF &amp; &#38450; DDos &#65292;&#29978;&#33267; Cloudflare Workers &#33021;&#35731;&#24037;&#31243;&#24107;&#22312; edge proxy &#20013;&#22519;&#34892; js &#20195;&#30908;&#65292;&#24050;&#28982;&#25104;&#28858;&#32178;&#36335;&#26368;&#37325;&#35201;&#30340;&#22522;&#24314;&#20043;&#19968;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uxTK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ce076e-2e69-4bb2-af9e-4ce87fe97f3b_1024x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uxTK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ce076e-2e69-4bb2-af9e-4ce87fe97f3b_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!uxTK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ce076e-2e69-4bb2-af9e-4ce87fe97f3b_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!uxTK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ce076e-2e69-4bb2-af9e-4ce87fe97f3b_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!uxTK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ce076e-2e69-4bb2-af9e-4ce87fe97f3b_1024x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uxTK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ce076e-2e69-4bb2-af9e-4ce87fe97f3b_1024x1536.png" width="1024" height="1536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/35ce076e-2e69-4bb2-af9e-4ce87fe97f3b_1024x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1536,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3483183,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/182279446?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ce076e-2e69-4bb2-af9e-4ce87fe97f3b_1024x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uxTK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ce076e-2e69-4bb2-af9e-4ce87fe97f3b_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!uxTK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ce076e-2e69-4bb2-af9e-4ce87fe97f3b_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!uxTK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ce076e-2e69-4bb2-af9e-4ce87fe97f3b_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!uxTK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ce076e-2e69-4bb2-af9e-4ce87fe97f3b_1024x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>&#22914;&#27492;&#37325;&#35201;&#22522;&#24314;&#20854;&#26550;&#27083;&#26159;&#20160;&#40636;&#21602;&#65311;&#19968;&#36215;&#36879;&#36942;&#19979;&#38754;&#21839;&#38988;&#20358;&#25506;&#35342;&#65306;</p><h1>&#22914;&#20309;&#23559;&#21934;&#19968; Domain &#21305;&#37197;&#21040;&#19981;&#21516;&#22320;&#29702;&#20301;&#32622;&#30340; edge proxy&#65311;</h1><p>CDN &#39318;&#35201;&#21151;&#33021;&#26159;&#20381;&#29031;&#29992;&#25142;&#22320;&#29702;&#20301;&#32622;&#65292;&#23559;&#30456;&#21516; domain &#30340;&#35531;&#27714;&#36865;&#21040;&#38626;&#20182;&#36817;&#30340; edge proxy&#12290;</p><p>&#36890;&#24120;&#19968;&#20491; Domain &#23565;&#25033;&#19968;&#20491; public IP&#65292;&#32780; Geo DNS &#25903;&#25588;&#30456;&#21516; Domain &#20381;&#29031;&#22320;&#29702;&#20301;&#32622;&#21305;&#37197;&#19981;&#21516; public IP&#65292;&#22312; DNS &#20998;&#23652;&#26597;&#35426;&#19979;&#65292;&#26371;&#25214;&#21040; Geo DNS &#20006;&#29992; client IP &#35299;&#26512;&#22320;&#29702;&#20301;&#32622;&#24460;&#26597;&#21040; public IP&#12290;</p><p>&#20294;&#35442;&#26041;&#27861;&#26377;&#35377;&#22810;&#32570;&#40670;&#65306;</p><p>1. &#20551;&#35373; Geo DNS &#22352;&#33853;&#22312;&#32654;&#22283;&#27231;&#25151;&#65292;&#28858;&#20102;&#25214;&#21040; public IP &#21487;&#33021;&#20808;&#32350;&#21040;&#36611;&#36960;&#30340;&#22320;&#26041;<br>2. DNS &#26377;&#24555;&#21462;&#19988; TTL &#21487;&#33021;&#24456;&#38263;&#65292;&#33509;&#35201;&#26367;&#25563; public IP &#26371;&#38656;&#35201;&#19968;&#27573;&#26178;&#38291;&#25165;&#29983;&#25928;&#65292;&#30332;&#29983;&#25925;&#38556;&#36983;&#31227;&#28961;&#27861;&#21363;&#26178;&#29983;&#25928;</p><p>&#37027;&#26377;&#27794;&#26377;&#26356;&#24555;&#65292;&#21487;&#29992;&#24615;&#26356;&#22909;&#30340;&#26041;&#24335;&#65311;</p><p>&#33287;&#20854;&#23559;&#19968;&#20491; Domain &#32129;&#23450;&#19981;&#21516; public IP&#65292;<strong>Cloudflare &#29992; anycast &#25216;&#34899;&#23559;&#19968;&#20491; public IP &#26144;&#23556;&#21040;&#19981;&#21516;&#20301;&#32622;&#30340;&#27231;&#22120;&#19978;</strong>&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TIFm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TIFm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 424w, https://substackcdn.com/image/fetch/$s_!TIFm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 848w, https://substackcdn.com/image/fetch/$s_!TIFm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 1272w, https://substackcdn.com/image/fetch/$s_!TIFm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TIFm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png" width="797" height="442" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:442,&quot;width&quot;:797,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TIFm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 424w, https://substackcdn.com/image/fetch/$s_!TIFm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 848w, https://substackcdn.com/image/fetch/$s_!TIFm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 1272w, https://substackcdn.com/image/fetch/$s_!TIFm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe100dac6-cf57-4fad-9224-7983aa6eb4e0_797x442.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: https://blog.cloudflare.com/unimog-cloudflares-edge-load-balancer/</p><h1>anycast &#22914;&#20309;&#23559;&#19968;&#20491; public IP &#26144;&#23556;&#21040;&#19981;&#21516;&#20301;&#32622;&#30340;&#27231;&#22120;&#19978;&#65311;</h1><p>&#32178;&#36335;&#20998;&#25104; Local Area Network (LAN) &amp; Wide Area Network (WAN)&#65292;&#30456;&#21516;&#21312;&#22495;&#26371;&#29992;&#30456;&#21516;&#32178;&#22495;&#65292;&#20363;&#22914;&#20013;&#33775;&#38651;&#20449; (ISP) &#26159; 36.224.0.0/13&#65292;&#32780;&#30456;&#21516;&#32178;&#22495;&#19979;&#65292;&#32178;&#32218;&#30001;&#19968;&#20491; Autonomous System (AS) &#24314;&#32622;&#33287;&#31649;&#29702;&#65292;&#20659;&#36664;&#24456;&#24555;&#65292;&#29978;&#33267;&#19981;&#29992; CDN&#12290;</p><p>&#30070;&#23553;&#21253;&#36914;&#20837; WAN &#24460;&#65292;&#36317;&#38626;&#25289;&#38263;&#65292;&#35201;&#36328; AS &#20043;&#38291;&#20659;&#36664;&#65292;&#19981;&#21516; AS &#31649;&#29702;&#19981;&#21516;&#32178;&#22495;&#65292;&#24444;&#27492;&#38656;&#35201; protocol &#20132;&#25563;&#36335;&#30001;&#36039;&#35338; (aka IP Prefix)&#65292;&#35442; protocol &#28858; Border Gateway Protocol (BGP)&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hKER!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hKER!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 424w, https://substackcdn.com/image/fetch/$s_!hKER!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 848w, https://substackcdn.com/image/fetch/$s_!hKER!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!hKER!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hKER!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg" width="800" height="615" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:615,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hKER!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 424w, https://substackcdn.com/image/fetch/$s_!hKER!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 848w, https://substackcdn.com/image/fetch/$s_!hKER!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!hKER!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb387b521-7f9f-431f-a623-8a808d9f330d_800x615.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://www.cloudns.net/blog/understanding-bgp-a-comprehensive-guide-for-beginners/">https://www.cloudns.net/blog/understanding-bgp-a-comprehensive-guide-for-beginners/</a></p><p>&#20363;&#22914;&#20013;&#33775;&#38651;&#20449;&#29992; BGP &#21578;&#35380;&#26085;&#26412; ISP 36.224.0.0/13 &#26159;&#25105;&#36000;&#36012;&#30340;&#65292;&#30070;&#26085;&#26412; ISP &#36865; request &#21040; 36.224.1.1 &#26178;&#65292;&#26371;&#23559; request forward &#21040;&#20013;&#33775;&#38651;&#20449;&#30340; border router&#65292;&#30001;&#35442; router &#23559; request &#36865;&#21040; server &#19978;&#12290;</p><p>&#32780; anycast &#21487;&#23559;&#19968;&#32068; IP Prefix &#36879;&#36942; BGP &#33287;&#19981;&#21516; AS &#35387;&#20874;&#22312;&#19981;&#21516;&#30340; border router &#19978;&#65292;&#19981;&#21516; border router &#32000;&#37636;&#19981;&#21516;&#30340; routing table&#65292;&#30456;&#21516;&#30340; public IP &#26371;&#22240;&#28858;&#20358;&#28304; AS &#19981;&#21516;&#65292;forward &#21040;&#19981;&#21516; border router&#65292;&#26368;&#32066;&#21040;&#19981;&#21516; server &#19978;&#12290;</p><p><strong>Cloudflare &#20316;&#28858;&#29544;&#31435; AS&#65292;&#21487;&#36319;&#19981;&#21516; AS &#35387;&#20874; IP Prefix (e.g 103.21.244.0/22)&#65292;&#19981;&#21516; AS &#29992;&#30070;&#22320;&#30340; border router &#21644; edge proxy &#36000;&#36012;&#35442;&#32178;&#22495;&#25152;&#26377; IP</strong>&#65292;&#20363;&#22914;&#24478;&#21488;&#28771;&#36865; request &#21040; 103.21.244.1&#65292;&#36879;&#36942; BGP &#25214;&#21040;&#21488;&#28771;&#30070;&#22320;&#30340; border router &#65292;&#26368;&#32066;&#35531;&#27714;&#36865;&#21040;&#21488;&#28771;&#30070;&#22320; edge proxy&#12290;</p><p><strong>BGP &#26159; layer 3 protocol&#65292;forward request &#19981;&#38656;&#35201;&#23652;&#23652;&#35299;&#26512;&#65292;&#25928;&#33021;&#22909;&#65292;&#19988;&#21487;&#29992;&#24615;&#26356;&#39640;</strong>&#65292;&#20363;&#22914; 103.21.244.1 &#22312;&#26085;&#26412;&#30340; edge proxy &#22240;&#28858;&#27231;&#25151;&#22833;&#28779;&#20986;&#21839;&#38988;&#65292;&#19981;&#29992;&#23559; domain &#25563;&#25104;&#21478;&#19968;&#20491; public IP&#65292;&#26085;&#26412; ISP &#36879;&#36942; BGP &#26371;&#30332;&#29694;&#21488;&#28771;&#26377;&#36335;&#21487;&#36890;&#24448; 103.21.244.1&#65292;&#20006; forward &#36942;&#21435;&#65292;&#38614;&#28982;&#36317;&#38626;&#35722;&#36960;&#65292;&#20294;&#30906;&#20445;&#21487;&#29992;&#24615;&#12290;</p><h1>anycast + BGP &#26159;&#23436;&#32654; Solution &#21966;&#65311;</h1><p>anycast &#22522;&#26044; BGP &#36335;&#30001;&#35215;&#21063;&#23559;&#30456;&#21516; public IP &#36865;&#24448;&#38752;&#36817;&#29992;&#25142;&#30340; server&#65292;&#20294; BGP &#20006;&#19981;&#20381;&#29031;&#22320;&#29702;&#20301;&#32622;&#25110;&#32773;&#23553;&#21253; RTT &#27770;&#23450;&#36335;&#30001;&#65292;&#32780;&#26159; AS Path &#30340;&#25104;&#26412;&#65292;&#32780;&#25104;&#26412;&#20027;&#35201;&#38752; Admin &#37197;&#32622; (policy based)&#12290;</p><p>&#20363;&#22914; A &#22283;&#33287; B &#22283;&#32178;&#32218;&#23565;&#25509;&#26178;&#65292;A &#22283;&#33509;&#36319;&#24456;&#22810;&#20854;&#20182; AS &#23565;&#25509;&#65292;B &#22283;&#23601;&#26371;&#21463;&#24800;&#65292;&#22240;&#27492; A &#22283;&#21487;&#33021;&#26371;&#20687; B &#22283;&#25910;&#37666;&#65292;&#33509;&#23553;&#21253;&#24478; B &#22283;&#20986;&#30332;&#65292;&#21487;&#32147;&#30001; A &#25110; C &#21040; D&#65292;&#20551;&#35373; C &#27794;&#25910;&#37666;&#65292;&#23601;&#26371;&#20808;&#36208; C&#65292;&#21363;&#20415;&#30446;&#30340;&#22320;&#38626; A &#26356;&#36817;&#12290;</p><p><strong>&#32780; Cloudflare &#26371;&#33287; AS &#23565;&#25509; Local AS Path &#30906;&#20445;&#20778;&#20808;&#27402;&#12290;</strong></p><p>note: &#35443;&#32048; BGP route &#35215;&#21063;&#21487;&#21443;&#32771;<a href="https://networklessons.com/bgp/bgp-attributes-and-path-selection">&#36889;&#35041;</a>&#12290;</p><p>&#21478;&#22806; BGP &#26377;&#21163;&#25345;&#21839;&#38988;&#65292;&#39405;&#23458;&#21487;&#29992;&#30456;&#21516; IP Prefix &#33287;&#20854;&#20182; AS &#35387;&#20874;&#65292;&#20006;&#35373;&#27861;&#35731;&#21040;&#36948;&#20182;&#30340; AS Path &#25104;&#26412;&#35722;&#20302;&#65292;&#23601;&#21487;&#33021;&#25226;&#21407;&#26412;&#26371;&#36208;&#21040;&#27491;&#30906; Cloudflare &#27969;&#37327;&#36681;&#21040;&#39405;&#23458;&#26381;&#21209;&#19978;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VxRG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VxRG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 424w, https://substackcdn.com/image/fetch/$s_!VxRG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 848w, https://substackcdn.com/image/fetch/$s_!VxRG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 1272w, https://substackcdn.com/image/fetch/$s_!VxRG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VxRG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png" width="800" height="416" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:416,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VxRG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 424w, https://substackcdn.com/image/fetch/$s_!VxRG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 848w, https://substackcdn.com/image/fetch/$s_!VxRG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 1272w, https://substackcdn.com/image/fetch/$s_!VxRG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c23aa-1800-4a17-a4fc-78790e9442a6_800x416.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://blog.cloudflare.com/bgp-hijack-detection/">https://blog.cloudflare.com/bgp-hijack-detection/</a></p><p>&#35299;&#27861;&#26159;&#35387;&#20874; IP Prefix &#26178;&#35201;&#39511;&#35657; AS &#36523;&#20221;&#65292;&#39006;&#20284; HTTPS &#30340; domain &#24977;&#35657;&#39511;&#35657;&#65292;&#20294;&#38750;&#25152;&#26377; AS &#37117;&#20570;&#36889;&#20214;&#20107;&#65292;&#25152;&#20197;&#20173;&#26377;&#39080;&#38570;&#65292;&#21487;&#29992;  https://isbgpsafeyet.com/  &#26597;&#20320;&#30340; ISP &#26377;&#27794;&#26377;&#39511;&#35657;&#27969;&#31243;&#12290;</p><p>&#21478;&#22806; anycast &#29305;&#24615;&#35731;&#30456;&#21516; public IP &#22312;&#21516;&#21312;&#22495;&#20063;&#21487;&#26377;&#22810;&#20491; proxy server&#65292;&#22240;&#27492; TCP &#23553;&#21253;&#21487;&#33021;&#36865;&#24448;&#19981;&#21516; server&#65292;&#23566;&#33268;&#20197;&#19979;&#21839;&#38988;&#65306;</p><p>&#30070; client &#33287; server &#24314;&#31435; TCP &#36899;&#32218;&#24460;&#65292;&#28858;&#20102;<strong>&#30906;&#20445;&#23553;&#21253;&#30340;&#38918;&#24207;&#24615;&#65292;server kernel &#26371;&#22312;&#35352;&#25014;&#39636;&#20013;&#35352;&#37636; TCP &#36899;&#32218; ID &#21644;&#23565;&#25033;&#29376;&#24907;</strong>&#65292;&#20363;&#22914;&#25910;&#21040;&#21738;&#20123;&#23553;&#21253;&#65292;&#19979;&#19968;&#20491;&#23553;&#21253;&#32232;&#34399;&#31561;&#65292;&#33509;<strong>&#30456;&#21516; TCP &#36899;&#32218;&#23553;&#21253;&#36865;&#24448;&#19981;&#21516; server &#19988;&#35442; server &#27794;&#26377;&#23565;&#25033;&#36899;&#32218;&#29376;&#24907;&#26371;&#38364;&#38281;&#36899;&#32218;</strong>&#12290;</p><h1>&#22914;&#20309;&#35299;&#27770; anycast &#21934;&#19968; public IP &#26377;&#22810;&#21488; server &#23566;&#33268; TCP &#26039;&#32218;&#21839;&#38988;&#65311;</h1><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.chillvic.dev/subscribe?"><span>Subscribe now</span></a></p><p>&#19968;&#20491;&#36328;&#21312;&#23553;&#21253;&#32178;&#36335;&#36335;&#24465;&#28858;&#65306;<br>1. client &#24478; ISP gateway &#20986;&#30332;&#65292;&#36879;&#36942; BGP &#36984;&#21040; border gateway<br>2. border gateway &#20659;&#32102; NAT&#65292;NAT &#23559; dest ip &#24478; public ip &#36681;&#25104; private ip<br>3. NAT &#20659;&#32102; private network &#30340; edge proxy</p><p>&#30070; border gateway &#30332;&#29694;&#30456;&#21516; dest ip &#26377;&#22810;&#26781;&#36335;&#24465;&#26178;&#65292;&#26371;&#29992; <strong>ECMP (Equal-Cost Multi-Path)</strong> &#31639;&#27861;&#65292;hash(source ip, source port, dest ip, dest port) % path_cnt &#26041;&#24335; forward&#65292;&#30906;&#20445;&#30456;&#21516;&#36899;&#32218;&#23553;&#21253;&#24448;&#21516;&#20491; NAT &amp; edge proxy&#12290;</p><p>&#20294;&#22686;&#21152;&#25110;&#28187;&#23569; edge proxy&#65292;ECMP &#31639;&#27861;&#26371;&#19981;&#19968;&#33268;&#65292;&#19988;&#28961;&#27861;&#20381;&#29031; proxy workload &#20998;&#30332;&#12290;</p><p>&#22240;&#27492; Cloudflare &#20351;&#29992; XDP (<a href="https://open.substack.com/pub/chillvic/p/observability-without-the-surgery?utm_campaign=post-expanded-share&amp;utm_medium=post%20viewer">ebpf</a> ) &#38283;&#30332;&#20102; unimog Layer 4 Load balancer&#65292;&#35731;&#27599;&#20491; proxy server &#26377;&#36681;&#30332;&#23553;&#21253;&#33021;&#21147;&#65292;ebpf &#33021;&#22312; user space process &#23526;&#20316; control panel&#65292;&#24392;&#24615;&#39640;&#65292;&#20363;&#22914;&#29992; <a href="https://github.com/kkdai/maglev">meglev hashing</a> &#36319;&#30435;&#25511; proxy workload &#20358;&#35519;&#25972;&#36335;&#30001;&#12290;</p><p>&#19988; proxy &#26377; forward &#33021;&#21147;&#23601;&#19981;&#38656;&#35201; NAT &#36681;&#30332;&#65292;proxy &#21487;&#29992; Tunneling &#23559;&#23553;&#21253;&#23553;&#35037;&#19968;&#23652;&#65292;&#20462;&#25913; dest ip &#25104; private IP &#36865;&#20986;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gGs7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gGs7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 424w, https://substackcdn.com/image/fetch/$s_!gGs7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 848w, https://substackcdn.com/image/fetch/$s_!gGs7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 1272w, https://substackcdn.com/image/fetch/$s_!gGs7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gGs7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png" width="757" height="406" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d44ef998-1e71-4875-a561-8c984b442c35_757x406.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:406,&quot;width&quot;:757,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gGs7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 424w, https://substackcdn.com/image/fetch/$s_!gGs7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 848w, https://substackcdn.com/image/fetch/$s_!gGs7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 1272w, https://substackcdn.com/image/fetch/$s_!gGs7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44ef998-1e71-4875-a561-8c984b442c35_757x406.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://blog.cloudflare.com/unimog-cloudflares-edge-load-balancer/">https://blog.cloudflare.com/unimog-cloudflares-edge-load-balancer/</a></p><p>&#38500;&#20102; Layer 4 Load balancer&#65292;Cloudflare &#36996;&#22312; Layer 4 &#20351;&#29992;&#20854;&#20182;&#25216;&#34899;&#65292;&#20063;&#23601;&#26159; QUIC&#65281;</p><h1>&#20160;&#40636;&#26159; QUIC&#65311;QUIC &#35299;&#27770;&#20160;&#40636;&#21839;&#38988;&#65311;</h1><p>QUIC &#26159;&#22522;&#26044; UDP &#38283;&#30332;&#30340; Layer 4 &#26032;&#21332;&#23450;&#65292;&#20027;&#35201;&#25645;&#37197; HTTP/3 &#65292;&#29992;&#20358;&#35299;&#27770; HTTP/2 &amp; TCP &#30340;&#25928;&#33021;&#21839;&#38988;&#65306;</p><h3><strong>Head-of-Line Blocking</strong></h3><p>HTTP/2 &#35299;&#27770; HTTP/1 Layer 7 Head-of-Line Blocking&#65292;&#19981;&#29992;&#31561;&#30070;&#21069; request &#30340; response &#23601;&#33021;&#36865;&#19979;&#19968;&#20491; request&#65292;&#21487;&#29992;&#19968;&#20491; TCP connection &#21516;&#26178;&#36865;&#20986;&#22810;&#20491; request&#65292;&#25033;&#29992;&#23652;&#25910;&#21040;&#19981;&#21516; request &#23565;&#25033; response &#23553;&#21253;&#24460;&#65292;&#26371;&#29992; stream id &#32068;&#22238;&#23436;&#25972; payload&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4qid!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4qid!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 424w, https://substackcdn.com/image/fetch/$s_!4qid!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 848w, https://substackcdn.com/image/fetch/$s_!4qid!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 1272w, https://substackcdn.com/image/fetch/$s_!4qid!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4qid!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png" width="625" height="618" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:618,&quot;width&quot;:625,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4qid!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 424w, https://substackcdn.com/image/fetch/$s_!4qid!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 848w, https://substackcdn.com/image/fetch/$s_!4qid!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 1272w, https://substackcdn.com/image/fetch/$s_!4qid!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce233a1f-f212-4377-ab0c-e53eb7ffd8b3_625x618.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://juejin.cn/post/6844903984524705800">https://juejin.cn/post/6844903984524705800</a></p><p>&#20294; Layer 4 &#20063;&#26377; Head-of-Line Blocking &#65292;TCP &#35222;&#35282;&#28961;&#27861;&#20998;&#36776;&#23553;&#21253;&#23660;&#26044;&#19981;&#21516; request&#65292;&#26371;&#23559;&#23553;&#21253;&#35222;&#28858;&#30456;&#21516;&#36899;&#32218;&#19988;&#35201;&#26377;&#24207;&#22320;&#25509;&#25910;&#65292;&#30070; A response &#23569;&#20102;&#19968;&#20491;&#23553;&#21253;&#65292;&#21363;&#20415; B response &#30340; payload &#24050;&#32147;&#23436;&#25972;&#25269;&#36948;&#65292;&#21482;&#35201;&#36986;&#22833;&#23553;&#21253;&#27794;&#21040;&#65292;kernel &#23652;&#23601;&#19981;&#26371;&#25226; B response payload &#32102; user space process&#12290;</p><p>QUIC &#35299;&#27861;&#26159;&#23559; Layer 7 &#30340; stream id &#25644;&#31227;&#21040; Layer 4 &#35299;&#26512;&#65292;&#27599;&#20491; stream &#23553;&#21253;&#35201;&#26377;&#24207;&#65292;&#36328; stream &#19981;&#31649;&#65292;&#27492;&#22806;&#30001;&#26044; HTTP/3 &#22312;&#25033;&#29992;&#23652; (i.e &#28687;&#35261;&#22120;) &#21487;&#35299;&#26512;&#23553;&#21253;&#37325;&#32068; payload&#65292;QUIC &#19981;&#29992;&#22312; kernel &#32173;&#35703;&#22810;&#20491; stream &#30340;&#23553;&#21253;&#25490;&#24207;&#65292;&#38477;&#20302; kernel &#35352;&#25014;&#39636;&#31649;&#29702;&#35079;&#38620;&#24230;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uGTS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uGTS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 424w, https://substackcdn.com/image/fetch/$s_!uGTS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 848w, https://substackcdn.com/image/fetch/$s_!uGTS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 1272w, https://substackcdn.com/image/fetch/$s_!uGTS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uGTS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png" width="800" height="457" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b14cec7d-3d3d-4666-a04d-d48742377551_800x457.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:457,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uGTS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 424w, https://substackcdn.com/image/fetch/$s_!uGTS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 848w, https://substackcdn.com/image/fetch/$s_!uGTS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 1272w, https://substackcdn.com/image/fetch/$s_!uGTS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14cec7d-3d3d-4666-a04d-d48742377551_800x457.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://www.researchgate.net/figure/The-head-of-line-blocking-problem-and-the-stream-based-solution_fig1_344551663">https://www.researchgate.net/figure/The-head-of-line-blocking-problem-and-the-stream-based-solution_fig1_344551663</a></p><h3>&#36899;&#32218;&#24314;&#31435;&#35201;&#25569;&#25163;</h3><p>TCP &#20659;&#36039;&#26009;&#21069;&#65292;&#35201;&#20808; Client SYN =&gt; Server SYN-ACK =&gt; Client Client-ACK &#24460;&#25165;&#38283;&#22987;&#20659;&#36865;&#36039;&#26009;&#65292;&#32780; QUIC &#26159; client &#22312;&#30332;&#36865;&#31532;&#19968;&#20491; SYN &#26178;&#65292;&#36899;&#24118;&#25226; data &#30332;&#20986;&#21435;&#65292;&#31561;&#26044; 0-RTT &#23601;&#21487;&#20659;&#36664;&#36039;&#26009;&#12290;</p><p>&#19981;&#36942;&#25903;&#25588; TLS &#26371;&#26159; 1-RTT&#65292;&#20363;&#22914;&#36879;&#36942; Diffie&#8211;Hellman &#31639;&#27861; &#65306;</p><p>1. Client =&gt; public key =&gt; Server<br>2. Server &#29992; server&#8217;s private key + client&#8217;s public key &#31639;&#20986;&#19968;&#20491; share secret<br>3. Server =&gt; session ticket (i.e &#21152;&#23494;&#30340; share secret) + server&#8217;s public key =&gt; Client</p><p>Client &#29992; client&#8217;s private key + server&#8217;s public key &#31639;&#20986;&#19968;&#27171; share secret&#65292;&#29992;&#35442; secret &#21152;&#23494; request&#65292;&#36899;&#21516; session ticket &#20659;&#32102; server&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Y-v-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Y-v-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 424w, https://substackcdn.com/image/fetch/$s_!Y-v-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 848w, https://substackcdn.com/image/fetch/$s_!Y-v-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 1272w, https://substackcdn.com/image/fetch/$s_!Y-v-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Y-v-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png" width="800" height="419" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:419,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Y-v-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 424w, https://substackcdn.com/image/fetch/$s_!Y-v-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 848w, https://substackcdn.com/image/fetch/$s_!Y-v-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 1272w, https://substackcdn.com/image/fetch/$s_!Y-v-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bfae427-7358-4c82-b6fe-4bb3ce922422_800x419.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://vocal.com/voip/quic/">https://vocal.com/voip/quic/</a></p><p>&#27492;&#22806; session ticket &#21487;&#20786;&#23384;&#22312; client &#30828;&#30879;&#20013;&#65292;&#26039;&#32218;&#24460;&#20173;&#21487;&#32396;&#29992;&#65292;&#37325;&#36899;&#19981;&#29992;&#20132;&#25563; public key &#31639; share secret&#65292; &#21487;&#30452;&#25509;&#20659;&#36039;&#26009;&#26159;&#30495; 0-RTT&#65292;&#20294;&#39080;&#38570;&#23601;&#26159;&#37325;&#25918;&#25915;&#25802;&#65292;&#22240;&#27492; server side &#26371;&#23450;&#26399;&#25563;&#29986;&#29983; session ticket &#30340;&#21152;&#23494; key &#20197;&#21450;&#35373;&#23450; session ticket TTL&#65292;&#20006;&#21482;&#20801;&#35377; GET request &#21487; 0-RTT&#12290;</p><p>&#38500;&#20102;&#20778;&#21270;&#25928;&#33021;&#65292;QUIC &#20063;&#23526;&#29694;&#37325;&#20659;&#36319;&#27969;&#37327;&#25511;&#21046;&#27231;&#21046; &#65292;&#20363;&#22914;&#30070; server memory buffer &#28415;&#20102;&#65292;&#26371;&#21483; client &#20808;&#19981;&#35201;&#20659;&#65292;&#25110;&#32773; RTT time &#22826;&#38263;&#20063;&#26371;&#21483; client &#20808;&#19981;&#35201;&#20659;&#26032;&#30340;&#65292;&#31561;&#36986;&#28431;&#23553;&#21253;&#37117;&#25910;&#21040;&#12290;</p><p>&#20659;&#32113; TCP &#27794;&#26377; stream &#27010;&#24565;&#65292;&#30456;&#21516;&#23553;&#21253;&#65292;&#21363;&#20415;&#37325;&#20659;&#24207;&#34399;&#20063;&#30456;&#21516;&#65292;&#23566;&#33268;&#25910;&#21040; ACK &#26178;&#19981;&#30693;&#36947;&#26159;&#31532;&#19968;&#20491;&#23553;&#21253;&#36996;&#26159;&#37325;&#20659;&#23553;&#21253;&#30340; ACK&#65292;&#31639; RTT &#26371;&#19981;&#28310;&#12290;</p><p>&#32780; QUIC &#38918;&#24207;&#26159; stream &#27770;&#23450;&#65292;stream &#20839;&#26377;&#29544;&#31435; seq&#65292;&#23553;&#21253; id &#21487;&#20840;&#22495; (&#36328; stream) &#36958;&#22686;&#65292;&#21487;&#20998;&#36776;ACK &#26159;&#37325;&#20659;&#30340;&#36996;&#26159;&#31532;&#19968;&#20491;&#30340;&#65292;RTT &#26356;&#31934;&#28310;&#65292;&#27969;&#37327;&#25511;&#21046;&#26356;&#19981;&#26371;&#35492;&#21028;&#12290;</p><p>&#27492;&#22806; QUIC &#37325;&#20659;&#36319;&#27969;&#37327;&#25511;&#21046;&#26159;&#22312; user space &#23526;&#29694;&#30340;&#65292;kernel &#23601;&#26159; UDP&#65292;&#24392;&#24615;&#26356;&#22823;&#65292;&#21487;&#37341;&#23565;&#26989;&#21209;&#38656;&#27714;&#35519;&#25972;&#65292;&#20363;&#22914;&#20018;&#27969;&#24773;&#22659;&#20013;&#65292;&#37325;&#20659;&#35201;&#27714;&#19981;&#39640;&#65292;&#20294;&#27969;&#37327;&#35201;&#25511;&#21046;&#22909;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AMcy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AMcy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 424w, https://substackcdn.com/image/fetch/$s_!AMcy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 848w, https://substackcdn.com/image/fetch/$s_!AMcy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 1272w, https://substackcdn.com/image/fetch/$s_!AMcy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AMcy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png" width="800" height="357" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:357,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AMcy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 424w, https://substackcdn.com/image/fetch/$s_!AMcy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 848w, https://substackcdn.com/image/fetch/$s_!AMcy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 1272w, https://substackcdn.com/image/fetch/$s_!AMcy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ec7921b-ea46-4e2a-8e0d-2945f17d4e8b_800x357.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://datatracker.ietf.org/meeting/98/materials/slides-98-edu-sessf-quic-tutorial-00.pdf">https://datatracker.ietf.org/meeting/98/materials/slides-98-edu-sessf-quic-tutorial-00.pdf</a></p><h1>&#38500;&#20102;&#25928;&#33021;&#20778;&#21270;&#65292;Cloudflare &#20351;&#29992; QUIC &#36996;&#26377;&#20160;&#40636;&#22909;&#34389;&#65311;</h1><p>Cloudflare &#29992; rust &#23526;&#20316;&#20102; QUIC &#21151;&#33021; (<a href="https://github.com/cloudflare/quiche">https://github.com/cloudflare/quiche</a>) &#20006;&#22312;&#23526;&#20316;&#20013;&#30332;&#29694;&#22909;&#34389;&#36319;&#25361;&#25136;&#65306;</p><h3>&#22909;&#34389;&#8202;&#8212;&#8202;Connection Migration</h3><p>TCP &#36899;&#32218; ID &#26159; (src_ip, src_port, dest_ip, dest_port) &#19968;&#26086;&#29992;&#25142;&#20999;&#25563;&#32178;&#36335;&#20006;&#25913;&#35722; src ip (e.g 5G =&gt; 4G)&#65292;&#36899;&#32218;&#23601;&#35201;&#37325;&#24314;&#31435;&#65292;&#20294; QUIC &#36899;&#32218; ID &#26159;&#38568;&#27231;&#32232;&#34399;&#65292;&#20786;&#23384;&#22312; Client &#31471;&#65292;&#29992;&#25142;&#20999;&#25563;&#32178;&#36335; CID &#19968;&#27171;&#23601;&#21487;&#36776;&#35672;&#29376;&#24907;&#12290;</p><p>&#22312;&#19978;&#38754; anycast &#26550;&#27083;&#25552;&#21040;&#65292;&#19968;&#33324; router &#22312; Layer 3 &#26371;&#29992; ECMP hash(src_ip, src_port, dest_ip, dest_port) &#27770;&#23450;&#36335;&#30001;&#65292;&#30070;&#29992;&#25142; src ip &#25913;&#35722;&#65292;&#30456;&#21516; CID &#20173;&#26371; forward &#21040;&#19981;&#21516; server&#65292;&#32780; Cloudflare &#21482;&#35201;&#22312; unimog layer 4 load balancer &#21152;&#19978; CID forward&#65292;&#23601;&#33021;&#23526;&#29694;&#29992;&#25142;&#25563;&#32178;&#36335;&#19981;&#37325;&#36899;&#30340;&#21151;&#33021;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!d-QA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!d-QA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 424w, https://substackcdn.com/image/fetch/$s_!d-QA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 848w, https://substackcdn.com/image/fetch/$s_!d-QA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!d-QA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!d-QA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg" width="800" height="580" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:580,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!d-QA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 424w, https://substackcdn.com/image/fetch/$s_!d-QA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 848w, https://substackcdn.com/image/fetch/$s_!d-QA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!d-QA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec48a853-7e5c-49f2-8291-b56b5b6cb5c4_800x580.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: https://zhuanlan.zhihu.com/p/311221111</p><h3>&#25361;&#25136;&#8202;&#8212;&#8202;Reflection Attacks</h3><p>QUIC &#24314;&#27083;&#22312; UDP &#19978;&#65292;&#32780; reflection attacks &#26159; UDP &#24120;&#35211;&#25915;&#25802;&#65292;&#39405;&#23458;&#20605;&#36896;&#29992;&#25142; IP&#65292;&#29992;&#35442; IP &#19981;&#26039;&#21521; server &#35531;&#27714;&#22823;&#37327;&#36039;&#26009;&#65292;&#23566;&#33268;&#29992;&#25142;&#32178;&#36335;&#22622;&#29190;&#65292;&#20363;&#22914; QUIC &#30340; TLS &#35201;&#20659; cert + public key &#32102; client&#65292;&#26159;&#19968;&#22823;&#22376;&#36039;&#26009;&#65292;&#39405;&#23458;&#21487;&#19981;&#26039;&#30332;&#36865; TLS &#35531;&#27714;&#35731;&#29992;&#25142;&#19981;&#26039;&#25910;&#21040;&#36039;&#26009;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!x2rJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!x2rJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 424w, https://substackcdn.com/image/fetch/$s_!x2rJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 848w, https://substackcdn.com/image/fetch/$s_!x2rJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 1272w, https://substackcdn.com/image/fetch/$s_!x2rJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!x2rJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png" width="800" height="402" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:402,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!x2rJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 424w, https://substackcdn.com/image/fetch/$s_!x2rJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 848w, https://substackcdn.com/image/fetch/$s_!x2rJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 1272w, https://substackcdn.com/image/fetch/$s_!x2rJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77348327-3d5d-40b2-a757-e252d3b6763f_800x402.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://docs.aws.amazon.com/whitepapers/latest/aws-best-practices-ddos-resiliency/udp-reflection-attacks.html">https://docs.aws.amazon.com/whitepapers/latest/aws-best-practices-ddos-resiliency/udp-reflection-attacks.html</a></p><p>TCP &#29992;&#23569;&#37327;&#36039;&#26009; hand shake &#36991;&#20813;&#35442;&#21839;&#38988;&#65292;&#25910;&#21040; Client ACK &#24460;&#25165;&#20659; cert + public key&#65292;&#33509;&#39405;&#23458;&#20605;&#36896; IP &#26159;&#25910;&#19981;&#21040; SYN-ACK &#20063;&#28961;&#27861;&#22238;&#20659; Client ACK&#65292;&#22240;&#27492;&#26681;&#35299;&#20173;&#26159; hand shake&#65292;server &#36865;&#19968;&#20491;&#21152;&#23494; token &#32102; client &#20006;&#35201;&#27714;&#20182;&#22238;&#20659;&#65292;&#20294;&#35442;&#26041;&#27861;&#29351;&#29298; 0-RTT &#29305;&#24615;&#65292;&#22240;&#27492; Cloudflare &#22312;&#22039;&#35430; ECDSA cert &#25110;&#22739;&#32302; cert &#36039;&#26009;&#12290;</p><p>Cloudflare &#38500;&#20102;&#29992; rust &#23526;&#20316; QUIC &#20043;&#22806;&#65292;&#36996;&#23526;&#20316;&#20102; proxy server&#8202;&#8212;&#8202;pingora &#29992;&#20358;&#21462;&#20195; nginx &#12290;</p><h1>&#28858;&#20160;&#40636; Cloudflare &#19981;&#29992; nginx &#35201;&#33258;&#24049;&#38283;&#30332; pingora&#65311;</h1><p>nginx &#26159; process based &#26550;&#27083;&#65292;&#29992; socket SO_REUSEPORT system call &#35731;&#22810;&#20491; process bind &#30456;&#21516; port&#65292;kernel &#20381;&#29031; hash(src_id, src_port, dest_ip, dest_port) &#20998;&#37197; socket &#32102; process &#34389;&#29702;&#12290;</p><p>process based &#32570;&#40670;&#26159; share memory &#23526;&#20316;&#35079;&#38620;&#19988;&#26377;&#38480;&#21046;&#65292;&#20363;&#22914; proxy =&gt; original server &#30340;&#36899;&#32218;&#19981;&#33021;&#20849;&#29992;&#65292;&#19988; nginx &#26159; c &#23531;&#30340;&#65292;&#26377; memory leak &#39080;&#38570;&#12290;</p><p>Cloudflare &#29992; rust &#23531;&#20102;&#19968;&#20491; thread based &#30340; proxy&#8202;&#8212;&#8202;pingora&#65292;&#27839;&#29992; nginx &#30340;&#26550;&#27083;&#65292;&#22810;&#20491; kernel thread bind &#30456;&#21516; port&#65292;&#27599;&#20491; thread &#26377;&#29544;&#31435; epoll instance&#65292;&#20849;&#20139; original server tcp &#36899;&#32218;&#36039;&#35338;&#65292;&#32780;&#22312; payload &#29305;&#22823;&#25110;&#27284;&#26696;&#20659;&#36664;&#24773;&#22659;&#29992; zero copy &#36991;&#20813;&#22823;&#37327; bytes &#24478; kernel space copy &#21040; user space&#65292;&#26371;&#21507; CPU&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zJVi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zJVi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!zJVi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!zJVi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!zJVi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zJVi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg" width="800" height="800" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:800,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zJVi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!zJVi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!zJVi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!zJVi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb652ea3f-de17-46d2-bee7-3b112309f10d_800x800.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://www.linkedin.com/posts/pal-arnab_what-is-pingora-pingora-is-a-new-http-proxy-activity-7106102391397113856-B8rJ/">https://www.linkedin.com/posts/pal-arnab_what-is-pingora-pingora-is-a-new-http-proxy-activity-7106102391397113856-B8rJ/</a></p><p>&#27492;&#22806; nginx &#26377;&#35377;&#22810;&#38283;&#30332;&#21253;&#34993;&#65292;&#20363;&#22914;&#29992; lua script &#25844;&#20805;&#21151;&#33021;&#65292;&#20294; lua &#24369;&#22411;&#21029;&#19981;&#22909;&#32173;&#35703;&#65292;&#25928;&#33021;&#20063;&#36611;&#24046;&#65292;nginx &#27169;&#32068;&#21270;&#30090;&#24456;&#22810;&#21151;&#33021;&#65292;&#26377;&#20123;&#21151;&#33021;&#29992;&#19981;&#21040;&#21371;&#26371;&#24433;&#38911;&#25928;&#33021;&#65292;benchmark &#32080;&#26524; pingora &#27604; nginx &#21534;&#21520;&#37327;&#22823;&#65292;CPU &#29992;&#37327;&#23569;&#20063;&#36611;&#31337;&#23450;&#12290;</p><h1>Cloudflare &#22914;&#20309;&#38450;&#31684; DDos&#65311;</h1><p>anycast &#26412;&#36523;&#27604; Geo DNS &#26356;&#33021;&#36969;&#25033; DDos&#65292;&#30070;&#39405;&#23458;&#29992; DNS &#35299;&#26512;&#21040; IP &#24460;&#25915;&#25802;&#65292;&#35531;&#27714;&#26371;&#34987; BGP &#20998;&#27969;&#21040;&#19981;&#21516;&#22320;&#26041;&#65292;&#23660;&#26044; layer 3 &#20998;&#27969;&#12290;</p><p>&#32780; layer 3 &#38450; DDos &#27231;&#21046;&#36996;&#26377; &#21453;&#21521;&#36335;&#30001;&#27298;&#26597;&#65292;DDos &#20013;&#65292;&#28858;&#36991;&#20813;&#25910;&#21040; server response &#26371;&#20605;&#36896; src ip&#65292;&#22240;&#27492; layer 3 &#21487;&#27298;&#26597; routing table &#20013;&#26159;&#21542;&#23384;&#22312;&#21487;&#22238;&#21435;&#36335;&#24465;&#65292;&#33509;&#27794;&#20195;&#34920; src ip &#26159;&#20605;&#36896;&#65292;&#19999;&#26820;&#23553;&#21253;&#12290;</p><p>layer 4 &#30340; DDos &#25915;&#25802;&#24120;&#35211;&#30340;&#26377; SYN flood&#65292;TCP &#20132;&#25569; client &#36865;&#20986;&#31532;&#19968;&#20491; SYN&#65292;server &#25910;&#21040;&#26371;&#22312; kernel &#35041;&#32000;&#37636; tcp &#29376;&#24907; (src ip, src port, init seq number etc) &#20006;&#22238;&#20659; SYN-ACK&#65292;SYN flood &#26159;&#20659;&#36865;&#22823;&#37327; TCP SYN &#35731; kernel &#35352;&#25014;&#39636;&#22622;&#28415;&#22823;&#37327;&#29376;&#24907;&#12290;</p><p>SYN flood &#35299;&#27861;&#20043;&#19968;&#26159;&#29992; SYN cookies&#65292;&#23559;&#29376;&#24907;&#32232;&#30908;&#25104;&#19968;&#20491;&#25976;&#23383;&#30070;&#20316; init seq number&#65292;&#25918;&#22312; ACK &#35041;&#38754;&#19981;&#20786;&#23384;&#22312;&#35352;&#25014;&#39636;&#65292;&#30070; client &#25910;&#21040;&#24460;&#35201;&#22238;&#20659; CLIENT-ACK (seq=init seq number+1)&#65292;server &#25910;&#21040;&#30906;&#23450;&#36899;&#32218;&#24314;&#31435;&#25104;&#21151;&#22312;&#35299;&#30908;&#29376;&#24907;&#20786;&#23384;&#21040;&#35352;&#25014;&#39636;&#12290;</p><p>&#27492;&#22806;&#20063;&#26371;&#29992; eBPF &#22312; kernel &#23652;&#25554;&#20837; hook &#65292;&#30435;&#25511; PPS (Packets Per Second) &amp; BPS (Bit Per Second) &#35519;&#25972; layer 4 rate limit &#31574;&#30053;&#12290;</p><p>&#26368;&#32066; layer 7 rate limit &#19981;&#26159;&#21934;&#32020; rule based&#65292;&#26159;&#36879;&#36942; Bot Management &#20849;&#20139;&#20840;&#29699; proxy &#34987;&#25915;&#25802;&#32147;&#39511;&#65292;&#20998;&#20139;&#20998;&#26512;&#34892;&#28858;&#27169;&#24335;&#32080;&#26524;&#65292;&#30070;&#32654;&#22283;&#34987;&#25915;&#25802;&#26178;&#65292;&#30456;&#38364;&#25976;&#25818;&#21487;&#21516;&#27493;&#32102;&#26085;&#26412;&#65292;&#30456;&#21516; bot &#23601;&#28961;&#27861;&#25915;&#25802;&#21040;&#26085;&#26412;&#12290;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wLus!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wLus!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 424w, https://substackcdn.com/image/fetch/$s_!wLus!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 848w, https://substackcdn.com/image/fetch/$s_!wLus!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 1272w, https://substackcdn.com/image/fetch/$s_!wLus!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wLus!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png" width="800" height="439" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/52269e1c-7abe-477b-a450-003a88d5262a_800x439.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:439,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wLus!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 424w, https://substackcdn.com/image/fetch/$s_!wLus!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 848w, https://substackcdn.com/image/fetch/$s_!wLus!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 1272w, https://substackcdn.com/image/fetch/$s_!wLus!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52269e1c-7abe-477b-a450-003a88d5262a_800x439.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>image source: <a href="https://blog.cloudflare.com/cloudflare-bot-management-machine-learning-and-more/">https://blog.cloudflare.com/cloudflare-bot-management-machine-learning-and-more/</a></p><h1>&#32080;&#35542;</h1><p>&#30070;&#24478; CDN Server &#29702;&#35299; Cloudflare &#21487;&#33021;&#26371;&#35469;&#28858;&#26159;&#19968;&#20491;&#26377; Cache &#21151;&#33021;&#30340; edge proxy&#65292;&#20294;&#24478; OSI &#32178;&#36335;&#26550;&#27083;&#35282;&#24230;&#65292;&#26371;&#30332;&#29694;&#20182;&#20570;&#20102;&#24456;&#22810;&#20107;&#24773;&#65306;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!V-5R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7221062d-65c6-4b50-b7dc-faac6f59485e_3663x7565.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!V-5R!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7221062d-65c6-4b50-b7dc-faac6f59485e_3663x7565.png 424w, https://substackcdn.com/image/fetch/$s_!V-5R!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7221062d-65c6-4b50-b7dc-faac6f59485e_3663x7565.png 848w, https://substackcdn.com/image/fetch/$s_!V-5R!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7221062d-65c6-4b50-b7dc-faac6f59485e_3663x7565.png 1272w, https://substackcdn.com/image/fetch/$s_!V-5R!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7221062d-65c6-4b50-b7dc-faac6f59485e_3663x7565.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!V-5R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7221062d-65c6-4b50-b7dc-faac6f59485e_3663x7565.png" width="1456" height="3007" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7221062d-65c6-4b50-b7dc-faac6f59485e_3663x7565.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:3007,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1003090,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.chillvic.dev/i/182279446?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7221062d-65c6-4b50-b7dc-faac6f59485e_3663x7565.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!V-5R!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7221062d-65c6-4b50-b7dc-faac6f59485e_3663x7565.png 424w, https://substackcdn.com/image/fetch/$s_!V-5R!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7221062d-65c6-4b50-b7dc-faac6f59485e_3663x7565.png 848w, https://substackcdn.com/image/fetch/$s_!V-5R!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7221062d-65c6-4b50-b7dc-faac6f59485e_3663x7565.png 1272w, https://substackcdn.com/image/fetch/$s_!V-5R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7221062d-65c6-4b50-b7dc-faac6f59485e_3663x7565.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>&#30456;&#20449;&#22823;&#23478;&#30475;&#23436;&#36889;&#31687;&#24460;&#65292;&#22312;&#21435;&#30475; Cloudflare &#30340;&#25925;&#38556;&#22577;&#21578;&#25991;&#31456;&#33021;&#26356;&#22909;&#22320;&#29702;&#35299;&#20182;&#20497;&#25552;&#21040;&#30340;&#25216;&#34899;&#21839;&#38988;&#12290;</p><h1>References:</h1><p><a href="https://blog.cloudflare.com/unimog-cloudflares-edge-load-balancer/">https://blog.cloudflare.com/unimog-cloudflares-edge-load-balancer/</a><br><a href="https://blog.cloudflare.com/the-road-to-quic/">https://blog.cloudflare.com/the-road-to-quic/</a><br><a href="https://blog.cloudflare.com/how-we-built-pingora-the-proxy-that-connects-cloudflare-to-the-internet/https://www.cloudflare.com/ru-ru/learning/dns/what-is-anycast-dns/">https://blog.cloudflare.com/how-we-built-pingora-the-proxy-that-connects-cloudflare-to-the-internet/https://www.cloudflare.com/ru-ru/learning/dns/what-is-anycast-dns/</a><br><a href="https://blog.cloudflare.com/async-quic-and-http-3-made-easy-tokio-quiche-is-now-open-source/">https://blog.cloudflare.com/async-quic-and-http-3-made-easy-tokio-quiche-is-now-open-source/</a><br><a href="https://medium.com/codavel-blog/quic-vs-tcp-tls-and-why-quic-is-not-the-next-big-thing-d4ef59143efd">https://medium.com/codavel-blog/quic-vs-tcp-tls-and-why-quic-is-not-the-next-big-thing-d4ef59143efd</a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Observability without the surgery: How to monitor your code without touching a single line of source.]]></title><description><![CDATA[eBPF: The &#8220;Superpowers&#8221; for Linux Kernel Observability]]></description><link>https://www.chillvic.dev/p/observability-without-the-surgery</link><guid isPermaLink="false">https://www.chillvic.dev/p/observability-without-the-surgery</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Sun, 21 Dec 2025 08:19:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Tks4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e2998b3-0c2f-41bc-96dc-e2277b741402_4800x3595.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>eBPF (Extended Berkeley Packet Filter) is a revolutionary technology that allows us to run sandboxed programs within the Linux kernel. It enables us to enhance system security and observability without modifying a single line of application code. </p><p>One of its most powerful features is real-time monitoring of CPU usage, memory allocation, and network packet inspection at the kernel level.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Tks4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e2998b3-0c2f-41bc-96dc-e2277b741402_4800x3595.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Tks4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e2998b3-0c2f-41bc-96dc-e2277b741402_4800x3595.png 424w, https://substackcdn.com/image/fetch/$s_!Tks4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e2998b3-0c2f-41bc-96dc-e2277b741402_4800x3595.png 848w, https://substackcdn.com/image/fetch/$s_!Tks4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e2998b3-0c2f-41bc-96dc-e2277b741402_4800x3595.png 1272w, https://substackcdn.com/image/fetch/$s_!Tks4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e2998b3-0c2f-41bc-96dc-e2277b741402_4800x3595.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Tks4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e2998b3-0c2f-41bc-96dc-e2277b741402_4800x3595.png" width="1456" height="1090" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4e2998b3-0c2f-41bc-96dc-e2277b741402_4800x3595.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1090,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:259896,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://chillvic.substack.com/i/182168417?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e2998b3-0c2f-41bc-96dc-e2277b741402_4800x3595.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Tks4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e2998b3-0c2f-41bc-96dc-e2277b741402_4800x3595.png 424w, https://substackcdn.com/image/fetch/$s_!Tks4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e2998b3-0c2f-41bc-96dc-e2277b741402_4800x3595.png 848w, https://substackcdn.com/image/fetch/$s_!Tks4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e2998b3-0c2f-41bc-96dc-e2277b741402_4800x3595.png 1272w, https://substackcdn.com/image/fetch/$s_!Tks4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e2998b3-0c2f-41bc-96dc-e2277b741402_4800x3595.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1><strong>How to implement real-time monitoring without changing the code?</strong></h1><p>When an application runs, it interacts with hardware and resources via <strong>System Calls (syscalls)</strong>. For example, <code>read()</code> and <code>write()</code> are used for File and Network I/O.</p><p>By attaching <strong>hooks</strong> to these syscalls, we can intercept them right before they execute or right after they finish. This allows us to collect execution parameters, return values, and precise timing data&#8212;all without the application ever knowing it&#8217;s being watched. For instance, hooking <code>read()</code> and <code>write()</code> allows you to monitor HTTP requests or database queries in real-time.</p><h1><strong>Isn&#8217;t it dangerous to hook the Kernel?</strong></h1><p><strong>Arbitrarily inserting code into the kernel is extremely risky.</strong> A simple bug&#8212;such as a division by zero or an infinite loop&#8212;can crash the entire kernel and trigger a kernel panic, bringing down every process on the machine.</p><p>To make safe kernel extensibility possible, eBPF relies on <strong>a restricted programming model and strict verification</strong>, rather than trust.</p><p>Although eBPF programs can be written in C syntax, they are not general-purpose programs and <strong>must conform to strict compilation and verification constraints.</strong> <strong>During compilation,</strong> <strong>unsupported constructs&#8212;such as heap allocation (</strong><code>malloc</code><strong>) or unrestricted pointer usage&#8212;are rejected</strong>, because the eBPF instruction set simply does not support them.</p><p>After compilation, the resulting eBPF bytecode is passed to the kernel. Before it is allowed to execute, <strong>the eBPF verifier performs a full safety analysis. The verifier ensures that the program cannot consume unbounded resources</strong>&#8212;no infinite loops, no recursion, no excessive stack usage, and no unsafe memory access.</p><p>Finally, the eBPF program can be safely executed inside the kernel. At this stage, the <strong>kernel must be able to transform the verified eBPF bytecode into executable machine code.</strong></p><p><strong>Early eBPF implementations executed bytecode through an interpreter-based virtual machine.</strong> While functionally correct, interpretation introduced significant overhead and was unsuitable for performance-critical kernel paths.</p><p><strong>Modern eBPF therefore relies on JIT compilation, which is capable of transforming eBPF bytecode into native machine code for the target CPU architecture, allowing eBPF programs to run at near-native speed within the kernel runtime.</strong></p><h1><strong>How is the collected data stored?</strong></h1><p>Since eBPF programs are restricted, they cannot perform complex I/O operations (like writing directly to an external database). Instead, <strong>eBPF provides eBPF Maps&#8212;efficient data structures (Hash maps, Arrays, Ring Buffers, etc.) shared between the kernel and user space.</strong></p><p>These maps can be accessed efficiently using <code>mmap</code>, a virtual memory mechanism that maps kernel-managed physical pages into the virtual address space of a user-space process. </p><p><strong>With this approach, user-space programs can read data directly from memory, avoiding repeated </strong><code>read()</code><strong>-style system calls that would otherwise require copying data between kernel and user space.</strong></p><p>Once the data is read from memory, the user-space program can then forward it to a database, monitoring system, or any other external service.</p><h1><strong>Can we monitor functions that don&#8217;t trigger System Calls?</strong></h1><p>Yes. While many eBPF hooks (like <code>sk_msg</code>) focus on the network or socket layers, eBPF also provides <strong>uprobes (User Probes)</strong>.</p><p>Unlike syscall hooks, uprobes can modify the binary in memory. They insert a &#8220;trap&#8221; instruction at the entry and exit points of a specific function in your application. </p><p>When the process reaches a probed function, <strong>execution is interrupted by a trap that transfers control to the kernel, where the associated eBPF hook</strong>  <strong>(e.g., using </strong><code>bpf_ktime_get_ns</code><strong> to record CPU time)  is executed</strong>. This can happen both at function entry and at function return, allowing eBPF programs to observe execution before and after the function runs.</p><h1><strong>How can I start building with eBPF?</strong></h1><p>Let&#8217;s build a simple project that uses <code>uprobes</code> to measure a function&#8217;s execution time.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.chillvic.dev/subscribe?"><span>Subscribe now</span></a></p><h3>Prerequisites</h3><ul><li><p><strong>Vagrant &amp; Virtual Machine</strong>: eBPF is natively supported only on Linux. If you are using macOS or Windows, you must develop within a Linux environment (e.g., Ubuntu via Vagrant).</p></li><li><p><strong>Clang &amp; LLVM</strong>: BPF programs are written in C and compiled into bytecode using Clang/LLVM.</p></li><li><p><strong>Go</strong>: We will use Go to write the user-space process that manages the eBPF lifecycle.</p></li></ul><h3>Step 1: Define eBPF Maps and Structures</h3><p>First, we define a <strong>Hash Map</strong> to store function entry timestamps (indexed by Process ID), a <strong>Ring Buffer</strong> to transfer calculated durations to the user-space process, and an <strong>event</strong> struct to standardize the data format shared between the kernel and user space.</p><pre><code>
// Define a hash map to store start times; map name is "start_times"
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 1024);
    __type(key, u32);
    __type(value, u64);
} start_times SEC(".maps");

// Define a ring buffer to send events to user space; map name is "events"
struct {
    __uint(type, BPF_MAP_TYPE_RINGBUF);
    __uint(max_entries, 256 * 1024);
} events SEC(".maps");

// Define the event structure for data transfer
struct event {
    u32 pid;
    u64 start_time;
    u64 duration_ns;
};</code></pre><h3><strong>Step 2 : write a eBPF program</strong></h3><p>The <code>SEC</code> macro is an eBPF-specific tool used to define the hook or section type for a specific block of code.</p><h4>Entry Hook</h4><p>This hook triggers at the start of the function, records the current timestamp, and stores it in the hash map.</p><pre><code>SEC("uprobe")
int trace_func_entry(struct pt_regs *ctx) {
    // get current pid by removing lower 32 bits which is tid
    u32 pid = bpf_get_current_pid_tgid() &gt;&gt; 32;
    u64 ts = bpf_ktime_get_ns();

    // store the start time in the map
    bpf_map_update_elem(&amp;start_times, &amp;pid, &amp;ts, BPF_ANY);
    bpf_printk("trace_func_entry hit: PID %d\n", pid);
    return 0;
}</code></pre><h4>Exit Hook</h4><p>This hook triggers when the function returns. It calculates the elapsed time and submits the result to the ring buffer.</p><pre><code>SEC("uprobe")
int trace_func_exit(struct pt_regs *ctx) {
    // get current pid by removing lower 32 bits which is tid
    u32 pid = bpf_get_current_pid_tgid() &gt;&gt; 32;
    u64 *start_ts = bpf_map_lookup_elem(&amp;start_times, &amp;pid);
    
    if (!start_ts) return 0;
    u64 end_ts = bpf_ktime_get_ns();
    // initialize and submit event to ring buffer
    struct event *e = bpf_ringbuf_reserve(&amp;events, sizeof(*e), 0);
    if (e) {
        e-&gt;pid = pid;
        e-&gt;duration_ns = end_ts - *start_ts;
        bpf_ringbuf_submit(e, 0);
    }
    bpf_printk("trace_func_exit hit: PID %d\n", pid);

    // cleanup the start time from the map
    bpf_map_delete_elem(&amp;start_times, &amp;pid);
    return 0;
}</code></pre><h3>Step 3: Write the User-Space Process</h3><p>The user-space process (written in Go) is responsible for:</p><ol><li><p>Loading the eBPF bytecode into the kernel.</p></li><li><p>Attaching the <code>uprobe</code> hooks by resolving the binary path and function offsets.</p></li><li><p>Initializing the ring buffer and consuming events for display.</p></li></ol><p>We use the <code>github.com/aquasecurity/libbpfgo</code> library. Note that <code>libbpfgo</code> depends on <code>libbpf</code> (C library), so you must use <strong>CGO</strong> for compilation.</p><pre><code>// Event definition shared with eBPF program
// struct event { u32 pid; u64 start_time; u64 duration_ns; };
type Event struct {
&#9;Pid        uint32
&#9;_          [4]byte // Padding for alignment
&#9;StartTime  uint64
&#9;DurationNs uint64
}

func main() {
&#9;binaryPath := os.Args[1]
&#9;symbolName := os.Args[2]

&#9;_, err := os.Stat(binaryPath)
&#9;if err != nil {
&#9;&#9;terminate(fmt.Errorf("binary path error: %v", err))
&#9;}

&#9;// load eBPF object file
&#9;bpfModule, err := libbpfgo.NewModuleFromFile("main.ebpf.o")
&#9;if err != nil {
&#9;&#9;terminate(err)
&#9;}
&#9;defer bpfModule.Close()

&#9;// load eBPF program into the kernel
&#9;if err := bpfModule.BPFLoadObject(); err != nil {
&#9;&#9;terminate(err)
&#9;}

&#9;// get and attach Uprobe (Entry)
&#9;entryProg, err := bpfModule.GetProgram("trace_func_entry")
&#9;if err != nil {
&#9;&#9;terminate(err)
&#9;}

&#9;offset, err := common.SymbolToOffset(binaryPath, symbolName)
&#9;if err != nil {
&#9;&#9;terminate(err)
&#9;}

&#9;probeLink, err := entryProg.AttachUprobe(-1, binaryPath, uint32(offset))
&#9;if err != nil {
&#9;&#9;terminate(fmt.Errorf("failed to attach uprobe: %v", err))
&#9;}
&#9;if probeLink == nil {
&#9;&#9;terminate(fmt.Errorf("failed to attach uprobe: link is nil"))
&#9;}
&#9;defer probeLink.Destroy()

&#9;// get and attach Uprobe (Exit)
&#9;exitProg, err := bpfModule.GetProgram("trace_func_exit")
&#9;if err != nil {
&#9;&#9;terminate(err)
&#9;}

&#9;returnOffsets, err := FindReturnOffsets(binaryPath, symbolName)
&#9;if err != nil {
&#9;&#9;terminate(fmt.Errorf("failed to find return offsets: %v", err))
&#9;}
&#9;if len(returnOffsets) == 0 {
&#9;&#9;terminate(fmt.Errorf("no return offsets found for symbol: %s", symbolName))
&#9;}
&#9;uretLink, err := exitProg.AttachURetprobe(-1, binaryPath, uint32(offset+returnOffsets[0]))
&#9;if err != nil {
&#9;&#9;terminate(fmt.Errorf("failed to attach uretprobe: %v", err))
&#9;}
&#9;if uretLink == nil {
&#9;&#9;terminate(fmt.Errorf("failed to attach uretprobe: link is nil"))
&#9;}
&#9;defer uretLink.Destroy()

&#9;// initialize Ring Buffer
&#9;eventsChannel := make(chan []byte)
&#9;rb, err := bpfModule.InitRingBuf("events", eventsChannel)
&#9;if err != nil {
&#9;&#9;terminate(err)
&#9;}

&#9;// start Ring Buffer polling
&#9;rb.Poll(1000)

&#9;// setup signal handling
&#9;sigChan := make(chan os.Signal, 1)
&#9;signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
&#9;fmt.Println("Tracing... Press Ctrl+C to stop.")
&#9;ctx, cancel := context.WithCancel(context.Background())
&#9;// event processing loop
&#9;go func() {
&#9;&#9;for {
&#9;&#9;&#9;select {
&#9;&#9;&#9;case &lt;-ctx.Done():
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;default:
&#9;&#9;&#9;}
&#9;&#9;&#9;rawBytes := &lt;-eventsChannel
&#9;&#9;&#9;var event Event
&#9;&#9;&#9;err := binary.Read(bytes.NewReader(rawBytes), binary.LittleEndian, &amp;event)
&#9;&#9;&#9;if err != nil {
&#9;&#9;&#9;&#9;fmt.Printf("failed to decode received data: %v\n", err)
&#9;&#9;&#9;&#9;continue
&#9;&#9;&#9;}
&#9;&#9;&#9;fmt.Printf("PID: %d | Function Duration: %v ms\n",
&#9;&#9;&#9;&#9;event.Pid, float64(event.DurationNs)/1e6)
&#9;&#9;}
&#9;}()

&#9;&lt;-sigChan
&#9;cancel()
&#9;rb.Stop()
&#9;fmt.Println("Exiting...")
}

func terminate(err error) {
&#9;fmt.Fprintf(os.Stderr, "Error: %v\n", err)
&#9;os.Exit(1)
}</code></pre><h3>Full Codebase</h3><p>To simplify setup, you can access the entire codebase&#8212;including the Vagrant configuration and Makefile&#8212;at the link below: <strong>[<a href="https://github.com/vx416/ebpf_test">https://github.com/vx416/ebpf_test</a>]</strong></p><h1><strong>Conclusion</strong></h1><p>eBPF enables safe, efficient, and real-time observability at the kernel level without requiring any modifications to the application code. </p><p>To leverage its power, we don't need to reinvent the wheel&#8212;we can rely on proven tools like:</p><ul><li><p><strong>Pyroscope</strong>: Utilizes eBPF to generate high-resolution, real-time CPU flame graphs for continuous profiling.</p></li><li><p><strong>Pixie</strong>: A Kubernetes-native observability platform that uses eBPF to automate request tracing, database query profiling, and process-level CPU analysis.</p></li></ul>]]></content:encoded></item><item><title><![CDATA[Stop Trying to Build the "Perfect" System: A Practical Guide to CAP Theorem.]]></title><description><![CDATA[Why every distributed system is a game of trade-offs, from etcd&#8217;s consistency to Cassandra&#8217;s availability.]]></description><link>https://www.chillvic.dev/p/stop-trying-to-build-the-perfect</link><guid isPermaLink="false">https://www.chillvic.dev/p/stop-trying-to-build-the-perfect</guid><dc:creator><![CDATA[Chill Vic]]></dc:creator><pubDate>Sat, 20 Dec 2025 09:57:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!jbcc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87534a23-61f6-4639-8e1c-f812016ed442_832x1248.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jbcc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87534a23-61f6-4639-8e1c-f812016ed442_832x1248.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jbcc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87534a23-61f6-4639-8e1c-f812016ed442_832x1248.png 424w, https://substackcdn.com/image/fetch/$s_!jbcc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87534a23-61f6-4639-8e1c-f812016ed442_832x1248.png 848w, https://substackcdn.com/image/fetch/$s_!jbcc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87534a23-61f6-4639-8e1c-f812016ed442_832x1248.png 1272w, https://substackcdn.com/image/fetch/$s_!jbcc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87534a23-61f6-4639-8e1c-f812016ed442_832x1248.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jbcc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87534a23-61f6-4639-8e1c-f812016ed442_832x1248.png" width="832" height="1248" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/87534a23-61f6-4639-8e1c-f812016ed442_832x1248.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1248,&quot;width&quot;:832,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1410836,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://chillvic.substack.com/i/182157665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87534a23-61f6-4639-8e1c-f812016ed442_832x1248.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jbcc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87534a23-61f6-4639-8e1c-f812016ed442_832x1248.png 424w, https://substackcdn.com/image/fetch/$s_!jbcc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87534a23-61f6-4639-8e1c-f812016ed442_832x1248.png 848w, https://substackcdn.com/image/fetch/$s_!jbcc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87534a23-61f6-4639-8e1c-f812016ed442_832x1248.png 1272w, https://substackcdn.com/image/fetch/$s_!jbcc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87534a23-61f6-4639-8e1c-f812016ed442_832x1248.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Today, I&#8217;m going to talk about the famous CAP theorem in a practical way by answering the following questions:</p><ul><li><p>What is a distributed system and why do people use it?</p></li><li><p>What is the CAP theorem?</p></li><li><p>How do you choose between designing a CP or an AP system?</p></li></ul><h1>What is a distributed system and why do people use it?</h1><p>A distributed system consists of multiple independent machines that collaborate via communication protocols. The benefits of such a system are <strong>availability</strong> and <strong>flexibility</strong>.</p><p>When multiple machines work together to accomplish tasks, you don&#8217;t have to worry if one or two machines stop working unexpectedly&#8202;&#8212;&#8202;because the others continue operating.</p><p>Additionally, when the system encounters a sudden surge in throughput, you can simply add new machines without any downtime. <strong>In contrast, vertical scalability (upgrading a single machine) typically requires downtime and has physical limitations.</strong></p><p>Although distributed systems offer critical advantages, <strong>designing a perfect distributed system is impractical.</strong></p><p><strong>That&#8217;s where the CAP theorem comes into play to guide architectural decisions.</strong></p><h1>What is the CAP theorem?</h1><p>In a system with many machines, <strong>it&#8217;s unrealistic to expect everything to work flawlessly.</strong> Since machines communicate over networks, and network conditions are inherently unstable, routers may fail, bandwidth may become saturated, and packets may be delayed&#8202;&#8212;&#8202;making it impossible to assume timely delivery.</p><p>As a system architect, you must design for failure and build robustness into your system.</p><p>So what happens when some machines can&#8217;t communicate with each other?</p><p>In a distributed database, a machine crash or a lost network connection <strong>can lead to inconsistent data&#8202;&#8212;&#8202;because some machines may miss updates and fall out of sync. As a result, users accessing different servers may see different versions of the same data.</strong></p><p><strong>This is the moment when you have to make a trade-off:</strong></p><ul><li><p>If you prioritize data consistency, you must halt the system until the crashed machine recovers and synchronizes missing data.</p></li><li><p>If you prioritize availability, you allow the system to continue operating despite temporary inconsistencies.</p></li></ul><p>This trade-off is at the heart of the CAP theorem:</p><blockquote><p><strong>Consistency and Availability cannot both be fully guaranteed when your distributed system must tolerate network partitions.</strong></p></blockquote><p>CAP stands for:</p><p>P&#8202;&#8212;&#8202;Partition Tolerance</p><p>A&#8202;&#8212;&#8202;Availability</p><p>C&#8202;&#8212;&#8202;Consistency</p><p>Every distributed system must make trade-offs among these three properties, typically sacrificing either consistency (C) or availability (A). <strong>Partition tolerance (P) cannot be sacrificed, because a distributed system must assume that partition failures will occur.</strong></p><h1><strong>How to Choose Between CP and AP Systems?</strong></h1><p>Now that you understand the CAP theorem, let&#8217;s explore how to choose between CP and AP systems using database systems as examples.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.chillvic.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.chillvic.dev/subscribe?"><span>Subscribe now</span></a></p><p>When designing a database, <strong>users primarily care about read and write operations, and different business contexts may create higher loads on either reads or writes.</strong> Thus, your system should prioritize the more critical operation.</p><h3><strong>If your system handles heavy write throughput:</strong></h3><p>You will need multiple machines to handle write requests. However, <strong>with multiple writers, maintaining consistency becomes more challenging, because it&#8217;s difficult to reach consensus among multiple leaders.</strong></p><p>Since read consistency is less critical in this scenario, temporary data inconsistencies can be tolerated. In this case, you should choose an AP system. The system prioritizes availability, ensuring that users can continue writing new data even when some machines are down.</p><h3><strong>Cassandra: An AP System Example</strong></h3><p><strong>Cassandra</strong> is a distributed database optimized for high write throughput and is a classic example of an <strong>AP system</strong>. </p><p>It accepts writes on multiple nodes and propagates updates to replicas asynchronously. <strong>When conflicts occur, Cassandra typically resolves them using a timestamp-based Last-Write-Wins (LWW) rule, where writes with newer timestamps overwrite older ones.</strong> </p><p>As a result, occasional read inconsistencies can occur, but Cassandra prioritizes write availability and guarantees eventual consistency, allowing it to scale extremely well.</p><h3><strong>If your system prioritizes read consistency:</strong></h3><p>You may deploy several machines to handle reads and boost read performance, but only one machine should handle writes to avoid conflicts.</p><p>With a single source of truth for writes, you can ensure that every update is consistently synchronized across the system. <strong>However, if the single write node crashes, the system must elect a new write node&#8202;&#8212;&#8202;a process that causes temporary downtime, sacrificing availability.</strong> So, consistency is guaranteed, but availability is compromised during failures.</p><h3><strong>etcd: An CP System Example</strong></h3><p><strong>etcd</strong> is a distributed key-value store primarily used for storing system metadata.</p><p><strong>Because metadata is at the heart of system coordination &#8212; for example, Kubernetes uses etcd to store cluster state and scheduling information &#8212; data inconsistency can lead to inconsistent system behavior and unpredictable errors.</strong> Moreover, metadata is typically read very frequently but updated relatively infrequently.</p><p><strong>To guarantee strong consistency, etcd uses the Raft consensus algorithm to ensure that every update is committed and replicated across the cluster before it becomes visible.</strong> It also provides multiple follower nodes to serve read requests, improving read performance while maintaining consistency.</p><h1>Conclusion</h1><p>The CAP theorem reminds us that no distributed system can simultaneously guarantee consistency, availability, and partition tolerance. When designing a system, it&#8217;s crucial to understand your business priorities, choose the right technologies, and make conscious trade-offs.</p>]]></content:encoded></item></channel></rss>