▶ Cinematic fable · Watch on YouTube ▶ 影片版寓言 · 在 YouTube 观看

京城东华门内有一座文渊阁,阁内藏天下典籍数万卷。

地底地库阴冷深邃,寻一卷书要小厮举着火把上下爬三道石梯、翻半个时辰木箱。为了免去学士们空等,阁中正堂特辟出一长排沉香木案,专作“案头书架”。

木案的位置极有限,满打满算,只能平摆一百卷书。 学士要看的书若恰好在案上,伸手便能展读;若不在案上,就只能合目静坐,等小厮下地库翻箱倒柜。因此,案上该摆哪一百卷书,成了文渊阁历任掌书官最费思量的营生。

头一任掌书官崇尚“尝鲜”。 他定下的章程简单明了:凡刚被学士借阅过的书,便摆在木案最前头;若是案台摆满了一百卷,就把在案尾落灰最久的一卷打回地库。

这套章程寻常日子倒也过得去,直到有一年秋天,礼部来了一位修纂偏门草木谱的老学士。老学士闭门十日,将地库里八十余卷谁也用不着的冷僻苗药经书挨个调出来翻了一遍。 每翻一本,案尾便有一本经史子集被无情扫回地库。 三日之内,《论语》《史记》《营造法式》全被赶到了地底下,整张沉香木案全被冷僻药草谱塞满。老学士修毕草谱飘然离去,随后赶来的满堂翰林要看常备经典,却发现一本不剩,小厮们在石梯上跑得吐了血。

第二任掌书官吸取教训,改立“常青”之法。 他在每卷书的象牙签上用朱笔画正字,谁被借阅过一次,便添一笔。唯有累计笔画最多的前一百卷,才配留在案上。

可不过半年,这套新规矩又撞了南墙。 前朝留下的旧历书与科举范文,早年积攒了数百道朱笔画痕,纵然三年无人问津,依旧稳如泰山地霸占着案头;而几部刚从南洋传译过来的精妙水利舆图,因刚刚入阁、正字尚少,哪怕天天有年轻官吏来借,只要合上书本,便立刻被扔回地库。木案成了一潭发臭的死水,新知的苗头被老朽的功劳簿活活扼死。

两任掌书官相继去职,文渊阁迎来了第三任白发掌事。

老掌事在案台前踱了三日,既不单取尝鲜,也不偏信常青,而是在沉香木案的正中央嵌了一根可左右滑动的紫檀算筹。

算筹将一百卷的案台划作两半: 左边叫尝鲜架,专放新近借阅过一次的书; 右边叫常青架,唯有借阅过两次及以上的熟书,才能升入此架。 两架合起来,实打实占满一百卷。算筹往左移,尝鲜架变小、常青架扩充;算筹往右移,常青架缩编、尝鲜架拓宽。

可这根算筹究竟该往哪边移?谁说了算?

老掌事的绝招,藏在案台底下的两只青铜细筒里。他命人裁剪了极细的纸条,立下两条名曰“游魂”的薄册: 第一册叫尝鲜游魂簿:凡在尝鲜架上被挤掉的书,真书送回地库,书名却写在细纸条上,塞进左边的铜筒; 第二册叫常青游魂簿:凡在常青架上被挤掉的熟书,真书送回地库,书名同样撕一张纸条,塞进右边的铜筒。

这两只铜筒里装的不是书,只是一缕缕书名的“游魂”,因此丝毫不占案头的一百卷实额。

奥妙随之而起。

若有学者来借书,案上没有,小厮伸手掏出左边的尝鲜游魂簿,眼睛一亮:“此书前些日子刚在尝鲜架上待过,尸骨未寒!” 老掌事当即下令:将紫檀算筹向右拨动一格,尝鲜架扩容一席,常青架腾退一席,并从小厮手里把那卷书接回案头。 “既然刚被赶走的书又被找了回来,说明眼下尝鲜架给窄了,朝廷正渴求新学,得给新书留更大的地盘!”

