Cache framework in java

Кеширование данных — Java Spring

Многократно вычитывая одни и те же данные, встает вопрос оптимизации, данные не меняются или редко меняются, это различные справочники и др. информация, т.е. функция получения данных по ключу — детерминирована. Тут наверно все понимают — нужен Кеш! Зачем всякий раз повторно выполнять поиск данных или вычисление?

Так вот здесь я покажу как делать кеш в Java Spring и поскольку это тесно связанно скорее всего с Базой данных, то и как сделать это в СУБД на примере одной конкретной.

Кеш в Spring

Далее все поступают примерно одинаково, в Java используют различные HasMap, ConcurrentMap и др. В Spring тоже для это есть решение, простое, удобное, эффективное. Я думаю что в большинстве случаев это поможет в решении задачи. И так, все что нужно, это включить кеш и аннотировать функцию.

@SpringBootApplication @EnableCaching public class DemoCacheAbleApplication < public static void main(String[] args) < SpringApplication.run(DemoCacheAbleApplication.class, args); >> 

Кешируем данные поиска функции

 @Cacheable(cacheNames="person") public Person findCacheByName(String name) < //. >

В аннотации указывается название кеша и есть еще другие параметры. Работает как и ожидается так, первый раз код выполняется, результат поиска помещается в кеш по ключу (в данном случае name) и последующие вызовы код уже не выполняется, а данные извлекаются из кеша.

Пример реализации репозитория «Person» с использованием кеша

@Component public class PersonRepository < private static final Logger logger = LoggerFactory.getLogger(PersonRepository.class); private Listpersons = new ArrayList<>(); public void initPersons(List persons) < this.persons.addAll(persons); >private Person findByName(String name) < Person person = persons.stream() .filter(p ->p.getName().equals(name)) .findFirst() .orElse(null); return person; > @Cacheable(cacheNames="person") public Person findCacheByName(String name) < logger.info("find person . " + name); final Person person = findByName(name); return person; >> 
@RunWith(SpringRunner.class) @SpringBootTest public class DemoCacheAbleApplicationTests < private static final Logger logger = LoggerFactory.getLogger(DemoCacheAbleApplicationTests.class); @Autowired private PersonRepository personRepository; @Before public void before() < personRepository.initPersons(Arrays.asList(new Person("Иван", 22), new Person("Сергей", 34), new Person("Игорь", 41))); >private Person findCacheByName(String name) < logger.info("begin find " + name); final Person person = personRepository.findCacheByName(name); logger.info("find result = " + person.toString()); return person; >@Test public void findByName() < findCacheByName("Иван"); findCacheByName("Иван"); >> 
@Test public void findByName()

, первый раз происходит вызов, поиск, в второй раз результат берется уже из кеша. Это видно в консоли

image

Удобно, можно точечно оптимизировать существующий функционал. Если в функции более одного аргумента, то можно указать имя параметра, какой использовать в качестве ключа.

 @Cacheable(cacheNames="person", key="#name") public Person findByKeyField(String name, Integer age)  

Есть и более сложные схемы получения ключа, это в документации.

Но конечно встанет вопрос, как обновить данные в кеше? Для этой цели есть две аннотации.

Функция с этой аннотацией будет всегда вызывать код, а результат помещать в кеш, таким образом она сможет обновить кеш.

Добавлю в репозиторий два метода: удаления и добавления Person

 public boolean delete(String name) < final Person person = findByName(name); return persons.remove(person); >public boolean add(Person person)

Выполню поиск Person, удалю, добавлю, опять поиск, но по прежнему буду получать одно и тоже лицо из кеша, пока не вызову «findByNameAndPut»

 @CachePut(cacheNames="person") public Person findByNameAndPut(String name)
 @Test public void findCacheByNameAndPut()

image

Другая аннотация это @CacheEvict

Позволяет не просто посещать хранилище кеша, но и выселять. Этот процесс полезен для удаления устаревших или неиспользуемых данных из кеша.

По умолчанию Spring для кеша использует — ConcurrentMapCache, если есть свой отличный класс для организации кеша, то это возможно указать в CacheManager

@SpringBootApplication @EnableCaching public class DemoCacheAbleApplication < public static void main(String[] args) < SpringApplication.run(DemoCacheAbleApplication.class, args); >@Bean public CacheManager cacheManager() < SimpleCacheManager cacheManager = new SimpleCacheManager(); cacheManager.setCaches(Arrays.asList( new ConcurrentMapCache("person"), new ConcurrentMapCache("addresses"))); return cacheManager; >> 

Там же указываются имена кешей, их может быть несколько. В xml конфигурации это указывается так:

public class Person < private String name; private Integer age; public Person(String name, Integer age) < this.name = name; this.age = age; >public String getName() < return name; >public Integer getAge() < return age; >@Override public String toString()

image

  4.0.0 com.example demoCacheAble 0.0.1-SNAPSHOT jar DemoCacheAble Demo project for Spring Boot org.springframework.boot spring-boot-starter-parent 2.0.6.RELEASE  UTF-8 UTF-8 1.8   org.springframework.boot spring-boot-starter-cache  org.springframework.boot spring-boot-starter-test test     org.springframework.boot spring-boot-maven-plugin     

Кеш в Oracle PL-SQL функции

Ну и в конце, тем кто не пренебрегает мощностью СУБД, а использует ее, могут использовать кеширование на уровне БД, в дополнение или как альтернативу. Так например в Oracle не менее элегантно можно превратить обычную функцию, в функцию с кешированием результата, добавив к ней

