mcpField
C
caching-strategist

caching-strategist

github.com/patricio0312rev開発63266 回インストール41 週間前に更新
リポジトリ

caching-strategist について

ソフトウェア開発者向けのキャッシュ戦略設計スキルです。キャッシュ層、キー、TTL、無効化、ウォームアップ、正しさの確認を扱います。

主な機能

  1. 01CDN、アプリ、DB、クライアントのキャッシュ設計
  2. 02階層型キャッシュキーと TTL の設計
  3. 03Cache-aside と無効化フローの実装
  4. 04キャッシュのウォームアップとスタンピード防止
  5. 05フォールバック、監視、正しさの確認

活用シーン

  1. 01更新頻度に応じた TTL の選定
  2. 02書き込み時のキャッシュ無効化ルールの設計
  3. 03人気クエリの重複読み込みの削減
  4. 04キャッシュ障害時のフォールバックと監視の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/patricio0312rev/skills --skill caching-strategist

インストール後、Claude Code で/caching-strategistを入力して読み込まれたか確認します。

詳細

キャッシュ戦略

パフォーマンスと一貫性を高める、効果的なキャッシュ戦略を設計します。

キャッシュレイヤー

CDN:静的アセット、公開ページ(TTL:日/週) アプリケーションキャッシュ(Redis):API レスポンス、セッション(TTL:分/時間) データベースキャッシュ:クエリ結果(TTL:秒/分) クライアントキャッシュ:ブラウザー/アプリのローカルキャッシュ

キャッシュキー戦略

// Hierarchical key structure
const CACHE_KEYS = {
  user: (id: string) => `user:${id}`,
  userPosts: (userId: string, page: number) => `user:${userId}:posts:${page}`,
  post: (id: string) => `post:${id}`,
  postComments: (postId: string) => `post:${postId}:comments`,
};

// Include version in keys for easy invalidation
const CACHE_VERSION = "v1";
const key = `${CACHE_VERSION}:${CACHE_KEYS.user(userId)}`;

TTL 戦略

const TTL = {
  // Frequently changing
  REALTIME: 10, // 10 seconds
  SHORT: 60, // 1 minute

  // Moderate updates
  MEDIUM: 300, // 5 minutes
  STANDARD: 3600, // 1 hour

  // Rarely changing
  LONG: 86400, // 1 day
  VERY_LONG: 604800, // 1 week
};

// Usage
await redis.setex(key, TTL.MEDIUM, JSON.stringify(data));

キャッシュアサイドパターン

export const getCachedUser = async (userId: string): Promise<User> => {
  const key = CACHE_KEYS.user(userId);

  // Try cache first
  const cached = await redis.get(key);
  if (cached) {
    return JSON.parse(cached);
  }

  // Cache miss - fetch from DB
  const user = await db.users.findById(userId);

  // Store in cache
  await redis.setex(key, TTL.STANDARD, JSON.stringify(user));

  return user;
};

キャッシュ無効化

// Invalidate on update
export const updateUser = async (userId: string, data: UpdateUserDto) => {
  const user = await db.users.update(userId, data);

  // Invalidate cache
  await redis.del(CACHE_KEYS.user(userId));

  // Invalidate related caches
  await redis.del(CACHE_KEYS.userPosts(userId, "*"));

  return user;
};

// Tag-based invalidation
const addCacheTags = (key: string, tags: string[]) => {
  tags.forEach((tag) => {
    redis.sadd(`cache_tag:${tag}`, key);
  });
};

const invalidateByTag = async (tag: string) => {
  const keys = await redis.smembers(`cache_tag:${tag}`);
  if (keys.length) {
    await redis.del(...keys);
    await redis.del(`cache_tag:${tag}`);
  }
};

キャッシュウォーミング

// Pre-populate cache for common queries
export const warmCache = async () => {
  const popularPosts = await db.posts.findPopular(100);

  for (const post of popularPosts) {
    const key = CACHE_KEYS.post(post.id);
    await redis.setex(key, TTL.LONG, JSON.stringify(post));
  }
};

// Schedule warming
cron.schedule("0 */6 * * *", warmCache); // Every 6 hours

キャッシュスタンピードの防止

// Use locks to prevent multiple simultaneous fetches
export const getCachedWithLock = async (
  key: string,
  fetchFn: () => Promise<any>
) => {
  const cached = await redis.get(key);
  if (cached) return JSON.parse(cached);

  const lockKey = `lock:${key}`;
  const acquired = await redis.set(lockKey, "1", "EX", 10, "NX");

  if (acquired) {
    try {
      // Fetch and cache
      const data = await fetchFn();
      await redis.setex(key, TTL.STANDARD, JSON.stringify(data));
      return data;
    } finally {
      await redis.del(lockKey);
    }
  } else {
    // Wait for other request to finish
    await new Promise((resolve) => setTimeout(resolve, 100));
    return getCachedWithLock(key, fetchFn);
  }
};

キャッシュの正確性チェックリスト

- [ ] Cache keys are unique and predictable
- [ ] TTL is appropriate for data freshness
- [ ] Invalidation happens on all updates
- [ ] Related caches invalidated together
- [ ] Cache stampede prevention in place
- [ ] Fallback to DB if cache fails
- [ ] Monitoring cache hit rate
- [ ] Cache size doesn't grow unbounded
- [ ] Sensitive data not cached or encrypted
- [ ] Cache warming for critical paths

ベストプラクティス

  • 不変データは積極的にキャッシュします
  • 頻繁に変わるデータには短い TTL を設定します
  • 読み取り時ではなく、書き込み時に無効化します
  • ヒット率を監視し、調整します
  • 一括無効化にはタグを使用します
  • キャッシュスタンピードを防止します
  • キャッシュがダウンした場合に備えて、適切に縮退します

出力チェックリスト

  • キャッシュキーの命名戦略
  • データ型ごとの TTL 値
  • 無効化のトリガーを文書化
  • キャッシュアサイドの実装
  • スタンピードの防止
  • キャッシュウォーミング戦略
  • 監視/メトリクスの設定
  • 正確性チェックリストの完了

コメント