spring-boot - AWS ElasticCache Redis 的 Spring Data 随机变慢,用户负载较高
问题描述
我最近继承了这个Java Spring API,Java不是我的强项,所以请多多包涵。
我们正在运行org.springframework.boot:spring-boot-starter-data-redis:2.1.0.RELEASE
Lettuce 以连接 AWS 中的 Redis/ElastiCache。
这个 API 受到其他 API 以及我们的前端的影响。它是一个存储基本用户状态 JSON 对象 (~1.2kb) 的基本 API。
在前期,一切都很好,我们一次看到几十个人,没什么大不了的。
在 prod 中,我们有成千上万的用户,我们开始在这个端点上看到非常长的延迟时间。使用 DataDog,我们在火焰图中看到我们的调用redisUserRepository.findUserByid()
可能需要几秒钟到几分钟才能运行!快速通话不到 70 毫秒。根据 DataDog 的说法,它会使用HGETALL
(据我所知,这就是它从 Redis 获取数据的方式?)进行数百到数千次调用。
在 AWS 中签出 Redis
配置:
- 节点类型:cache.m5.large
- 2个节点
- 1个分片
- 传输中加密:是
- 静态加密:是
- Redis 身份验证:是的
监控:
- CPU 低于 5%
- 发动机低于 5%
- 缓存命中率为 100%
- 约 15,000,000 中的网络字节
- 字节输出 ~100,000,000
- 电流连接峰值约为 15
- 当前项目是 114,300(每小时增加约 600 个,这会导致一些问题吗?我感觉我们没有正确管理这些数据,我们没有 114k 用户,探索我们的代码)
- 用于缓存的字节为 99,700,000
由于我们使用 Spring Data 连接到 redis 和生菜,我可以在这里做什么?一些谷歌搜索给出了一些较旧的文章,一些说生菜不是很好。
如果您需要更多代码,请告诉我:
package com.domain.searchconfiguration.domain.user;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;
import org.springframework.data.redis.core.index.Indexed;
@RedisHash("user")
public class RedisUser {
@Id
private Long id;
@Indexed
private String userId;
private String profile;
@Indexed
private String ruleId;
public RedisUser(String userId, String profile, String ruleId) {
this.userId = userId;
this.profile = profile;
this.ruleId = ruleId;
}
public RedisUser() {
}
public Long getId() {
return id;
}
public String getUserId() {
return userId;
}
public String getProfile() {
return profile;
}
public String getRuleId() {
return ruleId;
}
public void setProfile(String profile) {
this.profile = profile;
}
}
package com.domain.searchconfiguration.domain.user;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface RedisUserRepository extends CrudRepository<RedisUser, String> {
public RedisUser findByUserId(String userId);
public RedisUser findByRuleId(String ruleId);
public List<RedisUser> findAllByRuleId(String ruleId);
}
package com.domain.searchconfiguration.config;
import io.lettuce.core.ReadFrom;
import org.slf4j.Logger;
import org.springframework.boot.autoconfigure.data.redis.LettuceClientConfigurationBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
@Configuration
@EnableRedisRepositories(basePackages = {"com.domain.searchconfiguration.domain.user", "com.domain.searchconfiguration.domain.rule"})
public class RedisConfig {
private static final Logger log = org.slf4j.LoggerFactory.getLogger(RedisConfig.class);
@Bean
public LettuceClientConfigurationBuilderCustomizer lettuceClientConfigurationBuilderCustomizer() {
return p -> p.readFrom(ReadFrom.NEAREST).useSsl().disablePeerVerification();
}
@Bean
public RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<byte[], byte[]> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
解决方案
推荐阅读
- phpstorm - 更改文件后目录的PhpStorm蓝色
- android - Emulator Api 19 比 Emulator Api 27 快
- fatal-error - 致命错误:ESP8266WiFi.h:没有这样的文件或目录
- javascript - stepwizard stepPosition 不起作用
- sql - 对于 oracle SQL 中的每个循环,使用动态列显示为输出
- ruby-on-rails - 编辑和删除时对象 ID 混乱
- angular - Angular 5 - 使用默认值验证输入字段
- swift - Swift Firebase 函数错误:NSCocoaErrorDomain
- docker - 文件系统上的 Docker 映像
- informatica-powercenter - 在开始工作流之前是否总是需要在 Informatica 中创建目标数据库表?