2016-01-22 26 views
1

我做了這個簡單的Node.js應用:高RAM使用

var express = require('express'); 
var app = express(); 
var alasql = require('alasql'); 
var url = require('url'); 

var port = 3000; 

app.get('/getuser', function(request, response) { 
    var queryObject = url.parse(request.url, true).query; 
    var country = queryObject.country; 
    var nameset = queryObject.nameset; 
    var state = queryObject.state; 
    var selectAll; 

    if (country == "US" && state !== null && state !== "") { 
     alasql.promise("SELECT * from JSON('database.json') WHERE Country = ? AND NameSet = ? AND State = ?", [country, nameset, state]). 
     then(function(res) { 
      if (res !== null && res.length > 0) { 
       var result = res[Math.floor(Math.random() * res.length + 1)]; 
       response.writeHead(200, { 
        'Content-Type': 'text/plain' 
       }); 

       response.end(JSON.stringify(result)); 
      } else { 
       response.writeHead(200, { 
        'Content-Type': 'text/plain' 
       }); 

       response.end("noresults"); 
      } 
     }).catch(function(err) { 
      console.log('Does the database.json file exists? there was an error:', err); 
     }); 


    } else { 
     alasql.promise("SELECT * from JSON('database.json') WHERE Country = ? AND NameSet = ?", [country, nameset]). 
     then(function(res) { 
      if (res !== null && res.length > 0) { 
       var result = res[Math.floor(Math.random() * res.length + 1)]; 
       response.writeHead(200, { 
        'Content-Type': 'text/plain' 
       }); 

       response.end(JSON.stringify(result)); 
      } else { 
       response.writeHead(200, { 
        'Content-Type': 'text/plain' 
       }); 

       response.end("noresults"); 
      } 
     }).catch(function(err) { 
      console.log('Does the database.json file exists? there was an error:', err); 
     }); 
    } 
}); 

app.listen(port); 

正如你所看到的,我加載database.json文件,做一些關於它的alasql查詢並返回數據作爲迴應。 database.json大小約爲50MB。 我的問題是,這個應用程序使用400-600MB的RAM!

我也做了這個版本,我打開使用.require的database.json文件,但內存消耗是一樣的!

var express = require('express'); 
var app = express(); 
var alasql = require('alasql'); 
var url = require('url'); 

var port = 3000; 

var database = require('./database.json'); 


app.get('/getuser', function(request, response) { 
    var queryObject = url.parse(request.url, true).query; 
    var country = queryObject.country; 
    var nameset = queryObject.nameset; 
    var state = queryObject.state; 
    var selectAll; 

    if (country == "US" && state !== null && state !== "") { 
     selectAll = alasql("SELECT * from ? WHERE Country = ? AND NameSet = ? AND State = ?", [database, country, nameset, state]); 
    } else { 
     selectAll = alasql("SELECT * from ? WHERE Country = ? AND NameSet = ?", [database, country, nameset]); 
    } 

    if (selectAll !== null && selectAll.length > 0) { 
     var res = selectAll[Math.floor(Math.random() * selectAll.length + 1)]; 

     response.writeHead(200, { 
      'Content-Type': 'text/plain' 
     }); 

     response.end(JSON.stringify(res)); 

    } else { 
     response.writeHead(200, { 
      'Content-Type': 'text/plain' 
     }); 

     response.end("noresults"); 
    } 
}); 

app.listen(port); 

我在做什麼錯,我想這是關於我的JSON文件大小的問題?它是55000條記錄的數組,每條記錄有20個字段,如果該信息對您有幫助?

+0

RAM內存的使用是穩定的還是隻是一個高峯?以下是與節點相關的一些問題:https://github.com/nodejs/node/issues/856 –

+0

這是JSON的嚴重缺陷之一:它需要比給定輸入多十倍的內存。 –

+0

@RandallValenciano它是穩定的 – kecman

回答

3

事實上,它在磁盤上是50MB,在比較內存時不是特別有用。

根據數據庫JSON中的內容,它可能比磁盤表示中的要大得多。

以一個整數爲例,如果您的JSON中的值爲5,則它只佔用1個字節的ASCII,但在Javascript中佔用8個字節,因爲所有數字均爲8個字節。如果考慮到跟蹤JSON對象本身及其子項等所需的引用數量,則最終的結果可能比磁盤上的表示大得多。

+0

您是否有其他解決方案來滿足我的需求?我基本上需要做一個類似SQL的查詢,並從數據庫中選擇55000條記錄中的一些數據,其中包含20個不同類型的字段,其中一些是數字,一些是日期,一些是文本。我有這個數據在JSON文件。我不能使用MySQL或任何類似的東西,因爲所有東西都必須打包在node.js應用程序中,不能使用其他軟件。 – kecman

+1

我會考慮的第一件事是你是否需要將整個對象留在記憶中。從查詢的外觀來看,您的JSON數據庫可能僅僅是一個文件,它充滿了換行符分隔的較小記錄對象,一次一行地輸入,解析和過濾,然後將匹配記錄返回給用戶。然後你的記憶只受到你迴歸的數量的限制。 –

+1

或者,如果您確實需要SQL解決方案,請考慮一個可以對記錄進行分區的數據庫,並且只會將更相關的部分讀入內存。我其實並不是一個龐大的節點傢伙,但是使用谷歌搜索似乎表明這是一個選擇:http://www.tingodb.com/特別關注這些功能以及它們如何使用內存與文件。 –