【Mongodb-01】Mongodb亿级数据性能测试和压测

mongodb数据性能测试

  • 一,mongodb数据性能测试
        • 1,mongodb数据库创建和索引设置
        • 2,线程池+批量方式插入数据
        • 3,一千万数据性能测试
        • 4,两千万数据性能测试
        • 5,五千万数据性能测试
        • 6,一亿条数据性能测试
        • 7,压测
        • 8,总结

一,mongodb数据性能测试

如需转载,请标明出处:https://zhenghuisheng.blog.csdn.net/article/details/139505973

之前公司将用户的游戏数据存储在mysql中,就是直接将json数据存储到mysql数据库里面,几个月不到,数据库里面已经有两亿条数据,而且每行中每个json数据量也比较大,导致占用的磁盘容量也比较大,因此为了解决mysql带来多方面的瓶颈,最终选择使用mongodb来代替mysql。为了测试mongodbdb的性能以及是否满足需求,因此做了以下测试,对mongodb在高流量时验证其增删改查的效率,以及对其进行压测

服务器配置:2核4g轻量级服务器 磁盘容量 70GB

每条数据大概在500个字节,索引有一个id主键索引,还有一个parentId和category的联合唯一索引,这里两个字段能保证唯一性,因此用唯一索引效率更优

1,mongodb数据库创建和索引设置

首先在Java代码中创建一个实体类,用这个类作为json对象插入到文档中即可。

@Data
public class Archive {private String id;//账号idprivate String parentId;private String category;private String content;
}

随后在mongodb中创建一个数据库,然后再该库下面建立一个名为 archive 的集合,mongodb的集合就是类似于mysql的表,两者概念是一样的。由于后期数据量可能非常大,因此根据mongodb官方文档所说,在数据插入前,尽量提前建立索引,为了满足业务需求,这里选择创建一个联合索引,由于我这边业务能保证要加索引的两个字段的唯一性,因此选择直接添加唯一索引

db.users.createIndex({parentId: 1,category:1}, {unique: true})

如果navicate操作不方便的话,可以安装一个 Mongodb Compass 可视化工具,如下图,很多操作都是可以在这个可视化图形界面上面直接操作的
在这里插入图片描述

2,线程池+批量方式插入数据

由于这边主要是io操作将数据插入,不需要计算之类的,因此选择使用io密集型线程池,接下来自定义一个线程池

