Garnet 简史
大家好!我想从这篇博客开始,简要介绍一下 Garnet 的历史以及它是如何诞生的。在微软研究院,我们长期以来一直致力于存储技术。2016 年,我们开始着手设计一种基于 epoch 保护和强大存储 API 的新型键值存储。这个项目名为 FASTER,于 2018 年开源,并在微软内部和更广泛的社区中获得了广泛关注。FASTER 拥有超过 6k 颗星和超过 50 万次 NuGet 下载。在接下来的几年里,我们构建了后续功能,例如可恢复性 (CPR) 和无服务器支持 (Netherite),该项目也得到了广泛采用。
大约在 2021 年,我们注意到对远程缓存存储的巨大兴趣,特别是使用 Redis 的 RESP API 等 API。开发人员喜欢 API 和部署模型(作为单独的进程/服务)的灵活性。与直接访问云数据库相比,成本节约推动了缓存层的采用,这些缓存层很快就占据了大型服务运营成本的很大一部分。当疫情爆发,在线服务使用量激增时,对降低此类缓存层的成本和提高性能(吞吐量和延迟)的需求非常强烈。
我们接受了构建一个名为 Garnet 的新系统的挑战,该系统可以在客户端-服务器设置中提供极高的端到端性能,同时通过采用最流行的网络协议 RESP,使客户端基本保持不变。经过大量的设计工作,我们提出了一种服务器线程模型,该模型确实可以对基本 get 和 set 操作的端到端性能产生巨大的(通常是数量级的)影响,而且无需修改客户端代码。这使我们有信心构建 Garnet 的功能集,以用于实际场景。
下一个问题是 API 覆盖范围。Redis API 非常庞大,而我们只是一个小型研究团队。幸运的是,我们的技术栈基于 .NET,它在性能和库丰富性方面都取得了巨大进步。我们设计了一种通用而强大的方式来定义和使用自定义数据结构,并能够通过重用 C# 中的数据结构快速实现 Sorted Set、List 和 Hash 等复杂数据类型。然后,我们还构建了 HyperLogLog 和 Bitmap 等复杂结构,并添加了事务和可扩展性功能。
下一个要求是横向扩展和恢复,为此我们设计了预写操作日志、分片能力、复制以及用于动态横向扩展的键迁移。通过保持与 Redis API 的基本兼容性,我们能够以现有客户端代码基本不变的方式添加这些功能。
经过数千次单元测试以及与微软第一方团队合作部署 Garnet 到生产环境的几年时间(更多内容将在未来的博客文章中发布!),我们觉得是时候像五年前发布 FASTER 一样公开它了。我们希望全球的开发人员都能受益于这项强大的技术,并为代码库做出贡献。我们认为现代 C# 代码库在这方面会特别有吸引力,因为它易于扩展、维护和贡献。作为微软研究院的成员,我们也希望学术界的人们能够进行研究,与我们合作,并扩展系统的各个方面。
所以,探索 Garnet,看看你是否能在你的应用程序中找到它的用武之地,考虑帮助我们扩展它的功能,并一如既往地告诉我们你的想法!