Bentocache

JavaScriptTypeScriptライブラリキャッシュマルチティアL1L2スタンピード保護グレース期間

GitHub概要

Julien-R44/bentocache

🍱 Bentocache is a robust multi-tier caching library for Node.js applications

スター586
ウォッチ5
フォーク24
作成日:2023年8月4日
言語:TypeScript
ライセンス:MIT License

トピックス

cachecachingmulti-tiermysqlnodejspostgresqlredissqliteupstash

スター履歴

Julien-R44/bentocache Star History
データ取得日時: 2025/10/22 10:04

ライブラリ

Bentocache

概要

Bentocacheは、Node.jsアプリケーション向けの堅牢なマルチティアキャッシュライブラリです。L1/L2キャッシュ層、スタンピード保護、グレース期間を提供する先進的なキャッシュソリューションとして設計されています。

詳細

Bentocache(ベントキャッシュ)は、基本的な使用から高度なマルチレベル設定まで対応できる、パフォーマンスと柔軟性を兼ね備えたキャッシュシステムです。マルチティアアーキテクチャにより、インメモリキャッシュの高速性と分散キャッシュの永続性の両方を活用できます。L1層(ローカルキャッシュ)では、LRUアルゴリズムによりメモリ内に高速アクセス可能なデータを保存し、L2層(分散キャッシュ)では、Redisなどを使用してデータの永続化を行います。複数インスタンス環境では、RedisやRabbitMQなどのBusを介してローカルインメモリキャッシュの同期を実現します。多様なドライバー(Redis、Upstash、Database、DynamoDB、Filesystem、In-memory)をサポートし、あらゆる状況に対応可能です。TypeScriptで構築されており、ESModulesとの互換性も確保されています。

メリット・デメリット

メリット

  • マルチティアアーキテクチャ: L1/L2キャッシュ層による最適なパフォーマンス
  • スタンピード保護: 同時実行時のファクトリー関数の重複実行を防止
  • グレース期間: データソース障害時でも期限切れキャッシュを一時的に提供
  • 豊富なドライバー: Redis、MongoDB、DynamoDB、ファイルシステムなど多様な選択肢
  • TypeScript完全対応: 型安全性と優れた開発体験
  • イベント監視: パフォーマンス監視とメトリクス収集機能
  • 人間可読TTL: lukeed/msによる直感的な時間指定(例:'2.5h')

デメリット

  • 複雑性: マルチティア設定は単純なキャッシュより設定が複雑
  • 学習コスト: 高度な機能を活用するには概念理解が必要
  • オーバーヘッド: 小規模アプリケーションには過剰な場合がある
  • 新しいライブラリ: 比較的新しく、実績が他の成熟したライブラリより少ない
  • 依存関係: 複数ドライバー使用時の依存関係管理が必要

主要リンク

書き方の例

基本的なセットアップ

import { BentoCache, bentostore } from 'bentocache'
import { memoryDriver } from 'bentocache/drivers/memory'

const bento = new BentoCache({
  default: 'cache',
  stores: {
    cache: bentostore()
      .useL1Layer(memoryDriver({ maxSize: '10mb' }))
  }
})

// 基本的な使用方法
await bento.set({ key: 'user:42', value: { name: 'jul' } })
console.log(await bento.get({ key: 'user:42' }))

マルチティア構成

import { BentoCache, bentostore } from 'bentocache'
import { memoryDriver } from 'bentocache/drivers/memory'
import { redisDriver, redisBusDriver } from 'bentocache/drivers/redis'

const redisConnection = { host: 'localhost', port: 6379 }
const bento = new BentoCache({
  default: 'multitier',
  stores: {
    multitier: bentostore()
      // L1 キャッシュ: インメモリキャッシュ(最大10MB)
      .useL1Layer(memoryDriver({ maxSize: '10mb' }))
      // L2 キャッシュ: Redis分散キャッシュ
      .useL2Layer(redisDriver({ connection: redisConnection }))
      // Bus: インスタンス間でのL1キャッシュ同期
      .useBus(redisBusDriver({ connection: redisConnection }))
  }
})

getOrSetパターン

router.get('/products/:id', async (req, res) => {
  const productId = req.params.id
  const product = await bento.getOrSet({
    key: `product:${productId}`,
    factory: () => Product.find(productId),
    ttl: '1m', // 1分間キャッシュ
  })

  res.json(product)
})

グレース期間の設定

const bento = new BentoCache({
  default: 'cache',
  grace: '6h',        // 6時間のグレース期間
  graceBackoff: '30s', // 30秒のバックオフ
  stores: {
    cache: bentostore().useL1Layer(memoryDriver())
  }
})

タグを使用したキャッシュ管理

// タグを付けてキャッシュを設定
await bento.getOrSet({
  key: 'foo',
  factory: () => getFromDb(),
  tags: ['tag-1', 'tag-2']
})

// タグによる一括削除
await bento.deleteByTags({ tags: ['tag-1'] })

ネームスペースによるキー管理

const users = bento.namespace('users')

users.set({ key: '32', value: { name: 'foo' } })
users.set({ key: '33', value: { name: 'bar' } })

// ネームスペース内の全キーをクリア
users.clear()

イベント監視

bento.on('cache:hit', (event) => {
  console.log('キャッシュヒット:', event)
})

bento.on('cache:miss', (event) => {
  console.log('キャッシュミス:', event)
})

アダプティブキャッシング

const authToken = await bento.getOrSet({
  key: 'token',
  factory: async (options) => {
    const token = await fetchAccessToken()
    // トークンの有効期限に基づいてTTLを動的設定
    options.setOptions({ ttl: token.expiresIn })
    return token
  }
})