反之,若来客要的书在右边的常青游魂簿里现了身,老掌事立刻将算筹向左拨动一格: “常青架上的老朋友刚落入地库就被唤回,说明经典不可荒废,得把常青架的台面扩得更宽!”

更妙的是拨动的快慢。若是尝鲜簿里积压了上百张怨魂纸条,而常青簿里空空如也,算筹每一次向右滑动便快如飞矢;若是两边相若,算筹便小步微调。

自此,文渊阁案头的紫檀算筹像有了呼吸一般,随着全阁学士的借阅风尚自如摇摆。 遇到老学士通读百卷药谱,尝鲜架迅速吞吐,却丝毫不会伤及常青架上的治国大典;遇到治学研讨重温经籍,常青架便稳稳舒展,将常用工具书牢牢锁在案上。

不需要任何神机妙算的事前推测,也不需要哪位大人拍脑袋下令,几缕游魂与一根算筹,便让一座阁楼的百年藏书,活出了骨肉神采。

— — —

这是什么

这就是存储与操作系统领域被誉为最优雅、最具自适应能力的缓存淘汰算法——自适应替换缓存(Adaptive Replacement Cache,简称 ARC)。

在计算机缓存设计中,最核心的命题是在有限的内存空间(大小为 $c$)内决定“淘汰谁”:

  • LRU(Least Recently Used,最近最少使用):优先淘汰最久未被访问的数据。长于捕获数据的时效性(Recency),但极度脆弱于一次性全表扫描(Scan)——一个偶发的大遍历就会将长期高频的热点全部挤出缓存;
  • LFU(Least Frequently Used,最不经常使用):依据历史累计访问频次淘汰。长于捕获数据的频率(Frequency),但极难适应工作负载的动态迁移——过去频繁访问但已过时的“历史热点”会霸占缓存无法衰退,导致新数据无论多有价值都难以进入。

2003 年,IBM 科学家 Nimrod Megiddo 与 Dharmendra S. Modha 提出了 ARC 算法,彻底终结了 Recency 与 Frequency 之间长达数十年的非此即彼。

ARC 的核心架构由两个双向链表和两个虚拟“幽灵链表(Ghost Lists)”组成:

  1. $T_1$ 链表(Recency):存放最近仅被访问过一次的数据(物理驻留在缓存中);
  2. $T_2$ 链表(Frequency):存放近期被访问过两次及以上的数据(物理驻留在缓存中); $T_1 \cup T_2$ 的物理数据总和始终等于缓存容量上限 $c$。
  3. $B_1$ 幽灵链表(Recency Ghost):当 $T_1$ 满溢淘汰时,数据内容被丢弃,但其元数据标识(Key / Page ID)被移入 $B_1$ 记录,不占物理数据空间;
  4. $B_2$ 幽灵链表(Frequency Ghost):当 $T_2$ 满溢淘汰时,数据内容被丢弃,其元数据标识被移入 $B_2$ 记录。

整个算法的灵魂在于一个动态学习参数 $p$(目标分界线):

  • 当请求命中 $B_1$ 时,意味着系统最近对“新数据”误判了早衰,算法便增大 $p$,动态扩大 $T_1$ 的容量配额;
  • 当请求命中 $B_2$ 时,意味着系统最近对“常驻热点”剔除过急,算法便减小 $p$,将更多缓存配额偏向 $T_2$。
  • 调节的步长(Step Size)不是固定的,而是根据 $ B_2 / B_1 $ 或 $ B_1 / B_2 $ 的比率动态缩放——哪一边的幽灵更多,算筹朝哪边调节的推力就越强。

