背景说明

近期北京理财频道反馈用来存放股市实时数据的MongoDB数据库写响应请求很慢,难以跟上业务写入速度水平。我们分析了线上现场的情况,发现去年升级到SSD磁盘后,数据持久化的磁盘IO开销已经不是瓶颈.通过日志分析,线上单次写入(更新)请求大多在数十毫秒这个级别,数据库端观察几个主要的db在繁忙时通常有95%以上的时间在进行锁等待。线上数据库并发很高,接近1000个连接,所以怀疑是并发争用表锁导致性能不足。

我们知道MongoDB的mmap存储引擎一直是库/表级锁,因此任何写操作并发越高锁争用造成的性能损耗越大。为了改善锁并发性能MongoDB,升级到行级锁引擎应该能够改善线上更新数据的性能瓶颈。3.0的WT存储引擎和toku开发的tokumx存储引擎都号称实现了行级锁和多版本并发控制。因此,为了确定我们升级的方向,决定使用线上类似的场景,对三种存储引擎进行一次性能测试,评估最能改善并发更新写的方案。

我们取得了线上最繁忙的stock和stock_status数据,并且仿照线上并发更新最频繁的根据证券code更新的方式,在测试环境进行测验。

硬件环境

CPU:  24 核 Intel(R) Xeon(R) CPU E5-2630 0 @ 2.30GHz

内存:  48G

磁盘:  SSD

MongoDB版本

1. Mmap存储引擎 MongoDB-2.6.9

2. Toku存储引擎 MongoDB-2.4.10

3. WiredTiger存储引擎 MongoDB 3.0.5

测试用例

从线上将股票信息表数据导入测试环境,创建与线上一致的索引,股票码code_id为唯一索引。

单纯写测试:从股票表stock中抽取1000个code_id,用随机函数获取其中一个code_id,对这一行数据进行一次update操作;

读写混合测试:在一定并发度的写操作情况下,以同样并发度通过code_id读取一行数据,读写混合比例为1:1。

测试脚本

1.写测试脚本

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import multiprocessing
import time
import random
import pymongo
client = pymongo.MongoClient("172.17.1.234", 27017)
db = client.stock
def get_id():
 code_list = [1000个code_id]
 code_loct = random.randint(0, 999)
 up_value  = random.randint(10, 99)/10.0
 return code_list[code_loct], up_value
def update_func():  
 while True:
   code_id, up_value = get_id()    
   db.stock.update_one({"CODE":str(code_id)},{"$set":
{"ASK1":str(up_value),"ASK2":str(up_value),"ASK3":str(up_value),"ASK4":str(up_value),"ASK5":str(up_value),"ASKVOL1":str(up_value),"ASKVOL2":str(up_value),"ASKVOL3":str(up_value),"ASKVOL4":str(up_value),"ASKVOL5":str(up_value),"BID1":str(up_value),"BID2":str(up_value),"BID3":str(up_value),"BID4":str(up_value),"BID5":str(up_value)}})
if __name__ == "__main__":
 pool = multiprocessing.Pool(processes=并发度)  
 for i in xrange(10000000):
   pool.apply_async(update_func,)
 pool.close()
 pool.join()  
 print "\n"  print "All done."
2.读测试脚本
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import multiprocessing
import time
import random
import pymongo
client = pymongo.MongoClient("172.17.1.234", 27017)
db = client.stock
def get_id():
 code_list = [1000个code_id]
 code_loct = random.randint(0, 499)  
 return code_list[code_loct]
def update_func(): 
 while True:
   code_id = get_id()    
 db.stock.find_one({"CODE":str(code_id)},{"CODE":1,"ASK1":1,"ASK2":1})
if __name__ == "__main__":
 pool = multiprocessing.Pool(processes=并发度)  
 for i in xrange(1000000):
    pool.apply_async(update_func,)
 pool.close()
 pool.join()  
 print "\n"
 print "All done."

测试结果

1.单纯写的测试结果

结论:WiredTiger在纯update测试场景中性能明显高于toku和mmap

a.toku和mmap并发度超过32后TPS稳定在1.4万到1.5万左右,此时整体DB的锁争用非常高

b.WiredTiger表现良好,128并发度时TPS处理能力达到5万多,更高并发下处理能力逐渐下降,稳定在3万到4万之间

2.读写1比1混合的测试结果

结论:WiredTiger在读写1比1混合测试场景中,综合能力优于toku和mmap,且读写互不影响,都比较稳健

 

a.WiredTiger在读写混合测试场景中更新性能明显高于toku和mmap,读性能在高于256时不如toku和mmap,但是读写互不影响且性能较为稳定

b.mmap在高并发情况下读性能良好,但是更新性能下降很明显,受读的影响较大

c.toku在读写两端就像是WiredTiger和mmap的中庸版

读写混合模式下,WiredTiger在32到256之间的并发情况下,综合能力优于toku和mmap,其他并发度情况下读写综合能力相近

小结

由测试结果可以看出,3.0的WT引擎对多并发更新的场景明显好于其他两种引擎,TPS性能有较大的提升,因此建议线上升级3.0并且更换存储引擎。

目前线上已经在测试环境部署了3.0的数据库,等待应用反馈回归测试结果,如果一切顺利,打算尽快升级

 

原创文章  

禁止其他公众账号转载

