c# - Apache 点燃 2.1 : Getting a "Conflicting type IDs" error after upgrading from 2. 0

标签 c# ignite

从 Apache Ignite 2.0 升级到 2.1 (.Net) 后,我收到错误“类型 ID 冲突 [type1='Row', type2='Row', typeId=113114]”。升级后我没有更改任何代码,所以我想知道如何创建和使用动态二进制对象的期望是否改变了?我查看了 AddType 方法。也许它应该返回而不是抛出,也许方法的名称具有误导性,它应该是 GetOrAddType?

添加类型方法: https://github.com/apache/ignite/blob/efd299f401ea34e040037c76be0c9f86e0e8e239/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs#L667

堆栈跟踪:

   at Apache.Ignite.Core.Impl.Binary.Marshaller.ThrowConflictingTypeError(Object type1, Object type2, Int32 typeId)
   at Apache.Ignite.Core.Impl.Binary.Marshaller.AddType(Type type, Int32 typeId, String typeName, Boolean userType, Boolean keepDeserialized, IBinaryNameMapper nameMapper, IBinaryIdMapper idMapper, IBinarySerializerInternal serializer, String affKeyFieldName, Boolean isEnum)
   at Apache.Ignite.Core.Impl.Binary.Marshaller.AddUserType(BinaryTypeConfiguration typeCfg, TypeResolver typeResolver)
   at Apache.Ignite.Core.Impl.Binary.Marshaller.GetDescriptor(Boolean userType, Int32 typeId, Boolean requiresType, String typeName, Type knownType)
   at Apache.Ignite.Core.Impl.Binary.Marshaller.GetDescriptor(String typeName)
   at Apache.Ignite.Core.Impl.Binary.Binary.GetBuilder(String typeName)
   at MyCompany.DataFabric.Core.CacheManagers.Table.RowCacheManager.BuildRow(Int64 rowNumber, String row, Boolean setColumnFields) in C:\Users\me\Documents\GitLab\Platform\Core\CacheManagers\Table\RowCacheManager.cs:line 140
   at MyCompany.DataFabric.Core.CacheManagers.Table.RowCacheManager.<>c__DisplayClass26_1.<WriteAsync>b__1(KeyValuePair`2 r) in C:\Users\me\Documents\GitLab\Platform\Core\CacheManagers\Table\RowCacheManager.cs:line 128
   at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()
   at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
   at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object )

这就是我的代码:

public async Task WriteAsync(IEnumerable<string> rows, long startRowNum = 0) {
    // Create the cache if it doesn't exist, yet
    await this.GetOrCreateRowCache();

    using (var ds = m_ignite.GetDataStreamer<string, object>(CacheName).WithKeepBinary<string, IBinaryObject>()) {
        try {
            ds.AllowOverwrite = true;
            ds.Receiver = new RowStreamReceiver {
                TableId = TableId
            };

            Parallel.ForEach(rows.Select((r, i) => new KeyValuePair<long, string>(i, r)), r => {
                var rowNum = r.Key + startRowNum;
                if (rowNum % 10000 == 0) {
                    Console.WriteLine($"Put [Row: {r.Key}, Thread: {Thread.CurrentThread.ManagedThreadId}]");
                }
                var pair = BuildRow(rowNum, r.Value, false);
                // ReSharper disable once AccessToDisposedClosure
                ds.AddData(pair);
            });
        } finally {
            Console.WriteLine("Flushing");
            ds.Flush();
        }
    }
}

public KeyValuePair<string, IBinaryObject> BuildRow(long rowNumber, string row, bool setColumnFields = true) {
    var builder = m_ignite.GetBinary().GetBuilder(TypeName);

    var rowId = row.GetHashString();
    builder.SetField(PrimaryKeyName, rowId);
    builder.SetField(RowNumberName, rowNumber);
    builder.SetField(RawName, row);

    if (setColumnFields) {
        SetColumnFields(m_table, row, builder);
    }

    return new KeyValuePair<string, IBinaryObject>(rowId, builder.Build());
}

最佳答案

我已经重现并提交了该错误:https://issues.apache.org/jira/browse/IGNITE-5931

这是一个竞争条件,我认为它也存在于2.0中(这段代码在2.1和2.0中是相同的)。还有另外两个地方正确地完成了类似的检查,期望出现多线程场景,但是忘记了这个。

解决方法 1:在 BinaryConfiguration 中注册类型:

        var cfg = new IgniteConfiguration
        {
            BinaryConfiguration = new BinaryConfiguration
            {
                Types = new[] {"Row"}
            }
        };

解决方法 2:同步对 GetBuilder 方法的访问(将其置于锁中)。实际处理不必加锁,因此性能不会受到影响。

关于c# - Apache 点燃 2.1 : Getting a "Conflicting type IDs" error after upgrading from 2. 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45494512/

相关文章:

java - 点燃异常 : Query execution failed ScanQuery

用值作为对象列表点燃查询缓存

c# - 如何确保 C# 项目中配置文件的更改导致 DLL 重建?

c# - 如何通过仅发送类的名称而不是类本身作为参数来获取类的类型?

java - Java/C# 中浮点计算的显着精度差异

javascript - 服务器端的 AngularJS 变量

java - Apache Ignite Cache 设置与当前机器的亲和性

c# - 如何强制 C# 异步操作以...同步方式运行?

java - 分页点燃缓存的正确方法是什么?

java - springboot缓存自动刷新redis和apache ignite