Как сохранить объект 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 (или аналогичной), поддерживающей это напрямую: я бы посоветовал против этого по причинам разделения интересов. Тем не менее, методы расширения, как правило, позволяют легко обеспечить это несколькими строками вспомогательных методов в вашем собственном коде.

Другие вопросы по тегам