做出更快的响应并减少对昂贵的数据库查询的依赖。
图片来源——维基百科
在 API 设计期间更常见的是,每个 API 可能会在从数据库或外部 API 调用中查询数据后进行响应。有时有些表的数据不经常更改,这意味着这些表不是事务性的。
数据库查询或外部 API 调用非常昂贵。在这种情况下,我们可以将这些数据缓存到更快的存储中,并从该存储中为我们的客户端提供服务,而不是从那里获取。
为了实现这个目标,Redis 来了。它不仅可以缓存数据,还可以定期与数据库持久化,并且可以在分布式系统中工作。
Redis代表远程字典服务器,是一种基于密钥库的、快速的、开源的基于内存的数据存储。它的主要用途是用作数据库、缓存、消息代理和队列。
根据网站Redis.io:
Redis 是一个开源(BSD 许可)的内存数据结构存储,用作数据库、缓存和消息代理。
Redis 支持字符串、列表、哈希、位图、地理空间索引、hyperloglogs
集合和流等数据类型。它还支持异步复制,具有非常快速的非阻塞首次同步、自动重新连接以及 netsplit 上的部分重新同步。
在本文中,我们将学习。
- Redis的用例
- 在 docker 容器中配置 Redis 并连接应用程序
- Redis、 MySQL、JPA与Spring Boot应用程序的详细信息级别实现
- 缓存在多实例部署中如何工作的数据分析
- 共享代码库
要使用 Redis 锁实现分布式锁定,您可以查看这篇文章。
我们的应用架构如下所示
图片来源-作者
我们在这里做什么?
- 我们有一个在 docker 容器中运行3406端口的MySQL 数据库
- 在 docker容器上的端口6379中运行的 Redis 服务器。Redis 服务器用作二级缓存。
- 名为 country_service 的应用程序实例。它有两个实例,并且都连接到同一个 MySQL 和 Redis 服务器。
- 在应用中,它很简单——该国的一些 CRUD 操作。
为什么以及何时应该使用缓存
缓存是将非事务性数据存储到中间高速数据存储层(缓存)的机制。在大多数情况下,缓存存储数据在相对较快的硬件系统中,使其存储和检索过程可能更高效、更快。
- Redis 将所有内容存储在主内存中;因此,它的存储和检索比数据库检索查询要快得多。
- 它也是持久的,因此它将定期与数据库同步数据。这个持久性级别可以是可配置的;通过打开持久性,您可以创建一个临时缓存。
- 根据 redis.io
Redis 还支持简单到设置的主从异步复制,具有非常快的非阻塞首次同步、自动重新连接以及网络拆分上的部分重新同步
- 与简单的其他键值数据存储不同,Redis 具有多种数据结构。Redis 数据类型包括 Strings、List、Sets、Sorted Sets、Hashes、Bitmaps、HyperLogLogs。
Redis 配置
您可以将 Redis 服务器版本下载到您的机器中。在本文中,我们将使用docker 容器中的 Redis 服务器。
拉取 docker 镜像
docker pull redis
从下载的镜像运行 docker 容器
sudo docker run — name my-redis-container -p 6379:6379 -d redis
现在您的 Redis 服务器正在默认端口6379上运行
图片来源-作者
Redis 实现
我们的build.gradle
文件如下:
c3p0
在这里,我们为与数据库的连接池添加了 MySQL 和依赖项。spring-boot-starter-data-jpa
对于 Redis 依赖项
我们的application.yml
文件结构如下:
在这里,我们使用正确的凭据配置了 MySQL 和JPA 。对于缓存,我们使用了 Redis 并添加了 Redis IP 和端口用于连接。
应用程序类代码如下:
在这里,我们添加@EnableCaching
了启用 Redis 缓存。
实体类和表结构如下:
这里, id 是主键和自动增量。其他的字段是名称,代码
实体类如下所示。
我们的存储库类如下所示。
在这里,它是一个基本的CrudRepositoery
并添加了一些 JPA 接口方法,如通过条目 id 查找条目、查找所有条目和通过 id 删除条目。
服务方法如下:
在这里,我们添加了一些方法,例如save
,findById
和delete
。其描述如下:
保存数据 ( CachePut
)
在保存数据期间,我们使用 JPA 存储库将数据保存到表 country 中。
我们CachePut
在这个方法中使用了注解。此注解用于更新缓存。这里,key 将是国家 ID,value 将是 Redis 密钥存储中的国家对象。
- 在保存方法期间,它将数据保存到数据库中。保存成功后,会在 Redis 缓存中保存一份副本。
- 在缓存期间,键是国家 ID,值是国家对象。
- 一旦缓存完成,所有实例/节点尝试使用国家/地区 id 获取数据将直接从缓存中获取。所以它不会进一步查询数据库。
获取数据(可缓存)
findById
方法有注解Cacheable
,而这个注解表示应用程序会缓存调用这个方法的结果。
- 在 API 调用期间,首先,它将使用国家 ID 从缓存中搜索。如果找到,那么它将作为响应返回。如果没有找到,那么它将从数据库中获取。
- 从任何节点缓存完成后,所有连接的节点将自动找到该缓存值。
- 缓存
time-to-live
有价值。在那之后,Redis 将从缓存中清除该数据。
删除数据 (CacheEvict)
delete
方法有注解CacheEvict
并且这个注解表示调用一个方法可以通过国家ID从缓存中逐出。
- 在 API 调用期间,它将从数据库中删除国家实体,并从缓存中删除该条目。
- 删除后,任何实例都不会从搜索 API 中找到该值。
控制器方法
控制器/端点的代码如下
通过调用此方法,您可以检查其输出
代码库
您可以从此GitHub 存储库中检查代码库
结论
缓存对于开发人员和分布式系统来说是一个非常重要和强大的工具。根据您的数据类型和业务性质,您可以在系统中引入 Redis 缓存以获得更好的性能。
感谢您阅读本文。我希望你喜欢这个。
如果你想学习使用 Spring Cloud 和 docker 实现微服务,这篇文章可以提供帮助。
资源
1. Redis
2. Redis: in-memory data store. How it works and why you should use it
3. https://www.atlantic.net/hipaa-data-centers/ashburn-virginia-hosting/why- redis-has-become-so-popular-fast-open-source/
4. https://www.baeldung.com/spring-data-redis-tutorial
5. https://pavankjadda.medium.com/implement-hibernate -2nd-level-cache-with-redis-spring-boot-and-spring-data-jpa-7cdbf5632883
6. Spring Boot Redis Cache Example - NetSurfingZone