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

06-14 1251阅读

一,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 可视化工具,如下图,很多操作都是可以在这个可视化图形界面上面直接操作的

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

          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 
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]