多层父子数据 聚合、查询 存储层的调研记录

224 阅读4分钟

这是很久之前 做的调研,今天偶尔看到,发一下 哈哈

其实一句话就是 分布式数据聚合 分2种

  1. 多服务 的数据聚合为 宽表 / 父子结构的数据结构
  2. 有可能一个库的某个表 数据变更,需要告诉A 服务,为了和 业务系统进行抽离,所以有一个 数据监听 / 朔源的中间系统, 另外还能提供 数据 的变化记录 ,我们还分为 内部数据 / 外部数据 进行维护

背景:

之前的数据 查询是根据PGSQL 进行查询,4层的父子数据 需要3个join 才能解决 为了解决这种多次join的情况,希望把数据聚合 ,然后一个sql 进行查询

初步调研结果(存储端)

结论: 使用es 原因在文档中

需要确定:

1 mongdb 对于这种join 聚合数据的查询能不能满足需求

可以存储json ,支持数据的存储

2 大数据量的查询性能

不能设置并排索引,查询性能 不能保证,扩展性不足

步骤:

1 先insert 数据 然后进行select 看看数据查询对不对

mongodb性能测试

mongodb的性能高,提到大数据我们可能就会想到这个数据库,那么它的性能究竟如何,需要我们实践与探讨。

基本信息:

  • mongodb版本:3.2
  • 系统:linux
  • 内存:4G
  • CPU:2.6 GHZ

测试用例需求

测试需求内容

collection name:user_scores

insert 36w records.

{
	"id": 2,
	"updateTime":ISODate("2018-01-11T09:34:55.556Z"),
	"name": "mongdb",
	"person": {
		"name": "张三 ",
		"sex": 1
	},
	"agentPerson": {
		"name": "代理人 ",
		"sex": 1,
		"tel": 133333333444
	},
	"list": [{
		"circumstances": "他欠我 200元工资",
		"guarantee": [{
			"money": 1345,
			"text": "我干活了 但是没给钱"
		}],
		"auditRecords": {
			"auditLogs": [{
					"content": "第一次审批通过",
					"updateTime":ISODate("2018-01-11T09:34:55.556Z")
				},
				{
					"content": "第二次审批通过",
					"updateTime":ISODate("2018-01-11T09:34:55.556Z")
				},
				{
					"content": "第三次审批通过",
					"updateTime":ISODate("2018-01-11T09:34:55.556Z")
				}
			],
			"opinion": "审核意见"
		}
	}]
}


按分数 updateTime desc 排序,取前一百条记录.

生成测试数据代码


for (var i = 3; i < 100000 ; i++) {

var  myself=
{
	"id": i,
	"updateTime":ISODate("2018-01-11T09:34:55.556Z"),
	"name": "mongdb",
	"person": {
		"name": "张三" + i,
		"sex": 1
	},
	"agentPerson": {
		"name": "代理人 ",
		"sex": 1,
		"tel": 133333333444
	},
	"list": [{
		"circumstances": "他欠我 200元工资",
		"guarantee": [{
			"money": 1345,
			"text": "我干活了 但是没给钱" + i
		}],
		"auditRecords": {
			"auditLogs": [{
					"content": "第一次审批通过" + i,
					"updateTime":ISODate("2018-01-11T09:34:55.556Z")
				},
				{
					"content": "第二次审批通过" + i,
					"updateTime":ISODate("2018-01-11T09:34:55.556Z")
				},
				{
					"content": "第三次审批通过" + i,
					"updateTime":ISODate("2018-01-11T09:34:55.556Z")
				}
			],
			"opinion": "审核意见" + i
		}
	}]
}

	db.hrm.insert(myself)
}


生成数据时间大概:10分钟

测试查询效率代码

