ITPub博客

首页 > 应用开发 > XML/XSL > 为什么需要本地缓存?

为什么需要本地缓存?

投稿 XML/XSL 作者:crucz025 时间:2026-01-28 17:07:27 0 删除 编辑

加了Redis分布式缓存后有所改善,但网络IO的开销依然存在,特别是对时效性要求高的数据。

这时候,本地缓存的价值就凸显出来了。

本地缓存是什么?

简单说就是将数据存储在 应用进程的内存中,实现数据的快速访问。

它的访问速度通常是纳秒级,而分布式缓存(如Redis)是毫秒级,数据库查询更是毫秒到秒级。

01 为什么需要本地缓存?

在深入具体方案前,我们先搞清楚本地缓存的核心价值。


// 没有缓存的用户查询服务 @Service public class CategoryServiceWithoutCache {         @Autowired     private CategoryMapper categoryMapper;         public Category getCategoryById (Long categoryId) {         // 每次调用都直接查询数据库         return categoryMapper.selectById(categoryId);    }         // 假设这个接口每秒被调用1000次

@Service public class CategoryServiceWithCache {         @Autowired     private CategoryMapper categoryMapper;         // 使用ConcurrentHashMap作为本地缓存     private final Map<Long, Category> categoryCache = new ConcurrentHashMap <>();         public Category getCategoryById (Long categoryId) {         // 1. 先查缓存         Category category = categoryCache.get(categoryId);         if (category != null ) {             return category;   // 缓存命中,直接返回        }                 // 2. 缓存未命中,查询数据库        category = categoryMapper.selectById(categoryId);         if (category != null ) {             // 3. 将数据放入缓存            categoryCache.put(categoryId, category);        }        

declare ( strict_types = 1 ) ; function ext_version ( string $ext ) : ? string {     $v = phpversion ( $ext ) ;     return $v === false ? null : $v ; } $snapshot = [     'php_version' => PHP_VERSION ,     'php_version_id' => PHP_VERSION_ID ,     'sapi' => PHP_SAPI ,     'os' => PHP_OS_FAMILY . ' ' . php_uname ( 'r' ) ,     'ini_loaded' => php_ini_loaded_file ( ) ,     'ini_scanned' => php_ini_scanned_files ( ) ,     'extensions' => [ ] , ] ; $exts = get_loaded_extensions ( ) ; sort ( $exts ) ; foreach ( $exts as $ext ) {     $snapshot [ 'extensions' ] [ $ext ] = ext_version ( $ext ) ;

pull_request : jobs :   tests :     runs-on : ubuntu - latest     strategy :       fail-fast : false       matrix :         php : [ '8.3' , '8.5' ] # 调整为你的当前版本 + 目标版本     steps :       - uses : actions/checkout@v4       - name : Setup PHP         uses : shivammathur/setup - php@v2         with :           php-version : $ { { matrix.php } }           tools : composer : v2           coverage : none       - name : Install dependencies         run : composer install - - no - interaction - - prefer - dist       - name : Run tests         run : vendor/bin/phpunit


# 生成模拟的降水量数据 (单位: mm) np.random.seed( 42 )   # 为了结果可复现 降水量 = np.random.uniform( 30 , 150 , size= len (月份))   # 随机生成30-150mm的数据 # --- 2. 创建图形 --- fig, (ax1, ax2) = plt.subplots( 1 , 2 , figsize=( 14 , 7 ), facecolor= "white" ) # --- 2.1 绘制传统条形图 --- # ... 省略 ... # --- 2.2 绘制径向条形图 --- # 计算每个条形的角度位置 # ... 省略 ... # 使用极坐标子图 ax2 = plt.subplot( 122 , projection= "polar" ) # 关键:设置 'bottom' 参数为 inner_radius,这样条形就从 inner_radius 开始画,长度为 radii bars = ax2.bar(    theta,    radii,    width= 0.4 ,    bottom=inner_radius,    color= "lightcoral" ,    edgecolor= "darkred" ,    alpha= 0.7 , ) # 添加数值标签 (在条形内部,靠近外侧) for angle, radius, month in zip (theta, radii, 月份):    ax2.text(        angle,        inner_radius + radius / 2 ,         f" {radius: .1f}" ,        ha= "center" ,        va= "center" ,        fontsize= 8 ,        color= "black" ,    ) # 添加月份标记 (在条形外部) # ... 省略 ...

from math import log10 labels = list ( "ABCDEFG" ) data = [ 21 , 57 , 88 , 14 , 76 , 91 , 26 ] # ... 省略 ... #create colors along a chosen colormap colors = [cm.terrain(i / n) for i in range (n)] #create figure, axis fig, ax = plt.subplots() #create rings of donut chart for i in range (n):    current_outer_radius = r - i * w    innerring, _ = ax.pie([m - data[i], data[i]], pant.com.cn,                          radius = current_outer_radius,                          startangle = 90 ,                          colors = [ "white" , colors[i]])

public class ReentrantLockDemo { xyzdh.cn,    // 创建非公平锁(默认),若需公平锁:new ReentrantLock(true)     private static final ReentrantLock lock = new ReentrantLock ();     public static void doTask () {         // 1. 普通获取锁(不可中断)        lock.lock();         try {             // 临界区代码(线程安全)            System.out.println(Thread.currentThread().getName() + " 执行任务" );            Thread.sleep( 1000 );        } catch (InterruptedException e) {            Thread.currentThread().interrupt();        } finally {             // 必须在finally中释放锁,否则锁永远无法释放            lock.unlock();        }    }     // 超时获取锁示例     public static void tryLockWithTimeout () {         try {             // 尝试在2秒内获取锁,获取成功返回true,失败返回false             if (lock.tryLock( 2 , java.util.concurrent.TimeUnit.SECONDS)) {                 try {                    System.out.println(Thread.currentThread().getName() + " 超时获取锁成功" );                } finally {                    lock.unlock();winered.cn,                }            } else {                System.out.println(Thread.currentThread().getName() + " 超时获取锁失败" );            }        } catch (InterruptedException e) {            Thread.currentThread().interrupt();        }    }     public static void main (String[] args) {         // 测试普通获取锁         new Thread (ReentrantLockDemo::doTask, "线程1" ).start();         new Thread (ReentrantLockDemo::doTask, "线程2" ).start();       pant.com.cn,          // 测试超时获取锁

import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.core.PriorityOrdered; import org.springframework.lang.Nullable; /** * @author yangfh * @date 2023-12-14 21:30 **/ public class User implements InitializingBean , DisposableBean { private Long id; private String username; private String email; private Address address; private Long age; public User () { System.out.println( "User 无参构造函数: " + this .toString()); } public User (Long id, String username, String email, Address address) { this .id = id; this .username = username; this .email = email; this .address = address; System.out.println( "User 有参构造函数: " + this .toString()); } public void initMethod () { System.out.println( "User initMethod" ); } public void destroyMethod () { System.out.println( "User destroyMethod" ); } @Override public void afterPropertiesSet () throws Exception { System.out.println( "User afterPropertiesSet" ); } @Override public void destroy () throws Exception { System.out.println( "User destroy" ); } public UserServiceImpl () { System.out.println( "UserServiceImpl 无参构造" ); } @Override public Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException { System.out.println( "UserServiceImpl postProcessBeforeInitialization 增强处理 [" +beanName+ "]" ); return BeanPostProcessor. super .postProcessBeforeInitialization(bean, beanName); } @Override,yousLab.com public Object postProcessAfterInitialization (Object bean, String beanName) throws BeansException { System.out.println( "UserServiceImpl postProcessAfterInitialization 增强处理 [" +beanName+ "]" ); return BeanPostProcessor. super .postProcessAfterInitialization(bean, beanName);wsbbt.com, } @Override public void postProcessBeanFactory (ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println( "UserServiceImpl postProcessBeanFactory beanFactory 增强处理 [" +beanFactory+ "]" ); } @Override public void setApplicationContext (ApplicationContext applicationContext) throws BeansException { System.out.println( "UserServiceImpl setApplicationContext " );51xinku.com,

  xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"qssfzm.com,   xmlns:context= "http://www.springframework.org/schema/context"   xmlns:aop= "http://www.springframework.org/schema/cache"   xsi:schemaLocation= " http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context qzsxy.com, https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> < bean id= "address" class= "org.yang.learn.spring.dto.Address" > < constructor-arg value= "深圳"/> < constructor-arg value= "罗湖"/> < constructor-arg value= "xxx街道101号"/> </ bean> < bean id= "user" njyf.com.cn, class= "org.yang.learn.spring.dto.User" init-method= "initMethod" destroy-method= "destroyMethod" > < property name= "username" value= "张三"> </ property> < property name= "age" value= "9764534"> </ property> </ bean> < bean id= "userService" class= "org.yang.learn.spring.dto.UserServiceImpl" > </ bean>


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70048956/viewspace-3109286/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2026-01-28

  • 博文量
    15
  • 访问量
    13025