برنامه نویسی

برنامه Spring Boot خود را شارژ کنید: Master Distributed Caching برای عملکرد سریع رعد و برق

Summarize this content to 400 words in Persian Lang
مطمئناً، من مستقیماً به موضوع استراتژی های ذخیره سازی پیشرفته Spring Boot با کش های توزیع شده می پردازم.

هنگام افزایش عملکرد برنامه، حافظه پنهان یک تغییر دهنده بازی است. من آن را در بسیاری از پروژه های Spring Boot شگفت زده کرده ام. اما بیایید واقعی باشیم، ذخیره سازی اولیه تنها شما را تا این حد می رساند. وقتی با بارهای سنگین و چندین نود سرور سروکار دارید، باید بازی خود را تقویت کنید.

اینجاست که کش های توزیع شده وارد می شوند. آنها مانند ابرقهرمانان دنیای ذخیره سازی هستند. Redis و Hazelcast دو گزینه محبوب هستند که من با آنها موفقیت زیادی کسب کرده ام. آنها به شما امکان می دهند داده های کش شده را در چندین نمونه از برنامه خود به اشتراک بگذارید، که برای مقیاس پذیری بسیار مهم است.

بیایید با Redis شروع کنیم. سریع است، همه کاره است، و با چکمه‌های Spring خوب بازی می‌کند. در اینجا نحوه تنظیم آن آمده است:

ابتدا وابستگی های لازم را به pom.xml خود اضافه کنید:

org.springframework.boot
spring-boot-starter-data-redis

org.springframework.boot
spring-boot-starter-cache

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سپس Redis را در application.properties خود پیکربندی کنید:

spring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون، شما آماده استفاده از Redis به عنوان کش خود هستید. اما اینجاست که جالب می شود. Spring Boot نکات جالبی را ارائه می دهد که باعث می شود ذخیره سازی در حافظه نهان بسیار آسان شود. بیایید به یک مثال عملی نگاه کنیم:

