我从事理论物理工作,并且做了大量的计算机模拟。我的职责的一个重要部分是对结果的分析。我进行模拟并将数值结果存储在一个简单名称的文件中。通常我有很多名称非常相似的数据文件,过了一段时间我不记得文件对应的参数类型。我在想,也许存在一种更好的方法来存储来自模拟的数值结果,例如一些数据库(SQL,MongoDB等),我可以在其中放置一些关于程序参数,名称,日期等的评论 - 一种带有数字数据的库。我只是在一个地方组织得很好。你知道这样的事吗?你如何存储计算机模拟的数值数据?
典型程序如下所示。假设我们想模拟三体问题的时间演变。我们有三个不同质量的物体与牛顿力相互作用。我想测试这些物体如何在空间中移动,具体取决于:相对质量值,初始位置 - 6个参数。我为一个参数选择运行模拟并将其保存在文件中:three_body_m1 = 0p1_m2 = 0p3_(其余).dat - 一个文件中总共1 + 3 * 3(3d)列数据的所有双精度。然后我午餐gnuplot,python等,并将它们可视化。原则上,不同模拟的数据之间没有关系,但我可以用它们来制作比较图。
答案 0 :(得分:1)
在相同的nodejs上下文中,您可以
使用socket.io-stream + fs模块将大xyz数据文件流式传输到服务器,并使用mongodb模块将文件名+参数保存到数据库。(最多1页编码,但更多用于复杂的服务器通话)
如果数据适合ram并且您不必立即保存,则可以使用redis模块轻松地将所有内容发送到服务器缓存(作为键值对,例如data-> xyzData和parameters- > simulationParameters和user-> name_surname)并从中高速读取。如果您需要服务器中的其他进程将数据作为文件,您可以转而使用ramdisk,并将大部分RAM带宽作为文件缓存。(需要更多的ram,但速度很快)
mongodb缓慢(即使有优化)用于保存数百万个粒子xyz数据,但这是最简单,最快速的参数保存和共享安装。
使用all可能会更好。
通讯方案可以是:
如果有任何待处理的写入/读取/编辑,数据服务器会与缓存服务器进行对话,从中消耗作业。
计算服务器与缓存服务器的对话,以生成读/写/编辑作业或使用计算作业。
客户端可以与缓存服务器通信以进行只读。
管理员也可以放置自己的数据或制作计算作业或阅读内容。
计算服务器,数据服务器和缓存服务器可以轻松地放在同一台计算机上,也可以移动到其他计算机上,这要归功于nodejs的强大功能和无数模块,如redis,socket.io-stream,fs,ejs,express(例如,客户等
缓存服务器可以将一些数据卸载到另一个缓存服务器并重定向(或者将数据映射到它)
只要RAM保持,缓存服务器就可以同时传送N个数据服务器和M个计算服务器。
你的网络速度慢吗?您只需使用3-5行额外代码(两端)即可使用gzip模块即时压缩数据
你没钱?
data server cluster
\
\
\ client
\ client /
\ / /
\ / /
mainframe cache and database server ----- compute cluster
| \
| \
support cache server admin
将一些文件发送到另一台计算机(或同一台)的一个非常简单的示例:
var pipeline_n = 8;
var fs = require("fs");
// server part accepting files
{
var io = require('socket.io').listen(80);
var ss = require('socket.io-stream');
var path = require('path');
var ctr = 0;
var ctr2 = 0;
io.of('/user').on('connection', function (socket) {
var z1 = new Date();
for (var i = 0; i < pipeline_n; i++) {
ss(socket).on('data'+i.toString(), function (stream, data) {
var t1 = new Date();
stream.pipe(fs.createWriteStream("m://bench_server" + ctr + ".txt"));
ctr++;
stream.on("finish", function (p) {
var len = stream._readableState.pipes.bytesWritten;
var t2 = new Date();
ctr2++;
if (ctr2 == pipeline_n) {
var z2 = new Date();
console.log(len * pipeline_n);
console.log((z2 - z1));
console.log("throughput: " + ((len * pipeline_n) / ((z2 - z1)/1000.0))/(1024*1024)+" MB/s");
}
});
});
}
});
}
//client or another server part sending a file
//(you can change it to do parts of same file instead of same file n times),
//just a dummy file sending code to stress other server
for (var i = 0; i < pipeline_n; i++)
{
var io = require('socket.io-client');
var ss = require('socket.io-stream');
var socket = io.connect('http://127.0.0.1/user');
var stream = ss.createStream();
var filename = 'm://bench.txt'; // ramdrive or cluster of hdd raid
ss(socket).emit('data'+i.toString(), stream, { name: filename });
fs.createReadStream(filename).pipe(stream);
}
这是测试mongodb的插入与批量插入性能(这可能是一种错误的基准测试方法,但很简单,只是取消注释 - 在您想要基准测试的部分)
var mongodb = require('mongodb');
var client = mongodb.MongoClient;
var url = 'mongodb://localhost:2019/evdb2';
client.connect(url, function (err, db) {
if (err) {
console.log('fail:', err);
} else {
console.log('success:', url);
var collection = db.collection('tablo');
var bulk = collection.initializeUnorderedBulkOp();
db.close();
//benchmark insert
//var t = 0;
//t = new Date();
//var ctr = 0;
//for (var i = 0; i < 1024 * 64; i++)
//{
// collection.insert({ x: i + 1, y: i, z: i * 10 }, function (e, r) {
// ctr++;
// if (ctr == 1024 * 64)
// {
// var t2 = 0;
// db.close();
// t2 = new Date();
// console.log("insert-64k: " + 1000.0 / ((t2.getTime() - t.getTime()) / (1024 * 64)) + " insert/s");
// }
// });
//}
// benchmark bulk insert
//var t3 = new Date();
//for (var i = 0; i < 1024 * 64; i++)
//{
// bulk.insert({ x: i + 1, y: i, z: i * 10 });
//}
//bulk.execute();
//var t4 = new Date();
//console.log("bulk-insert-64k: " + 1000.0/((t4.getTime() - t3.getTime()) / (1024 * 64)) + " insert/s");
// db.close();
}
});
请务必在此之前设置mongodb和/或redis服务器。还有来自nodejs命令提示符的“npm install module_name”必需模块。