.NET Thin Client操作Ignite缓存触发“Too many open cursors”异常
异常信息
Exception : "Apache.Ignite.Core.Client.IgniteClientException: 50000: Too many open cursors (either close other open cursors or increase the limit through ClientConnectorConfiguration.maxOpenCursorsPerConnection) [maximum=128, current=128]
at Apache.Ignite.Core.Impl.Client.Cache.CacheClient2.HandleError[T](ClientStatusCode status, String msg) at Apache.Ignite.Core.Impl.Client.ClientSocket.DecodeResponse[T](BinaryHeapStream stream, Func2 readFunc, Func3 errorFunc) at Apache.Ignite.Core.Impl.Client.ClientSocket.DoOutInOp[T](ClientOp opId, Action1 writeAction, Func2 readFunc, Func3 errorFunc)
at Apache.Ignite.Core.Impl.Client.ClientFailoverSocket.DoOutInOp[T](ClientOp opId, Action1 writeAction, Func2 readFunc, Func3 errorFunc) at Apache.Ignite.Core.Impl.Client.Cache.CacheClient2.DoOutInOp[T](ClientOp opId, Action1 writeAction, Func2 readFunc)
at Apache.Ignite.Core.Impl.Client.Cache.CacheClient2.Query[T](SqlFieldsQuery sqlFieldsQuery, Func3 readerFunc)
at Apache.Ignite.Linq.Impl.CacheFieldsQueryExecutor.ExecuteSingle[T](QueryModel queryModel, Boolean returnDefaultWhenEmpty)
at Remotion.Linq.Clauses.StreamedData.StreamedSingleValueInfo.ExecuteSingleQueryModel[T](QueryModel queryModel, IQueryExecutor executor)
at Remotion.Linq.Clauses.StreamedData.StreamedSingleValueInfo.ExecuteQueryModel(QueryModel queryModel, IQueryExecutor executor)
at Apache.Ignite.Linq.Impl.CacheFieldsQueryProvider.Execute[TResult](Expression expression)
问题根源
该异常是因为客户端单连接上打开的游标数达到了Ignite默认上限(128)。你的场景中同时使用Apache.Ignite.Linq和IFieldsQueryCursor执行查询,且大量SQL查询仅通过Select转换为IEnumerable(延迟执行),导致游标无法及时关闭,持续占用资源。
解决方案
1. 显式释放游标资源
IFieldsQueryCursor实现了IDisposable接口,必须确保使用后及时释放:
- 使用
using语句自动管理游标生命周期,避免手动遗漏:
using (var cursor = cache.Query(new SqlFieldsQuery("SELECT id, name FROM MyCache"))) { // 立即将结果加载到内存,同时释放游标 var resultList = cursor.Select(row => new { Id = row.GetValue<int>(0), Name = row.GetValue<string>(1) }).ToList(); // 处理resultList }
- 避免仅将游标转换为
IEnumerable而不立即枚举:延迟执行会让游标保持打开状态,直到枚举完成,高并发场景下极易触发上限。
2. 调整服务器端游标上限
如果业务确实需要更多并发游标,可修改Ignite服务端配置增大maxOpenCursorsPerConnection值:
- XML配置方式:
<bean class="org.apache.ignite.configuration.IgniteConfiguration"> <property name="clientConnectorConfiguration"> <bean class="org.apache.ignite.configuration.ClientConnectorConfiguration"> <!-- 根据业务需求设置合适值,比如256或更高 --> <property name="maxOpenCursorsPerConnection" value="256"/> </bean> </property> </bean>
-.NET代码配置方式(若服务端用.NET启动):
var igniteCfg = new IgniteConfiguration { ClientConnectorConfiguration = new ClientConnectorConfiguration { MaxOpenCursorsPerConnection = 256 } }; Ignition.Start(igniteCfg);
3. 优化查询并发模式
- 减少同时打开的游标数量,批量处理查询请求,避免短时间内发起大量查询。
- 对于Ignite LINQ查询,确保查询结果被及时枚举或转换为集合(如
ToList()),避免游标长时间占用连接资源。
内容的提问来源于stack exchange,提问作者parikshanth

