readFrom.БЛИЖАЙШИЕ настройки не работают корректно

#spring-data-redis #lettuce

#повторный просмотр весенних данных #салат

Вопрос:

Настройка сервера и Redis

Я настраиваю серверы Redis на AWS, как показано ниже.

точка доступа-северо-восток-1

  • 10.0.100.21 redis / master @ap-northeast-1b
  • 10.0.100.38 redis / replica #1 @ap-northeast-1c
  • 10.0.100.62 redis / replica #2 @ap-northeast-1d

Эти узлы находятся в одном и том же VPC. Версия Redis = 6.0.9

 [ec2-user@ip-10-0-100-21 redis-6.0.9]$ uname -a
Linux ip-10-0-100-21.ap-northeast-1.compute.internal 4.14.193-149.317.amzn2.x86_64 #1 SMP Thu Sep 3 19:04:44 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
[ec2-user@ip-10-0-100-21 redis-6.0.9]$
  

Время отклика Ping

10.0.100.21

 [ec2-user@ip-10-0-100-21 ~]$ ping -c 3 10.0.100.21
PING 10.0.100.21 (10.0.100.21) 56(84) bytes of data.
64 bytes from 10.0.100.21: icmp_seq=1 ttl=255 time=0.014 ms
64 bytes from 10.0.100.21: icmp_seq=2 ttl=255 time=0.039 ms
64 bytes from 10.0.100.21: icmp_seq=3 ttl=255 time=0.028 ms

--- 10.0.100.21 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2054ms
rtt min/avg/max/mdev = 0.014/0.027/0.039/0.010 ms
[ec2-user@ip-10-0-100-21 ~]$ ping -c 3 10.0.100.38
PING 10.0.100.38 (10.0.100.38) 56(84) bytes of data.
64 bytes from 10.0.100.38: icmp_seq=1 ttl=255 time=2.65 ms
64 bytes from 10.0.100.38: icmp_seq=2 ttl=255 time=2.60 ms
64 bytes from 10.0.100.38: icmp_seq=3 ttl=255 time=2.69 ms

--- 10.0.100.38 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 2.607/2.649/2.691/0.068 ms
[ec2-user@ip-10-0-100-21 ~]$ ping -c 3 10.0.100.62
PING 10.0.100.62 (10.0.100.62) 56(84) bytes of data.
64 bytes from 10.0.100.62: icmp_seq=1 ttl=255 time=1.97 ms
64 bytes from 10.0.100.62: icmp_seq=2 ttl=255 time=1.85 ms
64 bytes from 10.0.100.62: icmp_seq=3 ttl=255 time=2.01 ms

--- 10.0.100.62 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 1.857/1.950/2.014/0.067 ms
[ec2-user@ip-10-0-100-21 ~]$
  

10.0.100.38

 [ec2-user@ip-10-0-100-38 ~]$ ping -c 3 10.0.100.21
PING 10.0.100.21 (10.0.100.21) 56(84) bytes of data.
64 bytes from 10.0.100.21: icmp_seq=1 ttl=255 time=2.62 ms
64 bytes from 10.0.100.21: icmp_seq=2 ttl=255 time=3.84 ms
64 bytes from 10.0.100.21: icmp_seq=3 ttl=255 time=2.63 ms

--- 10.0.100.21 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 2.621/3.032/3.846/0.577 ms
[ec2-user@ip-10-0-100-38 ~]$ ping -c 3 10.0.100.38
PING 10.0.100.38 (10.0.100.38) 56(84) bytes of data.
64 bytes from 10.0.100.38: icmp_seq=1 ttl=255 time=0.016 ms
64 bytes from 10.0.100.38: icmp_seq=2 ttl=255 time=0.027 ms
64 bytes from 10.0.100.38: icmp_seq=3 ttl=255 time=0.028 ms

--- 10.0.100.38 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2027ms
rtt min/avg/max/mdev = 0.016/0.023/0.028/0.007 ms
[ec2-user@ip-10-0-100-38 ~]$ ping -c 3 10.0.100.62
PING 10.0.100.62 (10.0.100.62) 56(84) bytes of data.
64 bytes from 10.0.100.62: icmp_seq=1 ttl=255 time=1.12 ms
64 bytes from 10.0.100.62: icmp_seq=2 ttl=255 time=1.05 ms
64 bytes from 10.0.100.62: icmp_seq=3 ttl=255 time=1.14 ms

