Mongodb亿级别数据操作

最近因为公司业务关系每天需要将300w+的数据,双十一高峰时期为3000w+的数据快速查询并进行转储,而这个过程中查询是个头疼的问题,因为加上老数据总量将近3.2亿的数据量,查询起来如果不得当则会一不小心就暴掉了Mongodb,就容易发生惨烈的从删库到跑路。

基础条件:

SpringBoot项目

引入依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

// application.yml引入配置
data:
  mongodb:
    uri: mongodb://root:123565@localhost:27017/admin
    option:
        min-connection-per-host: 0
        max-connection-per-host: 100
        threads-allowed-to-block-for-connection-multiplier: 5
        server-selection-timeout: 30000
        max-wait-time: 120000
        max-connection-idle-time: 0
        max-connection-life-time: 0
        connect-timeout: 10000
        socket-timeout: 0
        socket-keep-alive: false
        ssl-enabled: false
        ssl-invalid-host-name-allowed: false
        always-use-m-beans: false
        heartbeat-socket-timeout: 20000
        heartbeat-connect-timeout: 20000
        min-heartbeat-frequency: 500
        heartbeat-frequency: 10000
        local-threshold: 15

难点:

  • 查询优化
  • 数据存储优化
  • 异步编程数据安全

方案:

  1. 查询需要同步总数据量
  2. 查询当天Mysql是否进行分区
  3. 根据日期条件查询并进行根据商户、用户、批次进行分组
  4. 对其最终商户、用户、批次、日期进行条件查询统计该批次需同步总数量(num)
  5. 对其最终商户、用户、批次、日期进行条件查询按照id排序进行查询(只查询一条,划重点了:根据id排序升序排序)
  6. 采用分页进行查询每页查询数量然后进行同步,比如 (pageSize = 1w,则需同步pageCount = num /pageSize +1)
  7. 使用分页查询但是不要使用skip+limit查询(如果使用skip+limit数据量大时会出现mongodb连接超时,其他查询业务无法进行),因为skip效率太低,使用大于当前id和limit pageSize进行查询
  8. 每次查询前对id进行更新,查询到的数据最后一条数据的id进行替换

因为涉及到公司安全只能提供思路部分代码 (=.=)

数据同步单表查询保存效率在 (10w+/minute)

Mongodb操作

一、条件+分组查询

Criteria criteria = new Criteria();
criteria.andOperator(
    Criteria.where("createDate").gte(new Date(startDate)),
    Criteria.where("createDate").lt(new Date(endDate))
                );
Aggregation aggregation = Aggregation.newAggregation(
                    Aggregation.match(criteria),
                    Aggregation.group("userId").count().as("count")
            ).withOptions(AggregationOptions.builder().allowDiskUse(true).build());
List<Map> list = mongoTemplate.aggregate(aggregation, item, Map.class).getMappedResults();

二、基本多条件查询

Criteria criteria = new Criteria();
// 等于条件     (mysql:=)
criteria.and("userName").is(queryForm.getUserName());
// 模糊条件查询  (mysql:like ('%content%'))
criteria.and("content").regex(queryForm.getContent(), "i");
// 大于等于条件  (mysql:>=)
criteria.and("createDate").gte(DateUtil.beginOfDay(queryForm.getStartDate()));
// 小于等于条件  (mysql:<=)
criteria.and("createDate").lte(DateUtil.endOfDay(queryForm.getEndDate()));
// 分页查询
int start = (pageNum - 1) * pageSize;
int limit = pageSize;
Query query = new Query(criteria).with(Sort.by(Sort.Direction.DESC, "createDate")).skip(start).limit(limit);

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值