以下是我用来创建GRPC系统的proto文件,该系统从数据库/ 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 Getting Started。我在服务器上使用这些类来存储数据库查询的结果,并尝试将这些对象保存到memcached。不幸的是,protobuf对象没有被添加到memcached中。以下是我将其添加到memcached的方法,当我尝试添加它时,isKeyFirstTimeCreated
的值为false。
isKeyFirstTimeCreated = mc.Store(StoreMode.Add, key, t, DateTime.Now.Add(cacheDuration));
根据memcached的要求,所有必须存储在memcached中的对象都需要是Serializable。但是自动生成的protobuf类不可序列化(至少是c#使用的二进制格式化程序)。现在,由于类是部分实现,我使它们可序列化,但由于RepeatedField不是Serializable,因此没有帮助。
IMO,应该有一个更好的方法或一些机制,允许我将protobuf对象直接保存到memcached中,但不幸的是谷歌搜索在这方面对我没什么帮助。我可以通过两种方式实现这一目标
通过将protobuf对象中的数据复制到可序列化对象,然后将其保存到memcached中以供将来参考
将数据复制到可serilizable对象中,并使用该对象填充protobuf对象。
但这两个人接近需要额外的工作。有没有更好的方法来实现这一目标?
[PS:我正在使用proto3,因此它支持c#]
答案 0 :(得分:1)
几乎所有缓存存储都支持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.ToBase64String
和Convert.FromBase64String
)。
对于直接支持这个的memcached库(或类似的):我会建议不要将此问题分离出来。但是,扩展方法通常可以很容易地在您自己的代码中的辅助方法中提供几行。