@Slf4j
public class ThreadPoolUtil {public static ThreadPoolExecutor pool = null;public static synchronized ThreadPoolExecutor getThreadPool() {if (pool == null) {//获取当前机器的cpuint cpuNum = Runtime.getRuntime().availableProcessors();int maximumPoolSize = cpuNum * 2 ;pool = new ThreadPoolExecutor(maximumPoolSize - 2,maximumPoolSize,5L,   //5sTimeUnit.SECONDS,new LinkedBlockingQueue<>(),  //数组有界队列Executors.defaultThreadFactory(), //默认的线程工厂new ThreadPoolExecutor.AbortPolicy());  //直接抛异常,默认异常}return pool;}
}

第二步就是定义一个线程任务,到时将任务丢到线程池里面,其代码如下,该任务实现Callable接口,每个线程插入10万条,每次批量插入100条数据,大概就是需要1000次

@Data
public class ArchiveTask implements Callable {private MongoTemplate mongoTemplate;public ArchiveTask(MongoTemplate mongoTemplate){this.mongoTemplate = mongoTemplate;}@Overridepublic Object call() throws Exception {List<Archive> list = new ArrayList<>();for (int i = 1; i <= 100000; i++) {Archive archive = new Archive();archive.setCategory("score");archive.setId(SnowflakeUtils.nextOrderId());archive.setParentId(SnowflakeUtils.nextOrderId());Map<String,String> map = new HashMap<>();StringBuilder sb = new StringBuilder();for (int j = 0; j < 15; j++) {sb.append(UUID.randomUUID());}map.put("key" + i, sb.toString());archive.setContent(JSON.toJSONString(map));list.add(archive);if (i%100 == 0){mongoTemplate.insertAll(list);list.clear();	//手动gc,100个对象没被引用会被回收list = new ArrayList<>();}}return null;}
}

最后定义一个测试类或者一个接口,我这边使用接口,部分代码如下,循环100次,就是会创建100个线程任务,随后将这个线程任务丢到线程池中,100乘以100000就是1千万条数据

@Resource
private MongoTemplate mongoTemplate;
static ThreadPoolExecutor threadPool = ThreadPoolUtil.getThreadPool();
@GetMapping("/add")
public void test(){for (int i = 0; i < 100; i++) {ArchiveTask archiveTask = new ArchiveTask(mongoTemplate);threadPool.submit(archiveTask);}log.info("数据添加完成");
}
3,一千万数据性能测试

mongodb性能测试,此时archive 集合中已有10134114条数据,平均每条数据大小674字节,1千多万条,此时的存储大小为5.5个g,索引的总大小为459m

接下来通过唯一索引查询一条数据,这里直接通过parentId查询一条数据,此时数据还是在不断插入的

db.archive.find({parentId:"2405291858848274156091867143"})

是的,如下图所示,1000多万条数据里面查询,只需要25ms即可将数据放回,当然这里没有在高流量的情况下进行压测。

在这里插入图片描述

4,两千万数据性能测试

此时archive集合来到了两千万条,每条数据和之前一样,平均大小是674字节,数据总大小来到了10.92G,内存大小12.65g,索引总大小是913m
在这里插入图片描述

接下来测试查询效率,依旧使用上面的这个parentId,由于设置的是parentId+category的联合唯一索引,接下来两个参数一起查

db.archive.find({parentId:"2405291858848274156091867143",category:"score"})

2000万的数据查询结果如下,只需要21ms,和上面的25ms慢了将近4ms,但是这4ms可以忽略

在这里插入图片描述

5,五千万数据性能测试

由于70G的磁盘容量已经只剩48G,因此在content字段将500字节的值调小,调整到150个字节,以便能插入更多数据。将上面的StringBuilder拼接的15个uuid改成1个uuid

map.put("key" + i,UUID.randomUUID().toString());

此时数据来到50245694条数据,每条数据平均大小372kb,总存储大小12.66g,内存中的总大小17.45g,索引大小目前只有2.8g

在这里插入图片描述

为了保证拿到的parentId是一次没有查询过的,手动的插入一批数据,手动单条插入20条数据,耗时600ms,在插入数据时会改变索引,插入数据会稍微慢些。此时的插入操作都是在多线程插入大量数据的时候测试的

db.archive.insertOne({parentId:"2024111222337",category:"score1",content:"cbasbsadhpasdbsaodgs"})
db.archive.insertOne({parentId:"2024111222337",category:"score2",content:"cbasbsadhpasdbsaodgs"})
....

此时第一次查询这条数据,共耗时153ms,共查出20条数据

在这里插入图片描述

再第二次查询之后,花费78ms,内部应该也是会将查询结果加入到缓存中,方便第二次查询

在这里插入图片描述

在上面的插入操作中由于会破坏到索引结构,因此耗时久一点。接下来看这个更新操作,

db.archive.updateOne({ parentId: "2024111222337",category:"score1" },{ $set: { content: "cbasbsadhpasdbsaodgsscore" } }
);

其结果如下,更新了一条数据,只花费了13毫秒的时间,因此更新操作速度是很快的。由于这里每一条数据都是唯一数据,因此不测试批量更新

在这里插入图片描述

最后测试删除数据,将这20条数据全部删除,总共花费18毫秒

在这里插入图片描述

6,一亿条数据性能测试

数据通过多线程+批量插入的方式来到一亿条,存储大小15.5g,索引长度是6g

db.archive.countDocuments()  //查询共有多少条数据
100082694

在这里插入图片描述

接下来往里面重新插入一部分数据,往里面插入20条数据,大概花费160多ms,插入数据会导致索引重构,所以耗时久一些,批量插入性能会更快。重新插入的数据可以保证这条数据没被查过,并且知道parentId是什么

db.archive.insertOne({parentId:"20240531101059",category:"score1",content:"abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy"})
....

接下来测试查询数据,只需要19ms

db.archive.find({parentId:"20240531101054"},{parentId:1,category:1}) //只返回部分字段
db.archive.find({parentId:"20240531101058"})

在这里插入图片描述

更新数据如下,只需要10ms

db.archive.updateOne({ parentId: "20240531101059",category:"score1" },{ $set: { content: "cbasbsadhpasdbsaodgsscore" } }
);

在这里插入图片描述

7,压测

以下压测都是数据达到1亿之后进行测试的,并且都是使用的2核4g的服务器

在1s内同时1000个线程插入数据,每个线程插入20条数据,中位数24,吞吐量391

在这里插入图片描述

在1s内10000个线程插入数据,也是每个线程批量插入20条数据,可以发现就算是2核4g这么垃圾的轻量级服务器,10000qps也是毫无压力的

在这里插入图片描述

插入数据会破坏索引,相对于修改和查询是更慢的,接下来测试1s内10000个线程同时执行增改查,吞吐量可以达到2251.7

在这里插入图片描述

部分代码片段如下,让10000个线程随机的执行增改查的操作,在1s内是毫无压力的

在这里插入图片描述

8,总结

通过上面的数据以及mongodb的响应来看,mongodb的性能还是非常不错的。看看GPT对这种数据的评价,gpt也认为mongodb是非常合适的。当然不管什么数据和业务,只要其本质是 json 数据,不管json内部结构多复杂,用mongodb都是非常合适的。mongodb还适合存一些订单数据,地理数据,大数据等等,其应用范围是非常广泛的

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/853257.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL-----InnoDB的自适应哈希索引

InnoDB存储引擎监测到同样的二级索引不断被使用&#xff0c;那么它会根据这个二级索引&#xff0c;在内存上根据二级索引树(B树)上的二级索引值&#xff0c;在内存上构建一个哈希索引&#xff0c;来加速搜索。 查看是否开启自适应哈希索引 show variables like innodb_adapti…

JavaScript常见面试题(一)

文章目录 1. JavaScript有哪些数据类型&#xff0c;它们的区别&#xff1f;2.数据类型检测的方式有哪些3. 判断数组的方式有哪些4.null和undefined区别5.typeof null 的结果是什么&#xff0c;为什么&#xff1f;6.intanceof 操作符的实现原理及实现7.为什么0.10.2 ! 0.3&…

Fluent固体运动的设置方法(1)

1 概述 固体运动是某些CFD问题中必须要考虑的因素&#xff0c;如风扇的旋转。相关问题可分类如下&#xff1a; 问题类型是否为刚体运动规律是否已知无特定称呼YY六自由度运动问题YN流固耦合问题NN 在 Fluent 中&#xff0c;有多种方法表征固体运动&#xff0c;包括&#xff1…

【医学图像处理】从ADNI中下载样本的MMSE数据

MMSE是什么&#xff1f; 简易精神状态检查&#xff08;MMSE&#xff0c;Mini-Mental State Examination&#xff09;是一种广泛使用的认知功能评估工具。它通常用于临床和研究环境中筛查痴呆症及评估其严重程度。MMSE通过考察患者的多种认知功能来进行评估&#xff0c;包括算术…

深度学习(八)——神经网络:卷积层

一、卷积层Convolution Layers函数简介 官网网址&#xff1a;torch.nn.functional — PyTorch 2.0 documentation 由于是图像处理&#xff0c;所以主要介绍Conv2d。 class torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride1, padding0, dilation1, groups1, b…

C++初学者指南第一步---3.输入和输出(基础)

C初学者指南第一步—3.输入和输出&#xff08;基础&#xff09; 1. I/O Streams(I/O流) #include <iostream>int main () {int i;// read value into istd::cin >> i; // print value of istd::cout << i << \n; }数据的来源和目标 …

解决MyBatis获取刚插入数据的ID值

解决MyBatis获取刚插入数据的ID值 Mybatis获取刚插入数据的ID值有很多解决方法&#xff0c;目前采用以下方式进行获取。 添加完数据后直接返回刚添加数据的id // UserDao.java public static void addUser() throws Exception{InputStream resourceAsStream Resources.getR…

绝了!篇篇10万+的AI治愈系插画,完整版项目拆解(附提示词)!

大家好&#xff0c;我是向阳 最近&#xff0c;治愈系插画在小某薯上热度很高&#xff0c;比如这个号&#xff0c;每一篇的笔记数据都不错&#xff0c;2个月时间涨粉7.3万。 然后&#xff0c;我偶然发现&#xff0c;有人把这样的治愈插画用到公某号爆文的配图上&#xff0c;每一…

Passper for ZIP 安装教程 (ZIP密码恢复软件)

前言 Passper for ZIP是一款功能强大且实用的ZIP密码恢复软件。当你忘记了压缩包的密码时&#xff0c;这个工具可以轻松解决这个问题。只需按照界面上的提示操作&#xff0c;选择文件&#xff0c;然后选择解码的方式&#xff0c;即可轻松等待恢复完成。该软件支持四种密码恢复…

软考初级网络管理员__Web网站的建立、管理维护以及网页制作单选题

1.在HTML 中&#xff0c;用于输出“>”符号应使用()。 gt \gt > %gt 2.浏览器本质上是一个&#xff08;&#xff09;。 连入Internet的TCP/IP程序 连入Internet的SNMP程序 浏览Web页面的服务器程序 浏览Web页面的客户程序 3.HTML 语言中&#xff0c;单选按钮的…

ollama 多模态llava图像识别理解模型使用

参考: https://llava-vl.github.io/ https://ollama.com/blog/vision-models https://blog.csdn.net/weixin_42357472/article/details/137666022 下载: ollama run llava:13bcli使用 图片地址前面空格就行 describe this image: /ai/a1.jpg

笔记本电脑安装属于自己的Llama 3 8B大模型和对话客户端

选择 Llama 3 模型版本&#xff08;8B&#xff0c;80 亿参数&#xff09; 特别注意&#xff1a; Meta 虽然开源了 Llama 3 大模型&#xff0c;但是每个版本都有 Meta 的许可协议&#xff0c;建议大家在接受使用这些模型所需的条款之前仔细阅读。 Llama 3 模型版本有几个&…

在矩池云使用GLM-4的详细指南(无感连GitHubHuggingFace)

GLM-4-9B 是智谱 AI 推出的最新一代预训练模型 GLM-4 系列中的开源版本&#xff0c;在多项测试中表现出超越已有同等规模开源模型的性能&#xff0c;它能兼顾多轮对话、网页浏览、代码执行、多语言、长文本推理等多种功能&#xff0c;性能更加强大。其多模态语言模型GLM-4V-9B在…

socket收发数据的处理

1. TCP 协议是一种基于数据流的协议 Socket的Receive方法只是把接收缓冲区的数据提取出来,当系统的接收缓冲区为空,Receive方法会被阻塞,直到里面有数据。 Socket的Send方法只是把数据写入到发送缓冲区里,具体的发送过程由操作系统负责。当操作系统的发送缓冲区满了,Send方法会…

《TCP/IP网络编程》(第十五章)套接字和标准I/O

之前数据通信时&#xff0c;使用的是read&write函数以及其他各种I/O函数&#xff0c;本章将使用标准I/O函数&#xff0c;例如C语言的fopen、fgetc、fputs等等&#xff1b;C语言的cout、cin等等 1.使用标准I/O函数的优点 ①跨平台兼容性&#xff1a; 标准I/O函数通常是跨平…

大数据实训项目(小麦种子)-04、大数据实训项目JavaWeb环境搭建

文章目录 前言运行前准备工作1、安装Hadoop3.1.0配置winutils原因描述配置方式注意点&#xff08;hadoop.dll拷贝System32目录下&#xff09; 2、hive运行报错&#xff08;The dir: /tmp/hive on HDFS should be writable. &#xff09; 项目环境搭建参考资料 前言 博主介绍&a…

【LLM之RAG】RAFT论文阅读笔记

研究背景 论文针对的主要问题是如何将预训练的大型语言模型&#xff08;LLMs&#xff09;适应特定领域的检索增强生成&#xff08;RAG&#xff09;。这些模型通常在广泛的文本数据上进行预训练&#xff0c;已经表现出在广义知识推理任务上的优越性能。然而&#xff0c;在特定领…

Google Earth Engine(GEE)——在控制台上答应出一个button按钮

函数: ui.Button(label, onClick, disabled, style) A clickable button with a text label. Arguments: label (String, optional): The buttons label. Defaults to an empty string. onClick (Function, optional): A callback fired when the button is clicked. T…

面试题 17.06. 2出现的次数

题解&#xff1a;. - 力扣&#xff08;LeetCode&#xff09;. - 力扣&#xff08;LeetCode&#xff09; 数位 DP 通用模板_哔哩哔哩_bilibili class Solution { public:int numberOf2sInRange(int n) {std::string str to_string(n);int len str.size();std::vector<std:…

SUSTAINABILITY,SCIESSCI双检期刊还能投吗?

本期&#xff0c;小编给大家介绍的是一本MDPI出版社旗下SCIE&SSCI双检“毕业神刊”——SUSTAINABILITY。据悉&#xff0c;早在2024年1月&#xff0c;ElSEVIER旗下的Scopus数据库已暂停收录检索期刊SUSTAINABILITY所发表文章&#xff0c;同时重新评估是否继续收录该期刊。随…