汪微的博客
zane,做一个有思维的开发者

汪微的博客

zanePerfor前端监控平台性能优化之数据库分表

2018年11月22日167 browse

为什么要分表

  • zanePerfor可以创建多个应用,并进行数据的上报统计。

  • 每个应用同类型的数据存放在同一张表中会造成单表的数据存储量非常大,索引文件的体积相应的也会很大。

  • 在单表中,需要对每个应用的appId做索引,如果分表此索引则可去掉。

  • 这样就造成了单表的读写性能都会相应的降低。


分表的优势

  • 解决了单表的数据存储大小压力

  • 解决了单表的读写压力

  • 减少索引字段和索引体积大小

  • 应用解耦与查询性能的提升


分表的劣势

  • 分表唯一的劣势是在Mongodb集群架构中分片变得需要频繁的维护
  • 每新增一个应用,就会动态的新增一张表,如果此表需要做分片,那么就需要初始化一次分片规则


zanePerfor分表图



在zanePerfor中的代码实现:

1、在servers启动时,在app对象下挂载一个models对象,用来存储所有的Schema对象

// 在app.js下挂载models对象

'use strict';

module.exports = async app => {
    app.models = {};
};


2、需要分表的model中,在app.models下挂载一个按某字段拆分表的方法

'use strict';

module.exports = app => {
    const mongoose = app.mongoose;
    const Schema = mongoose.Schema;
    const conn = app.mongooseDB.get('db3');

    const WebAjaxsSchema = new Schema({
        app_id: { type: String }, 
        create_time: { type: Date, default: Date.now },
        ...
    });


    // ----------拆表代码如下:-----------
    // 此处根据appId拆表
    app.models.WebAjaxs = function(appId) {
        return conn.model(`web_ajaxs_${appId}`, WebAjaxsSchema);
    };

    // ----------默认写法(不拆表)---------
    // return conn.model(`web_ajaxs`, WebAjaxsSchema);
};


3、调用方式

调用方式也很简单,跟默认的调用方式有一点小区别 (下面以调用单个ajax详情为例)

// 获得单个ajax详情信息
async getDetailForId(appId, id) {
	// ---------拆表调用方式---------
    return await this.app.models.WebAjaxs(appId).findOne({ _id: id }).read('sp').exec() || {};
    
    // ---------默认调用方式---------
    // return await this.ctx.model.WebAjaxs.findOne({ _id: id }).read('sp').exec() || {};

}


备注:应用根据appId拆表,因此所有查询操作需要传入appId进行查询。

以上只是实践的一种方式,同理,还可以通过 时间日期拆表,其他字段拆表。

zanePerfor暂时只做分表,暂未做分库,已经能满足绝大部分业务需求,若某一天觉得不能满足业务需求的时候再考虑是否分库。


博主 zane 发表于 2018-11-22 12:25:16,添加在了 node.js 标签下

打赏

您的支持将鼓励我继续努力与分享。

扫码打赏,建议金额1-10元

提醒:打赏金额将直接进此方账号,无法退款,请您谨慎操作。

评论

正在加载验证码......

提交

👍👍👍

2019-01-21 18:56:51

👍👍👍

2018-12-11 19:00:13

41555

2018-12-07 15:51:26