redisとin-memory-cacheのパフォーマンス調べてみた
2022/04/22
主に以下の違いが知りたくて、実際に時間を測って調べてみました。
- 複数key保存、単一key保存での処理速度の違い
- redisとin-memory-cacheの具体的なパフォーマンス差
方法
以下のuserオブジェクトを1000件、10000件、100000件、保存・取得したときの時間をそれぞれ計測してみました。
user.ts
const user = {
id: i,
name: 'Takashi',
location: 'Kyoto',
company: 'Idutsu',
age: 30,
frends: [
{
id: 15000,
name: 'Takashi',
},
{
id: 15001,
name: 'Takashi',
},
],
}
保存、取得する際には単一key、複数keyに分けての計測をそれぞれ行っています。
※ 計測に使用したcodeのイメージ (Clickで詳細)
test.ts
async function test() {
const users = [...Array(100000)].map((_, i) => ({
id: i,
name: 'Takashi',
location: 'Kyoto',
company: 'Idutsu',
age: 30,
frends: [
{
id: 15000,
name: 'Takashi',
},
{
id: 15001,
name: 'Takashi',
},
],
}));
// Set Parallel
console.time('cache-set-para');
await Promise.all(
users.map(async (user) =>
cacheService.setAsync(`user_${user.id}`, JSON.stringify(user)),
),
);
console.timeEnd('cache-set-para');
console.time('redis-set-para');
await Promise.all(
users.map(async (user) =>
redisService.setAsync(`user_${user.id}`, JSON.stringify(user)),
),
);
console.timeEnd('redis-set-para');
// Get Parallel
console.time('cache-get-para');
const keyReg = /user_/;
const cacheKeys = await cacheService.keysAsync(keyReg);
await Promise.all(cacheKeys.map(async (key) => cacheService.getAsync(key)));
console.timeEnd('cache-get-para');
console.time('redis-get-para');
const redisKeys = await redisService.keysAsync('user_*');
await Promise.all(redisKeys.map(async (key) => redisService.getAsync(key)));
console.timeEnd('redis-get-para');
// Set Once
console.time('cache-set-once');
await cacheService.setAsync('all-users', JSON.stringify(users));
console.timeEnd('cache-set-once');
console.time('redis-set-once');
await redisService.setAsync('all-users', JSON.stringify(users));
console.timeEnd('redis-set-once');
// Get Once
console.time('cache-get-once');
await cacheService.getAsync('all-users');
console.timeEnd('cache-get-once');
console.time('redis-get-once');
await redisService.getAsync('all-users');
console.timeEnd('redis-get-once');
console.log('FINISH');
}
結果
結果は以下のとおりになりました。
method | 1000件 | 10000件 | 100000件 |
---|---|---|---|
redis set once | 5.422 ms | 16.63 ms | 109.812 ms |
redis set para | 24.306 ms | 179.134 ms | 1146 ms |
redis get once | 0.671 ms | 3.027 ms | 66.624 ms |
redis get para | 15.523 ms | 132.765 ms | 1064 ms |
cache set once | 0.763 ms | 7.525 ms | 98.416 ms |
cache set para | 4.21 ms | 45.129 ms | 334.195 ms |
cache get once | 0.017 ms | 0.012 ms | 0.023 ms |
cache get para | 0.906 ms | 0.726 ms | 0.792 ms |
表のmethod
はそれぞれ以下を意味しています。
set once
: 複数オブジェクトを1つのkeyで保存set para
: 複数オブジェクトをそれぞれ別のkeyで並列保存get once
: 複数オブジェクトを1つのkeyで取得get para
: 複数オブジェクトをそれぞれ別のkeyで並列取得
考察
まず、処理速度に関してはネットワーク通信部分がない分in memory cacheのほうがredisより(当たり前ですが)早いです。
また、redis、in-memory-cacheともに同一データであれば複数keyに分けて保存・取得するよりも単一keyで保存・取得したほうが、今回の例では早いことがわかりました。 それなりのデータ量(今回の100000件)でも単一keyのほうが早いので、基本的にはパフォーマンスを考えると単一key運用が良さそうです。
ただし、件数が増えるごとに単一key、複数keyの保存・取得時間比が小さくなっているので、単一keyのほうが早いとはいってもデータ量に限度はありそうです。 データ量が増えると一括保存などにそれなりの時間がかかるようになってくるので、 データ量が大きい、かつ、データ更新頻度が高い場合はkeyを分けて運用したほうがいいかもしれません。