SQL/MongoDB 连接并发测试

       最近一直在搞mongodb 文件服务器大量文件并发上传测试,在官方文档发现mongo是线程安全的,支持单一连接下的并发操作。印象ADO.NET 似乎不支持单一连接并发。于是,测试一下来证实这个疑虑。(前两篇小记一直纠结mongodb吃内存导致并发文件上传变慢问题,经过这两天测试,发现文件并发上传越来越慢的瓶颈是磁盘的IO读写的瓶颈)

以10W条/20W条 记录写入测试,下面是测试结果

操作 10W w/s 20W w/s 操作方式 备注
1 79.958 163.396 主线程 有池 单连接 单打开 单打开指的一次open close 内执行所有写入操作
2 79.958 164.412 主线程 有池 单连接 多打开 多打开指的写入一次就open close一次
        总结:可以看出有池的情况open close基本没有性能消耗。
MSDN官方解释,池的效果在minpoolsize不为零的情况,
总保持相应数量的活动连接,当Open的时候实现直接用了活动连接,
而Close操作并没close,只是又将活动连接放回池里。
3 79.13 163.396 主线程 无池 单连接 单打开  
4 290.334 620.694 主线程 无池 单连接 多打开  
        总结:无池的情况下,open close非常消耗性能,由于没池每次Open
Close 都要打开关闭连接 ,所以效率没有池高。
5 49.13 142.33 单线程 无池 单连接 单打开 异步执行反而快了?测了几次都这个结果
6 326.495 865.44 单线程 无池 单连接 多打开  
         
7 137.985   有池 单连接 单打开 10线程并行写入  写入锁 Ado.net 不支持单连接并行写入 通过线程锁控制实现
8 141.464   有池 单连接 多打开 10线程并行写入  写入锁 Ado.net 不支持单连接并行写入 通过线程锁控制实现
        总结:单连接通过写入锁控制多线程写入速度明显慢了很多,
单连接并不适合并发写入操作。
9 18.943 37.815 有池 10连接并行 单打开  相当于操作1 ----  10个单连接 单打开 的并行操作
10 19.658 41.793 有池 10连接并行 多打开  相当于操作1 ----  10个单连接 多打开 的并行操作
        总结: 多线程并行多连接的操作效果还是很理想的,发挥了多线程任务的优势。Connection是非线安全的,也就是说最好为每个线程单独创建一个数据库连接实例是最理想的。
         

可以确定的是ado.net connection 是非线程安全的 一个连接下一次open close 过程不允许并发,并且多次open close并发会相互冲突 (想并发只能通过锁来控制了,但这个不用想肯定效率不高)。

      而mongodb 则在这方面具有优势, mongo是线程安全的。一个连接下是允许并行写入操作的,同样mongodb 可以多连接并发,然后每个连接下又可以多并发写入操作,这样每秒并写入记录数可以更高。mongodb的池,是预先创建指定数量的闲置连接,用到其中的连接的时候,该转为活动状态。经过这两天测试,mongodb的单连接的并行写入效率没有并行多连接写入的效率高。推测mongodb的单连接并行写入也采用了写锁或者队列,效率上可能低于多连接操作。因此在合理的并行线程内,合适的并行连接数写入很重要。

由此可见,不同的数据库池的设计理想有所不同。

而ado.net 写入并发实现只有下面两种合适的
一 有池-单连接 单打开  并发写入(引及写入锁) (锁的引入,反而导致速度下降,这个方案排除了)

二 无池-并发多连接   单打开                   这种不推荐 
二 有池-并发多连接   单打开/多打开          目前,测试只有这种情最理想

另外建议连接池的minpoolsize 要设置(不设置或设置为零,会在一定时间内关闭池内所有连接)但不要设置太高,否则会占用太多资源。详细可查看MSDN介绍。

在微软的Petshop以及很多开源项目曾经看到的SQLHelper此类的数据库存操作类大都是静态的? 为什么呢,因为静态方法在不引用静态字段的前提下是线程安全的。静态字段是多线程共享的,而静态方法在每个线程是都有一个副本,只要静态方法不调用静态字段则是线程安全的,因此我们看到为何SQL 单连接的情况都是使用静态方法,可以防止单连接并发操作。

你可能感兴趣的:(mongodb)