Эффективный способ добавления данных в хэш REDIS - PullRequest
0 голосов
/ 09 мая 2020

Я выполняю некоторые вычисления, где я сохраняю результаты в базе данных REDIS перед тем, как они будут отправлены в базу данных.

В настоящее время я выполняю пакетные операции для размера 10 тыс. Элементов на фрагмент, которые я процесс в отдельном экземпляре GAE (однопоточные вычисления с использованием NodeJS), хотя скорость вычислений действительно хорошая, действие PU SH, которое выполняет HSET операций, занимает много времени, поэтому оно вызывает некоторую задержку в разных потоках (поскольку REDIS является однопоточным - fyi я использую экземпляр Google REDIS Basi c).

Что я делаю не так? Как я могу сделать так, чтобы его выталкивали быстрее (например, в пакетном режиме или что-то еще), чем сейчас? мы можем сделать что-то вроде SQL transactions и pu sh, например, 10k элементов в одной транзакции HSET вместо добавления REDIS Ha sh каждый раз.

Каждый фрагмент (10k элементов) имеет размером ~ 43 МБ после сохранения в REDIS (итого 100 тыс. элементов дают 430 МБ). Для некоторых архитектурных проектов они должны храниться в одном REDIS ha sh.

Текущая скорость (миллисекунды), каждое задание выполняется параллельно в отдельном потоке:

"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"

Мы будем благодарны за любые отзывы.

Ответы [ 2 ]

1 голос
/ 09 мая 2020

Я протестировал его с использованием HSET и HMSET более 10000 значений, и я создал простую массовую функцию для обработки записей, с точки зрения простых данных это выглядит фантастически. 1001 *

В то время как библиотека npm redis не хотела, чтобы 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]);
}

Для массового добавления

1 голос
/ 09 мая 2020

то, что вы делаете, - это вызов hset несколько раз с одним ключом / значением. что плохо из-за задержки туда и обратно.

выполнение этого с 10k ключом / значением будет 10k круговых обходов.

вы можете использовать hset с несколькими ключами / значениями, поэтому это будет единственная поездка в Redis. например,

hset field1 value1 field2 value2 field3 value3

...