Maison  >  Article  >  interface Web  >  Mettre fin aux retards : mise en œuvre d'une mise en cache avancée et sécurisée pour les systèmes à forte demande

Mettre fin aux retards : mise en œuvre d'une mise en cache avancée et sécurisée pour les systèmes à forte demande

Patricia Arquette
Patricia Arquetteoriginal
2024-11-24 02:20:09180parcourir

Putting an End to Delays: Implementing Advanced and Secure Caching for High-Demand Systems

Introduction:

Dans le monde d’aujourd’hui, la rapidité et l’efficacité dans la réponse aux demandes sont d’une importance primordiale. Les systèmes à grande échelle et à fort trafic tels que les boutiques en ligne, les réseaux sociaux et les services bancaires sont confrontés à des quantités importantes de données et de demandes des utilisateurs. Cette forte demande impose non seulement une lourde charge aux serveurs et aux bases de données, mais peut également avoir un impact significatif sur l'expérience utilisateur. Dans de tels cas, la mise en œuvre d'un système de mise en cache peut être une solution efficace pour améliorer les performances et réduire la charge sur les ressources.

Cet article traite de la mise en œuvre d'un système de mise en cache avancé qui utilise une combinaison de cartes de hachage et d'arborescences AVL pour un accès plus rapide aux données. De plus, il utilise un mécanisme TTL (Time to Live) pour la gestion de l'expiration des données et la suppression automatisée des données, ainsi que la validation des entrées pour une sécurité renforcée. Ce système de mise en cache intelligent et sécurisé répond aux exigences essentielles des grands projets, offrant une solution puissante pour améliorer la vitesse et l'efficacité du service pour les utilisateurs.

1. Implémentation d'une arborescence AVL avec TTL

Pour gérer l'expiration des données, nous étendons la classe AVL avec un champ TTL. Ce champ précise le délai d'expiration de chaque élément de données et supprime automatiquement les données expirées.

// src/utils/avltree.ts

class AVLNode {
  key: string;
  value: any;
  ttl: number; // Time to live
  height: number;
  left: AVLNode | null;
  right: AVLNode | null;

  constructor(key: string, value: any, ttl: number) {
    this.key = key;
    this.value = value;
    this.ttl = Date.now() + ttl; // Expiry time
    this.height = 1;
    this.left = null;
    this.right = null;
  }

  isExpired(): boolean {
    return Date.now() > this.ttl;
  }
}

export class AVLTree {
  private root: AVLNode | null;

  constructor() {
    this.root = null;
  }

  private getHeight(node: AVLNode | null): number {
    return node ? node.height : 0;
  }

  private updateHeight(node: AVLNode): void {
    node.height = 1 + Math.max(this.getHeight(node.left), this.getHeight(node.right));
  }

  private rotateRight(y: AVLNode): AVLNode {
    const x = y.left!;
    y.left = x.right;
    x.right = y;
    this.updateHeight(y);
    this.updateHeight(x);
    return x;
  }

  private rotateLeft(x: AVLNode): AVLNode {
    const y = x.right!;
    x.right = y.left;
    y.left = x;
    this.updateHeight(x);
    this.updateHeight(y);
    return y;
  }

  private getBalance(node: AVLNode): number {
    return node ? this.getHeight(node.left) - this.getHeight(node.right) : 0;
  }

  insert(key: string, value: any, ttl: number): void {
    this.root = this.insertNode(this.root, key, value, ttl);
  }

  private insertNode(node: AVLNode | null, key: string, value: any, ttl: number): AVLNode {
    if (!node) return new AVLNode(key, value, ttl);

    if (key < node.key) {
      node.left = this.insertNode(node.left, key, value, ttl);
    } else if (key > node.key) {
      node.right = this.insertNode(node.right, key, value, ttl);
    } else {
      node.value = value;
      node.ttl = Date.now() + ttl;
      return node;
    }

    this.updateHeight(node);
    const balance = this.getBalance(node);

    if (balance > 1 && key < node.left!.key) return this.rotateRight(node);
    if (balance < -1 && key > node.right!.key) return this.rotateLeft(node);
    if (balance > 1 && key > node.left!.key) {
      node.left = this.rotateLeft(node.left!);
      return this.rotateRight(node);
    }
    if (balance < -1 && key < node.right!.key) {
      node.right = this.rotateRight(node.right!);
      return this.rotateLeft(node);
    }
    return node;
  }

  search(key: string): any {
    let node = this.root;
    while (node) {
      if (node.isExpired()) {
        this.delete(node.key);
        return null;
      }
      if (key === node.key) return node.value;
      node = key < node.key ? node.left : node.right;
    }
    return null;
  }

