您的位置:首页 > 房产 > 家装 > 谷粒商城实战笔记-151-缓存-缓存使用-本地缓存与分布式缓存

谷粒商城实战笔记-151-缓存-缓存使用-本地缓存与分布式缓存

2024/10/6 12:20:10 来源:https://blog.csdn.net/epitomizelu/article/details/141020611  浏览:    关键词:谷粒商城实战笔记-151-缓存-缓存使用-本地缓存与分布式缓存

文章目录

  • 一,本地缓存
      • 1,定义
    • 2,优点
    • 3,代码示例(Java)
    • 4,缺点
  • 二,分布式缓存
    • 1,定义
    • 2,优点
    • 3,缺点
    • 4,代码示例
  • 三,本地缓存与分布式缓存的适用场景
  • 四,缓存一致性的挑战与解决方案

前面的课程通过压测发现了很多问题,并进行了多次优化,包括一下方案:

  • 动静分离,把静态资源存储在nginx,缩短资源请求链路
  • 开启thymeleaf缓存
  • 调整jvm参数,扩大对内存及Eden区内存占比
  • 优化业务代码,减少查询数据库的次数

经过了这些优化措施之后,压测性能有了显著的提升,但距离压测通过标准还有不小差距。

对于三级分类数据,因为其改动较少,变化不大,数据一致性要求也不高,所以还可以通过缓存的方式尽量避免从数据库中读取数据,这会大幅提升性能。

缓存分为两种:

  • 本地缓存
  • 分布式缓存

一,本地缓存

1,定义

本地缓存(Local Cache)通常指的是在单个应用实例的内存中存储的缓存数据。这种缓存方式简单直接,通常使用编程语言内置的数据结构如哈希表(HashMap)来实现。

2,优点

  1. 访问速度快:由于数据存储在本地内存中,访问本地缓存几乎无网络延迟,可以快速响应数据请求。
  2. 简单易实现:大多数编程语言都提供了易于使用的集合类,如Java中的HashMap,Python中的dict,可以快速实现本地缓存。

3,代码示例(Java)

以下是一个简单的本地缓存实现示例,使用Java中的HashMap:

import java.util.HashMap;
import java.util.Map;public class LocalCacheExample {private Map<String, Object> cache = new HashMap<>();public Object getFromCache(String key) {// 尝试从本地缓存获取数据return cache.get(key);}public void addToCache(String key, Object value) {// 将数据放入本地缓存cache.put(key, value);}public static void main(String[] args) {LocalCacheExample localCache = new LocalCacheExample();// 假设我们缓存一个商品信息String productId = "123";Product product = getProductFromDatabase(productId); // 从数据库获取商品信息localCache.addToCache(productId, product);// 后续请求可以直接从缓存获取product = (Product) localCache.getFromCache(productId);if (product != null) {System.out.println("Product found in local cache.");} else {System.out.println("Product not found in local cache, fetching from DB.");}}private Product getProductFromDatabase(String id) {// 模拟数据库查询return new Product(id, "Sample Product");}
}class Product {private String id;private String name;public Product(String id, String name) {this.id = id;this.name = name;}// Getters and Setters
}

4,缺点

  1. 数据不一致:在多实例部署的情况下,每个实例可能拥有不同的本地缓存副本,导致数据不一致。
  2. 容量有限:缓存容量受限于单台服务器的内存大小,不适合存储大量数据。
  3. 扩展性差:本地缓存难以水平扩展,当系统负载增加时,可能需要更复杂的解决方案。
    ,

二,分布式缓存

在分布式系统中,数据的快速访问和一致性是至关重要的,这正是分布式缓存发挥作用的地方。以下是对分布式缓存的概述,包括其定义、优点、缺点以及代码示例。

1,定义

分布式缓存是一种将缓存数据分布在多个服务器或节点上的机制,这些服务器可以是物理机或虚拟机。它允许系统通过多个缓存节点共享数据,从而提高数据访问速度和系统扩展性。

2,优点

  1. 数据一致性:所有应用实例共享同一份缓存数据,确保了数据的一致性。
  2. 高可用性:通过冗余和故障转移机制,即使部分节点失败,缓存服务仍可继续提供服务。
  3. 扩展性强:可以通过增加更多的缓存节点来水平扩展,以应对不断增长的数据量和访问压力。
  4. 负载均衡:分布式缓存系统通常内置或支持负载均衡机制,可以均匀分配请求到各个节点。

3,缺点

  1. 访问速度相对较慢:与本地缓存相比,分布式缓存可能因为网络延迟而稍慢。
  2. 实现复杂:需要处理网络通信、数据分片、一致性协议等复杂问题。
  3. 成本较高:需要投资更多的硬件资源,以及维护分布式系统的复杂性。

4,代码示例

以下是使用Redis作为分布式缓存的一个简单示例。Redis是一个开源的内存数据结构存储系统,常用作分布式缓存解决方案。

import redis.clients.jedis.Jedis;public class RedisCacheExample {private static final String CACHE_HOST = "localhost";private static final int CACHE_PORT = 6379;public static void main(String[] args) {// 连接到Redis缓存服务器try (Jedis jedis = new Jedis(CACHE_HOST, CACHE_PORT)) {// 将数据放入缓存jedis.set("product:123", "Product Name");// 从缓存中获取数据String productName = jedis.get("product:123");System.out.println("Cached Product Name: " + productName);// 如果需要更新缓存中的数据jedis.set("product:123", "Updated Product Name");}}
}

在这个示例中,我使用Java的Jedis客户端连接到本地运行的Redis服务器,并将一个产品名称作为字符串存储在缓存中。之后,从缓存中检索并打印这个名称。如果产品信息更新了,也可以简单地更新缓存中的值。

三,本地缓存与分布式缓存的适用场景

  • 本地缓存:适用于单实例部署,或者对缓存数据一致性要求不高的场景。
  • 分布式缓存:适用于多实例部署,对数据一致性和高可用性有较高要求的场景。

四,缓存一致性的挑战与解决方案

  • 缓存穿透:通过设置合理的超时策略和使用布隆过滤器来防止。
  • 缓存雪崩:通过缓存数据的分布式过期策略来避免大量缓存同时过期。
  • 缓存击穿:对于热点数据,使用互斥锁或分布式锁来保证更新操作的原子性。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com