CREATE OR REPLACE FUNCTION GET_COUNTRY_NAME(P_CODE IN VARCHAR2) RETURN VARCHAR2 RESULT_CACHE IS CODE_RESULT VARCHAR2(50); BEGIN SELECT COUNTRY_NAME INTO CODE_RESULT FROM COUNTRIES WHERE COUNTRY_ID = P_CODE; -- имитация долгой работы dbms_lock.sleep (1); RETURN(CODE_RESULT); END; 

Источник

Cache framework in java

ApacheCon

Java Caching System

JCS is a distributed caching system written in Java. It is intended to speed up applications by providing a means to manage cached data of various dynamic natures. Like any caching system, JCS is most useful for high read, low put applications. Latency times drop sharply and bottlenecks move away from the database in an effectively cached system. Learn how to start using JCS.

The JCS goes beyond simply caching objects in memory. It provides numerous additional features:

  • Memory management
  • Disk overflow (and defragmentation)
  • Thread pool controls
  • Element grouping
  • Minimal dependencies
  • Quick nested categorical removal
  • Data expiration (idle time and max life)
  • Extensible framework
  • Fully configurable runtime parameters
  • Region data separation and configuration
  • Fine grained element configuration options
  • Remote synchronization
  • Remote store recovery
  • Non-blocking "zombie" (balking facade) pattern
  • Lateral distribution of elements via HTTP, TCP, or UDP
  • UDP Discovery of other caches
  • Element event handling
  • Remote server chaining (or clustering) and failover
  • Custom event logging hooks
  • Custom event queue injection
  • Custom object serializer injection
  • Key pattern matching retrieval
  • Network efficient multi-key retrieval

JCS 3.x works on JDK versions 1.8 and up. It has no mandatory external dependencies. See the document about upgrading.

JCS 2.x works on JDK versions 1.6 and up. It only has a dependency on Commons Logging. See the document about upgrading.

JCS is a Composite Cache

The foundation of JCS is the Composite Cache, which is the pluggable controller for a cache region. Four types of caches can be plugged into the Composite Cache for any given region: (1) Memory, (2) Disk, (3) Lateral, and (4) Remote. The Composite Cache orchestrates access to the various caches configured for use in a region.

The JCS jar provides production ready implementations of each of the four types of caches. In addition to the core four, JCS also provides additional plugins of each type.

LRU Memory Cache

The LRU Memory Cache is an extremely fast, highly configurable memory cache . It uses a Least Recently Used algorithm to manage the number of items that can be stored in memory. The LRU Memory Cache uses its own LRU Map implementation that is significantly faster than both the commons LRUMap implementation and the LinkedHashMap that is provided with JDK1.4 up. This makes JCS faster than its competitors .

Indexed Disk Cache

The Indexed Disk Cache is a fast, reliable, and highly configurable swap for cached data. The indexed disk cache follows the fastest pattern for disk swapping. Cache elements are written to disk via a continuous queue-based process. The length of the item is stored in the first few bytes of the entry. The offset is stored in memory and can be reference via the key. When items are removed from the disk cache, the location and size are recorded and reused when possible. Every aspect of the disk cache is configurable, and a thread pool can be used to reduce the number of queue worker threads across the system.

JDBC Disk Cache

The JDBC Disk Cache is a fast, reliable, and highly configurable disk cache. It stores both the keys and elements in a JDBC compatible database. The JDBC disk cache stores elements in a database as BLOBs. Periodically, the table is swept to remove expired elements. Multiple instances can be configured to use a common connection pool. A thread pool can be used to reduce the number of queue worker threads across the system. The MySQL version of the JDBC Disk Cache can optimize and repair tables.

TCP Lateral Cache

The TCP Lateral Cache provides an easy way to distribute cached data to multiple servers. It comes with a UDP discovery mechanism, so you can add nodes without having to reconfigure the entire farm. The TCP Lateral Cache works by establishing connections with socket server running on other nodes. Each node maintains a connection to every other. Only one server is needed for any number of regions. The client is able to re-establish connections if it looses its connection with another server. The TCP Lateral is highly configurable . You can choose to only send data, to not look for data on other servers, to send removes instead of puts, and to filter removes based on hash codes.

RMI Remote Cache

JCS also provides an RMI based Remote Cache Server . Rather than having each node connect to every other node, you can use the remote cache server as the connection point. Each node connects to the remove server, which then broadcasts events to the other nodes. To maintain consistency across a cluster without incurring the overhead of serialization, you can decide to send invalidation messages to the other locals rather than send the object over the wire. The remote cache server holds a serialized version of your objects, so it does not need to be deployed with your class libraries. The remote servers can be chained and a list of failover servers can be configured on the client.

What JCS is not

JCS is not a tag library or a web specific application. JCS is a general purpose caching system that can be used in web applications, services, and stand alone Java applications.

JCS is not a transactional distribution mechanism. Transactional distributed caches are not scalable. JCS is a cache not a database. The distribution mechanisms provided by JCS can scale into the tens of servers. In a well-designed service oriented architecture, JCS can be used in a high demand service with numerous nodes. This would not be possible if the distribution mechanism were transactional.

JCS does not use AOP. JCS is a high performance, non-invasive cache. It does not manipulate your objects so it can just send a field or two fewer over the wire.

JCS is not a fork, an offshoot, a branch, or any other derivation of JCS. Nor is JCS named after another library. JCS is a mature project that has been under development and in use since 2001. Over the years JCS has incorporated numerous bug fixes and has added dozens of features, making it the best designed and most feature rich caching solution available.

Copyright © 2002-2022 The Apache Software Foundation. All Rights Reserved.

Apache Commons, Apache Commons JCS, Apache, the Apache feather logo, and the Apache Commons project logos are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.

Источник

Читайте также:  Time and date input in html
Оцените статью