0

我有大量私有云中虚拟机的使用记录数据集。每小时都会为我的云中运行的每个 VM 生成这组记录。VM 都有一条记录,其中包含 RAM、内存等规格,并有一个 id: 字段对应于使用记录中的 virtualmachineid。我可以查询 API 并取回 XML 或 JSON 数据集,我选择了 JSON,因为它在线上更轻量级。

这是一条记录,有 13 种使用情况,分别对应磁盘使用情况、带宽、运行时间等:

Usage Record:                                                                    
  { account: 'user_1',                                                           
    accountid: 'c22ed7ed-e51a-4782-83a7-c72e2883eb99',                             
    domainid: 'f88d8bbf-a83b-4be1-a788-e2ab51eb9973',                              
    zoneid: '4a7f62a8-3248-47ee-bf94-d63dac2a6668',                                
    description: 'VM2 running time (ServiceOffering: 11) (Template: 215)',         
    usage: '1 Hrs',                                                                
    usagetype: 1,                                                                  
    rawusage: '1',                                                                 
    virtualmachineid: 'f6661f34-4d03-4128-b738-38c330f2499c',                      
    name: 'VM2',                                                                   
    offeringid: 'f1d82c2e-25e3-4c97-bae8-b6f916860faf',                            
    templateid: '2bf2e295-fdd6-4326-a652-6d07581be070',                            
    usageid: 'f6661f34-4d03-4128-b738-38c330f2499c',                               
    type: 'XenServer',                                                             
    startdate: '2012-12-25\'T\'22:00:00-06:00',                                    
    enddate: '2012-12-25\'T\'22:59:59-06:00' } 

我正在尝试做的事情:

我需要浏览 VM 列表,其中将有数百个,并且为每个 VM 构建上一期的使用情况报告,通常为一个月,但也可以是临时的。因此,在每个 VM 每月 10000 多条使用记录中,我需要计算每种使用类型的总数。

有没有比传统的循环循环循环再循环方法更有效、更新颖的方法?在伪代码中:

for (each vm in vms)
    for (each usage_record in usage_records)
        if (vm.id === usage_record.vmid)
            switch usage_record.usage_type
                case 1: its runtime
                case 2: its disk usage
                case 3: its some other type of usage
                ...

使用下划线,这是我到目前为止所做的:

_.each(virtualMachines.virtualmachine, function (vm) {   
    var recs = _.filter(usageList.usagerecord, function (foo) { 
        return (foo.virtualmachineid === vm.id && foo.usagetype === 1); 
    });
        console.log("recs count:" + recs.count); 
        //now, recs contains all the usage record type 1 for one VM  

 });                                                          

现在工作正常,但我不相信它已经优化并且不会随着 VM 数量的增加而扩展。对于每台虚拟机,数据集中都会添加 10,000 条额外的使用记录。

4

1 回答 1

3

由于您需要处理每个 VM需要每个 VM 的结果,因此我首先按 VM 对列表进行排序。之后,您应该只需要一个循环和一个“当前 VM 统计信息”对象。一旦您遇到列表中的下一个虚拟机,您就知道当前的统计信息是完整的。

sortRecordsByVM();
currentStats = { runtime: 0, disk: 0, other: 0 };
currentVM;
for each record
  if currentVM != record.VM
    writeToOutput(currenStats);
    currentStats = { runtime: 0, disk: 0, other: 0 };
  addRecordTo(record, currentStats);
writeToOutput(currenStats);

也就是说:我不认为迭代超过 10K 记录会给现代机器带来问题,所以我会从最简单的方法开始,只在出现性能问题时进行优化。

我只是不使用嵌套循环,而是将查找留给内置数据结构(通常比我倾向于第一次尝试编写的任何代码都更优化):

allStats = {};
for each record
  stats = allStats[record.VM];
  if (!stats)
    stats = { runtime: 0, disk: 0, other: 0 };
  addRecordTo(record, stats);
  allStats[record.VM] = stats;
于 2013-01-09T13:22:41.723 回答