이 연재글은 Redis 알아보기의 3번째 글입니다.

SpringBoot2와 redis cluster를 연동하고, redis command에 대해 설명합니다. 다음을 참고하여 프로젝트를 하나 생성합니다.
>> Intellij Community 프로젝트생성

Boot를 실행하기 위한 Application Class 생성

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.redis.cluster;
@SpringBootApplication
public class RedisClusterApplication {
public static void main(String[] args) {
SpringApplication.run(RedisClusterApplication.class, args);
}
}
package com.redis.cluster; @SpringBootApplication public class RedisClusterApplication { public static void main(String[] args) { SpringApplication.run(RedisClusterApplication.class, args); } }
package com.redis.cluster;

@SpringBootApplication
public class RedisClusterApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedisClusterApplication.class, args);
    }
}

build.gradle 수정

spring-boot-starter-data-redis를 이용하여 redis cluster를 연동합니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
plugins {
id 'org.springframework.boot' version '2.1.4.RELEASE'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
group = 'com.rest'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-freemarker'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'com.google.code.gson:gson'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
plugins { id 'org.springframework.boot' version '2.1.4.RELEASE' id 'java' } apply plugin: 'io.spring.dependency-management' group = 'com.rest' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-freemarker' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-redis' implementation 'com.google.code.gson:gson' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' runtimeOnly 'mysql:mysql-connector-java' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' }
plugins {
    id 'org.springframework.boot' version '2.1.4.RELEASE'
    id 'java'
}

apply plugin: 'io.spring.dependency-management'

group = 'com.rest'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-freemarker'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
    implementation 'com.google.code.gson:gson'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'com.h2database:h2'
    runtimeOnly 'mysql:mysql-connector-java'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

application.yml 수정

h2, jpa, redis 설정을 추가합니다. cluster 노드 정보를 넣고, redis에 패스워드가 있으면 패스워드 정보도 추가합니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
server:
port: 8081
spring:
datasource:
url: jdbc:h2:tcp://localhost/~/test
driver-class-name: org.h2.Driver
username: sa
jpa:
database-platform: org.hibernate.dialect.H2Dialect
properties.hibernate.hbm2ddl.auto: update
showSql: true
redis:
cluster:
nodes:
- 15.164.98.87:6300
- 15.164.98.87:6301
- 15.164.98.87:6302
- 15.164.98.87:6400
- 15.164.98.87:6401
- 15.164.98.87:6402
password: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
server: port: 8081 spring: datasource: url: jdbc:h2:tcp://localhost/~/test driver-class-name: org.h2.Driver username: sa jpa: database-platform: org.hibernate.dialect.H2Dialect properties.hibernate.hbm2ddl.auto: update showSql: true redis: cluster: nodes: - 15.164.98.87:6300 - 15.164.98.87:6301 - 15.164.98.87:6302 - 15.164.98.87:6400 - 15.164.98.87:6401 - 15.164.98.87:6402 password: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
server:
  port: 8081

spring:
  datasource:
    url: jdbc:h2:tcp://localhost/~/test
    driver-class-name: org.h2.Driver
    username: sa
  jpa:
    database-platform: org.hibernate.dialect.H2Dialect
    properties.hibernate.hbm2ddl.auto: update
    showSql: true
  redis:
    cluster:
      nodes:
        - 15.164.98.87:6300
        - 15.164.98.87:6301
        - 15.164.98.87:6302
        - 15.164.98.87:6400
        - 15.164.98.87:6401
        - 15.164.98.87:6402
    password: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

test/resources 아래에 logback_test.xml 생성