为什么重要

  • 零人工调优(Self-Tuning):系统在运行期自适应感知实际工作负载的访问特征(是突发批处理扫描,还是稳定循环热点),无需系统管理员手动配置命中权重或衰减周期;
  • 免疫扫描污染(Scan Resistance):当大规模顺序遍历爆发时,未命中两次的数据只会在 $T_1$ 内部快速周转流出并进入 $B_1$,绝不会污染和驱逐 $T_2$ 中积累的高频核心数据;
  • 极低的元数据开销:Ghost List 只保存数据项的哈希键或页号(数字节),却为调度器提供了长达一倍缓存深度的“历史悔棋视野”;
  • 工业界的黄金基准:ARC 成为了现代高性能文件系统(如 Sun/Oracle 的 ZFS 内核存储池)、分布式缓存和下一代通用数据库存储引擎对抗不可预测生产负载的核心基石。

隐喻对应表

  • 文渊阁长案限放一百卷书 → 物理缓存容量上限 $c$(快速内存(RAM)有限,能驻留的热数据总量受限)
  • 地底取书需费半个时辰 → 慢速底层存储(SSD / HDD)(缓存未命中(Cache Miss)时高昂的磁盘 I/O 代价)
  • 初任掌书官的尝鲜之法 → 经典 LRU(最近最少使用)(易受全量顺序扫描(Sequential Scan)污染致瘫痪)
  • 次任掌书官的划正字法 → 经典 LFU(最不经常使用)(历史热点阻碍新数据流入(Cache Pollution)且衰减复杂)
  • 正堂案头的尝鲜架 $T_1$ → $T_1$ 驻留链表(Recent Pages)(暂存仅被读取过一次的新数据页,占用物理内存)
  • 正堂案头的常青架 $T_2$ → $T_2$ 驻留链表(Frequent Pages)(存放至少读取过两次的高频数据页,占用物理内存)
  • 中央可滑动的紫檀算筹 → 目标分割参数 $p$(动态权衡 Recency 与 Frequency 占用预算的浮点阈值)
  • 案下铜筒里的两只游魂簿 → 幽灵元数据队列 $B_1$ 与 $B_2$(仅存 Key 不存 Payload 的 LRU 淘汰历史跟踪器)
  • 学者借书命中尝鲜簿 $B_1$ → $B_1$ Ghost Hit(幽灵命中)(说明工作负载偏向时效,自适应增大 $p$ 并扩容 $T_1$)
  • 学者借书命中常青簿 $B_2$ → $B_2$ Ghost Hit(幽灵命中)(说明工作负载偏向频次,自适应减小 $p$ 并扩容 $T_2$)
  • 怨魂纸条越多滑动越快 → 学习步长比率因子 $\Delta p$(按 $)

Inside the Donghua Gate of the Imperial City stood the Pavilion of Literary Abundance, guarding tens of thousands of classical scrolls and codices.

The subterranean vaults below were frigid and deep. To fetch a single text required runners with pine torches to descend three flights of damp stone steps and rummage through camphor chests for half an hour. To spare visiting scholars from endless waiting, the grand reading hall was furnished with a single long display table of polished aloeswood.

The table had strict physical limits: arranged end to end, it held exactly one hundred volumes. If a requested book rested on the table, a scholar could unfurl it in seconds; if it lay down below, one could only sit in silence while the runners ran through the dark vaults. Thus, which hundred volumes deserved a place upon that aloeswood table became the most vexing puzzle for the pavilion’s successive archivists.

The first archivist favored Recency. His rule was simple: whichever book had been read most recently was placed at the front of the table; when the hundred slots filled, the volume languishing longest at the far end was packed back down into the vault.

In ordinary times this sufficed, until one autumn, a scholar from the Ministry of Rites arrived to compile a compendium of obscure mountain herbs. For ten days behind closed doors, he summoned eighty rare, forgotten medicinal treatises from the vault, skimming each volume once. With every turn of an herb scroll, a classical chronicle was expelled from the table. Within three days, the Analects, the Records of the Grand Historian, and the Treatise on Architectural Methods were banished to the underworld, replaced entirely by treatises on wild moss and marsh grasses. When the herbalist departed and the imperial academies arrived for their daily studies, not a single foundational text remained; runners ran the stone stairs until their boots tore and their lungs burned.

The second archivist sought a cure by decreeing the rule of Frequency. On the ivory tag of every volume, he made a tally mark in vermillion ink each time it was read. Only the one hundred scrolls boasting the greatest cumulative tallies earned a seat on the table.

