
一、项目介绍
Garnet 是微软研究院(Microsoft Research)开源的下一代远程缓存存储(remote cache-store)项目,采用 MIT 许可证,全部核心代码使用 C# 编写并基于最新的 .NET 技术栈构建。它直接采用业界广泛使用的 RESP(Redis Serialization Protocol)作为有线协议,因此现有的 Redis 客户端几乎无需任何修改即可直连 Garnet,极大降低了迁移成本。项目在 GitHub 上长期保持活跃维护,CI、Release、NuGet 包均持续更新,论文已被 VLDB 2026 正式接收。
根据官方介绍,Garnet 在高并发连接、小批量请求场景下的吞吐与可扩展性优于同类开源缓存;在 Azure 虚拟机启用 Accelerated Networking 的条件下,其客户端 p99.9 延迟常常低于 300 微秒,非常适合作为实时在线业务、会话存储、排行榜、限流计数、消息中间件的底层缓存层。最新动态包括:预览版的 Vector Sets(基于 DiskANN 的近似最近邻向量检索)、Range Index(基于 Bf-Tree 的二级范围索引),以及面向云原生的分层存储与动态键迁移能力。如果你希望免运维,微软还提供了全托管的 Azure Cosmos DB Garnet Cache 服务,内置高可用、性能 SLA 与零基础设施管理。