유닛 테스트에서 log를 사용하기 위해 test/resources 아래에 logback_test.xml를 생성합니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>
%-5level %d{HH:mm:ss} %logger{15}.%method:%line - %msg%n
</pattern>
</encoder>
</appender>
<logger name="com.redis.cluster" level="debug" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
</configuration>
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration> <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern> %-5level %d{HH:mm:ss} %logger{15}.%method:%line - %msg%n </pattern> </encoder> </appender> <logger name="com.redis.cluster" level="debug" additivity="false"> <appender-ref ref="STDOUT" /> </logger> </configuration>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration>

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>
                %-5level %d{HH:mm:ss} %logger{15}.%method:%line - %msg%n
            </pattern>
        </encoder>
    </appender>

    <logger name="com.redis.cluster" level="debug" additivity="false">
        <appender-ref ref="STDOUT" />
    </logger>
</configuration>

RedisClusterTest 생성

Redis가 제공하는 명령어를 실습합니다.

자주 사용하는 기본 명령어

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
@Test
public void commonCommand() {
ValueOperations<String, String> valueOps = redisTemplate.opsForValue();
valueOps.set("key1", "key1value");
valueOps.set("key2", "key2value");
// Key 타입 조회.
assertEquals(DataType.STRING, redisTemplate.type("key1"));
// 존재하는 Key의 개수를 반환.
assertSame(2L, redisTemplate.countExistingKeys(Arrays.asList("key1", "key2", "key3")));
// Key가 존재하는지 확인
assertTrue(redisTemplate.hasKey("key1"));
// Key 만료 날짜 세팅
assertTrue(redisTemplate.expireAt("key1", Date.from(LocalDateTime.now().plusDays(1L).atZone(ZoneId.systemDefault()).toInstant())));
// Key 만료 시간 세팅
assertTrue(redisTemplate.expire("key1", 60, TimeUnit.SECONDS));
// Key 만료 시간 조회
assertThat(redisTemplate.getExpire("key1"), greaterThan(0L));
// Key 만료 시간 해제
assertTrue(redisTemplate.persist("key1"));
// Key 만료시간이 세팅 안되어있는경우 -1 반환
assertSame(-1L, redisTemplate.getExpire("key1"));
// Key 삭제
assertTrue(redisTemplate.delete("key1"));
// Key 일괄 삭제
assertThat(redisTemplate.delete(Arrays.asList("key1", "key2", "key3")), greaterThan(0L));
}
@Test public void commonCommand() { ValueOperations<String, String> valueOps = redisTemplate.opsForValue(); valueOps.set("key1", "key1value"); valueOps.set("key2", "key2value"); // Key 타입 조회. assertEquals(DataType.STRING, redisTemplate.type("key1")); // 존재하는 Key의 개수를 반환. assertSame(2L, redisTemplate.countExistingKeys(Arrays.asList("key1", "key2", "key3"))); // Key가 존재하는지 확인 assertTrue(redisTemplate.hasKey("key1")); // Key 만료 날짜 세팅 assertTrue(redisTemplate.expireAt("key1", Date.from(LocalDateTime.now().plusDays(1L).atZone(ZoneId.systemDefault()).toInstant()))); // Key 만료 시간 세팅 assertTrue(redisTemplate.expire("key1", 60, TimeUnit.SECONDS)); // Key 만료 시간 조회 assertThat(redisTemplate.getExpire("key1"), greaterThan(0L)); // Key 만료 시간 해제 assertTrue(redisTemplate.persist("key1")); // Key 만료시간이 세팅 안되어있는경우 -1 반환 assertSame(-1L, redisTemplate.getExpire("key1")); // Key 삭제 assertTrue(redisTemplate.delete("key1")); // Key 일괄 삭제 assertThat(redisTemplate.delete(Arrays.asList("key1", "key2", "key3")), greaterThan(0L)); }
@Test
public void commonCommand() {
    ValueOperations<String, String> valueOps = redisTemplate.opsForValue();
    valueOps.set("key1", "key1value");
    valueOps.set("key2", "key2value");
    // Key 타입 조회.
    assertEquals(DataType.STRING, redisTemplate.type("key1"));
    // 존재하는 Key의 개수를 반환.
    assertSame(2L, redisTemplate.countExistingKeys(Arrays.asList("key1", "key2", "key3")));
    // Key가 존재하는지 확인
    assertTrue(redisTemplate.hasKey("key1"));
    // Key 만료 날짜 세팅
    assertTrue(redisTemplate.expireAt("key1", Date.from(LocalDateTime.now().plusDays(1L).atZone(ZoneId.systemDefault()).toInstant())));
    // Key 만료 시간 세팅
    assertTrue(redisTemplate.expire("key1", 60, TimeUnit.SECONDS));
    // Key 만료 시간 조회
    assertThat(redisTemplate.getExpire("key1"), greaterThan(0L));
    // Key 만료 시간 해제
    assertTrue(redisTemplate.persist("key1"));
    // Key 만료시간이 세팅 안되어있는경우 -1 반환
    assertSame(-1L, redisTemplate.getExpire("key1"));
    // Key 삭제
    assertTrue(redisTemplate.delete("key1"));
    // Key 일괄 삭제
    assertThat(redisTemplate.delete(Arrays.asList("key1", "key2", "key3")), greaterThan(0L));
}

String structure command

redis command set, get에 대한 내용입니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
@Test
public void opsValue() {
ValueOperations<String, String> valueOps = redisTemplate.opsForValue();
Collection<String> cacheKeys = new ArrayList<>();
String cacheKey = "value_";
for (int i = 0; i < 10; i++) {
cacheKeys.add(cacheKey + i);
valueOps.set(cacheKey + i, String.valueOf(i), 60, TimeUnit.SECONDS);
}
List<String> values = valueOps.multiGet(cacheKeys);
assertNotNull(values);
assertEquals(10, values.size());
log.info("##### opsValue #####");
log.info("{}", values);
}
@Test public void opsValue() { ValueOperations<String, String> valueOps = redisTemplate.opsForValue(); Collection<String> cacheKeys = new ArrayList<>(); String cacheKey = "value_"; for (int i = 0; i < 10; i++) { cacheKeys.add(cacheKey + i); valueOps.set(cacheKey + i, String.valueOf(i), 60, TimeUnit.SECONDS); } List<String> values = valueOps.multiGet(cacheKeys); assertNotNull(values); assertEquals(10, values.size()); log.info("##### opsValue #####"); log.info("{}", values); }
@Test
public void opsValue() {
ValueOperations<String, String> valueOps = redisTemplate.opsForValue();
    Collection<String> cacheKeys = new ArrayList<>();
    String cacheKey = "value_";
    for (int i = 0; i < 10; i++) {
    cacheKeys.add(cacheKey + i);
    valueOps.set(cacheKey + i, String.valueOf(i), 60, TimeUnit.SECONDS);
    }
    List<String> values = valueOps.multiGet(cacheKeys);
    assertNotNull(values);
    assertEquals(10, values.size());
    log.info("##### opsValue #####");
    log.info("{}", values);
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
##### opsSortedSet #####
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
##### opsSortedSet ##### [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
##### opsSortedSet #####
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Lists structure command – 순서 있음. value 중복 허용

redis command lpush, llen, lrange, lpop, rpop에 대한 내용입니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
@Test
public void opsList() {
ListOperations<String, String> listOps = redisTemplate.opsForList();
String cacheKey = "valueList";
for (int i = 0; i < 10; i++)
listOps.leftPush(cacheKey, String.valueOf(i));
assertSame(DataType.LIST, redisTemplate.type(cacheKey));
assertSame(10L, listOps.size(cacheKey));
log.info("##### opsList #####");
log.info("{}", listOps.range(cacheKey, 0, 10));
assertEquals("0", listOps.rightPop(cacheKey));
assertEquals("9", listOps.leftPop(cacheKey));
assertEquals(true, redisTemplate.delete(cacheKey));
}
@Test public void opsList() { ListOperations<String, String> listOps = redisTemplate.opsForList(); String cacheKey = "valueList"; for (int i = 0; i < 10; i++) listOps.leftPush(cacheKey, String.valueOf(i)); assertSame(DataType.LIST, redisTemplate.type(cacheKey)); assertSame(10L, listOps.size(cacheKey)); log.info("##### opsList #####"); log.info("{}", listOps.range(cacheKey, 0, 10)); assertEquals("0", listOps.rightPop(cacheKey)); assertEquals("9", listOps.leftPop(cacheKey)); assertEquals(true, redisTemplate.delete(cacheKey)); }
@Test
public void opsList() {
    ListOperations<String, String> listOps = redisTemplate.opsForList();
    String cacheKey = "valueList";
    for (int i = 0; i < 10; i++)
        listOps.leftPush(cacheKey, String.valueOf(i));

    assertSame(DataType.LIST, redisTemplate.type(cacheKey));
    assertSame(10L, listOps.size(cacheKey));
    log.info("##### opsList #####");
    log.info("{}", listOps.range(cacheKey, 0, 10));
    assertEquals("0", listOps.rightPop(cacheKey));
    assertEquals("9", listOps.leftPop(cacheKey));
    assertEquals(true, redisTemplate.delete(cacheKey));
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
##### opsList #####
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
##### opsList ##### [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
##### opsList #####
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Hashes structure command – 순서 없음. key 중복 허용안함, value 중복 허용

redis command hset, hget, hlen, hdel에 대한 내용입니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
@Test
public void opsHash() {
HashOperations<String, String, String> hashOps = redisTemplate.opsForHash();
String cacheKey = "valueHash";
for (int i = 0; i < 10; i++)
hashOps.put(cacheKey, "key_" + i, "value_" + i);
assertSame(DataType.HASH, redisTemplate.type(cacheKey));
assertSame(10L, hashOps.size(cacheKey));
log.info("##### opsHash #####");
Set<String> hkeys = hashOps.keys(cacheKey);
for (String hkey : hkeys) {
log.info("{} / {}", hkey, hashOps.get(cacheKey, hkey));
}
assertEquals("value_5", hashOps.get(cacheKey, "key_5"));
assertSame(1L, hashOps.delete(cacheKey, "key_5"));
assertSame(null, hashOps.get(cacheKey, "key_5"));
}
@Test public void opsHash() { HashOperations<String, String, String> hashOps = redisTemplate.opsForHash(); String cacheKey = "valueHash"; for (int i = 0; i < 10; i++) hashOps.put(cacheKey, "key_" + i, "value_" + i); assertSame(DataType.HASH, redisTemplate.type(cacheKey)); assertSame(10L, hashOps.size(cacheKey)); log.info("##### opsHash #####"); Set<String> hkeys = hashOps.keys(cacheKey); for (String hkey : hkeys) { log.info("{} / {}", hkey, hashOps.get(cacheKey, hkey)); } assertEquals("value_5", hashOps.get(cacheKey, "key_5")); assertSame(1L, hashOps.delete(cacheKey, "key_5")); assertSame(null, hashOps.get(cacheKey, "key_5")); }
@Test
public void opsHash() {
    HashOperations<String, String, String> hashOps = redisTemplate.opsForHash();
    String cacheKey = "valueHash";
    for (int i = 0; i < 10; i++)
        hashOps.put(cacheKey, "key_" + i, "value_" + i);

    assertSame(DataType.HASH, redisTemplate.type(cacheKey));
    assertSame(10L, hashOps.size(cacheKey));
    log.info("##### opsHash #####");
    Set<String> hkeys = hashOps.keys(cacheKey);
    for (String hkey : hkeys) {
       log.info("{} / {}", hkey, hashOps.get(cacheKey, hkey));
    }
    assertEquals("value_5", hashOps.get(cacheKey, "key_5"));
    assertSame(1L, hashOps.delete(cacheKey, "key_5"));
    assertSame(null, hashOps.get(cacheKey, "key_5"));
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
##### opsHash #####
key_0 / value_0
key_1 / value_1
key_2 / value_2
key_3 / value_3
key_4 / value_4
key_6 / value_6
key_7 / value_7
key_8 / value_8
key_9 / value_9
key_5 / value_5
##### opsHash ##### key_0 / value_0 key_1 / value_1 key_2 / value_2 key_3 / value_3 key_4 / value_4 key_6 / value_6 key_7 / value_7 key_8 / value_8 key_9 / value_9 key_5 / value_5
##### opsHash #####
key_0 / value_0
key_1 / value_1
key_2 / value_2
key_3 / value_3
key_4 / value_4
key_6 / value_6
key_7 / value_7
key_8 / value_8
key_9 / value_9
key_5 / value_5

Set structure command – 순서 없음, value 중복 허용안함

redis command sadd, scard, smembers, sismember에 대한 내용입니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
@Test
public void opsSet() {
SetOperations<String, String> setOps = redisTemplate.opsForSet();
String cacheKey = "valueSet";
for (int i = 0; i < 10; i++)
setOps.add(cacheKey, String.valueOf(i));
assertSame(DataType.SET, redisTemplate.type(cacheKey));
assertSame(10L, setOps.size(cacheKey));
log.info("##### opsList #####");
log.info("{}", setOps.members(cacheKey));
assertEquals(true, setOps.isMember(cacheKey, "5"));
}
@Test public void opsSet() { SetOperations<String, String> setOps = redisTemplate.opsForSet(); String cacheKey = "valueSet"; for (int i = 0; i < 10; i++) setOps.add(cacheKey, String.valueOf(i)); assertSame(DataType.SET, redisTemplate.type(cacheKey)); assertSame(10L, setOps.size(cacheKey)); log.info("##### opsList #####"); log.info("{}", setOps.members(cacheKey)); assertEquals(true, setOps.isMember(cacheKey, "5")); }
@Test
public void opsSet() {
    SetOperations<String, String> setOps = redisTemplate.opsForSet();
    String cacheKey = "valueSet";
    for (int i = 0; i < 10; i++)
        setOps.add(cacheKey, String.valueOf(i));

    assertSame(DataType.SET, redisTemplate.type(cacheKey));     
    assertSame(10L, setOps.size(cacheKey));
    log.info("##### opsList #####");
    log.info("{}", setOps.members(cacheKey));
    assertEquals(true, setOps.isMember(cacheKey, "5"));
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
##### opsSet #####
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
##### opsSet ##### [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
##### opsSet #####
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

SortedSet structure command – 순서 있음, value 중복 허용안함

rediscommand zadd, zcard, zrange, zrank에 대한 내용입니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
@Test
public void opsSortedSet() {
ZSetOperations<String, String> zsetOps = redisTemplate.opsForZSet();
String cacheKey = "valueZSet";
for (int i = 0; i < 10; i++)
zsetOps.add(cacheKey, String.valueOf(i), i);
assertSame(DataType.ZSET, redisTemplate.type(cacheKey));
assertSame(10L, zsetOps.size(cacheKey));
log.info("##### opsSortedSet #####");
log.info("{}", zsetOps.range(cacheKey, 0, 10));
assertSame(0L, zsetOps.reverseRank(cacheKey, "9"));
}
@Test public void opsSortedSet() { ZSetOperations<String, String> zsetOps = redisTemplate.opsForZSet(); String cacheKey = "valueZSet"; for (int i = 0; i < 10; i++) zsetOps.add(cacheKey, String.valueOf(i), i); assertSame(DataType.ZSET, redisTemplate.type(cacheKey)); assertSame(10L, zsetOps.size(cacheKey)); log.info("##### opsSortedSet #####"); log.info("{}", zsetOps.range(cacheKey, 0, 10)); assertSame(0L, zsetOps.reverseRank(cacheKey, "9")); }
@Test
public void opsSortedSet() {
    ZSetOperations<String, String> zsetOps = redisTemplate.opsForZSet();
    String cacheKey = "valueZSet";
    for (int i = 0; i < 10; i++)
        zsetOps.add(cacheKey, String.valueOf(i), i);

    assertSame(DataType.ZSET, redisTemplate.type(cacheKey));
    assertSame(10L, zsetOps.size(cacheKey));
    log.info("##### opsSortedSet #####");
    log.info("{}", zsetOps.range(cacheKey, 0, 10));
    assertSame(0L, zsetOps.reverseRank(cacheKey, "9"));
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
##### opsSortedSet #####
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
##### opsSortedSet ##### [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
##### opsSortedSet #####
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Geo structure command – 좌표 정보 처리, 타입은 zset으로 저장.

redis command geoadd, geodist, geopos에 대한 내용입니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
@Test
public void opsGeo() {
GeoOperations<String, String> geoOps = redisTemplate.opsForGeo();
String[] cities = {"서울", "부산"};
String[][] gu = {{"강남구", "서초구", "관악구", "동작구", "마포구"}, {"사하구", "해운대구", "영도구", "동래구", "수영구"}};
Point[][] pointGu = {{new Point(10, -10), new Point(11, -20), new Point(13, 10), new Point(14, 30), new Point(15, 40)}, {new Point(-100, 10), new Point(-110, 20), new Point(-130, 80), new Point(-140, 60), new Point(-150, 30)}};
String cacheKey = "valueGeo";
// previous key delete
redisTemplate.delete(cacheKey);
for (int x = 0; x < cities.length; x++) {
for (int y = 0; y < 5; y++) {
geoOps.add(cacheKey, pointGu[x][y], gu[x][y]);
}
}
log.info("##### opsGeo #####");
Distance distance = geoOps.distance(cacheKey, "강남구", "동작구");
assertNotNull(distance);
assertEquals(4469610.0767, distance.getValue(), 4);
log.info("Distance : {}", distance.getValue());
List<Point> position = geoOps.position(cacheKey, "동작구");
assertNotNull(position);
for (Point point : position) {
assertEquals(14.000001847743988d, point.getX(), 4);
assertEquals(30.000000249977013d, point.getY(), 4);
log.info("Position : {} x {}", point.getX(), point.getY());
}
}
@Test public void opsGeo() { GeoOperations<String, String> geoOps = redisTemplate.opsForGeo(); String[] cities = {"서울", "부산"}; String[][] gu = {{"강남구", "서초구", "관악구", "동작구", "마포구"}, {"사하구", "해운대구", "영도구", "동래구", "수영구"}}; Point[][] pointGu = {{new Point(10, -10), new Point(11, -20), new Point(13, 10), new Point(14, 30), new Point(15, 40)}, {new Point(-100, 10), new Point(-110, 20), new Point(-130, 80), new Point(-140, 60), new Point(-150, 30)}}; String cacheKey = "valueGeo"; // previous key delete redisTemplate.delete(cacheKey); for (int x = 0; x < cities.length; x++) { for (int y = 0; y < 5; y++) { geoOps.add(cacheKey, pointGu[x][y], gu[x][y]); } } log.info("##### opsGeo #####"); Distance distance = geoOps.distance(cacheKey, "강남구", "동작구"); assertNotNull(distance); assertEquals(4469610.0767, distance.getValue(), 4); log.info("Distance : {}", distance.getValue()); List<Point> position = geoOps.position(cacheKey, "동작구"); assertNotNull(position); for (Point point : position) { assertEquals(14.000001847743988d, point.getX(), 4); assertEquals(30.000000249977013d, point.getY(), 4); log.info("Position : {} x {}", point.getX(), point.getY()); } }
@Test
public void opsGeo() {
    GeoOperations<String, String> geoOps = redisTemplate.opsForGeo();
    String[] cities = {"서울", "부산"};
    String[][] gu = {{"강남구", "서초구", "관악구", "동작구", "마포구"}, {"사하구", "해운대구", "영도구", "동래구", "수영구"}};
    Point[][] pointGu = {{new Point(10, -10), new Point(11, -20), new Point(13, 10), new Point(14, 30), new Point(15, 40)}, {new Point(-100, 10), new Point(-110, 20), new Point(-130, 80), new Point(-140, 60), new Point(-150, 30)}};
    String cacheKey = "valueGeo";

    // previous key delete
    redisTemplate.delete(cacheKey);

    for (int x = 0; x < cities.length; x++) {
        for (int y = 0; y < 5; y++) {
            geoOps.add(cacheKey, pointGu[x][y], gu[x][y]);
        }
    }

    log.info("##### opsGeo #####");
    Distance distance = geoOps.distance(cacheKey, "강남구", "동작구");
    assertNotNull(distance);
    assertEquals(4469610.0767, distance.getValue(), 4);
    log.info("Distance : {}", distance.getValue());
    List<Point> position = geoOps.position(cacheKey, "동작구");
    assertNotNull(position);
    for (Point point : position) {
        assertEquals(14.000001847743988d, point.getX(), 4);
        assertEquals(30.000000249977013d, point.getY(), 4);
        log.info("Position : {} x {}", point.getX(), point.getY());
    }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
##### opsGeo #####
Distance : 4469610.0767
Position : 14.000001847743988 x 30.000000249977013
##### opsGeo ##### Distance : 4469610.0767 Position : 14.000001847743988 x 30.000000249977013
##### opsGeo #####
Distance : 4469610.0767
Position : 14.000001847743988 x 30.000000249977013

HyperLogLog structure command – 집합의 원소의 개수 추정, 타입은 string으로 저장.

redis command pfadd, pfcount에 대한 내용입니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
@Test
public void opsHyperLogLog() {
HyperLogLogOperations<String, String> hyperLogLogOps = redisTemplate.opsForHyperLogLog();
String cacheKey = "valueHyperLogLog";
String[] arr1 = {"1", "2", "2", "3", "4", "5", "5", "5", "5", "6", "7", "7", "7"};
hyperLogLogOps.add(cacheKey, arr1);
log.info("##### opsHyperLogLog #####");
log.info("count : {}", hyperLogLogOps.size(cacheKey));
redisTemplate.delete(cacheKey);
}
@Test public void opsHyperLogLog() { HyperLogLogOperations<String, String> hyperLogLogOps = redisTemplate.opsForHyperLogLog(); String cacheKey = "valueHyperLogLog"; String[] arr1 = {"1", "2", "2", "3", "4", "5", "5", "5", "5", "6", "7", "7", "7"}; hyperLogLogOps.add(cacheKey, arr1); log.info("##### opsHyperLogLog #####"); log.info("count : {}", hyperLogLogOps.size(cacheKey)); redisTemplate.delete(cacheKey); }
@Test
public void opsHyperLogLog() {
    HyperLogLogOperations<String, String> hyperLogLogOps = redisTemplate.opsForHyperLogLog();
    String cacheKey = "valueHyperLogLog";
    String[] arr1 = {"1", "2", "2", "3", "4", "5", "5", "5", "5", "6", "7", "7", "7"};
    hyperLogLogOps.add(cacheKey, arr1);
    log.info("##### opsHyperLogLog #####");
    log.info("count : {}", hyperLogLogOps.size(cacheKey));
    redisTemplate.delete(cacheKey);
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
##### opsHyperLogLog #####
count : 7
##### opsHyperLogLog ##### count : 7
##### opsHyperLogLog #####
count : 7

최신 소스는 GitHub 사이트를 참고해 주세요.
https://github.com/codej99/SpringRedisCluster/tree/feature/rediscluster

연재글 이동[이전글] Redis – cluster
[다음글] Redis – Spring-data-redis : @Cacheable, @CachePut, @CacheEvict, @RedisHash