首页 > 解决方案 > AWS ElasticCache Redis 的 Spring Data 随机变慢,用户负载较高

问题描述

我最近继承了这个Java Spring API,Java不是我的强项,所以请多多包涵。

我们正在运行org.springframework.boot:spring-boot-starter-data-redis:2.1.0.RELEASELettuce 以连接 AWS 中的 Redis/ElastiCache。

这个 API 受到其他 API 以及我们的前端的影响。它是一个存储基本用户状态 JSON 对象 (~1.2kb) 的基本 API。

在前期,一切都很好,我们一次看到几十个人,没什么大不了的。

在 prod 中,我们有成千上万的用户,我们开始在这个端点上看到非常长的延迟时间。使用 DataDog,我们在火焰图中看到我们的调用redisUserRepository.findUserByid()可能需要几秒钟到几分钟才能运行!快速通话不到 70 毫秒。根据 DataDog 的说法,它会使用HGETALL(据我所知,这就是它从 Redis 获取数据的方式?)进行数百到数千次调用。

在 AWS 中签出 Redis

配置:

监控:

由于我们使用 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;
    }
}

标签: spring-bootredisamazon-elasticache

解决方案


推荐阅读