2

以下是我用来创建从数据库/memcached 获取数据的 GRPC 系统的 proto 文件。

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 Getting Started。我在服务器上使用这些类来存储数据库查询的结果并尝试将这些对象保存到 memcached。不幸的是,protobuf 对象没有被添加到 memcached 中。以下是我将它添加到 memcached 的方式,isKeyFirstTimeCreated当我尝试添加它时,它的值为 false。

 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#]

4

1 回答 1

1

几乎所有缓存存储都支持byte[]. 像 protobuf 这样的工具可以直接存储在 a 中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 库(或类似库):出于关注点分离的原因,我建议不要这样做。但是,扩展方法通常可以很容易地在您自己的代码中的帮助方法中用几行来提供它。

于 2016-02-15T21:14:31.603 回答