我最近一直在使用GitHub上的C#驱动程序玩MongoDB(它的速度非常快).在我正在测试的小单线程控制台应用程序中,一切正常.我可以在8秒内运行单线程添加1,000,000个文档(是的,百万个).如果我使用for循环范围之外的连接,我只能获得此性能.换句话说,我保持每个插入的连接打开,而不是连接每个插入.显然这是做作的.
我以为我会把它调到一个档位,看它是如何与多线程一起工作的.我这样做是因为我需要模拟一个包含多个并发请求的网站.我在15到50个线程之间旋转,在所有情况下仍然插入总共150,000个文档.如果我让线程运行,每个线程为每个插入操作创建一个新连接,性能就会停止.
显然,我需要找到一种共享,锁定或池连接的方法.这就是问题所在.连接到MongoDB的最佳做法是什么?连接是否应该在应用程序的生命周期内保持打开(每次操作都会有很长的延迟打开和关闭TCP连接)?
有没有人有MongoDB的任何现实世界或生产经验,特别是底层连接?
这是我使用为插入操作锁定的静态连接的线程示例.请提供可在Web环境中最大限度地提高性能和可靠性的建议!
private static Mongo _mongo;
private static void RunMongoThreaded()
{
_mongo = new Mongo();
_mongo.Connect();
var threadFinishEvents = new List<EventWaitHandle>();
for(var i = 0; i < 50; i++)
{
var threadFinish = new EventWaitHandle(false, EventResetMode.ManualReset);
threadFinishEvents.Add(threadFinish);
var thread = new Thread(delegate()
{
RunMongoThread();
threadFinish.Set();
});
thread.Start();
}
WaitHandle.WaitAll(threadFinishEvents.ToArray());
_mongo.Disconnect();
}
private static void RunMongoThread()
{
for (var i = 0; i < 3000; i++)
{
var db = _mongo.getDB("Sample");
var collection = db.GetCollection("Users");
var user = …Run Code Online (Sandbox Code Playgroud) c# performance connection-pooling mongodb mongodb-.net-driver
这是我的数据库连接字符串.到目前为止我没有设置最大池大小.
public static string srConnectionString =
"server=localhost;database=mydb;uid=sa;pwd=mypw;";
Run Code Online (Sandbox Code Playgroud)
那么目前我的应用程序支持多少个连接?增加连接池大小的正确语法是什么?
该应用程序是用C#4.0编写的.
它们会立即回滚吗?它们会在一段时间后回滚吗?他们是否处于未承诺状态?
如果使用连接池并且只是重置连接,行为是否相同?
sp_reset_connection似乎由SQL Server连接池调用,以确保从池中重用的连接重置其大部分设置.有没有人确切地知道它做了什么但不做什么呢?
例如,我从这篇文章中看到它没有重置事务隔离级别
据称Python的流行Requests库在其主页上是线程安全的,但没有给出进一步的细节.如果我调用requests.session(),我可以安全地将此对象传递给多个线程,如下所示:
session = requests.session()
for i in xrange(thread_count):
threading.Thread(
target=target,
args=(session,),
kwargs={}
)
Run Code Online (Sandbox Code Playgroud)
并在多个线程中使用相同的连接池发出请求?
如果是这样,这是推荐的方法,还是应该为每个线程提供自己的连接池?(假设所有单个连接池的总大小总计为一个大连接池的大小,如上所述.)每种方法的优缺点是什么?
为了测试,我将MYSQL(RDS)参数修改如下;
wait_timeout = 40(默认为 28800)
max_allowed_packet = 1GB(最大 - 只是为了确保问题不是由小数据包引起的)
net_read_timeout = 10
Interactive_timeout 不变
然后在没有pool_pre_ping设置选项的情况下测试我的应用程序(默认为 False),使应用程序保持非活动状态 40 秒,尝试登录,然后我得到
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: Traceback (most recent call last):
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: File "/var/www/api_server/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: context)
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: File "/var/www/api_server/venv/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 507, in do_execute
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: cursor.execute(statement, parameters)
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: File "/var/www/api_server/venv/lib/python3.6/site-packages/MySQLdb/cursors.py", line 206, in execute
Nov 14 20:05:20 …Run Code Online (Sandbox Code Playgroud) 我知道如果我实例化一个SqlConnection对象,我真的从连接池中获取连接.当我调用Open()时,它将打开连接.如果我在该SqlConnection对象上调用Close()或Dispose()方法,它将返回到连接池.
但是,这并没有真正告诉我它是否真的关闭,或者我是否仍然有一个与数据库的活动连接.
如何强制SqlConnection在网络级别关闭,或者至少告诉它什么时候关闭?
例:
using(SqlConnection conn = new SqlConnection(DBConnString)) {
conn.Open();
SqlCommand cmd = conn.CreateCommand();
...
cmd.ExecuteReader(CommandBehavior.CloseConnection);
...
}
Run Code Online (Sandbox Code Playgroud)
如果连接是TRULY关闭,则第二次和第三次运行也应该是300 ms.但我知道这些运行并没有真正关闭连接(我检查了SQL Server的活动监视器).它不需要额外的200ms来执行身份验证/等.
如何强制连接真正关闭?
思路
参考
我有一个基本的Spring JDBC应用程序,它具有非常基本的配置:
<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@1.1.1.1:1521:XXX"/>
<property name="username" value="username"/>
<property name="password" value="password"/>
</bean>
<bean id="dbThing" class="com.DbThing">
<property name="dataSource" ref="myDataSource"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
我想介绍一个连接池,并在阅读了几个线程后,我对使用哪个池库感到有点困惑.
似乎在SO上有更多学分的图书馆是CP30和DBCP.由于我使用的是Oracle,我还可以使用驱动程序提供的池数据源.我知道有更多的库可用 - 例如新的Apache Tomcat 7池库.
有没有我应该避免的图书馆?
我应该在给定的库中使用任何推荐的配置吗?
你想分享的任何"战争故事"?
我有一个grails应用程序,有高活动的flurries,但往往是一段时间不活动,可以持续几个小时到一个晚上.我注意到早上的第一个用户得到以下类型的异常,我相信这是由于池中的连接过时而MYSql数据库关闭它们.
我在Googling中发现了有关使用Connector/J连接属性'autoReconnect = true'是否是一个好主意的信息(以及即使连接被恢复,客户端是否仍会获得异常),或者是否设置其他属性将周期性地逐出或刷新空闲连接,测试借用等.Grails使用下面的DBCP.我目前有一个简单的配置,如下所示,我正在寻找一个答案,如何最好地确保在长时间非活动期间有效且未关闭后从池中抓取任何连接.
dataSource {
pooled = true
dbCreate = "update"
url = "jdbc:mysql://my.ip.address:3306/databasename"
driverClassName = "com.mysql.jdbc.Driver"
dialect = org.hibernate.dialect.MySQL5InnoDBDialect
username = "****"
password = "****"
properties {
//what should I add here?
}
}
Run Code Online (Sandbox Code Playgroud)
例外
2012-06-20 08:40:55,150 [http-bio-8443-exec-1] ERROR transaction.JDBCTransaction - JDBC begin failed
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 64,129,968 milliseconds ago. The last packet sent successfully to the server was 64,129,968 milliseconds ago. is longer than the server configured value of 'wait_timeout'. …Run Code Online (Sandbox Code Playgroud) database.yml中使用最广泛的选项如下:
adapter
encoding
database
pool
username
password
socket
host
port
timeout
Run Code Online (Sandbox Code Playgroud)
我知道使用上面的大部分但是池.所以我想知道database.yml中pool选项的用途是什么,或者我们需要为具有非常繁忙流量的应用程序设置任何其他参数.
sql ×4
mysql ×3
c# ×2
python ×2
sql-server ×2
ado.net ×1
c3p0 ×1
connector-j ×1
flask ×1
grails ×1
java ×1
mongodb ×1
performance ×1
spring ×1
transactions ×1