我有一個API端點,我試圖強調測試,它讀取非常大的數據庫集合(200萬個文檔)MongoDB
。每個查詢需要大約2秒然而,我遇到的問題是到數據庫的連接沒有正確合併,因此每個查詢順序運行而不是併發。MongoDB按順序執行查詢而不是並行執行查詢
我正在使用Mongoose連接到我的數據庫,我正在使用artillery.io進行測試。
這裏是我的連接代碼:
const mongoose = require('mongoose');
const Promise = require('bluebird');
const connectionString = process.env.MONGO_DB || 'mongodb://localhost/mydatabase';
mongoose.Promise = Promise;
mongoose.connect(connectionString, {
server: { poolSize: 10 }
});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error: '));
db.once('open', function() {
console.log('Connected to: ' + connectionString);
});
module.exports = db;
這是你的漂亮沼澤標準連接過程大概但最重要的部分是server: { poolSize: 10 }
線。
我使用下面的腳本爲artillery.io測試:
config:
target: 'http://localhost:1337'
phases:
-
duration: 10
arrivalRate: 5
name: "Warm-up"
scenarios:
-
name: "Search by postcodes"
flow:
-
post:
url: "/api/postcodes/gb_full/search"
headers:
Content-Type: 'application/json'
json:
postcodes:
- ABC 123,
- DEF 345,
- GHI 678
這個測試執行了10秒 對API的調用。現在,這裏的問題出在哪裏,這個API似乎執行查詢順序,請參見下面的測試結果:
"latency": {
"min": 1394.1,
"max": 57693,
"median": 30222.7,
"p95": 55396.8,
"p99": 57693
},
和數據庫日誌如下:
connection accepted from 127.0.0.1:60770 #1 (1 connection now open)
...
2017-04-10T18:45:55.389+0100 ... 1329ms
2017-04-10T18:45:56.711+0100 ... 1321ms
2017-04-10T18:45:58.016+0100 ... 1304ms
2017-04-10T18:45:59.355+0100 ... 1338ms
2017-04-10T18:46:00.651+0100 ... 1295ms
看起來好像API只使用一個連接,這似乎是正確的,但我的理解是,這將自動使poolSize
良好的使用,並執行這些查詢並行,而不是一次一個。
我在這裏做錯了什麼?我怎樣才能並行執行這些數據庫查詢?
編輯1 - 模型和查詢
爲了希望讓事情更清晰一點,我現在用的是以下模式:
const mongoose = require('mongoose');
const db = require('...');
const postcodeSchema = mongoose.Schema({
postcode: { type: String, required: true },
...
location: {
type: { type: String, required: true },
coordinates: [] //coordinates must be in longitude, latitude order.
}
});
//Define the index for the location object.
postcodeSchema.index({location: '2dsphere'});
//Export a function that will allow us to define the collection
//name so we'll pass in something like: GB, IT, DE ect for different data sets.
module.exports = function(collectionName) {
return db.model('Postcode', postcodeSchema, collectionName.toLowerCase());
};
凡db
對象是連接模塊解釋在這個問題的頂部。
,我使用下面的執行查詢:
/**
* Searches and returns GeoJSON data for a given array of postcodes.
* @param {Array} postcodes - The postcode array to search.
* @param {String} collection - The name of the collection to search, i.e 'GB'.
*/
function search(postcodes, collection) {
return new Promise((resolve, reject) => {
let col = new PostcodeCollection(collection.toLowerCase());
col.find({
postcode: { $in: postcodes }
})
.exec((err, docs) => {
if (err)
return reject(err);
resolve(docs);
});
});
}
這裏是功能如何可以被稱爲一個例子:
search(['ABC 123', 'DEF 456', 'GHI 789'], 'gb_full')
.then(postcodes => {
console.log(postcodes);
})
.catch(...);
再次重申,這些查詢被執行通過node.js
API,因此他們應該已經是是異步的,但是查詢本身一個接一個地被執行。因此,我認爲問題可能出在MongoDB方面,但我不知道哪裏可以開始尋找。這幾乎就好像MongoDB在已經有一個正在運行的情況下阻止對集合執行其他任何查詢。
我在Windows 10機器上本地運行mongod.exe
的實例。
在MongoDB方面,您是否有查詢搜索條件的索引?你對數據庫的響應時間應該小得多,看看[這裏](https://docs.mongodb.com/manual/indexes/「here」)。 –
是的,我有一個地理空間索引,但在這種情況下,它不會產生任何影響,因爲我通過未編入索引的郵政編碼進行搜索。請參閱我的問題上的編輯。 –
我在Postcode字段中添加了一個索引,現在它的速度非常快,謝謝你的提示。 +1。 –