二、项目结构与核心组件
Garnet 的整体栈可以拆分为"网络层 — 命令解析层 — 存储引擎层"三段,其官方架构图如上图所示。下面按运维视角逐一拆解关键组件,帮助你在部署前先建立心智模型。
1. 节点角色(单节点与集群)
Garnet 同时支持单节点模式与集群模式。单节点模式下,一个 GarnetServer 进程直接监听 TCP 端口(默认 6379),接收 RESP 命令并返回结果,启动即可作为独立缓存使用。集群模式下,Garnet 实现了完整的分片(sharding)、复制(replication)与动态键迁移(key migration)能力,节点之间通过 gossip 协议交换并演化集群状态,对外暴露标准的 CLUSTER 系列命令。需要特别注意的是:Garnet 当前的集群设计是被动式(passive)的——它不实现自动选主(leader election),而是响应由外部控制面(control plane)下发的 CLUSTER 命令,这与 Redis Cluster 自带的 gossip 自动选主策略不同。生产集群部署前,请务必阅读官方 Control Plane 文档,并提前规划好自己的编排器。
2. 存储层:Tsavorite 双 KV 存储
Garnet 的存储引擎名为 Tsavorite(即原 FASTER),由两个被统一操作日志绑定的键值存储组成:
- Main Store(主存储):针对原生字符串操作优化,在内存中精细管理对象生命周期,避免托管堆 GC 抖动,适合
GET/SET/EXPIRE等 KV 命令;写入直接进入追加日志,读路径走哈希索引。 - Object Store(对象存储,可选):针对复杂对象优化,在内存中以堆对象形式保存 Sorted Set、Set、Hash、List、Geo 等类型,落盘时序列化为二进制格式;这类数据的更新效率高,但占用托管堆较多内存。
存储层原生支持分层存储(内存、SSD、云端对象存储)、非阻塞 checkpoint、基于操作日志的崩溃恢复、多键事务(两阶段锁)以及内存碎片复用。上层 RESP API 通过一个"窄腰"的 Tsavorite 存储 API(read / upsert / delete / 原子 RMW,全部带异步回调)实现,把解析与查询处理和存储细节(并发、分层、checkpoint)完全解耦,便于后续演进。
3. 迁移、扩展与网络层
Garnet 支持在集群节点之间做动态键迁移以实现分片再平衡;同时提供 C# 编写的服务端存储过程(stored procedures)与模块(modules),允许开发者用 .NET 直接扩展原生字符串与自定义对象类型,并兼容 Lua 脚本。网络层采用共享内存设计,把 TLS 解密与存储交互都放在 IO 完成线程上,避免传统 shuffle 架构里的数据跨分片搬迁开销;未来还可接入内核旁路(kernel-bypass)网络栈以进一步压低尾延迟。TLS 基于 .NET 的 SslStream 实现,并支持基础访问控制(用户名密码)。
三、版本与环境要求
根据官方 Getting Started 页面,Garnet 当前主要面向 net10.0 目标框架,因此源码编译部署前需要准备:
- .NET 10 SDK:从 .NET 官网 下载对应操作系统与架构(x64 / ARM64)的 SDK 并安装;Linux 与 Windows 均支持。
- 操作系统:Linux(Ubuntu 20.04+ 推荐,CentOS / Rocky / Debian 亦可)或 Windows 10/11、Windows Server 2019+;macOS 可通过容器运行,不建议作为生产宿主。
- 构建工具:CLI 方式使用
dotnet build;Windows 图形化构建可使用 Visual Studio 2022 17.x 或 Visual Studio 2026 打开Garnet.slnx解决方案。 - 端口:默认监听 TCP
6379,绑定地址为IPAddress.Any与IPAddress.IPv6Any;公网部署前务必调整防火墙并启用认证。 - 资源:生产环境建议预留足够大的内存索引空间;使用 Docker 时需要
--ulimit memlock=-1以允许大页内存锁定;建议 SSD 作为数据盘以获得最佳持久化性能。 - 客户端:任意 Redis 客户端即可,C# 推荐 StackExchange.Redis,运维调试推荐
redis-cli或 RedisInsight。
如果你只是想快速体验而不编译源码,可以直接使用 NuGet 上的 garnet-server 全局工具,或拉取 ghcr.io/microsoft/garnet 容器镜像。具体兼容矩阵(如哪些 RESP 命令已支持、哪些仍在预览)请以官方 文档站点为准。
四、本地部署实操
下面给出四种本地部署方式,从源码编译到容器一键起,按团队熟悉度任选其一;所有命令均与官方 README / Getting Started 保持一致。
方式一:源码编译运行(dotnet run)
# 克隆仓库
git clone git@github.com:microsoft/garnet.git
cd garnet
# Release 模式编译(首次会还原 NuGet 包,需要联网)
dotnet build -c Release
# 可选:跑一遍测试套件做健康检查
dotnet test -c Release -f net10.0 -l "console;verbosity=detailed"
# 启动服务器(默认监听 0.0.0.0:6379)
cd main/GarnetServer
dotnet run -c Release -f net10.0
如果希望使用 512MB 的索引大小(默认值更小),可以追加参数:
dotnet run -c Release -f net10.0 -- -i 512m
查看全部可调参数(端口、绑定地址、索引/内存/页大小、数据与 checkpoint 路径、TLS、认证等):
dotnet run -c Release -f net10.0 -- --help
方式二:全局 .NET 工具(garnet-server)
无需克隆源码,直接通过 NuGet 安装:
dotnet tool install --global garnet-server
garnet-server
升级时使用 dotnet tool update --global garnet-server,卸载使用 dotnet tool uninstall -g garnet-server。这种方式适合开发机快速拉起一个本地 Garnet 实例调试客户端,不需要 Visual Studio 也不需要 git clone。
方式三:Docker 一键运行
Linux 宿主机(推荐 host 网络以获得最佳网络性能):
docker run --network=host --ulimit memlock=-1 ghcr.io/microsoft/garnet
带密码的基础认证部署(生产环境强烈建议):
docker run --network=host --ulimit memlock=-1 ghcr.io/microsoft/garnet \
--auth Password --password YourStrongPassword
macOS / Windows Docker Desktop(无法使用 host 网络,改用端口映射):
docker run -p 6379:6379 --ulimit memlock=-1 ghcr.io/microsoft/garnet
如果你习惯 Docker Compose,可以直接拉取官方 compose 文件:
wget https://raw.githubusercontent.com/microsoft/garnet/main/docker-compose.yml
docker compose up -d
docker ps | grep garnet
docker logs -f garnet-garnet-1
方式四:Redis 客户端连接与验证
Garnet 讲 RESP,因此任意 Redis 客户端都能连。最直接的验证方式是使用 redis-cli:
redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> set key hello-garnet
OK
127.0.0.1:6379> get key
"hello-garnet"
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> info server
# Server
version:...
process_id:...
tcp_port:6379
C# 应用可以使用 StackExchange.Redis,也可以使用 Garnet 自带的 GarnetClient。Windows 桌面用户推荐图形化客户端 RedisInsight,添加一个指向 127.0.0.1:6379 的连接即可。WSL 下连接 Windows 上的 Garnet 需要先用 ip route show | grep -i default | awk '{print $3}' 拿到宿主 IP,并在启动 Garnet 时加 --bind 0.0.0.0、把 GarnetServer.exe 加入 Windows 防火墙例外。验证部署是否成功的最低标准:redis-cli ping 返回 PONG、set/get 往返正常、info server 能看到进程与端口信息。
五、浏览器端 / 可视化管理
Garnet 本身是一个响应 RESP 协议的存储服务,不内置 Web 管理控制台。它的定位是"高性能存储内核",把可视化、编排、监控的工作交给生态工具与运维平台完成。如果你希望在浏览器中管理数据,推荐以下几条路径:

