<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>DSA on J2234's log</title><link>https://log.j2234.cc/tags/dsa/</link><description>Recent content in DSA on J2234's log</description><generator>Hugo -- gohugo.io</generator><language>ko</language><copyright>© 2026 J2234</copyright><lastBuildDate>Wed, 15 Apr 2026 15:04:15 +0000</lastBuildDate><atom:link href="https://log.j2234.cc/tags/dsa/index.xml" rel="self" type="application/rss+xml"/><item><title>Token bucket 알고리즘(feat.redis)</title><link>https://log.j2234.cc/posts/token-bucket-algorithm-scg/</link><pubDate>Sun, 21 Sep 2025 00:00:00 +0000</pubDate><guid>https://log.j2234.cc/posts/token-bucket-algorithm-scg/</guid><description>&lt;h2 class="relative group"&gt;Intro
 &lt;div id="intro" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#intro" aria-label="앵커"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;토큰 버킷(Token Bucket)알고리즘은 처리율 제한(rate limit)알고리즘 중 가장 유명한 알고리즘이에요. 대표적으로 Amazon, Google 등의 대규모 트래픽을 다루는 빅테크에서도 사용하죠.&lt;/p&gt;
&lt;p&gt;이 글에서는 토큰 버킷 알고리즘의 개념을 알아보고, 실제 어떻게 구현되는지까지 살펴볼게요&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;알고리즘 개념
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="2048"
 height="1483"
 src="https://log.j2234.cc/posts/token-bucket-algorithm-scg/attach/index-1776232397000_hu_9dce7e3d95d9f5d.webp"
 srcset="https://log.j2234.cc/posts/token-bucket-algorithm-scg/attach/index-1776232397000_hu_9dce7e3d95d9f5d.webp 800w, https://log.j2234.cc/posts/token-bucket-algorithm-scg/attach/index-1776232397000_hu_ebe65b5f64db5f5b.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/token-bucket-algorithm-scg/attach/index-1776232397000.webp"&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;토큰 버킷 알고리즘은 꽤 단순해요:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;버킷은 매초 &lt;code&gt;R&lt;/code&gt;개의 토큰이 채워짐&lt;/li&gt;
&lt;li&gt;버킷은 최대 &lt;code&gt;C&lt;/code&gt;개까지만 담을 수 있고, 넘치면 버림&lt;/li&gt;
&lt;li&gt;요청시엔
&lt;ul&gt;
&lt;li&gt;토큰이 있으면 → 토큰 소모 후 통과&lt;/li&gt;
&lt;li&gt;토큰이 없으면 → 429&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;여기서&lt;code&gt;C&lt;/code&gt;는 최대 버스트 처리량, &lt;code&gt;R&lt;/code&gt;은 평균 처리율을 의미해요. 이 두 값을 어떻게 튜닝하냐에 따라 시스템의 성능 특성을 조절할 수 있죠.&lt;/em&gt;&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/token-bucket-algorithm-scg/featured.webp"/></item><item><title>Cuckoo Filter실험-false negative?</title><link>https://log.j2234.cc/posts/cf-internals2/</link><pubDate>Tue, 09 Sep 2025 11:52:50 +0000</pubDate><guid>https://log.j2234.cc/posts/cf-internals2/</guid><description>&lt;h2 class="relative group"&gt;Intro
 &lt;div id="intro" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#intro" aria-label="앵커"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://log.j2234.cc/posts/cf-internals/" &gt;이전글&lt;/a&gt;에서 이어지는 내용이에요&lt;/p&gt;
