【Mongodb】Mongodb亿级数据性能测试和压测
一,mongodb数据性能测试
如需转载,请标明出处:https://zhenghuisheng.blog.csdn.net/article/details/139505973
mongodb数据性能测试
- 一,mongodb数据性能测试
- 1,mongodb数据库创建和索引设置
- 2,线程池+批量方式插入数据
- 3,一千万数据性能测试
- 4,两千万数据性能测试
- 5,五千万数据性能测试
- 6,一亿条数据性能测试
- 7,压测
- 8,总结
之前公司将用户的游戏数据存储在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; //账号id private 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) { //获取当前机器的cpu int cpuNum = Runtime.getRuntime().availableProcessors(); int maximumPoolSize = cpuNum * 2 ; pool = new ThreadPoolExecutor( maximumPoolSize - 2, maximumPoolSize, 5L, //5s TimeUnit.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; } @Override public Object call() throws Exception { List list = new ArrayList(); for (int i = 1; i Archive archive = new Archive(); archive.setCategory("score"); archive.setId(SnowflakeUtils.nextOrderId()); archive.setParentId(SnowflakeUtils.nextOrderId()); Map 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 for (int i = 0; i