以下是我用来创建从数据库/memcached 获取数据的 GRPC 系统的原型(prototype)文件。
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#]
最佳答案
几乎所有缓存存储都支持byte[]
。像 protobuf 这样的工具可以直接将它们存储在 byte[]
中,因此这里使用二进制序列化程序的最常见方法本质上是:
byte[] raw;
using(var ms = new MemoryStream(ms)) {
YourChosenSerializer.Serialize(ms, obj);
raw = ms.ToArray();
}
// now store raw
如果你的存储工具不支持 byte[]
,那么 string
通常是一个很好的替代品,但是 binary serializers 应该是 stores使用类似 base-64 编码的东西(通过 Convert.ToBase64String
和 Convert.FromBase64String
)。
至于直接支持此功能的 memcached 库(或类似库):出于关注点分离的原因,我建议不要这样做。但是,扩展方法通常可以很容易地在您自己的代码中的几行辅助方法中提供它。
关于c# - 如何在 memcached 中存储 protobuf 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35407425/