Недавно я изучаю Spring Boot 2.x для интеграции Redis, и я поделюсь этим с вами здесь, надеюсь, это будет вам полезно.
Что такое Редис
Redis — это бесплатная высокопроизводительная база данных с открытым исходным кодом. Имеет следующие преимущества (отОфициальный сайт Redis):
-
Чрезвычайно высокая производительность — Redis может читать 110 000 раз в секунду и записывать 81 000 раз в секунду.
-
Расширенные типы данных — Redis поддерживает операции с типами данных строк, списков, хэшей, наборов и упорядоченных наборов для двоичных случаев.
-
Атомарность — все операции в Redis являются атомарными, то есть они либо выполняются успешно, либо вообще не выполняются. Одна операция атомарна. Транзакции также поддерживаются для нескольких операций, то есть атомарности, обернутой инструкциями MULTI и EXEC.
-
Богатые возможности — Redis также поддерживает публикацию/подписку, уведомления, истечение срока действия ключа и многое другое.
Если вы хотите узнать больше о том, что Redis - это то, что вы можете обратиться к:Первое знакомство с Redis
Зачем использовать Redis
Зачем использовать Redis? С быстрым развитием информационных технологий с 21-го века мы открыли эру больших данных, данные резко возросли, а одновременный доступ резко возрос; это привело к трансформации и эволюции системного дизайна от единой архитектуры к распределенной. архитектура. Для проблемы кэширования, если система является монолитной, локальное кэширование может выполняться в одной JVM, например, для кэширования некоторых данных можно использовать HashMap. Но в распределенной системе есть много подсистем в большой системе, так как же они совместно используют кеш? Для этого требуется Redis, а Redis используется для реализации системы кэширования. Говорят, что «время создает героев». На самом деле, я хочу сказать, что широкомасштабное использование Redis тоже самое. Использование Redis в качестве системы кэширования заслуживает признания как с точки зрения производительности, так и с точки зрения параллелизма.
-
Производительность: если вы столкнулись с SQL, выполнение которого занимает много времени, а результаты меняются нечасто, лучше всего поместить запущенные результаты в кэш. Таким образом, последующие запросы считываются из кэша, что позволяет быстро реагировать на запросы.
-
Параллелизм: в случае большого параллелизма все запросы напрямую обращаются к базе данных, и база данных будет иметь исключения соединения. В настоящее время вам нужно использовать Redis для выполнения операции буферизации, чтобы запрос мог сначала получить доступ к Redis, а не напрямую к базе данных.
Подробнее о «Почему Redis», Blog Garden[Оригинал] Интенсивная лекция по обзору распределенного Redis, я думаю, что объяснение Redis в этом сообщении в блоге потрясающее, спасибо автору за то, что он терпеливо поделился им.
Как Spring Boot 2.x интегрирует Redis
Версия Spring Boot, которую я использую, — 2.1.0.При интеграции Redis 3.2 в соответствии с некоторыми старыми руководствами в Интернете во многих местах будут появляться сообщения об ошибках. Это связано с тем, что в Spring Boot 2.x внесены некоторые изменения, повлияют ли эти изменения на использование? Как мы изменим его, чтобы интегрировать? Теперь войдите в формальный процесс интеграции.
1. pom.xnl вводит зависимости
Вот предыдущие зависимости:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
Теперь он выдаст ошибку сборки проекта: «dependencies.dependency.version» для org.springframework.boot:spring-boot-starter-redis:jar отсутствует.Сообщите, что spring-boot-starter-redis:jar не может быть найден.
Это связано с тем, что spring-boot-starter-redis больше не поддерживается после Spring Boot 1.4, и вы можете заменить spring-boot-starter-data-redis. Если ваш файл pom сообщает об ошибке, проверьте, изменили ли вы spring-boot-starter-redis на spring-boot-starter-data-redis.
Spring Boot 2.x использует следующие зависимости:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2. application.properties добавить файл конфигурации
Вот файл конфигурации для предыдущей версии:
# REDIS (RedisProperties)
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=0
Если Spring Boot 2.x настроен таким образом, возникает ошибка, указывающая, что свойство «spring.redis.pool.max-active» устарело: вместо этого используйте «spring.redis.jedis.pool.max-idle». redis.pool.max-active» устарел, вместо него рекомендуется использовать «spring.redis.jedis.pool.max-idle».
Это связано с тем, что при настройке информации о пуле соединений Redis в версии 2.x свойства spring.redis.pool больше не используются, а клиент lettuce или jedis для Redis используется непосредственно для настройки. Текущая конфигурация выглядит следующим образом:
# REDIS (RedisProperties)
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=0
3. Настройте CacheManager
Вот предыдущий класс конфигурации RedisConfig:
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
CacheManager cacheManager = new RedisCacheManager(redisTemplate);
return cacheManager;
}
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
}
Теперь запись этого приведет к ошибке. Конструктор RedisCacheManager(RedisTemplate
Это связано с тем, что в версии Spring Boot 2.x был удален конструктор RedisCacheManager, а время истечения срока действия кэша по умолчанию нельзя установить с помощью предыдущего метода setDefaultExpiration.
Итак, как создать RedisCacheManager? Посмотрите, что говорится в официальной документации? Адрес документа:docs.spring.IO/весна-данные…
Официальный документ 5.13.1 Support for the Spring Cache Abstraction (поддержка Spring Cache Abstraction) — это описание того, как настроить кэш, я пытался перевести (синяя часть), но уровень английского ограничен, пожалуйста, почувствуйте бесплатно распылять.
Spring Redis provides an implementation for the Spring cache abstraction through the org.springframework.data.redis.cache package. To use Redis as a backing implementation, add RedisCacheManager to your configuration, as follows:
Spring Redis предоставляет реализацию абстракций Spring Cache в пакетах Org.SpringFramework.Data.Redis.cache. Чтобы использовать Redis в качестве реализации поддержки, вам необходимо добавить Rediscachemanager в конфигурацию, как показано ниже:
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
return RedisCacheManager.create(connectionFactory);
}
RedisCacheManager behavior can be configured with RedisCacheManagerBuilder, letting you set the default RedisCacheConfiguration, transaction behavior, and predefined caches.
RedisCacheManager можно настроить с помощью RedisCacheManagerBuilder, что позволяет настраивать конфигурацию RedisCacheConfiguration по умолчанию, поведение транзакций и предопределенные кэши.
RedisCacheManager cm = RedisCacheManager.builder(connectionFactory)
.cacheDefaults(defaultCacheConfig())
.initialCacheConfigurations(singletonMap("predefined", defaultCacheConfig().disableCachingNullValues()))
.transactionAware()
.build();
As shown in the preceding example, RedisCacheManager allows definition of configurations on a per-cache basis.
Как показано в приведенном выше примере, RedisCacheManager позволяет настраивать отдельные кэши.
The behavior of RedisCache created with RedisCacheManager is defined with RedisCacheConfiguration. The configuration lets you set key expiration times, prefixes, and RedisSerializer implementations for converting to and from the binary storage format, as shown in the following example:
Поведение RedisCacheManager для создания RedisCache определяется как RedisCacheConfiguration. Эта конфигурация позволяет задавать такие свойства, как время истечения срока действия ключа и значения, префикс и реализацию RedisSerializer для преобразования в формат двоичного хранилища и обратно следующим образом:
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(1))
.disableCachingNullValues();
RedisCacheManager defaults to a lock-free RedisCacheWriter for reading and writing binary values. Lock-free caching improves throughput. The lack of entry locking can lead to overlapping, non-atomic commands for the putIfAbsent and clean methods, as those require multiple commands to be sent to Redis. The locking counterpart prevents command overlap by setting an explicit lock key and checking against presence of this key, which leads to additional requests and potential command wait times.
RedisCacheManager по умолчанию не блокируется и используется для чтения и записи RedisCacheWriter двоичных значений. Кэширование без блокировки повышает пропускную способность. Отсутствие блокировки может привести к перекрытию неатомарных команд для методов putIfAbsent и clean, поскольку эти методы требуют отправки нескольких команд в Redis. Корреспонденты блокировки предотвращают перекрытие команд, устанавливая явно заблокированный ключ и проверяя его существование, что приводит к дополнительным запросам и потенциальной задержке выполнения команд.
It is possible to opt in to the locking behavior as follows:
Поведение блокировки также можно выбрать следующим образом:
RedisCacheManager cm = RedisCacheManager.build(RedisCacheWriter.lockingRedisCacheWriter())
.cacheDefaults(defaultCacheConfig())
...
By default, any key for a cache entry gets prefixed with the actual cache name followed by two colons. This behavior can be changed to a static as well as a computed prefix.
По умолчанию любой ключ записи кэша имеет префикс фактического имени кэша, за которым следуют два двоеточия. Это поведение можно изменить на статические префиксы и вычисляемые префиксы.
The following example shows how to set a static prefix:
В следующем примере показано, как установить статический префикс:
// static key prefix
RedisCacheConfiguration.defaultCacheConfig().prefixKeysWith("( ͡° ᴥ ͡°)");
The following example shows how to set a computed prefix:
// computed key prefix
RedisCacheConfiguration.defaultCacheConfig().computePrefixWith(cacheName -> "¯\_(ツ)_/¯" + cacheName);
The following table lists the default settings for RedisCacheManager:
В следующей таблице перечислены настройки по умолчанию для Rediscacheanager:
| Setting | Value |
|---|---|
| Cache Writer | Non-locking |
| Cache Configuration | RedisCacheConfiguration#defaultConfiguration |
| Initial Caches | None |
| Trasaction Aware | No |
The following table lists the default settings for RedisCacheConfiguration:
В следующей таблице перечислены параметры по умолчанию для RedisCacheConfiguration.
| Key Expiration | None |
|---|---|
| Cache null | Yes |
| Prefix Keys | Yes |
| Default Prefix | The actual cache name |
| Key Serializer | StringRedisSerializer |
| Value Serializer | JdkSerializationRedisSerializer |
| Conversion Service | DefaultFormattingConversionService with default cache key converters |
Для Spring Boot 2.x здесь я использую RedisCacheConfiguration, чтобы просто настроить время кэширования и завершить настройку RedisCacheManager.Код выглядит следующим образом:
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(1));
RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).build();
return cacheManager;
}
}
4. Сервисный уровень
Ситуация с использованием кеша в общем случае следующая: при первом доступе данные считываются из базы данных, а затем данные записываются в кеш, при повторном обращении к тому же контенту он считывается из кеша, а если кеша нет, то читается из базы.
При добавлении логики кеша после чтения содержимого из базы данных сначала задайте его в кеш, а затем добавьте поведение чтения из кеша.Если кеш пуст, читайте из базы данных.
Здесь создается только простой RedisService для доступа к кэшированным данным.
@Service
public class RedisService {
@Resource
private RedisTemplate<String, Object> redisTemplate;
public void set(String key, Object value) {
//更改在redis里面查看key编码问题
RedisSerializer redisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(redisSerializer);
ValueOperations<String, Object> vo = redisTemplate.opsForValue();
vo.set(key, value);
}
public Object get(String key) {
ValueOperations<String, Object> vo = redisTemplate.opsForValue();
return vo.get(key);
}
}
5. Слой модели
Класс сущности не изменился, он такой же, как и в предыдущей статье:
@Entity
@Table(name = "user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@Column(name = "username")
private String userName;
@Column(name = "password")
private String passWord;
public User() {
super();
}
public User(String userName, String passWord) {
super();
this.userName = userName;
this.passWord = passWord;
}
public User(Long id, String userName, String passWord) {
super();
this.id = id;
this.userName = userName;
this.passWord = passWord;
}
//省略getter和setter方法
}
6. Уровень контроллера
Добавьте два тестовых метода в user.Controller, один для записи в Redis и один для чтения из Redis:
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserRepository userRepository;
@Autowired
private RedisService redisService;
@RequestMapping("/saveUser")
public String saveUser(Long id, String userName, String passWord) {
User user = new User(id, userName, passWord);
redisService.set(id + "", user);
return "success";
}
@RequestMapping("/getUserById")
public User getUserById(Long id) {
User res = (User) redisService.get(id + "");
return res;
}
}
7. Тест
Чтобы протестировать Postman, посетитеhttp://localhost:8080//user/saveUser?id=12&userName=Howard&passWord=magician, — добавил Пользователь.
Взгляните на базу данных Redis, используйте ключ get для ее просмотра и получите объект:
http://localhost:8080//user/getUserById?id=12, получить пользователя по идентификатору.
Это лог-информация фильтра и перехватчика.Вы можете видеть, что нет работы с базой данных MySQL, и она напрямую читается из кеша, указывая на то, что конфигурация Redis вступила в силу:
Если вы обращаетесь к предыдущему интерфейсу, вы должны работать с базой данных:
Суммировать
Выше показан весь процесс интеграции Redis с Spring Boot 2.x, который немного отличается от предыдущей версии Spring Boot.
Из-за ограниченного уровня в тексте есть более или менее неточности, и я надеюсь, что вы, ребята, поправите меня!