前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用DbContextPool提高EfCore查询性能

使用DbContextPool提高EfCore查询性能

作者头像
心莱科技雪雁
修改2020-01-03 14:37:41
1.9K0
修改2020-01-03 14:37:41
举报
文章被收录于专栏:雪雁的专栏

长话短说

  上个月公司上线了一个物联网数据科学项目,我主要负责前端接收设备Event,并提供模型参数下载(数据科学团队会优化参数)。WebApp部署在Azure,模型参数使用Azure SQL Server存储。

最近从灰度测试转向全量部署之后,日志中时常出现:SQL Session会话超限的报错。

代码语言:javascript
复制
19/12/18 20:41:18 [Error].[Microsoft.EntityFrameworkCore.Query].[][0HLS3MS83SC3K:00000004].[http://******/api/v1/soc-prediction-model/all].[].[GetModeParameters] 
An exception occurred while iterating over the results of a query for context type 'Gridsum.SaicEnergyTracker.CarModelContext'.
Microsoft.Data.SqlClient.SqlException (0x80131904): Resource ID : 2. The session limit for the database is 300 and has been reached. See 'http://go.microsoft.com/fwlink/?LinkId=267637' for assistance.
Changed database context to 'saic-carmodel'.
Changed language setting to us_english.
   at Microsoft.Data.ProviderBase.DbConnectionPool.CheckPoolBlockingPeriod(Exception e)
   at Microsoft.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.WaitForPendingOpen()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()

排查

  Azure上使用的是SQL Server Basic Edition(好歹也是付费版),全量发布至今,日均SQL访问次数约为10000,查询了Azure SQL的使用限制文档:

一句话:付费级别和计算资源大小决定了Azure SQL最大会话数/请求数。

若要缓解,要么升级硬件资源,要么优化查询利用率。

本次使用EFCore操作SQL Server的方式, 是官方默认用法:

  • 依赖注入框架注册一个自定义的 DbContext类型
  • 在Controller构造函数中获取 DbContext实例

这意味着每次请求都会创建一个 DbContext实例, 可以想象到

① 在高并发请求下,连接数不断累积,最终某时刻会超过 Azure 的连接限制数量。

② 频繁创建和销毁 DbContext 实例,影响App Service自身性能。

EFCore2.0 为DbContext引入新的注册方式:透明地注册了 DbContext实例池:

代码语言:javascript
复制
services.AddDbContextPool<CarModelContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SQL")));

- 一如既往支持lambda方式注册连接字符串

- 默认的连接池数量为 128

- 每次使用完DbContext不会释放对象,而是重置并回收到DBContextPool

Web程序中通过重用池中DbContext实例可提高高并发场景下的吞吐量, 这在概念上类似于ADO.NET Provider原生的连接池操作方式,具有节省DbContext实例化成本的优点, 这也是EFCore2.0 其中一个性能亮点。

这么重要的使用方式竟然不在 EFCore Doc指南中默认演示,真是一个坑。

修改代码重新部署之后,历经几天测试,暂时未出现最开始的SqlException异常。

验证

回过头随机验证SQL Server会话中的有效连接数量:48

代码语言:javascript
复制

SELECT DEC.session_id, DEC.protocol_type, DEC.auth_scheme,
  DES.login_name, DES.login_time
FROM sys.dm_exec_sessions AS DES
  JOIN sys.dm_exec_connections AS DEC
    ON DEC.session_id = DES.session_id;

总结

① 提示EFCore2.0新推出的DbContextPool特性,有效提高SQL查询吞吐量

② 尝试使用SQL Server 内置脚本自证会话中有效连接数

+ https://stackoverflow.com/questions/48443567/adddbcontext-or-adddbcontextpool

+ https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-2.0#dbcontext-pooling

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 麦扣聊技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档