mongodb三种存储引擎高并发更新性能专题测试的更多相关文章

  1. MySQL三种存储引擎总结

    MySQL三种存储引擎 MyISAM.InnoDB.MEMORY 1.MyISAM MyISAM,3.23.34a前的默认存储引擎. 优缺点 优点 在于占用空间小,处理速度快. 缺点 不支持事务的完整 ...

  2. MySQL常见的三种存储引擎(InnoDB、MyISAM、MEMORY)

    简单来说,存储引擎就是指表的类型以及表在计算机上的存储方式. 存储引擎的概念是MySQL的特点,Oracle中没有专门的存储引擎的概念,Oracle有OLTP和OLAP模式的区分.不同的存储引擎决定了 ...

  3. MySQL常见的三种存储引擎

    原文链接:https://www.cnblogs.com/yuxiuyan/p/6511837.html 简单来说,存储引擎就是指表的类型以及表在计算机上的存储方式. 存储引擎的概念是MySQL的特点 ...

  4. 随笔-SQL的三种存储引擎即三种类型的表

    MYSQL 的环境变量:......server/bin下 引擎(Engine):是电子平台上开发程序或系统的核心组件.利用引擎,开发者可迅速建立.铺设程序所需的功能,或利用其辅助程序的运转.一般而言 ...

  5. mysql三-1:存储引擎

    一 什么是存储引擎 mysql中建立的库===>文件夹 库中建立的表===>文件 现实生活中我们用来存储数据的文件有不同的类型,每种文件类型对应各自不同的处理机制:比如处理文本用txt类型 ...

  6. Mysql(三)-1:存储引擎

    一 什么是存储引擎 mysql中建立的库===>文件夹 库中建立的表===>文件 现实生活中我们用来存储数据的文件有不同的类型,每种文件类型对应各自不同的处理机制:比如处理文本用txt类型 ...

  7. python、mysql三-1:存储引擎

    一 什么是存储引擎 mysql中建立的库===>文件夹 库中建立的表===>文件 现实生活中我们用来存储数据的文件有不同的类型,每种文件类型对应各自不同的处理机制:比如处理文本用txt类型 ...

  8. MySQL - 两种存储引擎 (MyISAM PK InnoDB) + MVCC

    总结 1.两种存储引擎各有各的有点,MyISAM专注性能,InnoDB专注事务.两者最大的区别就是InnoDB支持事务,和行锁. 2.InnoDB采用MVCC(Multi-Version Concur ...

  9. {MySQL存储引擎介绍}一 存储引擎解释 二 MySQL存储引擎分类 三 不同存储引擎的使用

    MySQL存储引擎介绍 MySQL之存储引擎 本节目录 一 存储引擎解释 二 MySQL存储引擎分类 三 不同存储引擎的使用 一 存储引擎解释 首先确定一点,存储引擎的概念是MySQL里面才有的,不是 ...

随机推荐

  1. Postgres和MySQL创建用户并授予db权限

    Postgresql和MySQL还是有很多不同的.就比如授权来说.当下有个业务场景,我们的报表数据库需要根据业务划分不同的db,然后创建对应的user. 如果是MySQL, 可以这样做 mysql&g ...

  2. Android -- 再来一发Notification

    之前写过一个Notificaiton的文章,用上面的方式去操作也是OK的,但是到后面的SDK之后,有些方法被弃用,甚至我到SDK23的时候,我发现有些方法直接没了,所以在这里重新写一下最新的用法. h ...

  3. Spark:几种给Dataset增加列的方式、Dataset删除列、Dataset替换null列

    几种给Dataset增加列的方式 首先创建一个DF对象: scala> spark.version res0: String = .cloudera1 scala> val , , 2.0 ...

  4. .NET 并行编程——数据并行

    本文内容 并行编程 数据并行 环境 计算 PI 矩阵相乘 把目录中的全部图片复制到另一个目录 列出指定目录中的所有文件,包括其子目录 最近,对多线程编程,并行编程,异步编程,这三个概念有点晕了,之前我 ...

  5. 微软BI 之SSIS 系列 - 平面文件格式的区别(Delimited,Fixed width,Ragged Right, Fixed width ...)

    开篇介绍 SSIS 中处理文件,一般在描述输出平面文件格式的时候通常会出现以下几种选项: Delimited - 默认输出列使用逗号分隔,也可以选择其它的诸如 | ,或者 Tab 等. Fixed W ...

  6. 最新整合maven+SSM+Tomcat 实现注册登录

    mybatis学习 http://www.mybatis.org/mybatis-3/zh/index.html Spring学习:http://blog.csdn.net/king1425/arti ...

  7. domino server端的Notes.ini详解

    Web代理监控与调式问题     Web代理在服务器的执行优先级是最高的,由Web代理引发的服务器宕机现象很多,但是我们很难监控Web代理的运行.通过对notes.ini的研究可以通过如下途径进行处理 ...

  8. Chrome禁止http自动转为https

    解决方法 在Chrome浏览器地址栏输入chrome://net-internals/#hsts 在Delete domain security policies 中输入要删除自动转换的域名 原因 将 ...

  9. imp-oracle10g数据库dmp导入到11g数据库提示IMP-00058,表或试图不存在

    拿了一份从10g数据库导出的dmp,本机安装的是11.2g的oracle数据库,执行imp导入后提示: IMP-00058: 遇到 ORACLE 错误 942ORA-00942: 表或视图不存在 开始 ...

  10. Github忽略keil工程生成的链接、编译等文件

    *.bak *.ddk *.edk *.lst *.lnp *.mpf *.mpj *.obj *.omf *.plg *.rpt *.tmp *.__i *.crf *.o *.d *.axf *. ...