如何在 memcached 中存储 protobuf 对象?
How to store protobuf object in memcached?
以下是我用来创建 GRPC 系统的原型文件,该系统从 database/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 中的对象都需要是可序列化的。但是自动生成的 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
通常是一个很好的替代品,但是 二进制序列化程序 应该使用类似base-64 编码(通过 Convert.ToBase64String
和 Convert.FromBase64String
)。
至于直接支持此功能的 memcached 库(或类似库):出于关注点分离的原因,我建议不要这样做。但是,扩展方法通常可以很容易地在您自己的代码中的几行辅助方法中提供它。
以下是我用来创建 GRPC 系统的原型文件,该系统从 database/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 中的对象都需要是可序列化的。但是自动生成的 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
通常是一个很好的替代品,但是 二进制序列化程序 应该使用类似base-64 编码(通过 Convert.ToBase64String
和 Convert.FromBase64String
)。
至于直接支持此功能的 memcached 库(或类似库):出于关注点分离的原因,我建议不要这样做。但是,扩展方法通常可以很容易地在您自己的代码中的几行辅助方法中提供它。