在将 mongo 持久性与 NEventStore 结合使用时,有什么方法可以压缩数据吗?

Jos*_*cis 6 compression mongodb event-sourcing neventstore .net-core

我正在使用 C#、Dotnet core 和NeventStore(版本 9.0.1),尝试评估它支持的开箱即用的各种持久性选项。

更具体地说,当尝试使用 mongo 持久性时,有效负载将在不应用任何压缩的情况下进行存储。

注意:当使用 NEventStore 的 SQL 持久性时,有效负载压缩完美发生,而不是使用 mongo 持久性。

我使用以下代码来创建事件存储并初始化:

    private IStoreEvents CreateEventStore(string connectionString) 
    { 
        var store = Wireup.Init() 
                        .UsingMongoPersistence(connectionString,  
                             new NEventStore.Serialization.DocumentObjectSerializer()) 
                        .InitializeStorageEngine() 
                        .UsingBsonSerialization() 
                        .Compress() 
                        .HookIntoPipelineUsing() 
                        .Build(); 
        return store; 
    }
Run Code Online (Sandbox Code Playgroud)

而且,我使用以下代码来存储事件:

public async Task AddMessageTostore(Command command) 
{ 
    using (var stream = _eventStore.CreateStream(command.Id)) 
         { 
                stream.Add(new EventMessage { Body = command }); 
                stream.CommitChanges(Guid.NewGuid()); 
         }
} 
Run Code Online (Sandbox Code Playgroud)

解决方法是: 在 IPipelineHook 中实现 PreCommit(CommitAttempt 尝试)和 Select 方法,并通过使用 gzip 压缩逻辑在 MongoDB 中实现事件压缩。

附加 SQL 和 mongo 持久性的数据存储映像: 在此输入图像描述

在此输入图像描述

所以,问题是:

  1. 我是否缺少其他一些选项或设置,以便在保存时压缩事件(调用压缩方法的流畅方式)?
  2. 上述解决方法是否明智,还是性能开销?

小智 1

我在使用NEventStore.Persistence.MongoDB时也遇到了同样的问题。

即使我使用了流畅的压缩方法,有效负载压缩在 mongo 持久性中也没有像 SQL 持久性那样完美地发生。最后,我通过自定义PreCommit(CommitAttempt attempts)Select(ICommit commit)方法内部的逻辑来实现压缩/解压。

用于压缩的代码:

using (var stream = new MemoryStream())
   {
      using (var compressedStream = new GZipStream(stream,
                                              CompressionMode.Compress))
        {

           var serializer = new JsonSerializer { 
                           TypeNameHandling = TypeNameHandling.None, 
                           ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
           };
           
           var writer = new JsonTextWriter(new StreamWriter(compressedStream));
           serializer.Serialize(writer, this);
           writer.Flush();
      }
    return stream.ToArray();
}
Run Code Online (Sandbox Code Playgroud)

解压使用的代码:

using (var stream = new MemoryStream(bytes))
 {
    var decompressedStream = new GZipStream(stream, CompressionMode.Decompress);
    var serializer = new JsonSerializer {  
                            TypeNameHandling = TypeNameHandling.None, 
                            ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
    };
    
   var reader = new JsonTextReader(new StreamReader(decompressedStream));
   var body = serializer.Deserialize(reader, type);
   return body as Command;
}
Run Code Online (Sandbox Code Playgroud)

我不确定这是否是正确的方法,或者这是否会对 EventStore 操作(如插入和选择)的性能产生任何影响。