Node.js 将数据附加到REDIS哈希的有效方法

Node.js 将数据附加到REDIS哈希的有效方法,node.js,typescript,google-app-engine,redis,Node.js,Typescript,Google App Engine,Redis,我正在进行一些计算,在将结果发送到数据库之前,我将其存储在REDIS数据库中 目前,我在单独的GAE实例(使用NodeJS的单线程计算)中处理每个块大小为10k项的批处理操作,虽然计算速度非常好,但执行HSET操作的推操作需要很长时间,因此会在不同的线程中造成一些延迟(由于REDIS是单线程的-仅供参考我正在使用Google REDIS基本实例) 我做错了什么?我怎样才能使它比现在更快地推进(比如批量或其他) const key = '123'; for (const [column, valu

我正在进行一些计算,在将结果发送到数据库之前,我将其存储在REDIS数据库中

目前,我在单独的GAE实例(使用NodeJS的单线程计算)中处理每个块大小为10k项的批处理操作,虽然计算速度非常好,但执行
HSET
操作的推操作需要很长时间,因此会在不同的线程中造成一些延迟(由于REDIS是单线程的-仅供参考我正在使用Google REDIS基本实例)

我做错了什么?我怎样才能使它比现在更快地推进(比如批量或其他)

const key = '123';
for (const [column, value] of results) {
   await this.appendRedisHashValue(key, column, value);
}

public async appendRedisHash(key: string, field: string, value: any) {
        const appendRedisHashAsync = promisify(this.redisClient.hset).bind(this.redisClient);
        return appendRedisHashAsync(key, field, JSON.stringify(value));
}
如您所见,我只是使用
HSET
逐个推送每个项目,想知道我们是否可以执行某种
SQL事务
,并在单个HSET事务中推送例如10k个项目,而不是每次追加REDIS散列

保存到REDIS后,每个区块(10k个项目)的大小约为43MB(因此总共100k个项目的大小为430MB)。对于某些架构设计而言,它必须存储在单个REDIS哈希中

当前速度(毫秒),每个作业在并行独立线程中运行:

"push": 13608
"finishedAt": "2020-05-08T22:51:26.045Z"

push": 13591,
"finishedAt": "2020-05-08T22:51:29.640Z"

"push": 15738,
"finishedAt": "2020-05-08T22:51:59.177Z"

"push": 21208,
"finishedAt": "2020-05-08T22:51:44.432Z"

"push": 13332,
"finishedAt": "2020-05-08T22:51:28.303Z"

"push": 10598,
"finishedAt": "2020-05-08T22:51:44.455Z"

"push": 27249,
"finishedAt": "2020-05-08T22:51:58.458Z"

"push": 36270,
"finishedAt": "2020-05-08T22:52:00.708Z"

"push": 25106,
"finishedAt": "2020-05-08T22:52:02.234Z"

"push": 12845,
"finishedAt": "2020-05-08T22:52:02.254Z"

如果您有任何反馈,我们将不胜感激。

您所做的是用一个键/值多次调用hset。这是不好的,因为往返延迟

按10k键/值进行操作将产生10k往返行程

您可以使用带有多个键/值的
hset
,这样就可以一次访问redis


hset field1 value1 field2 value2 field3 value3

您所做的是用一个键/值多次调用hset。这是不好的,因为往返延迟

按10k键/值进行操作将产生10k往返行程

您可以使用带有多个键/值的
hset
,这样就可以一次访问redis


hset field1 value1 field2 value2 field3 value3

我使用超过10000个值的hset和HMSET对其进行了测试,并创建了简单的批量函数来处理记录,从简单的数据角度来看,它看起来很棒,让我们看看它将如何在生产环境中结束

虽然
npm-redis
library不喜欢hset以这种方式放置它,但是
hmset
确实起到了奇怪的作用

const myarr = [];
const values = 10000;
for(let i = 0; i < values; i++) {
    myarr.push(`key${i}`);
    myarr.push('value');
}
await this.bulkRedisHash('myTest', myarr);
/*
    [Nest] 17800   - 2020-05-09 18:45:30   [FinalizeTaskService] starting +5ms
    [Nest] 17800   - 2020-05-09 18:45:30   [FinalizeTaskService] finished +21ms
 */
for (let i = 0; i < myarr.length; i++) {
    if (i % 2 !== 0) {
        await this.appendRedisHash('myTest2', myarr[i-1], myarr[i]);
    }
}
/*
   [Nest] 18396   - 2020-05-09 18:49:08   [FinalizeTaskService] starting +4ms
   [Nest] 18396   - 2020-05-09 18:49:09   [FinalizeTaskService] finished +795ms
*/

public async appendRedisHash(key: string, field: string, value: any) {
    const appendRedisHashAsync = promisify(this.redisClient.hset).bind(this.redisClient);
    return appendRedisHashAsync(key, field, value);
}

public async bulkRedisHash(key: string, keyValue: string[]) {
    const appendRedisHashAsync = promisify(this.redisClient.hmset).bind(this.redisClient);
    return appendRedisHashAsync(key, [...keyValue]);
}
const myarr=[];
常数值=10000;
for(设i=0;i

为了批量追加

我使用HSET和HMSET测试了10000多个值,并创建了简单的批量函数来处理记录,从简单数据的角度来看,它看起来很棒,让我们看看它将如何在生产环境中结束

虽然
npm-redis
library不喜欢hset以这种方式放置它,但是
hmset
确实起到了奇怪的作用

const myarr = [];
const values = 10000;
for(let i = 0; i < values; i++) {
    myarr.push(`key${i}`);
    myarr.push('value');
}
await this.bulkRedisHash('myTest', myarr);
/*
    [Nest] 17800   - 2020-05-09 18:45:30   [FinalizeTaskService] starting +5ms
    [Nest] 17800   - 2020-05-09 18:45:30   [FinalizeTaskService] finished +21ms
 */
for (let i = 0; i < myarr.length; i++) {
    if (i % 2 !== 0) {
        await this.appendRedisHash('myTest2', myarr[i-1], myarr[i]);
    }
}
/*
   [Nest] 18396   - 2020-05-09 18:49:08   [FinalizeTaskService] starting +4ms
   [Nest] 18396   - 2020-05-09 18:49:09   [FinalizeTaskService] finished +795ms
*/

public async appendRedisHash(key: string, field: string, value: any) {
    const appendRedisHashAsync = promisify(this.redisClient.hset).bind(this.redisClient);
    return appendRedisHashAsync(key, field, value);
}

public async bulkRedisHash(key: string, keyValue: string[]) {
    const appendRedisHashAsync = promisify(this.redisClient.hmset).bind(this.redisClient);
    return appendRedisHashAsync(key, [...keyValue]);
}
const myarr=[];
常数值=10000;
for(设i=0;i

批量追加

mset
不符合要求,因为这是用于简单的键/值存储,不用于散列,不确定管道,您是否有一些示例?您是否查看过Redis管道:?它有助于在一个连接中向Redis发送一系列命令,而不是通过redu在那里连续发送单个命令cing RTT(往返时间)对于每个命令。
mset
不符合要求,因为这是用于简单的键/值存储而不是散列,不确定管道,您是否有一些示例?您是否查看了Redis管道:?它有助于在一个连接中向Redis发送一系列命令,而不是通过减少连接来连续发送单个命令每个命令的RTT(往返时间)。是的,实际上正在考虑,但不确定我正在使用的“redis”库是否可以实现这一点,我认为我还发现了一个支持管道的ioredis库,我认为这将是此操作的最佳候选。是的,实际上正在考虑,但不确定这是否可行