Как сохранить объект protobuf в memcached?
Ниже приведен прототип файла, который я использую для создания системы 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 Getting Started. Я использую эти классы на сервере для хранения результатов запроса к БД и пытаюсь сохранить эти объекты в memcached. К сожалению, объект protobuf не добавляется в memcached. Ниже описано, как я добавляю его в memcached и значение isKeyFirstTimeCreated
ложно, когда я пытаюсь добавить его.
isKeyFirstTimeCreated = mc.Store(StoreMode.Add, key, t, DateTime.Now.Add(cacheDuration));
В соответствии с требованием к memcached все объекты, которые должны храниться в memcached, должны быть сериализуемыми. Но автоматически сгенерированные классы protobuf не сериализуемы (по крайней мере для двоичного форматера, который использует C#). Теперь, когда классы являются частичными реализациями, я сделал их сериализуемыми, но это не помогло, так как RepeatedField не Serializable.
IMO, должен быть лучший способ или какой-то механизм, который позволил бы мне сохранять объекты protobuf непосредственно в memcached, но, к сожалению, Googling мне не сильно помог в этом отношении.
Я могу добиться этого двумя способами
путем копирования данных из объекта protobuf в сериализуемый объект, а затем сохранить их в memcached для использования в будущем
скопируйте данные в сериализуемый объект и используйте этот объект для заполнения объекта protobuf.
Но эти два подхода требуют дополнительной работы. Есть ли лучший способ добиться этого?
[PS: я использую Proto3, следовательно, он поддерживает C#]
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 (или аналогичной), поддерживающей это напрямую: я бы посоветовал против этого по причинам разделения интересов. Тем не менее, методы расширения, как правило, позволяют легко обеспечить это несколькими строками вспомогательных методов в вашем собственном коде.