Yet within six months, this method hit an immovable wall. Dynastic examination primers and obsolete astronomical almanacs had amassed hundreds of historical marks over past decades. Though untouched for three years, they sat immovable upon the precious wood. Meanwhile, newly arrived charts on maritime irrigation, despite being requested daily by younger officials, could never overtake the ancient tallies and were swept underground the moment they were closed. The table stagnated into a swamp of old glory, smothering emerging wisdom under dead precedent.

Both archivists were dismissed in turn, making way for an old archivist whose beard was white as frost.

The elder spent three days pacing the table. He bowed neither to raw recency nor to stubborn frequency. Instead, he installed a movable sandalwood peg running inside a grooved track along the center of the aloeswood table.

The peg split the hundred-book table into two distinct regions: To the left was the Recent Shelf, holding books opened once in recent days; To the right was the Frequent Shelf, reserved solely for proven volumes summoned twice or more. Together, the two shelves held exactly one hundred physical volumes. Slide the peg left, and the Recent shelf shrank while the Frequent shelf expanded; slide it right, and the reverse took place.

Yet what guide should govern where the peg should slide?

The old master’s secret lay hidden within two slender bronze cylinders beneath the table. He cut strips of fine mulberry paper and hung two rolls termed the Ghost Ledgers: The first was the Recent Ghost Ledger: whenever a volume was evicted from the Recent Shelf, the physical codex returned to the vault, but its title slip was pinned inside the left bronze tube. The second was the Frequent Ghost Ledger: whenever a volume was evicted from the Frequent Shelf, the codex returned to the vault, while its title slip was pinned inside the right tube.

These cylinders held no heavy books, only ephemeral names on slips of paper; thus they consumed not a single inch of the precious hundred-volume table.

Here lay the wonder.

When a scholar asked for a book absent from the table, the runner looked into the left cylinder and cried: “This title was on our Recent shelf only days ago—its ink is barely cold!” The old archivist immediately ordered the sandalwood peg moved one notch to the right, widening the Recent shelf and narrowing the Frequent shelf, while the codex was brought back up to the table. “If an evicted recent title is summoned so soon,” the master reasoned, “our Recent shelf was starved. The court thirsts for fresh exploration; we must grant novelty more breathing room!”

Conversely, if a requested title emerged from the right cylinder—the Frequent Ghost Ledger—the master slid the peg left: “An old friend of the Frequent shelf was evicted and immediately needed! We must guard our lasting treasures and widen the Frequent domain!”

More ingenious still was the speed of the peg. If the Recent cylinder groaned with a hundred slips while the Frequent cylinder was bare, each slide to the right leaped by wide strides; when the two balanced, the peg drifted in microscopic increments.

From that hour forward, the sandalwood peg seemed to breathe in rhythm with the changing tides of the empire’s scholarship. When a scholar scanned dozens of herbal tracts, the Recent shelf accommodated the flow without ever disturbing the foundational canons anchored on the Frequent side. When the academy gathered for deep re-examination of ancient laws, the Frequent shelf expanded smoothly, holding the essential tools close at hand.

Without human guesswork, static rules, or decrees from on high, a handful of ghost slips and a sliding peg brought the living heart of tens of thousands of books into effortless, perpetual balance.

— — —

What it is

This is the algorithm widely celebrated as one of the most elegant and adaptive cache replacement policies in modern computing: the Adaptive Replacement Cache (ARC).

In cache architecture, the fundamental question is deciding which entry to evict when capacity $c$ is exhausted:

  • LRU (Least Recently Used): Evicts the item that has sat untouched the longest. It excels at capturing Recency, but collapses instantly in the face of sequential scans—a single bulk iteration flushes the entire working set out of memory;
  • LFU (Least Frequently Used): Evicts items with the lowest cumulative reference counts. It captures Frequency, but fails when workloads shift—stale “historical favorites” linger forever in memory, preventing newly valuable items from accumulating enough references to survive.

