代码之家  ›  专栏  ›  技术社区  ›  Jins Peter

如何在不序列化的情况下重新发现缓存大型C对象?

  •  0
  • Jins Peter  · 技术社区  · 6 年前

    在我的应用程序中,我们使用c dictionary在内存中缓存一个大型业务对象。

    为了对redis缓存进行json序列化/反序列化,我正在将大型多轮引用c对象(json序列化时大约300kb)转换为dto。

    由于参数化构造函数,我的业务层中的某些类型似乎无法轻松初始化。

    有没有一种方法可以在不序列化的情况下重新发现缓存?这样能把我缓存的对象还给我吗?

    1 回复  |  直到 5 年前
        1
  •  2
  •   rickvdbosch    6 年前

    有没有一种方法可以在不序列化的情况下重新发现缓存?

    简而言之: 是的。

    稍长一点的答案是:不,因为redis是基于字符串的。在这些字符串中,你可以存储各种各样的东西,但最终都归结为字符串。所以当你想在redis中存储一些东西的时候,你不能不序列化。

    redis不是 平原 键值存储,实际上是 数据结构 服务器,支持不同类型的值。这意味着,虽然在传统的键值中,将字符串键与字符串值相关联,但在redis中,该值不仅限于简单的字符串,而且还可以保存更复杂的数据结构。以下是redis支持的所有数据结构的列表,本教程将单独介绍这些数据结构:

    • 二进制安全字符串。
    • 列表:根据插入顺序排序的字符串元素集合。它们基本上是链表。
    • 集合:唯一的、未排序的字符串元素集合。
    • 排序集,类似于集合,但每个字符串元素都与一个浮点数(称为score)相关联。元素总是按其分数排序,因此与集合不同,可以检索一系列元素(例如,您可能会问:给我前10个,或后10个)。
    • 散列,是由与值关联的字段组成的映射。字段和值都是字符串。这与ruby或python散列非常相似。
    • 位数组(或简单的位图):使用特殊命令,可以像处理位数组一样处理字符串值:可以设置和清除单个位,将所有位设置为1,查找第一个设置或未设置的位,等等。
    • 超级日志:这是一种概率数据结构,用于估计集合的基数。别害怕,这比看起来简单多了…请参阅本教程的hyperloglog部分的后面部分。

    更多信息: An introduction to Redis data types and abstractions

        2
  •  0
  •   Jins Peter    5 年前

    可以。我知道我问这个问题已经很久了。但我们解决了这个问题。 我们使用了BinaryFormatter序列化程序,它基本上将.NET对象转换为内存映射并将其序列化为二进制数组。此内存映射可用于在没有公共默认构造函数的情况下重新创建原始对象。 早期版本的.NET支持此BinaryFormatter序列化。

    这种方法的缺点是,我们必须手动转到对象层次结构中的每个类,并给出 Serializable 将装饰属性赋予类。 另一个缺点是,只有包含非空值的属性才会被序列化。 这意味着,如果没有任何单元测试初始化要序列化的对象的某些或任何属性,则很可能会遇到运行时序列化异常,可以通过修饰类型轻松解决此异常 可串行化

    我们还可以使用其他序列化格式,如msgpack等。

    public class TheTypeToBeCached
    {
       public OneSubType Property1 {get;set;}
       public SecondSubType Property2 {get;set;}
    }
    
    public class OneSubType 
    {
        public ThirdSubType Property3 {get;set;}
        public ForthSubType Property4 {get;set;}
        public AnotherSubType Property5 {get;set;}
    }
    public class SecondSubType
    {
        public ForthSubType Property6 {get;set;}
        public AnotherSubType Property7 {get;set;}
    }
    public class ThridSubType
    {
        public SecondSubType Property8{get;set;}
    }
    public class ForthSubType
    {
        public SecondSubType Property9{get;set;}
    }
    public class AnotherSubType
    {
        public OneSubType Property10{get;set;}
    }
    

    上面的层次结构可以使用BinaryFormatter序列化程序进行序列化和反序列化,即使它具有多个round关系。

    [Serializable]
    public class TheTypeToBeCached
    {
       public OneSubType Property1 {get;set;}
       public SecondSubType Property2 {get;set;}
    }
    
    [Serializable]
    public class OneSubType 
    {
        public ThirdSubType Property3 {get;set;}
        public ForthSubType Property4 {get;set;}
        public AnotherSubType Property5 {get;set;}
    }
    
    [Serializable]
    public class SecondSubType
    {
        public ForthSubType Property6 {get;set;}
        public AnotherSubType Property7 {get;set;}
    }
    
    [Serializable]
    public class ThridSubType
    {
        public SecondSubType Property8{get;set;}
    }
    
    [Serializable]
    public class ForthSubType
    {
        public SecondSubType Property9{get;set;}
    }
    
    [Serializable]
    public class AnotherSubType
    {
        public OneSubType Property10{get;set;}
    }