- RedisInsight 桌面 / Web 端:Redis 官方提供的跨平台 GUI,支持浏览器式浏览 key、编辑 hash/zset、慢日志分析、Profiler 追踪,添加连接时填
host:port即可,对 Garnet 完全透明。 - 自建 Web 客户端:例如开源的 ioredis 配合 Web 前端,或基于社区 redis-web 类项目,通过 RESP 代理在浏览器里操作 key 空间,适合内部运维平台集成。
- 命令行 Web 终端:在堡垒机或内部管理后台嵌入一个基于 xterm.js 的 Web SSH / Web redis-cli,运维人员通过浏览器直接执行 RESP 命令,无需本地安装客户端。
Windows 用户也可以安装 Memurai 并使用其 memurai-cli 进行命令行操作。如果需要可视化监控集群状态、吞吐与延迟,建议结合 Prometheus + Grafana(Garnet 暴露的指标端点请以官方文档为准),把 QPS、延迟分位数、内存占用、磁盘 AOF 写入速率接入大盘。
六、API 用法与命令示例
Garnet 实现了广泛的 RESP 命令族:原生字符串(GET/SET/EXPIRE/APPEND 等)、分析型(HyperLogLog、Bitmap)、对象型(Sorted Set、List、Hash、Set、Geo),并支持客户端多键事务以及服务端 C# 存储过程 / Lua 脚本。下面给出几个常见调用方式。
1. 通过 redis-cli 执行 RESP 命令
redis-cli -p 6379 SET user:1001 '{"name":"Lin","level":3}' EX 3600
redis-cli -p 6379 HSET book:2001 title "Garnet Guide" price 59
redis-cli -p 6379 ZADD rank 100 alice 90 bob 95 carol
redis-cli -p 6379 ZREVRANGE rank 0 -1 WITHSCORES
redis-cli -p 6379 LPUSH queue:task "task-1"
redis-cli -p 6379 --eval script.lua , key1 key2 , arg1
2. 通过 curl / nc 发送原始 RESP 帧
curl 本身不讲 RESP,但你可以借助 nc 做最原始的连通性探测,理解协议本身:
# PING
printf '*1\r\n$4\r\nPING\r\n' | nc 127.0.0.1 6379
# 期望返回 +PONG
# SET foo bar
printf '*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n' | nc 127.0.0.1 6379
# GET foo
printf '*2\r\n$3\r\nGET\r\n$3\r\nfoo\r\n' | nc 127.0.0.1 6379
如果你已经在前面套了一个 HTTP 代理(例如 Nginx + redis-cgi 或自研 Sidecar),那么直接 curl http://127.0.0.1:8080/GET/foo 即可,具体路径取决于你的网关实现;不要把这种 HTTP 网关直接暴露到公网,否则等于把缓存裸奔。
3. 作为 .NET 库自托管嵌入
除了独立部署 GarnetServer,你还可以把 Garnet 当作库嵌入自己的 .NET 服务,与业务进程同生命周期发布:
using Garnet;
try {
using var server = new GarnetServer(args);
server.Start();
Thread.Sleep(Timeout.Infinite);
} catch (Exception ex) {
Console.WriteLine($"Unable to initialize server: {ex.Message}");
}
这种方式适合需要把缓存与业务进程打包发布、降低运维成本的场景,NuGet 包为 Microsoft.Garnet,参数 args 与命令行 garnet-server --help 列出的选项一一对应。
七、常见问题 FAQ 与排错
Q1:Garnet 和 Redis 是什么关系?能直接替代吗?
A:Garnet 由微软独立开发,仅在协议层兼容 RESP,与 Redis Ltd. 无任何隶属或赞助关系(参见官方 FAQ)。常见 KV、对象、Lua 场景可以平滑迁移,但部分 Redis 模块(Module API)、特定命令与集群自动化运维能力仍在补齐,生产切换前建议先在预发环境做兼容性回归与压测,再分批切流。
Q2:checkpoint / AOF 数据在不同版本之间能互通吗?
A:自 2.1.0 起,Garnet 存储格式已稳定;较新的 2.x 可以读取任何更早 2.x(≥2.1.0)产生的 checkpoint 与 AOF,但旧版本不能读新版本数据,预览特性(如 Vector Sets、Range Index)不在兼容范围内。升级前请先完整备份数据目录,并在测试环境验证恢复流程。
Q3:启动后外部机器连不上 6379 怎么办?
A:按顺序排查:① 确认服务监听地址,默认绑定 IPAddress.Any,若显式 --bind 成了 127.0.0.1 就只能本机访问;② 检查云服务器安全组与 iptables/firewalld 是否放行 6379;③ Docker 模式 macOS/Windows 必须用 -p 6379:6379 而不是 --network=host;④ 若启用了 --auth Password,客户端必须带 -a 密码 或在连接后执行 AUTH;⑤ 用 ss -lntp | grep 6379 确认端口确实处于 LISTEN。
Q4:运行一段时间后出现 OOM 或 GC 卡顿?
A:默认索引与内存配额偏小,可通过 -i(index size)、-m(memory size)等参数显式调大,例如 garnet-server -i 1g -m 4g;容器模式务必加 --ulimit memlock=-1,否则大页内存会被拒绝。对象存储(Sorted Set/Hash 等)占用托管堆较多数据,必要时关闭不需要的对象类型以减负,并关注 GC Pause 与托管堆回收频率。
Q5:WSL 或跨机器开发时 redis-cli 连不上 Windows 上的 Garnet?
A:启动 Garnet 时加 --bind 0.0.0.0;在 Windows Defender 防火墙中把 GarnetServer.exe 加入"允许的应用";在 WSL 里通过 ip route show | grep -i default | awk '{print $3}' 拿到宿主 IP,再 redis-cli -h <宿主IP> -p 6379。Windows 11 22H2+ 也可以开启 mirrored networking 模式简化互通。
Q6:生产环境要不要开启 TLS 与密码?
A:只要 Garnet 实例跨主机、跨可用区或暴露到非可信网络,就必须启用 TLS(基于 .NET SslStream)与密码认证;同机房纯内网且物理隔离的场景也建议至少加密码,避免被未授权扫描到后写入脏数据。命令行参数可在 --help 中查到 TLS 证书与密钥相关选项,证书建议使用 Let's Encrypt 或企业内部 CA 签发。
常见报错速查
Permission denied绑定 6379:Linux 下端口小于 1024 需要 root,或改用--port 6380;不要用sudo dotnet长期运行生产服务。Failed to load .NET runtime / You must install .NET:未安装与项目目标一致的 SDK,安装 .NET 10 SDK 后再重试。Connection refused:服务未起来或端口写错;先ss -lntp | grep 6379确认监听状态。WRONGPASS invalid username-password pair:启用了密码但客户端未携带,使用redis-cli -a YourPassword。- Docker 启动即退出:检查
docker logs,常见为 memlock 限制或数据目录权限问题,加--ulimit memlock=-1并以非 root 用户挂载数据卷。 Error reading from transport/ 连接频繁断开:多半是网络中间件(LB、安全组)空闲超时过小,建议把 TCP keepalive 与空闲超时调大,或在客户端启用连接池。
相关链接
- 项目主页:https://github.com/microsoft/garnet
- 官方文档:https://microsoft.github.io/garnet
- 快速上手:Getting Started
- Release 下载:GitHub Releases / NuGet garnet-server
- 托管服务:Azure Cosmos DB Garnet Cache
- 社区:Discord、官方 FAQ
以上命令与参数基于官方 README 与 Getting Started 文档整理,不同版本之间参数名可能有微调,实际部署时请以官方文档为准。建议在首次部署完成后,把 --help 输出的全部参数保存为团队内部基线,后续升级时再逐项 diff,避免遗漏新增的安全与性能开关。