我有一个简单的节点脚本,可以将不存在的文件从redis复制到elasticsearch。但是,我的脚本由于内存而失败。我意识到Node.js有1G内存的限制。我在redis中有大约1.7G的文件(根据Redis的说法)
# Memory
used_memory:1828855608
used_memory_human:1.70G
used_memory_rss:1768804352
used_memory_peak:1839670312
used_memory_peak_human:1.71G
这是我的简单节点脚本
'use strict';
const redis = require('redis');
const elasticsearch = require('elasticsearch');
const config = require('../config');
let client = redis.createClient({
host: config.redis.url,
port: config.redis.port
});
let esClient = elasticsearch.Client({
host: config.elasticsearch.url
});
client.keys('*', (err, keys) => {
if (err) {
console.log(err);
}
keys.forEach((key) => {
esClient.exists({
index: 'articles',
type: 'article',
id: key
}, (err, exists) => {
if (!exists) {
}
});
});
});
这就是我得到的错误。
<--- Last few GCs --->
56742 ms: Scavenge 1398.8 (1457.2) -> 1398.8 (1457.2) MB, 0.8 / 0 ms (+ 2.2 ms in 1 steps since last GC) [allocation failure] [incremental marking delaying mark-sweep].
57796 ms: Mark-sweep 1398.8 (1457.2) -> 1398.8 (1457.2) MB, 1054.1 / 0 ms (+ 3.2 ms in 2 steps since start of marking, biggest step 2.2 ms) [last resort gc].
58835 ms: Mark-sweep 1398.8 (1457.2) -> 1398.8 (1457.2) MB, 1038.5 / 0 ms [last resort gc].
<--- JS stacktrace --->
==== JS stack trace =========================================
Security context: 0x220f52737399 <JS Object>
1: test [native regexp.js:~132] [pc=0x2b04c4f8bd00] (this=0xdea7c8c02e9 <JS RegExp>,k=0xdea7c8b0741 <String[24]: /articles/article/1HcdBc>)
2: new constructor(aka ClientRequest) [_http_client.js:~19] [pc=0x2b04c4fa5ebd] (this=0xdea7c8c0459 <a ClientRequest with map 0x11d7d52ec4f1>,options=0xdea7c8c0409 <an Object with map 0x11d7d52f6731>,cb=0xdea7c8c03c1 <JS Function (SharedFunctionInfo...
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory
sh: line 1: 96220 Abort trap: 6 node scripts/copy-to-es.js
然而,Redis的1.7G是整个文档,但我认为我只是获取所有密钥来检查它是否存在于Elasticsearch中。我不确定为什么因为记忆而失败,我该如何克服这个?我使用的是Node 4.2.2
答案 0 :(得分:0)
似乎弹性搜索客户端可能是有原因的。有一个错误报告描述了您遇到的问题。您使用哪个版本的elasticsearch客户端?
答案 1 :(得分:0)
如果它只有一两个ES呼叫,我尝试使用普通HTTP请求(带请求或superAgent)而不是使用elasticsearch模块...
但是,我还会检查redis键占用多少内存:你的代码会立即将所有内存加载到内存中......