복붙노트

[REDIS] 어떻게 특정 슬롯 / 노드 레디 스 클러스터에 작성하는 jedis 사용

REDIS

어떻게 특정 슬롯 / 노드 레디 스 클러스터에 작성하는 jedis 사용

나는 레디 스 클러스터에 데이터를 기입의 성능을 향상시키기 위해 노력하고있어. 우리는 확장 성을 클러스터 모드로 레디 - 센티넬 이동할 계획이다.

그러나, 쓰기 작업의 성능은 매우 적은 레디 스 - 센티넬과 비교된다. 우리는 레디 스 - 센티넬에 파이프 라인을 활용하지만, 클러스터 모드는 파이프 라인을 지원하지 않습니다.

그래서 나는 그룹에 동일한 노드로 이동 파이프 라인을 사용하여 특정 노드에 배치를 보내는 모든 열쇠를 생각했다.

그래서, 어떤 노드 / 특정 키에 기록 될 슬롯 (클러스터에 기록하기 전에) / 컴퓨팅을 알고하는 방법 궁금하네요?

해결법

  1. ==============================

    1.해결 방법 1 : 키에 갈 것이라고되는 슬롯을 식별 할 수있는 솔루션을 찾을. JedisCluster 그것을 얻을 수있는 몇 가지 API를 가지고있다.

    해결 방법 1 : 키에 갈 것이라고되는 슬롯을 식별 할 수있는 솔루션을 찾을. JedisCluster 그것을 얻을 수있는 몇 가지 API를 가지고있다.

    INT slotNum = JedisClusterCRC16.getSlot (키); - 키의 슬롯 번호를 제공합니다.

    Set<HostAndPort> redisClusterNode = new HashSet<HostAndPort>();
    redisClusterNode.add(new HostAndPort(hostItem, port));
    
    JedisSlotBasedConnectionHandler connHandler = new 
                  JedisSlotBasedConnectionHandler(redisClusterNode, poolConfig, 60);
    
    Jedis jedis = connHandler.getConnectionFromSlot(slotNum);
    

    이 클러스터의 특정 노드 (Jedispool에서 내부적으로)을 jedis 객체를 제공합니다. 위의 jedis 개체와 이제 모든 명령은 쉽게 (클러스터) 특정 노드에 대한 파이프 라인 될 수 있습니다

    Pipeline pipeline = jedis.pipelined();
    pipeline.multi();
    for(Entry<String, Map<String, String>> kvf : kvfs.entrySet()) {
       pipeline.hmset(kvf.getKey(), kvf.getValue());
    }
    pipeline.exec();
    

    (JedisCluster 포함)이 방법에도 불구하고 키가 나에게 기대 성능을 제공하고 있지 않습니다로 이동되는 적절한 노드를했다, 나는 그것이 슬롯 번호와 (슬롯) 노드를 알고에 관련된 절차에 의한 것 같아요. 위 절차는 슬롯 번호를 포함 우리는 실제 노드 (jedis)를 얻으려고 할 때마다 (클러스터) 노드에 물리적으로 연결을 설정하는 것 같다. 그래서, 이것은 우리가 키 수백만이의 경우의 성능을 방해한다. 그래서, 상추 패키지를 사용하여 다른 방법 (아래) 이상이 와서 저를 도왔다.

    해결 방법 2 : 중고 상추 패키지 지원은 클러스터 모드에서 명령의 배치를 보내고있다.

         <groupId>biz.paluch.redis</groupId>
         <artifactId>lettuce</artifactId>
         <version>4.4.3.Final</version>
    

    코드 스 니펫 :

    RedisClusterClient client = RedisClusterClient.create(RedisURI.create("hostname", "port"));
    StatefulRedisClusterConnection<String, String> connection = client.connect();
    
    RedisAdvancedClusterAsyncCommands<String, String> commands = connection.async();
    // Disabling auto-flushing
    commands.setAutoFlushCommands(false);
    
    List<RedisFuture<?>> futures = new ArrayList<>();
    // kvf is of type Map<String, Map<String, String>>
    for (Entry<> e : kvf.entrySet())
    {
       futures.add(commands.hmset( (String) e.getKey(), (Map<String, String>) e.getValue()));
    }
    // write all commands to the transport layer
    commands.flushCommands();
    // synchronization example: Wait until all futures complete
    LettuceFutures.awaitAll(10, TimeUnit.SECONDS,
    futures.toArray(new RedisFuture[futures.size()]));
    

    참조 : https://github.com/lettuce-io/lettuce-core/wiki/Pipelining-and-command-flushing

  2. ==============================

    2.잘못된!

    잘못된!

    하나의 파이프 라인으로, 당신은 같은 노드에 동일한 연결에 여러 명령을 보낼 수 있습니다. 그것은이 노드가 단일 인스턴스 또는 레디 스 클러스터의 멤버인지 여부와는 아무 상관이있다.

    문제는 하나의 파이프 라인으로해야한다 그래서, 우리는 다수의 슬롯에 분산 키를 사용하여 여러 명령을 보낼 수 없습니다. 그것을 해결하기 위해, 당신은 그 키가 동일한 슬롯에 위치하고 싶다. 우리는 어떻게 달성 할 수 있습니까?

    당신은 수학을 직접 수행 할 필요가 없습니다. 동일한 해시 슬롯의 일부가 여러 개의 키를 강제로 해시 태그를 사용할 수 있습니다.

    그래서 당신은 동일한 해시 태그와 함께, 당신은 동일한 슬롯에 위치 할 그 키를, 이름을 변경해야합니다. 예를 들면 {사용자 ID} 사용자 이름과 {사용자 ID} 사용자 연령에 사용자 이름과 사용자 연령의 이름을 변경

    자세한 내용은 해시 태그의 문서를 참조하십시오.

  3. from https://stackoverflow.com/questions/49179753/using-jedis-how-to-write-to-a-specific-slot-node-in-redis-cluster by cc-by-sa and MIT license