--- 10.0.100.62 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 1.057/1.106/1.141/0.035 ms
[ec2-user@ip-10-0-100-38 ~]$
  

10.0.100.62

 [ec2-user@ip-10-0-100-62 ~]$ ping -c 3 10.0.100.21
PING 10.0.100.21 (10.0.100.21) 56(84) bytes of data.
64 bytes from 10.0.100.21: icmp_seq=1 ttl=255 time=1.95 ms
64 bytes from 10.0.100.21: icmp_seq=2 ttl=255 time=2.01 ms
64 bytes from 10.0.100.21: icmp_seq=3 ttl=255 time=2.00 ms

--- 10.0.100.21 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 1.954/1.991/2.014/0.045 ms
[ec2-user@ip-10-0-100-62 ~]$ ping -c 3 10.0.100.38
PING 10.0.100.38 (10.0.100.38) 56(84) bytes of data.
64 bytes from 10.0.100.38: icmp_seq=1 ttl=255 time=1.08 ms
64 bytes from 10.0.100.38: icmp_seq=2 ttl=255 time=1.12 ms
64 bytes from 10.0.100.38: icmp_seq=3 ttl=255 time=1.26 ms

--- 10.0.100.38 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 1.082/1.155/1.260/0.085 ms
[ec2-user@ip-10-0-100-62 ~]$ ping -c 3 10.0.100.62
PING 10.0.100.62 (10.0.100.62) 56(84) bytes of data.
64 bytes from 10.0.100.62: icmp_seq=1 ttl=255 time=0.014 ms
64 bytes from 10.0.100.62: icmp_seq=2 ttl=255 time=0.029 ms
64 bytes from 10.0.100.62: icmp_seq=3 ttl=255 time=0.026 ms

--- 10.0.100.62 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2030ms
rtt min/avg/max/mdev = 0.014/0.023/0.029/0.006 ms
[ec2-user@ip-10-0-100-62 ~]$
  

From the above, the nearest nodes to each are:

  • Nearest node of 10.0.100.21 is 10.0.100.21.
  • Nearest node of 10.0.100.38 is 10.0.100.38.
  • Nearest node of 10.0.100.62 is 10.0.100.62.

Application Setup

Java

 [ec2-user@ip-10-0-100-21 redis-6.0.9]$ java -version
openjdk version "11.0.9.1" 2020-11-04 LTS
OpenJDK Runtime Environment Corretto-11.0.9.12.1 (build 11.0.9.1 12-LTS)
OpenJDK 64-Bit Server VM Corretto-11.0.9.12.1 (build 11.0.9.1 12-LTS, mixed mode)
[ec2-user@ip-10-0-100-21 redis-6.0.9]$
  
  • Spring boot 2.4.0
  • Spring Data Redis 2.4.1
  • Lettuce 6.0.1

RedisConfig.java

 @Configuration
public class RedisConfig {
    @Value("${readFrom}")
    private String readFrom;

    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        RedisStaticMasterReplicaConfiguration config = new RedisStaticMasterReplicaConfiguration("10.0.100.21", 6379);
        config.addNode("10.0.100.38", 6379);
        config.addNode("10.0.100.62", 6379);
        LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
                .readFrom(ReadFrom.valueOf(readFrom)).build();
        return new LettuceConnectionFactory(config, clientConfig);
    }
    
    @Bean
    public RedisTemplate<?,?> redisTemplate(RedisTemplate<?,?> template) {
        template.setConnectionFactory(redisConnectionFactory());
        StringRedisSerializer serializer = new StringRedisSerializer();
        JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer();
        
        template.setKeySerializer(serializer);
        template.setValueSerializer(jdkSerializer);
        template.setHashKeySerializer(serializer);
        template.setHashValueSerializer(jdkSerializer);
        return template;
    }
}
  

SampleRunner.java

 @Component