@Test
public void count(){
    DBCollection coll = mongo.getCollection(DOC.MODEL_SCORES);
    // 先排序成绩倒序,再排序时间倒序,获取数据库游标
    DBCursor cursor = coll.find().sort(new BasicDBObject("date", -1) )
            .sort(new BasicDBObject("score", -1))
            .limit(100);

    while(cursor.hasNext()){
        DBObject obj = cursor.next();
        System.out.println(obj);
    }
}

无索引查询性能测试报告

  • 数据量: 36w 条数据
  • 消耗时间: `1.35s

测试数据仅供参考

添加索引查询性能测试报告

手动添加索引

db.hrm.ensureIndex ({  "updateTime": -1 })

OK,来看看测试报告

  • 数据量: 36w 条数据
  • 消耗时间: 添加索引之后 0.018s 但是 查询的东西不正确的时候 遍历表 2.6s mongdb 对于查询 不太友好

测试数据仅供参考

测试心得体会

es的查询呢

索引结构

{
	"settings": {
		"index.max_ngram_diff": 50,
		"analysis": {
			"analyzer": {
				"namegrams": {
					"type": "custom",
					"tokenizer": "keyword",
					"filter": [
						"ngrams_filter"
					]
				},
				"search_ngram": {
					"type": "custom",
					"tokenizer": "lowercase",
					"filter": [
						"truncate_filter",
						"lowercase"
					]
				},
				"minimize_analyzer": {
					"tokenizer": "my_tokenizer",
					"filter": [
						"lowercase"
					]
				},
				"comma": {
					"type": "pattern",
					"pattern": ","
				}
			},
			"filter": {
				"ngrams_filter": {
					"type": "ngram",
					"min_gram": 1,
					"max_gram": 8
				},
				"truncate_filter": {
					"type": "truncate",
					"length": 8
				}
			},
			"tokenizer": {
				"my_tokenizer": {
					"type": "ngram",
					"min_gram": 1,
					"max_gram": 10,
					"token_chars": [
						"letter",
						"digit"
					]
				}
			}
		}
	},
	"mappings": {
		"properties": {
			"id": {
				"type": "keyword"
			},
			"name": {
				"type": "text"
			},
			"person": {
				"type": "nested",
				"properties": {
					"name": {
						"type": "text"
					},
					"sex": {
						"type": "integer"
					}
				}
			},
			"agentPerson": {
				"type": "nested"
			},
			"list": {
				"type": "nested",
				"properties": {
					"circumstances": {
						"type": "text"
					},
					"guarantee": {
						"type": "nested",
						"money": {
							"type": "integer"
						},
						"text": {
							"type": "text",
							"analyzer": "minimize_analyzer",
							"search_analyzer": "search_ngram",
							"fields": {
								"keyword": {
									"type": "keyword"
								},
								"suggest": {
									"type": "completion",
									"analyzer": "search_ngram"
								}
							}
						}
					}
				}
			}
		}
	}
}

新建一个数据

{
 "id": 2,
 "name": "mongdb",
 "person": {
  "name": "张三 ",
  "sex": 1
 },
 "agentPerson": {
  "name": "代理人 ",
  "sex": 1,
  "tel": 133333333444
 },
 "list": [{
  "circumstances": "他欠我 200元工资",
  "guarantee": [{
   "money": 1345,
   "text": "我干活了 但是没给钱"
  }],
  "auditRecords": {
   "auditLogs": [{
     "content": "第一次审批通过"
    },
    {
     "content": "第二次审批通过"
    },
    {
     "content": "第三次审批通过"
    }
   ],
   "opinion": "审核意见"
  }
 }]
}

实现查询功能


{
    "query":{
        "bool":{
            "should":[
                {
                    "match_phrase":{
                        "list.guarantee.text": "1我"
                    }
                },
                {
                    "match":{
                        "person.name": "张三"
                    }
                }
            ]
        }
    }
}

es 总结

自动索引 性能很高,支持查询功能

总结

mongdb 因为不能设置并排索引 查询性能不能满足扩展性 用es 做存储层