  delete(key: string): void {
    this.root = this.deleteNode(this.root, key);
  }

  private deleteNode(node: AVLNode | null, key: string): AVLNode | null {
    if (!node) return null;

    if (key < node.key) {
      node.left = this.deleteNode(node.left, key);
    } else if (key > node.key) {
      node.right = this.deleteNode(node.right, key);
    } else {
      if (!node.left || !node.right) return node.left || node.right;
      let minLargerNode = node.right;
      while (minLargerNode.left) minLargerNode = minLargerNode.left;
      node.key = minLargerNode.key;
      node.value = minLargerNode.value;
      node.ttl = minLargerNode.ttl;
      node.right = this.deleteNode(node.right, minLargerNode.key);
    }
    this.updateHeight(node);
    const balance = this.getBalance(node);

    if (balance > 1 && this.getBalance(node.left!) >= 0) return this.rotateRight(node);
    if (balance < -1 && this.getBalance(node.right!) <= 0) return this.rotateLeft(node);
    if (balance > 1 && this.getBalance(node.left!) < 0) {
      node.left = this.rotateLeft(node.left!);
      return this.rotateRight(node);
    }
    if (balance < -1 && this.getBalance(node.right!) > 0) {
      node.right = this.rotateRight(node.right!);
      return this.rotateLeft(node);
    }
    return node;
  }
}

2. Service de mise en cache amélioré avec TTL et mécanismes de sécurité

Ce service utilise la classe AVLTree pour gérer les données de manière efficace et sécurisée. Il comprend un mécanisme de validation de base pour la sécurité des données.

// src/cache/cache.service.ts

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AVLTree } from '../utils/avltree';

@Injectable()
export class CacheService {
  private avlTree: AVLTree;
  private authorizedTokens: Set<string> = new Set(['your_authorized_token']); // Simple validation example

  constructor() {
    this.avlTree = new AVLTree();
  }

  validateToken(token: string): void {
    if (!this.authorizedTokens.has(token)) {
      throw new UnauthorizedException('Invalid access token');
    }
  }

  set(key: string, value: any, ttl: number, token: string): void {
    this.validateToken(token);
    this.avlTree.insert(key, value, ttl);
  }

  get(key: string, token: string): any {
    this.validateToken(token);
    return this.avlTree.search(key);
  }

  delete(key: string, token: string): void {
    this.validateToken(token);
    this.avlTree.delete(key);
  }
}

3. Contrôleur avec validation et TTL

Le contrôleur API utilise les méthodes set, get et delete pour stocker et récupérer les données en toute sécurité.

// src/cache/cache.controller.ts

import { Controller, Get, Post, Delete, Body, Param, Query } from '@nestjs/common';
import { CacheService } from './cache.service';

@Controller('cache')
export class CacheController {
  constructor(private readonly cacheService: CacheService) {}

  @Post('set')
  setCache(@Body() body: { key: string; value: any; ttl: number; token: string }) {
    this.cacheService.set(body.key, body.value, body.ttl, body.token);
    return { message: 'Data cached successfully' };
  }

  @Get('get/:key')
  getCache(@Param('key') key: string, @Query('token') token: string) {
    const value = this.cacheService.get(key, token);
    return value ? { value } : { message: 'Key not found or expired' };
  }

  @Delete('delete/:key')
  deleteCache(@Param('key') key: string, @Query('token') token: string) {
    this.cacheService.delete(key);
    return { message: 'Key deleted successfully' };
  }
}

Cas d'utilisation pratique du système de mise en cache

  1. Gestion de sessions pour les systèmes d'authentification :

    Exemple : Systèmes bancaires et financiers.

  2. Mise en cache API pour réduire la charge des requêtes :

    Exemple : applications météo et sites Web de change.

  3. Stockage du statut des utilisateurs en temps réel sur les plateformes en ligne :

    Exemple : applications de messagerie comme WhatsApp ou Telegram.

  4. Stockage des données de produits dans les boutiques en ligne :

    Exemple : Plateformes de commerce électronique à fort trafic comme Amazon.

Ces exemples démontrent que ce système de mise en cache peut réduire considérablement la charge de la base de données et du serveur, améliorant ainsi les temps de réponse des utilisateurs.

Conclusion

Dans cet article, nous avons conçu et implémenté un système de mise en cache avancé qui combine des arbres AVL et des cartes de hachage pour permettre un accès rapide aux données et une optimisation des performances du serveur. Le mécanisme TTL permet une gestion automatique de l'expiration des données, tandis que la validation des jetons garantit une sécurité adéquate.

Ce système de mise en cache intelligent est efficace et flexible, adapté aux applications à grande échelle avec des données dynamiques et sensibles, prenant en charge les exigences évolutives des architectures distribuées.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn