如何在内存缓存中存储 protobuf 对象

本文关键字:存储 protobuf 对象 缓存 内存 | 更新日期: 2023-09-27 18:34:41

以下是我用来创建一个GRPC系统的原型文件,该系统从数据库/memcached获取数据。

message CMSContent
{
    repeated ArticleSummary Articles = 1;
    uint32 RecordCount = 2;
}
service Article
{
    rpc ListByCategory(ArticleByCatURI) returns (CMSContent){}
}
message ArticleByCatURI
{
    uint32 ApplicationId = 1;        
}
message ArticleSummary
{
    uint32 ArticleId = 1;
    string ArticleName   = 2;
}

我创建了相应的 C# 类,如 GRPC 入门中所述。我在服务器上使用这些类来存储数据库查询的结果,并尝试将这些对象保存到memcached。不幸的是,protobuf 对象没有被添加到 memcached 中。以下是我将其添加到memcached的方式,当我尝试添加它时,isKeyFirstTimeCreated的值为假。

 isKeyFirstTimeCreated = mc.Store(StoreMode.Add, key, t, DateTime.Now.Add(cacheDuration));

根据 memcached 要求,必须存储在 memcached 中的所有对象都需要是可序列化的。但是自动生成的 protobuf 类是不可序列化的(至少对于 c# 使用的二进制格式化程序(。现在,由于这些类是部分实现,因此我使它们可序列化,但这无济于事,因为 RepeatedField 不可序列化。

IMO,应该有更好的方法或某种机制,允许我将protobuf对象直接保存到memcached中,但不幸的是,谷歌搜索在这方面对我没有太大帮助。

我可以通过两种方式实现这一目标

  • 将数据从 protobuf 对象复制到可序列化的对象,然后将其保存到 memcached 中以供将来参考

  • 将数据复制到可保护的对象中,并使用该对象填充 protobuf 对象。

但这两种方法需要额外的工作。有没有更好的方法来实现这一目标?

[PS:我正在使用proto3,因此它支持c#]

如何在内存缓存中存储 protobuf 对象

几乎所有缓存存储都支持 byte[] 。像protobuf这样的工具可以直接存储在byte[]中,所以这里最常见的二进制序列化器方法本质上是:

byte[] raw;
using(var ms = new MemoryStream(ms)) {
    YourChosenSerializer.Serialize(ms, obj);
    raw = ms.ToArray();
}
// now store raw

如果您的存储工具不支持 byte[] ,那么 string 通常是一个很好的替代品,但二进制序列化程序应该是使用 base-64 编码(通过 Convert.ToBase64StringConvert.FromBase64String(之类的东西进行存储。

至于直接支持这一点的memcached库(或类似库(:出于关注点分离的原因,我建议不要这样做。但是,扩展方法通常可以很容易地在您自己的代码的帮助程序方法中的几行中提供它。