public class SampleRunner implements ApplicationRunner {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("Runner - start");
        for(int i=0; i<10; i  ) {
            redisTemplate.opsForValue().get("key1");
            Thread.sleep(1000);
        }
        System.out.println("Runner - end");
    }

}
  

Запустите приложение на каждом узле.

java -DreadFrom= ближайший -jar redis-readfrom-sample-0.0.1-SNAPSHOT.jar

Результат

Запустите приложение на 10.0.100.21

 [ec2-user@ip-10-0-100-62 redis-6.0.9]$ src/redis-cli monitor | grep GET
1605364234.819490 [0 10.0.100.21:57060] "GET" "key1"
1605364235.825171 [0 10.0.100.21:57060] "GET" "key1"
1605364236.829514 [0 10.0.100.21:57060] "GET" "key1"
1605364237.832915 [0 10.0.100.21:57060] "GET" "key1"
1605364238.836488 [0 10.0.100.21:57060] "GET" "key1"
1605364239.839737 [0 10.0.100.21:57060] "GET" "key1"
1605364240.843086 [0 10.0.100.21:57060] "GET" "key1"
1605364241.847348 [0 10.0.100.21:57060] "GET" "key1"
1605364242.850784 [0 10.0.100.21:57060] "GET" "key1"
1605364243.858162 [0 10.0.100.21:57060] "GET" "key1"
  

=> Команды NG: Get должны быть отправлены на ближайший узел (10.0.100.21),
но отправлены на дальний узел (10.0.100.62).

Запустите приложение 10.0.100.38

 [ec2-user@ip-10-0-100-38 redis-6.0.9]$ src/redis-cli monitor | grep GET
1605364312.650791 [0 10.0.100.38:50216] "GET" "key1"
1605364313.655526 [0 10.0.100.38:50216] "GET" "key1"
1605364314.657089 [0 10.0.100.38:50216] "GET" "key1"
1605364315.659734 [0 10.0.100.38:50216] "GET" "key1"
1605364316.662639 [0 10.0.100.38:50216] "GET" "key1"
1605364317.664621 [0 10.0.100.38:50216] "GET" "key1"
1605364318.666050 [0 10.0.100.38:50216] "GET" "key1"
1605364319.668037 [0 10.0.100.38:50216] "GET" "key1"
1605364320.669549 [0 10.0.100.38:50216] "GET" "key1"
1605364321.671699 [0 10.0.100.38:50216] "GET" "key1"
  

=> OK

Запустите приложение на 10.0.100.62

 [ec2-user@ip-10-0-100-62 redis-6.0.9]$ src/redis-cli monitor | grep GET
1605364353.037076 [0 10.0.100.62:48454] "GET" "key1"
1605364354.041437 [0 10.0.100.62:48454] "GET" "key1"
1605364355.044409 [0 10.0.100.62:48454] "GET" "key1"
1605364356.047743 [0 10.0.100.62:48454] "GET" "key1"
1605364357.050808 [0 10.0.100.62:48454] "GET" "key1"
1605364358.053005 [0 10.0.100.62:48454] "GET" "key1"
1605364359.054525 [0 10.0.100.62:48454] "GET" "key1"
1605364360.056585 [0 10.0.100.62:48454] "GET" "key1"
1605364361.058127 [0 10.0.100.62:48454] "GET" "key1"
1605364362.060059 [0 10.0.100.62:48454] "GET" "key1"
  

=> OK

Нужны ли мне какие-либо дополнительные настройки?

Комментарии:

1. Я нашел описание ниже. > БЛИЖАЙШЕЕ чтение с любого узла кластера с наименьшей задержкой. > Задержка узлов определяется при обновлении топологии кластера. Если представление топологии никогда не обновляется, используются значения из начальных считанных узлов кластера. Считывается из. БЛИЖАЙШИЙ допустимый только в конфигурации кластера? Нельзя ли использовать его в конфигурации главной реплики или конфигурации sentinel?

2. Я проверил исходный код Lettuce и подтвердил, что readFrom . БЛИЖАЙШИЙ параметр допустим только в конфигурации кластера.

Ответ №1:

Вывод: readFrom.Значение «БЛИЖАЙШИЙ» допустимо только в конфигурациях кластера. Недопустимо в конфигурациях Sentinel или Master-Replica.