Memcache 深度解析 ------ 那个被 Redis 抢了风头但还在默默搬砖的老伙计
有人说 Memcache 已经死了,我说:你才死了,你全家都死了! 它只是低调得像你那个从不发朋友圈但工资最高的同事。
一、一句话介绍
Memcache 是一个高性能、分布式内存对象缓存系统。说人话就是:把数据库里查出来的数据往内存里一塞,下次再查就直接从内存拿,快到飞起。
二、整体架构
2.1 架构全景图(Mermaid 版)
#mermaid-svg-VbCwG4gKMzxnj4yK{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-VbCwG4gKMzxnj4yK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-VbCwG4gKMzxnj4yK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-VbCwG4gKMzxnj4yK .error-icon{fill:#552222;}#mermaid-svg-VbCwG4gKMzxnj4yK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VbCwG4gKMzxnj4yK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-VbCwG4gKMzxnj4yK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VbCwG4gKMzxnj4yK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VbCwG4gKMzxnj4yK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-VbCwG4gKMzxnj4yK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VbCwG4gKMzxnj4yK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VbCwG4gKMzxnj4yK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VbCwG4gKMzxnj4yK .marker.cross{stroke:#333333;}#mermaid-svg-VbCwG4gKMzxnj4yK svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VbCwG4gKMzxnj4yK p{margin:0;}#mermaid-svg-VbCwG4gKMzxnj4yK .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-VbCwG4gKMzxnj4yK .cluster-label text{fill:#333;}#mermaid-svg-VbCwG4gKMzxnj4yK .cluster-label span{color:#333;}#mermaid-svg-VbCwG4gKMzxnj4yK .cluster-label span p{background-color:transparent;}#mermaid-svg-VbCwG4gKMzxnj4yK .label text,#mermaid-svg-VbCwG4gKMzxnj4yK span{fill:#333;color:#333;}#mermaid-svg-VbCwG4gKMzxnj4yK .node rect,#mermaid-svg-VbCwG4gKMzxnj4yK .node circle,#mermaid-svg-VbCwG4gKMzxnj4yK .node ellipse,#mermaid-svg-VbCwG4gKMzxnj4yK .node polygon,#mermaid-svg-VbCwG4gKMzxnj4yK .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-VbCwG4gKMzxnj4yK .rough-node .label text,#mermaid-svg-VbCwG4gKMzxnj4yK .node .label text,#mermaid-svg-VbCwG4gKMzxnj4yK .image-shape .label,#mermaid-svg-VbCwG4gKMzxnj4yK .icon-shape .label{text-anchor:middle;}#mermaid-svg-VbCwG4gKMzxnj4yK .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-VbCwG4gKMzxnj4yK .rough-node .label,#mermaid-svg-VbCwG4gKMzxnj4yK .node .label,#mermaid-svg-VbCwG4gKMzxnj4yK .image-shape .label,#mermaid-svg-VbCwG4gKMzxnj4yK .icon-shape .label{text-align:center;}#mermaid-svg-VbCwG4gKMzxnj4yK .node.clickable{cursor:pointer;}#mermaid-svg-VbCwG4gKMzxnj4yK .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-VbCwG4gKMzxnj4yK .arrowheadPath{fill:#333333;}#mermaid-svg-VbCwG4gKMzxnj4yK .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-VbCwG4gKMzxnj4yK .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-VbCwG4gKMzxnj4yK .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VbCwG4gKMzxnj4yK .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-VbCwG4gKMzxnj4yK .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VbCwG4gKMzxnj4yK .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-VbCwG4gKMzxnj4yK .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-VbCwG4gKMzxnj4yK .cluster text{fill:#333;}#mermaid-svg-VbCwG4gKMzxnj4yK .cluster span{color:#333;}#mermaid-svg-VbCwG4gKMzxnj4yK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-VbCwG4gKMzxnj4yK .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-VbCwG4gKMzxnj4yK rect.text{fill:none;stroke-width:0;}#mermaid-svg-VbCwG4gKMzxnj4yK .icon-shape,#mermaid-svg-VbCwG4gKMzxnj4yK .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VbCwG4gKMzxnj4yK .icon-shape p,#mermaid-svg-VbCwG4gKMzxnj4yK .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-VbCwG4gKMzxnj4yK .icon-shape .label rect,#mermaid-svg-VbCwG4gKMzxnj4yK .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VbCwG4gKMzxnj4yK .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-VbCwG4gKMzxnj4yK .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-VbCwG4gKMzxnj4yK :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 🗄️ 数据持久层
🐘 Memcache 集群
👤 客户端层
缓存未命中
缓存未命中
缓存未命中
写入缓存
写入缓存
写入缓存
SpringBoot App #1
SpringBoot App #2
SpringBoot App #3
Memcache Node-1
127.0.0.1:11211
Memcache Node-2
127.0.0.1:11212
Memcache Node-3
127.0.0.1:11213
MySQL / PostgreSQL
慢如蜗牛但靠谱
2.2 内部架构
#mermaid-svg-7gjVT5qLc73yLXE6{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-7gjVT5qLc73yLXE6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-7gjVT5qLc73yLXE6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-7gjVT5qLc73yLXE6 .error-icon{fill:#552222;}#mermaid-svg-7gjVT5qLc73yLXE6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-7gjVT5qLc73yLXE6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-7gjVT5qLc73yLXE6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-7gjVT5qLc73yLXE6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-7gjVT5qLc73yLXE6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-7gjVT5qLc73yLXE6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-7gjVT5qLc73yLXE6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-7gjVT5qLc73yLXE6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-7gjVT5qLc73yLXE6 .marker.cross{stroke:#333333;}#mermaid-svg-7gjVT5qLc73yLXE6 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-7gjVT5qLc73yLXE6 p{margin:0;}#mermaid-svg-7gjVT5qLc73yLXE6 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-7gjVT5qLc73yLXE6 .cluster-label text{fill:#333;}#mermaid-svg-7gjVT5qLc73yLXE6 .cluster-label span{color:#333;}#mermaid-svg-7gjVT5qLc73yLXE6 .cluster-label span p{background-color:transparent;}#mermaid-svg-7gjVT5qLc73yLXE6 .label text,#mermaid-svg-7gjVT5qLc73yLXE6 span{fill:#333;color:#333;}#mermaid-svg-7gjVT5qLc73yLXE6 .node rect,#mermaid-svg-7gjVT5qLc73yLXE6 .node circle,#mermaid-svg-7gjVT5qLc73yLXE6 .node ellipse,#mermaid-svg-7gjVT5qLc73yLXE6 .node polygon,#mermaid-svg-7gjVT5qLc73yLXE6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-7gjVT5qLc73yLXE6 .rough-node .label text,#mermaid-svg-7gjVT5qLc73yLXE6 .node .label text,#mermaid-svg-7gjVT5qLc73yLXE6 .image-shape .label,#mermaid-svg-7gjVT5qLc73yLXE6 .icon-shape .label{text-anchor:middle;}#mermaid-svg-7gjVT5qLc73yLXE6 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-7gjVT5qLc73yLXE6 .rough-node .label,#mermaid-svg-7gjVT5qLc73yLXE6 .node .label,#mermaid-svg-7gjVT5qLc73yLXE6 .image-shape .label,#mermaid-svg-7gjVT5qLc73yLXE6 .icon-shape .label{text-align:center;}#mermaid-svg-7gjVT5qLc73yLXE6 .node.clickable{cursor:pointer;}#mermaid-svg-7gjVT5qLc73yLXE6 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-7gjVT5qLc73yLXE6 .arrowheadPath{fill:#333333;}#mermaid-svg-7gjVT5qLc73yLXE6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-7gjVT5qLc73yLXE6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-7gjVT5qLc73yLXE6 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7gjVT5qLc73yLXE6 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-7gjVT5qLc73yLXE6 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7gjVT5qLc73yLXE6 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-7gjVT5qLc73yLXE6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-7gjVT5qLc73yLXE6 .cluster text{fill:#333;}#mermaid-svg-7gjVT5qLc73yLXE6 .cluster span{color:#333;}#mermaid-svg-7gjVT5qLc73yLXE6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-7gjVT5qLc73yLXE6 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-7gjVT5qLc73yLXE6 rect.text{fill:none;stroke-width:0;}#mermaid-svg-7gjVT5qLc73yLXE6 .icon-shape,#mermaid-svg-7gjVT5qLc73yLXE6 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7gjVT5qLc73yLXE6 .icon-shape p,#mermaid-svg-7gjVT5qLc73yLXE6 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-7gjVT5qLc73yLXE6 .icon-shape .label rect,#mermaid-svg-7gjVT5qLc73yLXE6 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7gjVT5qLc73yLXE6 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-7gjVT5qLc73yLXE6 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-7gjVT5qLc73yLXE6 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 🔧 Memcache 内部结构
网络层
libevent 事件驱动
单线程但贼快
Slab Allocator
内存管理器
专治内存碎片
LRU 淘汰机制
不用的数据?
踢出去!
Hash 表
O(1) 查找
比找对象快多了
请求来了!
返回结果 / 踢老数据
2.3 Slab Allocation 内存管理(Memcache 的灵魂)
#mermaid-svg-s2xNFbxByNsXRyhH{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-s2xNFbxByNsXRyhH .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-s2xNFbxByNsXRyhH .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-s2xNFbxByNsXRyhH .error-icon{fill:#552222;}#mermaid-svg-s2xNFbxByNsXRyhH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-s2xNFbxByNsXRyhH .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-s2xNFbxByNsXRyhH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-s2xNFbxByNsXRyhH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-s2xNFbxByNsXRyhH .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-s2xNFbxByNsXRyhH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-s2xNFbxByNsXRyhH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-s2xNFbxByNsXRyhH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-s2xNFbxByNsXRyhH .marker.cross{stroke:#333333;}#mermaid-svg-s2xNFbxByNsXRyhH svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-s2xNFbxByNsXRyhH p{margin:0;}#mermaid-svg-s2xNFbxByNsXRyhH .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-s2xNFbxByNsXRyhH .cluster-label text{fill:#333;}#mermaid-svg-s2xNFbxByNsXRyhH .cluster-label span{color:#333;}#mermaid-svg-s2xNFbxByNsXRyhH .cluster-label span p{background-color:transparent;}#mermaid-svg-s2xNFbxByNsXRyhH .label text,#mermaid-svg-s2xNFbxByNsXRyhH span{fill:#333;color:#333;}#mermaid-svg-s2xNFbxByNsXRyhH .node rect,#mermaid-svg-s2xNFbxByNsXRyhH .node circle,#mermaid-svg-s2xNFbxByNsXRyhH .node ellipse,#mermaid-svg-s2xNFbxByNsXRyhH .node polygon,#mermaid-svg-s2xNFbxByNsXRyhH .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-s2xNFbxByNsXRyhH .rough-node .label text,#mermaid-svg-s2xNFbxByNsXRyhH .node .label text,#mermaid-svg-s2xNFbxByNsXRyhH .image-shape .label,#mermaid-svg-s2xNFbxByNsXRyhH .icon-shape .label{text-anchor:middle;}#mermaid-svg-s2xNFbxByNsXRyhH .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-s2xNFbxByNsXRyhH .rough-node .label,#mermaid-svg-s2xNFbxByNsXRyhH .node .label,#mermaid-svg-s2xNFbxByNsXRyhH .image-shape .label,#mermaid-svg-s2xNFbxByNsXRyhH .icon-shape .label{text-align:center;}#mermaid-svg-s2xNFbxByNsXRyhH .node.clickable{cursor:pointer;}#mermaid-svg-s2xNFbxByNsXRyhH .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-s2xNFbxByNsXRyhH .arrowheadPath{fill:#333333;}#mermaid-svg-s2xNFbxByNsXRyhH .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-s2xNFbxByNsXRyhH .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-s2xNFbxByNsXRyhH .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-s2xNFbxByNsXRyhH .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-s2xNFbxByNsXRyhH .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-s2xNFbxByNsXRyhH .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-s2xNFbxByNsXRyhH .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-s2xNFbxByNsXRyhH .cluster text{fill:#333;}#mermaid-svg-s2xNFbxByNsXRyhH .cluster span{color:#333;}#mermaid-svg-s2xNFbxByNsXRyhH div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-s2xNFbxByNsXRyhH .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-s2xNFbxByNsXRyhH rect.text{fill:none;stroke-width:0;}#mermaid-svg-s2xNFbxByNsXRyhH .icon-shape,#mermaid-svg-s2xNFbxByNsXRyhH .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-s2xNFbxByNsXRyhH .icon-shape p,#mermaid-svg-s2xNFbxByNsXRyhH .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-s2xNFbxByNsXRyhH .icon-shape .label rect,#mermaid-svg-s2xNFbxByNsXRyhH .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-s2xNFbxByNsXRyhH .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-s2xNFbxByNsXRyhH .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-s2xNFbxByNsXRyhH :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 📦 Slab Class 分级
💾 总内存 1GB
Page
1MB
Page
1MB
Page
1MB
...
Slab Class 1
Chunk: 96 bytes
Slab Class 2
Chunk: 120 bytes
Slab Class 3
Chunk: 152 bytes
Slab Class N
Chunk: 更大...
⚠️ 冷知识 :Memcache 把内存切成固定大小的 Chunk,就像大学宿舍------不管你是 1 个行李箱还是 10 个,每个床位面积都一样。这虽然有点浪费,但分配回收快啊!
2.4 分布式------一致性哈希
#mermaid-svg-4gXAfjoxWW3zT39s{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-4gXAfjoxWW3zT39s .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4gXAfjoxWW3zT39s .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4gXAfjoxWW3zT39s .error-icon{fill:#552222;}#mermaid-svg-4gXAfjoxWW3zT39s .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4gXAfjoxWW3zT39s .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4gXAfjoxWW3zT39s .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4gXAfjoxWW3zT39s .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4gXAfjoxWW3zT39s .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4gXAfjoxWW3zT39s .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4gXAfjoxWW3zT39s .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4gXAfjoxWW3zT39s .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4gXAfjoxWW3zT39s .marker.cross{stroke:#333333;}#mermaid-svg-4gXAfjoxWW3zT39s svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4gXAfjoxWW3zT39s p{margin:0;}#mermaid-svg-4gXAfjoxWW3zT39s .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-4gXAfjoxWW3zT39s .cluster-label text{fill:#333;}#mermaid-svg-4gXAfjoxWW3zT39s .cluster-label span{color:#333;}#mermaid-svg-4gXAfjoxWW3zT39s .cluster-label span p{background-color:transparent;}#mermaid-svg-4gXAfjoxWW3zT39s .label text,#mermaid-svg-4gXAfjoxWW3zT39s span{fill:#333;color:#333;}#mermaid-svg-4gXAfjoxWW3zT39s .node rect,#mermaid-svg-4gXAfjoxWW3zT39s .node circle,#mermaid-svg-4gXAfjoxWW3zT39s .node ellipse,#mermaid-svg-4gXAfjoxWW3zT39s .node polygon,#mermaid-svg-4gXAfjoxWW3zT39s .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4gXAfjoxWW3zT39s .rough-node .label text,#mermaid-svg-4gXAfjoxWW3zT39s .node .label text,#mermaid-svg-4gXAfjoxWW3zT39s .image-shape .label,#mermaid-svg-4gXAfjoxWW3zT39s .icon-shape .label{text-anchor:middle;}#mermaid-svg-4gXAfjoxWW3zT39s .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-4gXAfjoxWW3zT39s .rough-node .label,#mermaid-svg-4gXAfjoxWW3zT39s .node .label,#mermaid-svg-4gXAfjoxWW3zT39s .image-shape .label,#mermaid-svg-4gXAfjoxWW3zT39s .icon-shape .label{text-align:center;}#mermaid-svg-4gXAfjoxWW3zT39s .node.clickable{cursor:pointer;}#mermaid-svg-4gXAfjoxWW3zT39s .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-4gXAfjoxWW3zT39s .arrowheadPath{fill:#333333;}#mermaid-svg-4gXAfjoxWW3zT39s .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-4gXAfjoxWW3zT39s .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-4gXAfjoxWW3zT39s .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4gXAfjoxWW3zT39s .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-4gXAfjoxWW3zT39s .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4gXAfjoxWW3zT39s .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-4gXAfjoxWW3zT39s .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-4gXAfjoxWW3zT39s .cluster text{fill:#333;}#mermaid-svg-4gXAfjoxWW3zT39s .cluster span{color:#333;}#mermaid-svg-4gXAfjoxWW3zT39s div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-4gXAfjoxWW3zT39s .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-4gXAfjoxWW3zT39s rect.text{fill:none;stroke-width:0;}#mermaid-svg-4gXAfjoxWW3zT39s .icon-shape,#mermaid-svg-4gXAfjoxWW3zT39s .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4gXAfjoxWW3zT39s .icon-shape p,#mermaid-svg-4gXAfjoxWW3zT39s .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-4gXAfjoxWW3zT39s .icon-shape .label rect,#mermaid-svg-4gXAfjoxWW3zT39s .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4gXAfjoxWW3zT39s .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-4gXAfjoxWW3zT39s .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-4gXAfjoxWW3zT39s :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 🔵 一致性哈希环 0 ~ 2^32-1
Node A
哈希值: 1000
Node B
哈希值: 1亿
Node C
哈希值: 30亿
Key: user_100
哈希: 500 → 路由到 Node A
Key: user_200
哈希: 2亿 → 路由到 Node B
Key: user_300
哈希: 35亿 → 路由到 Node C
💡 关键理解 :Memcache 自身不搞分布式 ,节点之间老死不相往来,各管各的。分布式全靠客户端 用一致性哈希算出来 Key 该扔给哪个节点。这就是传说中的------各人自扫门前雪 架构。
三、使用场景
3.1 典型场景全景图
#mermaid-svg-AxomwgbW6H53hXvG{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-AxomwgbW6H53hXvG .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-AxomwgbW6H53hXvG .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-AxomwgbW6H53hXvG .error-icon{fill:#552222;}#mermaid-svg-AxomwgbW6H53hXvG .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-AxomwgbW6H53hXvG .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-AxomwgbW6H53hXvG .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-AxomwgbW6H53hXvG .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-AxomwgbW6H53hXvG .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-AxomwgbW6H53hXvG .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-AxomwgbW6H53hXvG .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-AxomwgbW6H53hXvG .marker{fill:#333333;stroke:#333333;}#mermaid-svg-AxomwgbW6H53hXvG .marker.cross{stroke:#333333;}#mermaid-svg-AxomwgbW6H53hXvG svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-AxomwgbW6H53hXvG p{margin:0;}#mermaid-svg-AxomwgbW6H53hXvG .edge{stroke-width:3;}#mermaid-svg-AxomwgbW6H53hXvG .section--1 rect,#mermaid-svg-AxomwgbW6H53hXvG .section--1 path,#mermaid-svg-AxomwgbW6H53hXvG .section--1 circle,#mermaid-svg-AxomwgbW6H53hXvG .section--1 polygon,#mermaid-svg-AxomwgbW6H53hXvG .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .section--1 text{fill:#ffffff;}#mermaid-svg-AxomwgbW6H53hXvG .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-AxomwgbW6H53hXvG .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .edge-depth--1{stroke-width:17;}#mermaid-svg-AxomwgbW6H53hXvG .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AxomwgbW6H53hXvG .disabled,#mermaid-svg-AxomwgbW6H53hXvG .disabled circle,#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:lightgray;}#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:#efefef;}#mermaid-svg-AxomwgbW6H53hXvG .section-0 rect,#mermaid-svg-AxomwgbW6H53hXvG .section-0 path,#mermaid-svg-AxomwgbW6H53hXvG .section-0 circle,#mermaid-svg-AxomwgbW6H53hXvG .section-0 polygon,#mermaid-svg-AxomwgbW6H53hXvG .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-AxomwgbW6H53hXvG .section-0 text{fill:black;}#mermaid-svg-AxomwgbW6H53hXvG .node-icon-0{font-size:40px;color:black;}#mermaid-svg-AxomwgbW6H53hXvG .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-AxomwgbW6H53hXvG .edge-depth-0{stroke-width:14;}#mermaid-svg-AxomwgbW6H53hXvG .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-AxomwgbW6H53hXvG .disabled,#mermaid-svg-AxomwgbW6H53hXvG .disabled circle,#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:lightgray;}#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:#efefef;}#mermaid-svg-AxomwgbW6H53hXvG .section-1 rect,#mermaid-svg-AxomwgbW6H53hXvG .section-1 path,#mermaid-svg-AxomwgbW6H53hXvG .section-1 circle,#mermaid-svg-AxomwgbW6H53hXvG .section-1 polygon,#mermaid-svg-AxomwgbW6H53hXvG .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .section-1 text{fill:black;}#mermaid-svg-AxomwgbW6H53hXvG .node-icon-1{font-size:40px;color:black;}#mermaid-svg-AxomwgbW6H53hXvG .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .edge-depth-1{stroke-width:11;}#mermaid-svg-AxomwgbW6H53hXvG .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AxomwgbW6H53hXvG .disabled,#mermaid-svg-AxomwgbW6H53hXvG .disabled circle,#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:lightgray;}#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:#efefef;}#mermaid-svg-AxomwgbW6H53hXvG .section-2 rect,#mermaid-svg-AxomwgbW6H53hXvG .section-2 path,#mermaid-svg-AxomwgbW6H53hXvG .section-2 circle,#mermaid-svg-AxomwgbW6H53hXvG .section-2 polygon,#mermaid-svg-AxomwgbW6H53hXvG .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .section-2 text{fill:#ffffff;}#mermaid-svg-AxomwgbW6H53hXvG .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-AxomwgbW6H53hXvG .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .edge-depth-2{stroke-width:8;}#mermaid-svg-AxomwgbW6H53hXvG .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AxomwgbW6H53hXvG .disabled,#mermaid-svg-AxomwgbW6H53hXvG .disabled circle,#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:lightgray;}#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:#efefef;}#mermaid-svg-AxomwgbW6H53hXvG .section-3 rect,#mermaid-svg-AxomwgbW6H53hXvG .section-3 path,#mermaid-svg-AxomwgbW6H53hXvG .section-3 circle,#mermaid-svg-AxomwgbW6H53hXvG .section-3 polygon,#mermaid-svg-AxomwgbW6H53hXvG .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .section-3 text{fill:black;}#mermaid-svg-AxomwgbW6H53hXvG .node-icon-3{font-size:40px;color:black;}#mermaid-svg-AxomwgbW6H53hXvG .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .edge-depth-3{stroke-width:5;}#mermaid-svg-AxomwgbW6H53hXvG .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AxomwgbW6H53hXvG .disabled,#mermaid-svg-AxomwgbW6H53hXvG .disabled circle,#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:lightgray;}#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:#efefef;}#mermaid-svg-AxomwgbW6H53hXvG .section-4 rect,#mermaid-svg-AxomwgbW6H53hXvG .section-4 path,#mermaid-svg-AxomwgbW6H53hXvG .section-4 circle,#mermaid-svg-AxomwgbW6H53hXvG .section-4 polygon,#mermaid-svg-AxomwgbW6H53hXvG .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .section-4 text{fill:black;}#mermaid-svg-AxomwgbW6H53hXvG .node-icon-4{font-size:40px;color:black;}#mermaid-svg-AxomwgbW6H53hXvG .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .edge-depth-4{stroke-width:2;}#mermaid-svg-AxomwgbW6H53hXvG .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AxomwgbW6H53hXvG .disabled,#mermaid-svg-AxomwgbW6H53hXvG .disabled circle,#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:lightgray;}#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:#efefef;}#mermaid-svg-AxomwgbW6H53hXvG .section-5 rect,#mermaid-svg-AxomwgbW6H53hXvG .section-5 path,#mermaid-svg-AxomwgbW6H53hXvG .section-5 circle,#mermaid-svg-AxomwgbW6H53hXvG .section-5 polygon,#mermaid-svg-AxomwgbW6H53hXvG .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .section-5 text{fill:black;}#mermaid-svg-AxomwgbW6H53hXvG .node-icon-5{font-size:40px;color:black;}#mermaid-svg-AxomwgbW6H53hXvG .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .edge-depth-5{stroke-width:-1;}#mermaid-svg-AxomwgbW6H53hXvG .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AxomwgbW6H53hXvG .disabled,#mermaid-svg-AxomwgbW6H53hXvG .disabled circle,#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:lightgray;}#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:#efefef;}#mermaid-svg-AxomwgbW6H53hXvG .section-6 rect,#mermaid-svg-AxomwgbW6H53hXvG .section-6 path,#mermaid-svg-AxomwgbW6H53hXvG .section-6 circle,#mermaid-svg-AxomwgbW6H53hXvG .section-6 polygon,#mermaid-svg-AxomwgbW6H53hXvG .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .section-6 text{fill:black;}#mermaid-svg-AxomwgbW6H53hXvG .node-icon-6{font-size:40px;color:black;}#mermaid-svg-AxomwgbW6H53hXvG .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .edge-depth-6{stroke-width:-4;}#mermaid-svg-AxomwgbW6H53hXvG .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AxomwgbW6H53hXvG .disabled,#mermaid-svg-AxomwgbW6H53hXvG .disabled circle,#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:lightgray;}#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:#efefef;}#mermaid-svg-AxomwgbW6H53hXvG .section-7 rect,#mermaid-svg-AxomwgbW6H53hXvG .section-7 path,#mermaid-svg-AxomwgbW6H53hXvG .section-7 circle,#mermaid-svg-AxomwgbW6H53hXvG .section-7 polygon,#mermaid-svg-AxomwgbW6H53hXvG .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .section-7 text{fill:black;}#mermaid-svg-AxomwgbW6H53hXvG .node-icon-7{font-size:40px;color:black;}#mermaid-svg-AxomwgbW6H53hXvG .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .edge-depth-7{stroke-width:-7;}#mermaid-svg-AxomwgbW6H53hXvG .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AxomwgbW6H53hXvG .disabled,#mermaid-svg-AxomwgbW6H53hXvG .disabled circle,#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:lightgray;}#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:#efefef;}#mermaid-svg-AxomwgbW6H53hXvG .section-8 rect,#mermaid-svg-AxomwgbW6H53hXvG .section-8 path,#mermaid-svg-AxomwgbW6H53hXvG .section-8 circle,#mermaid-svg-AxomwgbW6H53hXvG .section-8 polygon,#mermaid-svg-AxomwgbW6H53hXvG .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .section-8 text{fill:black;}#mermaid-svg-AxomwgbW6H53hXvG .node-icon-8{font-size:40px;color:black;}#mermaid-svg-AxomwgbW6H53hXvG .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .edge-depth-8{stroke-width:-10;}#mermaid-svg-AxomwgbW6H53hXvG .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AxomwgbW6H53hXvG .disabled,#mermaid-svg-AxomwgbW6H53hXvG .disabled circle,#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:lightgray;}#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:#efefef;}#mermaid-svg-AxomwgbW6H53hXvG .section-9 rect,#mermaid-svg-AxomwgbW6H53hXvG .section-9 path,#mermaid-svg-AxomwgbW6H53hXvG .section-9 circle,#mermaid-svg-AxomwgbW6H53hXvG .section-9 polygon,#mermaid-svg-AxomwgbW6H53hXvG .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .section-9 text{fill:black;}#mermaid-svg-AxomwgbW6H53hXvG .node-icon-9{font-size:40px;color:black;}#mermaid-svg-AxomwgbW6H53hXvG .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .edge-depth-9{stroke-width:-13;}#mermaid-svg-AxomwgbW6H53hXvG .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AxomwgbW6H53hXvG .disabled,#mermaid-svg-AxomwgbW6H53hXvG .disabled circle,#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:lightgray;}#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:#efefef;}#mermaid-svg-AxomwgbW6H53hXvG .section-10 rect,#mermaid-svg-AxomwgbW6H53hXvG .section-10 path,#mermaid-svg-AxomwgbW6H53hXvG .section-10 circle,#mermaid-svg-AxomwgbW6H53hXvG .section-10 polygon,#mermaid-svg-AxomwgbW6H53hXvG .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .section-10 text{fill:black;}#mermaid-svg-AxomwgbW6H53hXvG .node-icon-10{font-size:40px;color:black;}#mermaid-svg-AxomwgbW6H53hXvG .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .edge-depth-10{stroke-width:-16;}#mermaid-svg-AxomwgbW6H53hXvG .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AxomwgbW6H53hXvG .disabled,#mermaid-svg-AxomwgbW6H53hXvG .disabled circle,#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:lightgray;}#mermaid-svg-AxomwgbW6H53hXvG .disabled text{fill:#efefef;}#mermaid-svg-AxomwgbW6H53hXvG .section-root rect,#mermaid-svg-AxomwgbW6H53hXvG .section-root path,#mermaid-svg-AxomwgbW6H53hXvG .section-root circle,#mermaid-svg-AxomwgbW6H53hXvG .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-AxomwgbW6H53hXvG .section-root text{fill:#ffffff;}#mermaid-svg-AxomwgbW6H53hXvG .section-root span{color:#ffffff;}#mermaid-svg-AxomwgbW6H53hXvG .section-2 span{color:#ffffff;}#mermaid-svg-AxomwgbW6H53hXvG .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-AxomwgbW6H53hXvG .edge{fill:none;}#mermaid-svg-AxomwgbW6H53hXvG .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-AxomwgbW6H53hXvG :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Memcache
使用场景
页面缓存
HTML片段缓存
商品详情页
新闻列表页
Session共享
多Tomcat集群
Spring Session
登录状态保持
数据库查询缓存
热门商品列表
用户基本信息
配置项缓存
临时数据
验证码
接口限流计数器
CSRF Token
排行榜
简单的计数排行
PV/UV统计
3.2 什么时候用 Memcache,而不是 Redis?
| 场景 | 选 Memcache ✅ | 选 Redis 🚀 | 原因 |
|---|---|---|---|
| 简单 KV 缓存 | ✅ | ✅ | 都能干 |
| 只需 GET/SET | ✅ | ✅ | Memcache 更轻 |
| 需要持久化 | ❌ | ✅ | Memcache 重启数据就没了 |
| 需要 List/Hash/Set/ZSet | ❌ | ✅ | Memcache 只支持 String |
| 需要发布订阅 | ❌ | ✅ | Memcache 没有 |
| 需要事务/Lua 脚本 | ❌ | ✅ | Memcache 就是个傻快的 KV |
| 多核 CPU 场景 | ✅ | ⚠️ | Memcache 天然多线程 |
| 内存碎片敏感 | ✅ | ⚠️ | Slab 分配器更可控 |
四、市场份额
#mermaid-svg-0Oq1EmmeRdoIk3Ff{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0Oq1EmmeRdoIk3Ff .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .error-icon{fill:#552222;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .marker.cross{stroke:#333333;}#mermaid-svg-0Oq1EmmeRdoIk3Ff svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0Oq1EmmeRdoIk3Ff p{margin:0;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .pieCircle{stroke:#000000;stroke-width:2px;opacity:0.7;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .pieOuterCircle{stroke:#000000;stroke-width:1px;fill:none;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .pieTitleText{text-anchor:middle;font-size:25px;fill:#000000;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .slice{font-family:"trebuchet ms",verdana,arial,sans-serif;fill:#000000;font-size:17px;}#mermaid-svg-0Oq1EmmeRdoIk3Ff .legend text{fill:#000000;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:17px;}#mermaid-svg-0Oq1EmmeRdoIk3Ff :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 65% 18% 5% 5% 4% 3% 缓存中间件市场份额() Redis Memcache Hazelcast Couchbase Ehcache 其他
趋势解读:
- 🔴 Redis 确实一家独大,65%+ 的份额,独孤求败
- 🟡 Memcache 守住 ~18% 阵地,主要靠老牌互联网公司和简单场景
- 🟢 但注意:Facebook/Twitter/YouTube 等大厂还在重度使用 Memcache,毕竟人家祖传代码跑得好好的,凭啥换?
有个段子说得好:"Redis 是缓存界的瑞士军刀,Memcache 是缓存界的一把大铁锤。你只需要砸钉子的时候,锤子比军刀好用。"
五、常用命令
Memcache 的命令简单到令人发指,一共就十几个,跟 Redis 的上百个命令比简直小清新。
5.1 基本 CRUD
| 命令 | 语法 | 说明 | 人类翻译 |
|---|---|---|---|
set |
set <key> <flags> <exptime> <bytes>\r\n<value> |
存数据 | 给我存,有就覆盖 |
add |
add <key> <flags> <exptime> <bytes>\r\n<value> |
存数据(不存在才存) | 如果没人抢,我再存 |
replace |
replace <key> <flags> <exptime> <bytes>\r\n<value> |
替换已有数据 | 没有就别瞎存 |
get |
get <key> |
取数据 | 给我拿出来! |
gets |
gets <key> |
取数据 + CAS token | 拿出来,顺便给个版本号 |
delete |
delete <key> |
删数据 | 滚蛋! |
cas |
cas <key> <flags> <exptime> <bytes> <cas_token>\r\n<value> |
乐观锁更新 | 版本号对上了才给你改 |
5.2 进阶命令
| 命令 | 语法 | 说明 |
|---|---|---|
append |
append <key> <flags> <exptime> <bytes>\r\n<追加内容> |
往后面加东西 |
prepend |
prepend <key> <flags> <exptime> <bytes>\r\n<前置内容> |
往前面加东西 |
incr |
incr <key> <value> |
数值 +N |
decr |
decr <key> <value> |
数值 -N |
stats |
stats |
看运行状态 |
flush_all |
flush_all |
清空所有数据(慎用!堪比 rm -rf) |
5.3 Telnet 实战演示
bash
# 连上 Memcache(用 telnet,这很复古)
telnet 127.0.0.1 11211
# 存一个值
set username 0 3600 5
hello
STORED
# 取出来
get username
VALUE username 0 5
hello
END
# 让计数器 +1
set counter 0 0 1
1
STORED
incr counter 1
2
# 看看服务器状态
stats
STAT pid 12345
STAT uptime 86400
STAT time 1718265600
STAT version 1.6.21
STAT curr_items 1000
STAT total_items 50000
STAT bytes 104857600
STAT get_hits 999999
STAT get_misses 42
...
END
# 退出
quit
🎯 注意
exptime参数:0 表示永不过期(直到被 LRU 踢掉),秒级 Unix 时间戳(大于 30 天自动转换)。超过 30 天的时间戳处理是 Memcache 的特色魔法。
六、Java / SpringBoot 使用案例
6.1 添加依赖
xml
<!-- pom.xml -->
<dependency>
<groupId>net.spy</groupId>
<artifactId>spymemcached</artifactId>
<version>2.12.3</version>
</dependency>
<!-- Spring Cache 也需要缓存抽象支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
6.2 application.yml 配置
yaml
spring:
cache:
type: memcached
memcached:
servers: 127.0.0.1:11211,127.0.0.1:11212
protocol: BINARY
expiration: 300 # 默认过期时间(秒)
⚠️ 实际上 Spring Boot 官方没有内置 Memcache 的 CacheManager 实现,需要自己封装。下面就是。
6.3 MemcacheConfig 配置类
java
package com.example.demo.config;
import net.spy.memcached.AddrUtil;
import net.spy.memcached.ConnectionFactoryBuilder;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.FailureMode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
import java.util.Arrays;
@Configuration
@EnableCaching // 这个注解你不加,@Cacheable 就是个摆设
public class MemcacheConfig {
@Value("${memcached.servers:127.0.0.1:11211}")
private String servers;
@Bean
public MemcachedClient memcachedClient() throws IOException {
return new MemcachedClient(
new ConnectionFactoryBuilder()
.setProtocol(ConnectionFactoryBuilder.Protocol.BINARY)
.setFailureMode(FailureMode.Redistribute)
.setOpTimeout(3000)
.build(),
AddrUtil.getAddresses(servers) // 支持逗号分隔的多节点
);
}
@Bean
public CacheManager cacheManager(MemcachedClient memcachedClient) {
SimpleCacheManager manager = new SimpleCacheManager();
manager.setCaches(Arrays.asList(
new MemcachedCache("users", memcachedClient, 300),
new MemcachedCache("products", memcachedClient, 600)
));
return manager;
}
}
6.4 自定义 MemcachedCache
java
package com.example.demo.config;
import net.spy.memcached.MemcachedClient;
import org.springframework.cache.Cache;
import org.springframework.cache.support.AbstractValueAdaptingCache;
import java.util.concurrent.Callable;
public class MemcachedCache extends AbstractValueAdaptingCache {
private final String name;
private final MemcachedClient client;
private final int expiration;
public MemcachedCache(String name, MemcachedClient client, int expiration) {
super(true); // 允许存 null(但你最好别存 null)
this.name = name;
this.client = client;
this.expiration = expiration;
}
@Override
public String getName() {
return this.name;
}
@Override
public Object getNativeCache() {
return this.client;
}
// 核心方法:构建带命名空间的 key
private String buildKey(Object key) {
return this.name + ":" + key.toString();
}
@Override
protected Object lookup(Object key) {
return client.get(buildKey(key));
}
@Override
public void put(Object key, Object value) {
client.set(buildKey(key), expiration, value);
}
@Override
public void evict(Object key) {
client.delete(buildKey(key));
}
@Override
public void clear() {
// 注意:Memcache 不支持按命名空间清除,flush_all 会清掉所有节点!
// 所以这里我们...什么也不做,等它 LRU 自己过期吧
// 这就是 Memcache 不如 Redis 的地方之一 😅
}
@Override
public <T> T get(Object key, Callable<T> valueLoader) {
T value = (T) lookup(key);
if (value == null) {
synchronized (buildKey(key)) { // 防缓存击穿的简单互斥锁
value = (T) lookup(key);
if (value == null) {
try {
value = valueLoader.call();
put(key, value);
} catch (Exception e) {
throw new ValueRetrievalException(key, valueLoader, e);
}
}
}
}
return value;
}
}
6.5 Service 层使用缓存
java
package com.example.demo.service;
import com.example.demo.entity.User;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class UserService {
/**
* 查用户 ------ 先翻 Memcache 兜,没有再查库
* 结果会自动缓存,下次直接命中
*/
@Cacheable(value = "users", key = "#userId", unless = "#result == null")
public User getUserById(Long userId) {
// 假装这是个很慢的数据库查询
simulateSlowQuery();
return new User(userId, "张三_" + userId, "zhangsan@qq.com");
}
/**
* 更新用户 ------ 同时更新缓存(CachePut 每次都会执行方法并写入缓存)
*/
@CachePut(value = "users", key = "#user.id")
public User updateUser(User user) {
// 假装更新了数据库
return user;
}
/**
* 删除用户 ------ 顺带把缓存也清了
*/
@CacheEvict(value = "users", key = "#userId")
public void deleteUser(Long userId) {
// 假装删了数据库记录
}
private void simulateSlowQuery() {
try { Thread.sleep(50); } catch (InterruptedException e) { /* zzz */ }
}
}
6.6 直接用 MemcachedClient(不玩 Spring Cache 那套)
java
@Component
public class QuickCacheHelper {
@Autowired
private MemcachedClient client;
// 存
public void put(String key, Object value, int expireSeconds) {
client.set(key, expireSeconds, value);
}
// 取(带降级)
public <T> T getOrLoad(String key, int expireSeconds, Supplier<T> dbLoader) {
T value = (T) client.get(key);
if (value == null) {
value = dbLoader.get();
if (value != null) {
client.set(key, expireSeconds, value);
}
}
return value;
}
// 计数器:接口限流就用它
public long incr(String key, long delta) {
return client.incr(key, delta);
}
// 删
public void delete(String key) {
client.delete(key);
}
}
七、同类产品对比
#mermaid-svg-9jqLsSNOaqUU6uA7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-9jqLsSNOaqUU6uA7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-9jqLsSNOaqUU6uA7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-9jqLsSNOaqUU6uA7 .error-icon{fill:#552222;}#mermaid-svg-9jqLsSNOaqUU6uA7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-9jqLsSNOaqUU6uA7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-9jqLsSNOaqUU6uA7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-9jqLsSNOaqUU6uA7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-9jqLsSNOaqUU6uA7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-9jqLsSNOaqUU6uA7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-9jqLsSNOaqUU6uA7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-9jqLsSNOaqUU6uA7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-9jqLsSNOaqUU6uA7 .marker.cross{stroke:#333333;}#mermaid-svg-9jqLsSNOaqUU6uA7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-9jqLsSNOaqUU6uA7 p{margin:0;}#mermaid-svg-9jqLsSNOaqUU6uA7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 全能战神 性能王者 简易轻量 功能怪兽 Aerospike Ehcache Hazelcast Couchbase Memcache Redis 功能简单 功能丰富 性能低 性能高 "缓存中间件象限图"
详细对比表
| 特性 | Memcache | Redis | Ehcache | Couchbase | Hazelcast |
|---|---|---|---|---|---|
| 定位 | 纯 KV 缓存 | 数据结构服务器 | JVM 内缓存 | 分布式 NoSQL | 内存数据网格 |
| 数据类型 | 仅 String | String/Hash/List/Set/ZSet/Stream... | POJO | JSON/Document | POJO |
| 持久化 | ❌ | ✅ RDB + AOF | ✅ 磁盘持久化 | ✅ 内置 | ✅ |
| 集群 | 客户端分片 | Redis Cluster / Sentinel | Terracotta | 自带 | 自带 |
| 事务 | ❌ | ✅ (Lua) | ✅ (JTA) | ✅ (ACID) | ✅ |
| 发布订阅 | ❌ | ✅ | ✅ (JCache) | ❌ | ✅ |
| 多线程 | ✅ 天然多线程 | ⚠️ 6.0+ 引入多线程 IO | ✅ | ✅ | ✅ |
| Lua 脚本 | ❌ | ✅ | ❌ | ❌ | ❌ |
| 内存效率 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
| 学习曲线 | 平缓(20分钟上手) | 适中 | 平缓 | 陡峭 | 适中 |
| 社区生态 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
八、Redis 是不是完全替代了 Memcache?
结论先行:没有,也不可能完全替代。
#mermaid-svg-rNE7hQMRPLEn5Eyh{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rNE7hQMRPLEn5Eyh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rNE7hQMRPLEn5Eyh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rNE7hQMRPLEn5Eyh .error-icon{fill:#552222;}#mermaid-svg-rNE7hQMRPLEn5Eyh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rNE7hQMRPLEn5Eyh .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rNE7hQMRPLEn5Eyh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rNE7hQMRPLEn5Eyh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rNE7hQMRPLEn5Eyh .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rNE7hQMRPLEn5Eyh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rNE7hQMRPLEn5Eyh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rNE7hQMRPLEn5Eyh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rNE7hQMRPLEn5Eyh .marker.cross{stroke:#333333;}#mermaid-svg-rNE7hQMRPLEn5Eyh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rNE7hQMRPLEn5Eyh p{margin:0;}#mermaid-svg-rNE7hQMRPLEn5Eyh .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rNE7hQMRPLEn5Eyh .cluster-label text{fill:#333;}#mermaid-svg-rNE7hQMRPLEn5Eyh .cluster-label span{color:#333;}#mermaid-svg-rNE7hQMRPLEn5Eyh .cluster-label span p{background-color:transparent;}#mermaid-svg-rNE7hQMRPLEn5Eyh .label text,#mermaid-svg-rNE7hQMRPLEn5Eyh span{fill:#333;color:#333;}#mermaid-svg-rNE7hQMRPLEn5Eyh .node rect,#mermaid-svg-rNE7hQMRPLEn5Eyh .node circle,#mermaid-svg-rNE7hQMRPLEn5Eyh .node ellipse,#mermaid-svg-rNE7hQMRPLEn5Eyh .node polygon,#mermaid-svg-rNE7hQMRPLEn5Eyh .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rNE7hQMRPLEn5Eyh .rough-node .label text,#mermaid-svg-rNE7hQMRPLEn5Eyh .node .label text,#mermaid-svg-rNE7hQMRPLEn5Eyh .image-shape .label,#mermaid-svg-rNE7hQMRPLEn5Eyh .icon-shape .label{text-anchor:middle;}#mermaid-svg-rNE7hQMRPLEn5Eyh .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rNE7hQMRPLEn5Eyh .rough-node .label,#mermaid-svg-rNE7hQMRPLEn5Eyh .node .label,#mermaid-svg-rNE7hQMRPLEn5Eyh .image-shape .label,#mermaid-svg-rNE7hQMRPLEn5Eyh .icon-shape .label{text-align:center;}#mermaid-svg-rNE7hQMRPLEn5Eyh .node.clickable{cursor:pointer;}#mermaid-svg-rNE7hQMRPLEn5Eyh .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rNE7hQMRPLEn5Eyh .arrowheadPath{fill:#333333;}#mermaid-svg-rNE7hQMRPLEn5Eyh .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rNE7hQMRPLEn5Eyh .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rNE7hQMRPLEn5Eyh .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rNE7hQMRPLEn5Eyh .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rNE7hQMRPLEn5Eyh .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rNE7hQMRPLEn5Eyh .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rNE7hQMRPLEn5Eyh .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rNE7hQMRPLEn5Eyh .cluster text{fill:#333;}#mermaid-svg-rNE7hQMRPLEn5Eyh .cluster span{color:#333;}#mermaid-svg-rNE7hQMRPLEn5Eyh div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rNE7hQMRPLEn5Eyh .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rNE7hQMRPLEn5Eyh rect.text{fill:none;stroke-width:0;}#mermaid-svg-rNE7hQMRPLEn5Eyh .icon-shape,#mermaid-svg-rNE7hQMRPLEn5Eyh .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rNE7hQMRPLEn5Eyh .icon-shape p,#mermaid-svg-rNE7hQMRPLEn5Eyh .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rNE7hQMRPLEn5Eyh .icon-shape .label rect,#mermaid-svg-rNE7hQMRPLEn5Eyh .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rNE7hQMRPLEn5Eyh .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rNE7hQMRPLEn5Eyh .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rNE7hQMRPLEn5Eyh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ❓ 你的需求是什么?
只是简单 KV 缓存
要求极致性能
需要 List/Hash/Set
等复杂数据结构
需要持久化
数据不能丢
需要 Pub/Sub
消息通知
👉 Memcache
内存效率更高
多线程天然优势
👉 Redis
数据结构丰富
一个顶八个
👉 Redis
RDB + AOF
Memcache 重启即失忆
👉 Redis
Memcache 是哑巴
为什么 Memcache 没有被完全替代?
1. 内存效率更高
- Memcache 的 Slab Allocator 专为缓存量身定做,内存碎片更少
- Redis 的
jemalloc虽然也厉害,但数据结构复杂导致额外开销更大 - 同样 1GB 内存,Memcache 能存更多数据
2. 多线程优势
- Memcache 从出生就是多线程的,在多核 CPU 上能榨干性能
- Redis 长期单线程(6.0 才引入多线程 IO,主流程仍是单线程)
- 在高并发纯 KV 场景下,Memcache 有时反而更快
3. 简单就是王道
- 代码量小(Core 不到 2 万行),出问题好排查
- 没有复杂的数据结构,没有持久化焦虑
- "我就想存个字符串,你给我一把瑞士军刀干嘛?"
4. 大厂的惯性
- Facebook 的 Memcache 集群规模大到有自己的论文(Scaling Memcache at Facebook)
- 很多大厂的缓存体系早就围绕 Memcache 建好了,迁移成本太高
- "能用就别动"------运维第一定律
5. 场景分离
- Redis 现在更像是一个内存数据库,而不只是缓存
- Memcache 专注做纯缓存,职责单一不会乱来
架构演进中 Memcache 的定位
#mermaid-svg-WVSmKRXVl95qe2Lx{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-WVSmKRXVl95qe2Lx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WVSmKRXVl95qe2Lx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WVSmKRXVl95qe2Lx .error-icon{fill:#552222;}#mermaid-svg-WVSmKRXVl95qe2Lx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WVSmKRXVl95qe2Lx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WVSmKRXVl95qe2Lx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WVSmKRXVl95qe2Lx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WVSmKRXVl95qe2Lx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WVSmKRXVl95qe2Lx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WVSmKRXVl95qe2Lx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WVSmKRXVl95qe2Lx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WVSmKRXVl95qe2Lx .marker.cross{stroke:#333333;}#mermaid-svg-WVSmKRXVl95qe2Lx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WVSmKRXVl95qe2Lx p{margin:0;}#mermaid-svg-WVSmKRXVl95qe2Lx .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-WVSmKRXVl95qe2Lx .cluster-label text{fill:#333;}#mermaid-svg-WVSmKRXVl95qe2Lx .cluster-label span{color:#333;}#mermaid-svg-WVSmKRXVl95qe2Lx .cluster-label span p{background-color:transparent;}#mermaid-svg-WVSmKRXVl95qe2Lx .label text,#mermaid-svg-WVSmKRXVl95qe2Lx span{fill:#333;color:#333;}#mermaid-svg-WVSmKRXVl95qe2Lx .node rect,#mermaid-svg-WVSmKRXVl95qe2Lx .node circle,#mermaid-svg-WVSmKRXVl95qe2Lx .node ellipse,#mermaid-svg-WVSmKRXVl95qe2Lx .node polygon,#mermaid-svg-WVSmKRXVl95qe2Lx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-WVSmKRXVl95qe2Lx .rough-node .label text,#mermaid-svg-WVSmKRXVl95qe2Lx .node .label text,#mermaid-svg-WVSmKRXVl95qe2Lx .image-shape .label,#mermaid-svg-WVSmKRXVl95qe2Lx .icon-shape .label{text-anchor:middle;}#mermaid-svg-WVSmKRXVl95qe2Lx .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-WVSmKRXVl95qe2Lx .rough-node .label,#mermaid-svg-WVSmKRXVl95qe2Lx .node .label,#mermaid-svg-WVSmKRXVl95qe2Lx .image-shape .label,#mermaid-svg-WVSmKRXVl95qe2Lx .icon-shape .label{text-align:center;}#mermaid-svg-WVSmKRXVl95qe2Lx .node.clickable{cursor:pointer;}#mermaid-svg-WVSmKRXVl95qe2Lx .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-WVSmKRXVl95qe2Lx .arrowheadPath{fill:#333333;}#mermaid-svg-WVSmKRXVl95qe2Lx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-WVSmKRXVl95qe2Lx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-WVSmKRXVl95qe2Lx .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WVSmKRXVl95qe2Lx .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-WVSmKRXVl95qe2Lx .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WVSmKRXVl95qe2Lx .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-WVSmKRXVl95qe2Lx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-WVSmKRXVl95qe2Lx .cluster text{fill:#333;}#mermaid-svg-WVSmKRXVl95qe2Lx .cluster span{color:#333;}#mermaid-svg-WVSmKRXVl95qe2Lx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-WVSmKRXVl95qe2Lx .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-WVSmKRXVl95qe2Lx rect.text{fill:none;stroke-width:0;}#mermaid-svg-WVSmKRXVl95qe2Lx .icon-shape,#mermaid-svg-WVSmKRXVl95qe2Lx .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WVSmKRXVl95qe2Lx .icon-shape p,#mermaid-svg-WVSmKRXVl95qe2Lx .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-WVSmKRXVl95qe2Lx .icon-shape .label rect,#mermaid-svg-WVSmKRXVl95qe2Lx .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WVSmKRXVl95qe2Lx .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-WVSmKRXVl95qe2Lx .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-WVSmKRXVl95qe2Lx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 🏗️ 现代多层缓存架构
miss
miss
CDN
边缘缓存
Nginx
本地缓存
Memcache
分布式热点缓存
扛住 80% 流量
Redis
业务缓存 + 数据结构
MySQL
持久存储
客户端
🎯 最佳实践 :Memcache 做一级缓存扛流量,Redis 做二级缓存 + 业务数据,MySQL 兜底。三个人的电影,每个人都有名字。
九、幽默总结
┌─────────────────────────────────────────────────────────────┐
│ │
│ Memcache 就像是编程界的老牌螺丝刀: │
│ │
│ 🔧 功能不多,但每个都好用 │
│ 🔧 长得不帅,但干活实在 │
│ 🔧 有人嫌它过时,但它还在大厂核心系统里扛活 │
│ 🔧 Redis 是瑞士军刀,但你不能用军刀去拧所有的螺丝 │
│ │
│ 选型口诀: │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
│ 要存字符串 → 两个都行 │
│ 要存复杂数据 → Redis(Memcache 不伺候) │
│ 要持久化 → Redis(Memcache 说我记性不好) │
│ 要高并发简单 KV → Memcache(Redis 说你还嫩了点) │
│ 孩子才做选择,成年人两个都上 → 双缓存架构 👍 │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
│ │
└─────────────────────────────────────────────────────────────┘
📚 参考资料
- Memcached 官方 Wiki
- Scaling Memcache at Facebook(论文)
- spymemcached 客户端:GitHub