&lt;p&gt;&lt;a href="https://redis.io/docs/latest/develop/data-types/probabilistic/bloom-filter/" target="_blank" rel="noreferrer"&gt;Redis Bloom Filter&lt;/a&gt; 문서에는 BF가 집합에서 특정 항목이 “존재하지 않음을 보장”한다고 말해요: A Bloom filter can guarantee the absence of an item from a set. 하지만 &lt;a href="https://redis.io/docs/latest/develop/data-types/probabilistic/cuckoo-filter/" target="_blank" rel="noreferrer"&gt;Redis Cuckoo Filter&lt;/a&gt; 문서에는 “존재 여부를 확인할 수 있다”고만 말하고, 보장이라는 표현은 없죠.&lt;/p&gt;
&lt;p&gt;여러 자료들에서는(심지어 &lt;a href="https://en.wikipedia.org/wiki/Cuckoo_filter" target="_blank" rel="noreferrer"&gt;위키피디아&lt;/a&gt; 에도CF는 false negative가 없다고 설명하지만, 소스 코드를 뜯어보니 충분히 가능할 것 같아 직접 실험해봤어요.&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/cf-internals2/featured.webp"/></item><item><title>Cuckoo filter 원리</title><link>https://log.j2234.cc/posts/cf-internals/</link><pubDate>Mon, 08 Sep 2025 11:52:50 +0000</pubDate><guid>https://log.j2234.cc/posts/cf-internals/</guid><description>&lt;h2 class="relative group"&gt;Intro
 &lt;div id="intro" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#intro" aria-label="앵커"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Cuckoo Filter(CF)는 &lt;a href="https://log.j2234.cc/posts/bf-internals/" &gt;Bloom Filter&lt;/a&gt;처럼 메모리 효율적으로 집합에 원소가 있는지 &lt;em&gt;확률적으로&lt;/em&gt; 확인하는 자료구조에요.
BF보다 좀 더 많은 메모리를 필요로 하지만, 대신 원소를 &lt;strong&gt;삭제&lt;/strong&gt;할 수 있어요!&lt;/p&gt;
&lt;p&gt;이름에 뻐꾸기(cuckoo)가 들어간 데엔 꽤 흥미로운 이유도 있어요.
이제부터 CF의 개념과 동작 원리에 대해 살펴볼게요.&lt;/p&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;&lt;strong&gt;Cuckoo hashing&lt;/strong&gt;
 &lt;div id="cuckoo-hashing" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#cuckoo-hashing" aria-label="앵커"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;뻐꾸기는 남의 둥지에 몰래 알을 낳고, 부화한 후 관심을 독차지하기 위해 원래 있던 알들을 둥지 밖으로 밀어버리는 습성을 가지고 있어요. &lt;del&gt;쓰레기&lt;/del&gt;&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/cf-internals/featured.webp"/></item><item><title>Bloom Filter 원리</title><link>https://log.j2234.cc/posts/bf-internals/</link><pubDate>Thu, 04 Sep 2025 11:00:54 +0000</pubDate><guid>https://log.j2234.cc/posts/bf-internals/</guid><description>&lt;h2 class="relative group"&gt;Intro
 &lt;div id="intro" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#intro" aria-label="앵커"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Bloom Filter(BF)는 “특정 원소가 집합에 존재하는지” 여부를 효율적으로 검사하는 확률적 자료구조에요. &lt;a href="https://log.j2234.cc/posts/hll-internals/" &gt;HyperLogLog&lt;/a&gt; 처럼 Set의 메모리 부담을 줄이도록 설계되었으며 HLL이 카디널리티 추정에 특화되었다면, BF는 집합의 포함 여부 (in)에 특화되어 있죠.&lt;/p&gt;
&lt;p&gt;물론 확률적 자료구조인 만큼 100% 정확하진 않지만, 최소한 있는 걸 없다고 하진 않아요.&lt;/p&gt;
&lt;p&gt;이제부터 BF의 개념과 동작 원리에 대해 살펴볼게요.&lt;/p&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;BF 구조
 &lt;div id="bf-구조" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#bf-%ea%b5%ac%ec%a1%b0" aria-label="앵커"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Redis에서 BF는 다음과 같이 구현되어 있어요.&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/bf-internals/featured.webp"/></item><item><title>HyperLogLog 원리</title><link>https://log.j2234.cc/posts/hll-internals/</link><pubDate>Sun, 31 Aug 2025 06:14:11 +0000</pubDate><guid>https://log.j2234.cc/posts/hll-internals/</guid><description>&lt;h2 class="relative group"&gt;Intro
 &lt;div id="intro" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#intro" aria-label="앵커"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;데이터셋에서 고유 원소가 몇 개인지 알고 싶다면, 대개 &lt;code&gt;Set&lt;/code&gt;이 떠오르죠.
삽입·조회가 거의 O(1)에 가깝고, 집합 그 자체니깐요.&lt;/p&gt;
&lt;p&gt;그런데 &lt;code&gt;Set&lt;/code&gt;은 해시 값과 원본 값을 둘 다 들고 있어서
원소가 많아질수록 메모리를 끝도 없이 잡아먹어요.
그럼 &lt;strong&gt;거의 정확히&lt;/strong&gt; 고유 개수를 세면서도 메모리를 아낄 수 있을까요?&lt;/p&gt;
&lt;p&gt;바로 여기서 &lt;strong&gt;HyperLogLog&lt;/strong&gt;가 등장해요. (줄여서 HLL!)
HLL은 카디널리티를 추정하는 확률적 자료 구조인데,
정확도를 살짝 희생해서 공간(메모리)을 효율적으로 활용할 수 있어요.&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/hll-internals/featured.webp"/></item></channel></rss>