In 2003, Nimrod Megiddo and Dharmendra S. Modha of IBM Research introduced ARC, resolving the decades-old dichotomy between Recency and Frequency.

ARC organizes cache memory into two live lists and two virtual “Ghost Lists”:

  1. List $T_1$ (Recent): Contains pages accessed exactly once recently (physically present in cache);
  2. List $T_2$ (Frequent): Contains pages accessed at least twice recently (physically present in cache); The total number of physical pages across $T_1 \cup T_2$ is strictly capped at cache size $c$.
  3. Ghost List $B_1$ (Recent Metadata): When $T_1$ evicts an entry, its data payload is discarded, but its key/page identifier is retained in $B_1$. It consumes negligible memory;
  4. Ghost List $B_2$ (Frequent Metadata): When $T_2$ evicts an entry, its payload is discarded while its identifier is tracked in $B_2$.

The intelligence of the algorithm centers on a dynamic tuning parameter $p$ (the target partition boundary):

  • A hit in $B_1$ signals that recency was curtailed too aggressively; the algorithm increases $p$, shifting more cache budget toward $T_1$;
  • A hit in $B_2$ signals that frequent items were pruned prematurely; the algorithm decreases $p$, shifting budget back toward $T_2$.
  • The adjustment step $\Delta p$ is proportionally scaled by $ B_2 / B_1 $ or $ B_1 / B_2 $—the more slips that accumulate on one side, the more aggressively the boundary reacts.

Why it matters

  • Zero-Tuning Autonomics: ARC continuously reads the workload’s signature (whether dominated by exploratory scans or recurring hot loops) and recalibrates on the fly, eliminating brittle manual cache parameter tuning;
  • Scan Resistance: Sequential scans pass through $T_1$ and drain into $B_1$ without displacing the high-frequency items anchored securely in $T_2$;
  • Minimal Metadata Overhead: Ghost lists store only keys or hashes (a few bytes per entry), yet grant the cache a historical perspective equivalent to double the cache’s physical capacity;
  • Enterprise Foundation: ARC is the cornerstone of high-performance file systems (most notably the ZFS Adaptive Replacement Cache), modern SSD controllers, and high-throughput databases operating under volatile production workloads.

Metaphor mapping

  • Aloeswood table limited to 100 books → Physical cache capacity $c$ (Fast physical memory (RAM) holding a finite number of data blocks)
  • Thirty-minute vault fetch via torchlight → Slow backing storage (Disk / Network) (Cache miss requiring an expensive round-trip to secondary storage)
  • First archivist’s rule of recency → Classic LRU (Least Recently Used) (Susceptible to cache wipeout during full-table sequential scans)
  • Second archivist’s tally-mark rule → Classic LFU (Least Frequently Used) (Vulnerable to stale data pollution and unresponsive to workload drift)
  • Recent Shelf $T_1$ on the table → Cache list $T_1$ (Recent pages) (Houses pages referenced only once recently; physically resident in RAM)
  • Frequent Shelf $T_2$ on the table → Cache list $T_2$ (Frequent pages) (Houses pages referenced $\ge 2$ times; physically resident in RAM)
  • Sliding sandalwood peg → Target partition parameter $p$ (Floating threshold dynamically sizing the target capacity of $T_1$ vs $T_2$)
  • Ghost Ledgers $B_1$ and $B_2$ under the table → Virtual Ghost Lists $B_1$ and $B_2$ (Stores page keys/hashes without payloads to track eviction regret)
  • Scholar requesting a title in $B_1$ → Hit in Ghost List $B_1$ (Workload demands recency; increments $p$ to enlarge $T_1$ allocation)
  • Scholar requesting a title in $B_2$ → Hit in Ghost List $B_2$ (Workload demands frequency; decrements $p$ to enlarge $T_2$ allocation)
  • Peg sliding faster when one tube is full → Dynamic learning step size $\Delta p$ (Proportional step sizing scaled by $)
Daily Fables每日寓言 2026-09-11