@Service
public class UserService {
@Cacheable(value = “users”, key = “#id”)
public User getUserById(Long id) {
// Expensive database operation
return userRepository.findById(id).orElse(null);
}

@CachePut(value = “users”, key = “#user.id”)
public User updateUser(User user) {
// Update user in database
return userRepository.save(user);
}

@CacheEvict(value = “users”, key = “#id”)
public void deleteUser(Long id) {
// Delete user from database
userRepository.deleteById(id);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این مثال، @Cacheable نتیجه getUserById را در کش ذخیره می کند. دفعه بعد که با همان شناسه فراخوانی شد، به جای ضربه زدن به پایگاه داده، نتیجه ذخیره شده را برمی گرداند. @CachePut زمانی که کاربر به‌روزرسانی می‌شود، حافظه پنهان را به‌روزرسانی می‌کند و @CacheEvict زمانی که کاربر حذف می‌شود، آن را از حافظه پنهان حذف می‌کند.

اما اگر Redis سقوط کند چه؟ برنامه شما نباید به دلیل در دسترس نبودن حافظه پنهان متوقف شود. به همین دلیل بسیار مهم است که به خوبی با خرابی‌های حافظه پنهان رسیدگی کنید. شما می توانید این کار را با پیاده سازی CacheErrorHandler خود انجام دهید:

@Configuration
public class CacheConfig extends CachingConfigurerSupport {
@Override
public CacheErrorHandler errorHandler() {
return new CacheErrorHandler() {
@Override
public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
log.error(“Cache get error”, e);
}

@Override
public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
log.error(“Cache put error”, e);
}

@Override
public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) {
log.error(“Cache evict error”, e);
}

@Override
public void handleCacheClearError(RuntimeException e, Cache cache) {
log.error(“Cache clear error”, e);
}
};
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این کنترل کننده خطا به جای ایجاد استثنا، خطاهای حافظه نهان را ثبت می کند و به برنامه شما اجازه می دهد حتی اگر حافظه پنهان خاموش است به عملکرد خود ادامه دهد.

حالا بیایید در مورد کش چند سطحی صحبت کنیم. مثل این است که یک چاقوی ارتش سوئیس در جعبه ابزار ذخیره خود داشته باشید. ایده این است که از یک کش محلی سریع و محلی برای داده هایی که اغلب در دسترس هستند و یک کش توزیع شده برای داده هایی که کمتر به آنها دسترسی دارند استفاده شود. در اینجا نحوه اجرای آن آمده است:

@Configuration
@EnableCaching
public class MultilevelCacheConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
SimpleCacheManager cacheManager = new SimpleCacheManager();

List<Cache> caches = new ArrayList<>();
caches.add(new ConcurrentMapCache(“localCache”));
caches.add(new RedisCache(“distributedCache”, redisConnectionFactory));

cacheManager.setCaches(caches);
return cacheManager;
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این راه‌اندازی، یک کش محلی داریم که توسط ConcurrentMapCache پشتیبانی می‌شود و یک حافظه پنهان توزیع‌شده با پشتیبانی RedisCache. سپس می توانید از این کش ها در روش های سرویس خود استفاده کنید:

@Cacheable(cacheNames = {“localCache”, “distributedCache”}, key = “#id”)
public User getUserById(Long id) {
// Expensive database operation
return userRepository.findById(id).orElse(null);
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این روش ابتدا کش محلی و سپس کش توزیع شده را بررسی می کند و تنها در صورتی که داده ها در هیچکدام از کش ها یافت نشد به پایگاه داده ضربه می زند.

اما در مورد انسجام کش چطور؟ در یک سیستم توزیع‌شده، اطمینان از اینکه همه گره‌ها دید یکسانی از داده‌های کش دارند، بسیار مهم است. یکی از راه‌های رسیدن به این هدف، از طریق نامعتبر کردن حافظه پنهان است. وقتی داده ها به روز می شوند، باید کش را در تمام گره ها باطل کنید.

حاشیه‌نویسی @CacheEvict Spring می‌تواند در این مورد کمک کند، اما برای سناریوهای پیچیده‌تر، ممکن است نیاز به پیاده‌سازی یک Cache Resolver سفارشی داشته باشید. در اینجا یک مثال است:

@Component
public class CustomCacheResolver implements CacheResolver {
@Autowired
private CacheManager cacheManager;

@Override
public Collection extends Cache> resolveCaches(CacheOperationInvocationContext> context) {
String cacheName = determineCacheName(context);
return Collections.singleton(cacheManager.getCache(cacheName));
}

private String determineCacheName(CacheOperationInvocationContext> context) {
// Logic to determine cache name based on method parameters or other factors
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سپس می توانید از این حل کننده سفارشی در حاشیه نویسی های کش خود استفاده کنید:

@Cacheable(cacheResolver = “customCacheResolver”)
public User getUserById(Long id) {
// …
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این به شما کنترل دقیقی می دهد که کدام حافظه پنهان برای هر فراخوانی متد استفاده می شود.

یکی دیگر از تکنیک های پیشرفته گرم کردن حافظه پنهان است. این شامل پر کردن حافظه پنهان خود با داده هایی است که می دانید اغلب به آنها دسترسی خواهید داشت. این می تواند به طور قابل توجهی عملکرد را بهبود بخشد، به خصوص پس از پاک کردن حافظه پنهان یا راه اندازی مجدد برنامه. در اینجا یک مثال ساده آورده شده است:

@Component
public class CacheWarmer {
@Autowired
private UserService userService;

@Scheduled(fixedRate = 3600000) // Run every hour
public void warmCache() {
List<Long> popularUserIds = getPopularUserIds();
for (Long id : popularUserIds) {
userService.getUserById(id); // This will populate the cache
}
}

private List<Long> getPopularUserIds() {
// Logic to determine popular user IDs
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این روش هر ساعت اجرا می‌شود و محبوب‌ترین کاربران را واکشی می‌کند و از حضور آنها در حافظه پنهان اطمینان می‌دهد.

سیاست های زمان برای زندگی (TTL) یکی دیگر از جنبه های مهم ذخیره سازی است. آنها کمک می کنند تا اطمینان حاصل شود که حافظه پنهان شما کهنه نمی شود. با Redis، می توانید TTL را در سطح کش تنظیم کنید:

@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(60)); // Set TTL to 60 minutes

return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(config)
.build();
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

همچنین می توانید TTL های مختلف را برای کش های مختلف تنظیم کنید:

@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10));

Map<String, RedisCacheConfiguration> configs = new HashMap<>();
configs.put(“users”, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1)));
configs.put(“posts”, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(30)));

return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(defaultConfig)
.withInitialCacheConfigurations(configs)
.build();
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این یک TTL پیش‌فرض 10 دقیقه‌ای را با TTL‌های خاص برای کش «کاربران» و «پست‌ها» تعیین می‌کند.

حالا بیایید در مورد Hazelcast صحبت کنیم. این یکی دیگر از راه حل های ذخیره سازی توزیع شده قدرتمند است که به خوبی با Spring Boot ادغام می شود. در اینجا نحوه تنظیم آن آمده است:

ابتدا وابستگی Hazelcast را اضافه کنید:

com.hazelcast
hazelcast-spring

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سپس Hazelcast را پیکربندی کنید:

@Configuration
public class HazelcastConfig {
@Bean
public Config hazelCastConfig() {
return new Config()
.setInstanceName(“hazelcast-instance”)
.addMapConfig(
new MapConfig()
.setName(“usersCache”)
.setEvictionConfig(new EvictionConfig().setEvictionPolicy(EvictionPolicy.LRU))
.setTimeToLiveSeconds(2000));
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این یک نمونه Hazelcast را با نقشه ای به نام “usersCache” تنظیم می کند که از خط مشی اخراج LRU (حداقل استفاده اخیر) استفاده می کند و دارای TTL 2000 ثانیه است.

یکی از چیزهای جالب در مورد Hazelcast توانایی آن در مدیریت ساختارهای داده پیچیده است. به عنوان مثال، می توانید نتایج پرس و جو را در حافظه پنهان ذخیره کنید:

@Cacheable(value = “usersCache”, key = “#lastName”)
public List<User> getUsersByLastName(String lastName) {
return userRepository.findByLastName(lastName);
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این کل لیست کاربران با نام خانوادگی مشخص را در حافظه پنهان نگه می دارد. Hazelcast می تواند به طور موثر این لیست را ذخیره و بازیابی کند.

اما اگر به کنترل بیشتری بر رفتار ذخیره سازی خود نیاز داشته باشید، چه؟ اینجاست که پیاده‌سازی‌های کش سفارشی وارد می‌شوند. Spring Boot به شما امکان می‌دهد پیاده‌سازی‌های Cache خود را ایجاد کنید. در اینجا یک مثال ساده آورده شده است:

public class CustomCache implements Cache {
private final ConcurrentMap<Object, Object> store = new ConcurrentHashMap<>();
private final String name;

public CustomCache(String name) {
this.name = name;
}

@Override
public String getName() {
return this.name;
}

@Override
public Object getNativeCache() {
return this.store;
}

@Override
public ValueWrapper get(Object key) {
Object value = this.store.get(key);
return (value != null ? new SimpleValueWrapper(value) : null);
}

@Override
public void put(Object key, Object value) {
this.store.put(key, value);
}

@Override
public void evict(Object key) {
this.store.remove(key);
}

@Override
public void clear() {
this.store.clear();
}

// Implement other methods…
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سپس می توانید از این کش سفارشی در CacheManager خود استفاده کنید:

@Bean
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Arrays.asList(
new CustomCache(“cache1”),
new CustomCache(“cache2”)
));
return cacheManager;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این سطح از سفارشی‌سازی به شما امکان می‌دهد تا استراتژی‌های ذخیره‌سازی پیچیده را متناسب با نیازهای خاص خود پیاده‌سازی کنید.

در نتیجه، استراتژی‌های کش پیشرفته می‌توانند عملکرد و مقیاس‌پذیری برنامه‌های Spring Boot شما را به میزان قابل توجهی افزایش دهند. با استفاده از حافظه پنهان توزیع شده مانند Redis و Hazelcast، پیاده سازی کش چند سطحی، و استفاده از انتزاعات ذخیره سازی قدرتمند Spring، می توانید برنامه های قوی و با کارایی بالا ایجاد کنید که می توانند بارهای سنگین را به راحتی تحمل کنند.

به یاد داشته باشید، ذخیره سازی در حافظه پنهان قدرتمند است، اما یک گلوله نقره ای نیست. همیشه برنامه خود را نمایه کنید تا مطمئن شوید که استراتژی ذخیره سازی شما واقعاً عملکرد را بهبود می بخشد. و در مورد باطل کردن حافظه پنهان فراموش نکنید – به هر حال این یکی از سخت ترین مشکلات در علوم کامپیوتر است!

ذخیره سازی مبارک!

مخلوقات ما

حتماً خلاقیت های ما را بررسی کنید:

مرکز سرمایه گذار | زندگی هوشمند | دوره ها و پژواک ها | اسرار گیج کننده | هندوتوا | Elite Dev | مدارس JS

ما در حالت متوسط ​​هستیم

بینش کوآلای فنی | دوران و پژواک جهان | سرمایه گذار مرکزی متوسط | رازهای گیج کننده رسانه | رسانه علم و عصر | هندوتوای مدرن

مطمئناً، من مستقیماً به موضوع استراتژی های ذخیره سازی پیشرفته Spring Boot با کش های توزیع شده می پردازم.

هنگام افزایش عملکرد برنامه، حافظه پنهان یک تغییر دهنده بازی است. من آن را در بسیاری از پروژه های Spring Boot شگفت زده کرده ام. اما بیایید واقعی باشیم، ذخیره سازی اولیه تنها شما را تا این حد می رساند. وقتی با بارهای سنگین و چندین نود سرور سروکار دارید، باید بازی خود را تقویت کنید.

اینجاست که کش های توزیع شده وارد می شوند. آنها مانند ابرقهرمانان دنیای ذخیره سازی هستند. Redis و Hazelcast دو گزینه محبوب هستند که من با آنها موفقیت زیادی کسب کرده ام. آنها به شما امکان می دهند داده های کش شده را در چندین نمونه از برنامه خود به اشتراک بگذارید، که برای مقیاس پذیری بسیار مهم است.

بیایید با Redis شروع کنیم. سریع است، همه کاره است، و با چکمه‌های Spring خوب بازی می‌کند. در اینجا نحوه تنظیم آن آمده است:

ابتدا وابستگی های لازم را به pom.xml خود اضافه کنید:


    org.springframework.boot
    spring-boot-starter-data-redis


    org.springframework.boot
    spring-boot-starter-cache

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سپس Redis را در application.properties خود پیکربندی کنید:

spring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون، شما آماده استفاده از Redis به عنوان کش خود هستید. اما اینجاست که جالب می شود. Spring Boot نکات جالبی را ارائه می دهد که باعث می شود ذخیره سازی در حافظه نهان بسیار آسان شود. بیایید به یک مثال عملی نگاه کنیم:

@Service
public class UserService {
    @Cacheable(value = "users", key = "#id")
    public User getUserById(Long id) {
        // Expensive database operation
        return userRepository.findById(id).orElse(null);
    }

    @CachePut(value = "users", key = "#user.id")
    public User updateUser(User user) {
        // Update user in database
        return userRepository.save(user);
    }

    @CacheEvict(value = "users", key = "#id")
    public void deleteUser(Long id) {
        // Delete user from database
        userRepository.deleteById(id);
    }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این مثال، @Cacheable نتیجه getUserById را در کش ذخیره می کند. دفعه بعد که با همان شناسه فراخوانی شد، به جای ضربه زدن به پایگاه داده، نتیجه ذخیره شده را برمی گرداند. @CachePut زمانی که کاربر به‌روزرسانی می‌شود، حافظه پنهان را به‌روزرسانی می‌کند و @CacheEvict زمانی که کاربر حذف می‌شود، آن را از حافظه پنهان حذف می‌کند.

اما اگر Redis سقوط کند چه؟ برنامه شما نباید به دلیل در دسترس نبودن حافظه پنهان متوقف شود. به همین دلیل بسیار مهم است که به خوبی با خرابی‌های حافظه پنهان رسیدگی کنید. شما می توانید این کار را با پیاده سازی CacheErrorHandler خود انجام دهید:

@Configuration
public class CacheConfig extends CachingConfigurerSupport {
    @Override
    public CacheErrorHandler errorHandler() {
        return new CacheErrorHandler() {
            @Override
            public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
                log.error("Cache get error", e);
            }

            @Override
            public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
                log.error("Cache put error", e);
            }

            @Override
            public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) {
                log.error("Cache evict error", e);
            }

            @Override
            public void handleCacheClearError(RuntimeException e, Cache cache) {
                log.error("Cache clear error", e);
            }
        };
    }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این کنترل کننده خطا به جای ایجاد استثنا، خطاهای حافظه نهان را ثبت می کند و به برنامه شما اجازه می دهد حتی اگر حافظه پنهان خاموش است به عملکرد خود ادامه دهد.

حالا بیایید در مورد کش چند سطحی صحبت کنیم. مثل این است که یک چاقوی ارتش سوئیس در جعبه ابزار ذخیره خود داشته باشید. ایده این است که از یک کش محلی سریع و محلی برای داده هایی که اغلب در دسترس هستند و یک کش توزیع شده برای داده هایی که کمتر به آنها دسترسی دارند استفاده شود. در اینجا نحوه اجرای آن آمده است:

@Configuration
@EnableCaching
public class MultilevelCacheConfig {
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        SimpleCacheManager cacheManager = new SimpleCacheManager();

        List<Cache> caches = new ArrayList<>();
        caches.add(new ConcurrentMapCache("localCache"));
        caches.add(new RedisCache("distributedCache", redisConnectionFactory));

        cacheManager.setCaches(caches);
        return cacheManager;
    }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این راه‌اندازی، یک کش محلی داریم که توسط ConcurrentMapCache پشتیبانی می‌شود و یک حافظه پنهان توزیع‌شده با پشتیبانی RedisCache. سپس می توانید از این کش ها در روش های سرویس خود استفاده کنید:

@Cacheable(cacheNames = {"localCache", "distributedCache"}, key = "#id")
public User getUserById(Long id) {
    // Expensive database operation
    return userRepository.findById(id).orElse(null);
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این روش ابتدا کش محلی و سپس کش توزیع شده را بررسی می کند و تنها در صورتی که داده ها در هیچکدام از کش ها یافت نشد به پایگاه داده ضربه می زند.

اما در مورد انسجام کش چطور؟ در یک سیستم توزیع‌شده، اطمینان از اینکه همه گره‌ها دید یکسانی از داده‌های کش دارند، بسیار مهم است. یکی از راه‌های رسیدن به این هدف، از طریق نامعتبر کردن حافظه پنهان است. وقتی داده ها به روز می شوند، باید کش را در تمام گره ها باطل کنید.

حاشیه‌نویسی @CacheEvict Spring می‌تواند در این مورد کمک کند، اما برای سناریوهای پیچیده‌تر، ممکن است نیاز به پیاده‌سازی یک Cache Resolver سفارشی داشته باشید. در اینجا یک مثال است:

@Component
public class CustomCacheResolver implements CacheResolver {
    @Autowired
    private CacheManager cacheManager;

    @Override
    public Collection extends Cache> resolveCaches(CacheOperationInvocationContext> context) {
        String cacheName = determineCacheName(context);
        return Collections.singleton(cacheManager.getCache(cacheName));
    }

    private String determineCacheName(CacheOperationInvocationContext> context) {
        // Logic to determine cache name based on method parameters or other factors
    }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سپس می توانید از این حل کننده سفارشی در حاشیه نویسی های کش خود استفاده کنید:

@Cacheable(cacheResolver = "customCacheResolver")
public User getUserById(Long id) {
    // ...
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این به شما کنترل دقیقی می دهد که کدام حافظه پنهان برای هر فراخوانی متد استفاده می شود.

یکی دیگر از تکنیک های پیشرفته گرم کردن حافظه پنهان است. این شامل پر کردن حافظه پنهان خود با داده هایی است که می دانید اغلب به آنها دسترسی خواهید داشت. این می تواند به طور قابل توجهی عملکرد را بهبود بخشد، به خصوص پس از پاک کردن حافظه پنهان یا راه اندازی مجدد برنامه. در اینجا یک مثال ساده آورده شده است:

@Component
public class CacheWarmer {
    @Autowired
    private UserService userService;

    @Scheduled(fixedRate = 3600000) // Run every hour
    public void warmCache() {
        List<Long> popularUserIds = getPopularUserIds();
        for (Long id : popularUserIds) {
            userService.getUserById(id); // This will populate the cache
        }
    }

    private List<Long> getPopularUserIds() {
        // Logic to determine popular user IDs
    }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این روش هر ساعت اجرا می‌شود و محبوب‌ترین کاربران را واکشی می‌کند و از حضور آنها در حافظه پنهان اطمینان می‌دهد.

سیاست های زمان برای زندگی (TTL) یکی دیگر از جنبه های مهم ذخیره سازی است. آنها کمک می کنند تا اطمینان حاصل شود که حافظه پنهان شما کهنه نمی شود. با Redis، می توانید TTL را در سطح کش تنظیم کنید:

@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
    RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
        .entryTtl(Duration.ofMinutes(60)); // Set TTL to 60 minutes

    return RedisCacheManager.builder(redisConnectionFactory)
        .cacheDefaults(config)
        .build();
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

همچنین می توانید TTL های مختلف را برای کش های مختلف تنظیم کنید:

@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
    RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
        .entryTtl(Duration.ofMinutes(10));

    Map<String, RedisCacheConfiguration> configs = new HashMap<>();
    configs.put("users", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1)));
    configs.put("posts", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(30)));

    return RedisCacheManager.builder(redisConnectionFactory)
        .cacheDefaults(defaultConfig)
        .withInitialCacheConfigurations(configs)
        .build();
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این یک TTL پیش‌فرض 10 دقیقه‌ای را با TTL‌های خاص برای کش «کاربران» و «پست‌ها» تعیین می‌کند.

حالا بیایید در مورد Hazelcast صحبت کنیم. این یکی دیگر از راه حل های ذخیره سازی توزیع شده قدرتمند است که به خوبی با Spring Boot ادغام می شود. در اینجا نحوه تنظیم آن آمده است:

ابتدا وابستگی Hazelcast را اضافه کنید:


    com.hazelcast
    hazelcast-spring

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سپس Hazelcast را پیکربندی کنید:

@Configuration
public class HazelcastConfig {
    @Bean
    public Config hazelCastConfig() {
        return new Config()
            .setInstanceName("hazelcast-instance")
            .addMapConfig(
                new MapConfig()
                    .setName("usersCache")
                    .setEvictionConfig(new EvictionConfig().setEvictionPolicy(EvictionPolicy.LRU))
                    .setTimeToLiveSeconds(2000));
    }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این یک نمونه Hazelcast را با نقشه ای به نام “usersCache” تنظیم می کند که از خط مشی اخراج LRU (حداقل استفاده اخیر) استفاده می کند و دارای TTL 2000 ثانیه است.

یکی از چیزهای جالب در مورد Hazelcast توانایی آن در مدیریت ساختارهای داده پیچیده است. به عنوان مثال، می توانید نتایج پرس و جو را در حافظه پنهان ذخیره کنید:

@Cacheable(value = "usersCache", key = "#lastName")
public List<User> getUsersByLastName(String lastName) {
    return userRepository.findByLastName(lastName);
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این کل لیست کاربران با نام خانوادگی مشخص را در حافظه پنهان نگه می دارد. Hazelcast می تواند به طور موثر این لیست را ذخیره و بازیابی کند.

اما اگر به کنترل بیشتری بر رفتار ذخیره سازی خود نیاز داشته باشید، چه؟ اینجاست که پیاده‌سازی‌های کش سفارشی وارد می‌شوند. Spring Boot به شما امکان می‌دهد پیاده‌سازی‌های Cache خود را ایجاد کنید. در اینجا یک مثال ساده آورده شده است:

public class CustomCache implements Cache {
    private final ConcurrentMap<Object, Object> store = new ConcurrentHashMap<>();
    private final String name;

    public CustomCache(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public Object getNativeCache() {
        return this.store;
    }

    @Override
    public ValueWrapper get(Object key) {
        Object value = this.store.get(key);
        return (value != null ? new SimpleValueWrapper(value) : null);
    }

    @Override
    public void put(Object key, Object value) {
        this.store.put(key, value);
    }

    @Override
    public void evict(Object key) {
        this.store.remove(key);
    }

    @Override
    public void clear() {
        this.store.clear();
    }

    // Implement other methods...
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سپس می توانید از این کش سفارشی در CacheManager خود استفاده کنید:

@Bean
public CacheManager cacheManager() {
    SimpleCacheManager cacheManager = new SimpleCacheManager();
    cacheManager.setCaches(Arrays.asList(
        new CustomCache("cache1"),
        new CustomCache("cache2")
    ));
    return cacheManager;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این سطح از سفارشی‌سازی به شما امکان می‌دهد تا استراتژی‌های ذخیره‌سازی پیچیده را متناسب با نیازهای خاص خود پیاده‌سازی کنید.

در نتیجه، استراتژی‌های کش پیشرفته می‌توانند عملکرد و مقیاس‌پذیری برنامه‌های Spring Boot شما را به میزان قابل توجهی افزایش دهند. با استفاده از حافظه پنهان توزیع شده مانند Redis و Hazelcast، پیاده سازی کش چند سطحی، و استفاده از انتزاعات ذخیره سازی قدرتمند Spring، می توانید برنامه های قوی و با کارایی بالا ایجاد کنید که می توانند بارهای سنگین را به راحتی تحمل کنند.

به یاد داشته باشید، ذخیره سازی در حافظه پنهان قدرتمند است، اما یک گلوله نقره ای نیست. همیشه برنامه خود را نمایه کنید تا مطمئن شوید که استراتژی ذخیره سازی شما واقعاً عملکرد را بهبود می بخشد. و در مورد باطل کردن حافظه پنهان فراموش نکنید – به هر حال این یکی از سخت ترین مشکلات در علوم کامپیوتر است!

ذخیره سازی مبارک!


مخلوقات ما

حتماً خلاقیت های ما را بررسی کنید:

مرکز سرمایه گذار | زندگی هوشمند | دوره ها و پژواک ها | اسرار گیج کننده | هندوتوا | Elite Dev | مدارس JS


ما در حالت متوسط ​​هستیم

بینش کوآلای فنی | دوران و پژواک جهان | سرمایه گذار مرکزی متوسط | رازهای گیج کننده رسانه | رسانه علم و عصر | هندوتوای مدرن

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا