Docker


- 도커는 리눅스 컨테이너에 여러 기능을 추가함으로써 애플리케이션을 컨테이너로서 좀 더 쉽게 사용할 수 있게 만들어진 오픈소스 프로젝트이다.

- Go 언어로 작성 돼 있다.

- 도커와 관련된 프로젝트는 도커 컴포즈(Compose), 레지스트리, 도커머신, Kitematic 등 여러가지가 있지만 일반적으로 도커 엔진, 도커 관련 프로젝트를 일컫는다.


- 도커는 원래 리눅스에서 작동하는데 최적화 돼 있으므로, 윈도우 혹은 MAC OS에서 사용할 경우 일부 기능의 제약이 있을 수 있다.




가상 머신과 도커 컨테이너


기존의 가상화 기술은 하이퍼바이저를 이용해 여러 개의 운영체제를 하나의 호스트에서 생성해 사용하는 방식이었다.




출처: https://devnet.kentico.com/articles/running-kentico-in-a-docker-container

(기존의 가상화 머신과 도커의 비교)




그러나 각종 시스템 자원을 가상화하고 독립된 공간을 생성하는 작업은 하이퍼 바이저를 반드시 거치기에 일반 호스트에 비해 성능 손실이 발생한다. 즉 가상 머신은 완벽한 운영체제를 생성할 수 있다는 장점은 있지만 일반 호스트에 비해 성능 손실이 있으며, 이에 따른 배포에 부담이 있을 수 있다.


반면 도커 컨테이너는 가상화된 공간을 생성하기 위해 리눅스 자체 기능인 chroot, namespace, cgroup를 사용함으로서 프로세스 단위의 격리 환경을 만들기 때문에 성능의 손실이 거의 없다. 


컨테이너에 필요한 커널은 호스트의 커널을 공유해 사용할 수 있으며, 컨테이너 안에서 사용하는 애플리케이션을 구동하는데 필요한 라이브러리 및 실행파일만 존재하기 때문에 이미지의 크기가 줄어들게 된다.


도커 컨테이너 이미지는 코드, 런타임, 시스템 도구, 라이브러리 및 설정과 같은 애플리케이션 단위의 프로그램을 실행하는데 필요한 모든 것을 포함하는 경량 소프트웨어 패키지다.


컨테이너 이미지를 생성하여 실행(Runtime)할 때 컨테이너가 생성된다. - (이미지는 도커엔진이 실행하여 컨테이너로 만들어준다.)



정리하면 도커 컨테이너의 특징은 간단하게 3가지로 구분할 수 있다.


1) Standard : 컨테이너는 표준화된 소프트웨어이기에 손쉽게 개발, 배포가 가능하다.

2) LightWeight : 컨테이너는 OS의 커널을 공유하기 때문에 애플리케이션 별 OS가 필요하지 않다. 때문에 서버효율성이 증대된다.

3) Secure : 애플리케이션은 컨테이너에서 안전하며, 도커에서 기본적으로 안정성을 제공한다.








'Cloud & NoSQL & Middleware > Docker' 카테고리의 다른 글

Docker Network (2) - 브리지(bridge) network  (0) 2018.09.17
Docker Network (1) - docker0  (0) 2018.09.14
Docker Container - 명령어 & Volume  (0) 2018.09.09
Docker Engine, image  (0) 2018.09.08
Docker in MacOS 설치  (0) 2018.08.04


Gradle


compile('org.springframework.boot:spring-boot-starter-data-redis')

compile group: 'redis.clients', name: 'jedis', version: '2.9.0'







application.properties 설정


spring.cache.type=redis

spring.redis.host = 127.0.0.1 

spring.redis.password= 

spring.redis.port=6379








RedisConfig 클래스 생성


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.example.service.redis;
 
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
 
import redis.clients.jedis.JedisPoolConfig;
 
@Configuration
@ComponentScan("com.spring.redis")
public class RedisConfig {
 
    private @Value("${spring.redis.host}"String redisHost;
    private @Value("${spring.redis.port}"int redisPort;
    private @Value("${spring.redis.password}"String password;
 
    @Bean
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(30);
        jedisPoolConfig.setMinIdle(10);
        jedisPoolConfig.setTestOnBorrow(true);
        jedisPoolConfig.setTestOnReturn(true);
        return jedisPoolConfig;
    }
 
    @SuppressWarnings("deprecation")
    @Bean
    public JedisConnectionFactory redisConnectionFactory() {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig());
        jedisConnectionFactory.setHostName(redisHost);
        jedisConnectionFactory.setPort(redisPort);
        jedisConnectionFactory.setPassword(password);
        jedisConnectionFactory.setUsePool(true);
        return jedisConnectionFactory;
    }
 
    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory());
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new StringRedisSerializer());
        template.setEnableDefaultSerializer(false);
        template.setEnableTransactionSupport(true);
        return template;
    }
}
cs




Redis Client에서 가장 많이 사용되는 오픈소스는 Jedis/lettuce/Redisson  중 Jedis이다.


많이 쓴다는 것은 곧 그만큼 사용하기 쉽고 레퍼런스가 많다는 의미이다.


실제로 Jedis를 통해 손쉽게 사용할 수 있었다.


Spring에서 RedisTemplate을 통해 데이터에 엑세스할 뿐 아니라 ConnectionPool의 자원 관리 또한 알아서 해준다.


=> 실제론 JedisConnectionFactory를 통해서 수행




RedisTemplate을 통해 다음과 같은 데이터 타입을 다룰 수 있다.

String

@Resource(name="redisTemplate")
private ValueOperations<String, String> valueOperations;

Set

@Resource(name="redisTemplate")
private SetOperations<String, String> setOperations;

Sorted Set

@Resource(name="redisTemplate")
private ZSetOperations<String, String> zSetOperations;

Hashes

@Resource(name="redisTemplate")
private HashOperations<String, String, String> hashOperations;

List

@Resource(name="redisTemplate")
private ListOperations<String, String> listOperations;







'Cloud & NoSQL & Middleware > Redis' 카테고리의 다른 글

Redis Library  (2) 2018.11.17
Single Thread  (0) 2018.11.17
Redis 명령어  (0) 2018.08.04
Redis Pub/Sub Model  (0) 2018.07.01
Java에서 Redis 연동 테스트 (jedis)  (0) 2018.07.01

설치


- Docker는 맥에서 무료로 사용 가능하다.

- MacOS의 버전이 Mac OS Yosemite 10.10.3 이상이 필요하다. 이전 버전일 경우 Docker ToolBox를 이용해야한다.

- Docker for Mac에서 설치가능. 아래 링크 확인




https://docs.docker.com/docker-for-mac/install/










설치 확인


$ docker version


or


$ docker run hello-wolrd











'Cloud & NoSQL & Middleware > Docker' 카테고리의 다른 글

Docker Network (2) - 브리지(bridge) network  (0) 2018.09.17
Docker Network (1) - docker0  (0) 2018.09.14
Docker Container - 명령어 & Volume  (0) 2018.09.09
Docker Engine, image  (0) 2018.09.08
Docker?  (0) 2018.09.08


Command


Redis Client Too인 rdm이나,  CLI에서 관련 명령어를 수행하려면 https://redis.io/commands 에서 확인해보자.



ex)  저장된 키 값을 모두 지울 때 flushall

'Cloud & NoSQL & Middleware > Redis' 카테고리의 다른 글

Single Thread  (0) 2018.11.17
SpirngBoot에서 Redis 연동(Jedis)  (0) 2018.08.09
Redis Pub/Sub Model  (0) 2018.07.01
Java에서 Redis 연동 테스트 (jedis)  (0) 2018.07.01
MacOS에서 Redis 설치 및 실행  (0) 2018.07.01

Pub/Sub Model


Redis는 JMS나 IBM MQ 같은 메시징에 활용할 수 있는데 1:1 형태의 Queue뿐만 아니라 1:N 형태의 Publish/Subscribe 메시징도 지원한다(Publish/Subscribe 구조에서 사용되는 Queue를 일반적으로 Topic이라고 한다). 하나의 클라이언트가 메시지를 Publish하면 이 Topic에 연결되어 있는 다수의 클라이언트가 메시지를 받을 수 있는 구조이다(Publish/Subscribe 형태의 메시징에 대해서는 http://en.wikipedia.org/wiki/ Pub/sub를 참고하길 바란다).

재미있는 것 중에 하나는 일반적인 Pub/Sub 시스템의 경우 Subscribe하는 하나의 Topic에서만 Subscribe하는데 반해, Redis에서는 pattern matching을 통해 다수의 Topic에서 메시지를 Subscribe할 수 있다. 예를 들어 topic 이름이 music.pop, music.classic이라는 2개의 Topic이 있을 때, “PSUBSCRIBE music.*”라고 하면 2개의 Topic에서 동시에 메시지를 Subscribe할 수 있다.




출처: https://www.kdata.or.kr/info/info_04_view.html?field=&keyword=&type=techreport&page=38&dbnum=176019&mode=detail&type=techreport

'Cloud & NoSQL & Middleware > Redis' 카테고리의 다른 글

SpirngBoot에서 Redis 연동(Jedis)  (0) 2018.08.09
Redis 명령어  (0) 2018.08.04
Java에서 Redis 연동 테스트 (jedis)  (0) 2018.07.01
MacOS에서 Redis 설치 및 실행  (0) 2018.07.01
Redis 특징(3) - Redis Persistance  (0) 2018.06.29

Jedis


Java에서 Jedis Library를 사용하여 Redis에 연동한다.



https://mvnrepository.com/artifact/redis.clients/jedis/2.9.0








Connection Pool 및 set, get, 만료시간 지정



단순 테스트 용도라면 그냥 접근해도 좋지만, 성능을 염두하고 있다면 JedisPool을 사용해야 하며 Apache-common library도 함께 필요하다.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
 
public class Main {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        String host = "127.0.0.1";
        int port = 6379;
        int timeout = 3000;
        int db = 0;
        
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        
        JedisPool pool = new JedisPool(jedisPoolConfig,host,port,timeout,null,db);
        
        Jedis jedis = pool.getResource();
        
        //Connect 체크 
        System.out.println(jedis.isConnected());
        
jedis.set("key4""6");
        jedis.set("key5""6");
        
        // 데이터의 만료시간을 지정
        jedis.expire("key5",1);
        
        System.out.println(jedis.get("key5"));
        
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(jedis.get("key5"));
    
        if( jedis != null ){
            jedis.close();
        }
        pool.close();
        
    }
 
}
 
cs



>>true

>>6

>>null









list, hashes, set, sorted set 사용



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
 
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
 
public class Main {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
 
        String host = "127.0.0.1";
        int port = 6379;
        int timeout = 3000;
        int db = 2;
 
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
 
        JedisPool pool = new JedisPool(jedisPoolConfig, host, port, timeout, null, db);
 
        Jedis jedis = pool.getResource();
 
        // list 형태로 입력
        jedis.lpush("id""choi");
        jedis.lpush("id""keach");
        jedis.lpush("id""hoo");
 
        // 첫번 째 요소를 제거하고 꺼냄
        System.out.println(jedis.lpop("id"));
        // 마지막 요소를 제거하고 꺼냄
        System.out.println(jedis.rpop("id"));
 
        // hash 형태로 입력
        Map<StringString> score = new HashMap<>();
        score.put("kim""220");
        score.put("park""240");
 
        jedis.hmset("score", score);
 
        Map<StringString> getMap = jedis.hgetAll("score");
 
        Set<String> key = getMap.keySet();
 
        Iterator<String> keyIter = key.iterator();
 
        while (keyIter.hasNext()) {
            System.out.println(getMap.get(keyIter.next()));
        }
 
        // Set 형태로 입력
        jedis.sadd("user""user00");
        jedis.sadd("user""user01");
        jedis.sadd("user""user02");
 
        Set<String> user = jedis.smembers("user");
 
        Iterator<String> iter = user.iterator();
 
        while (iter.hasNext()) {
            System.out.println(iter.next());
        }
        
        
        // Sorted Set 형태로 입력
        jedis.zadd("sortedUser"1000"user00");
        jedis.zadd("sortedUser"1048"user01");
        jedis.zadd("sortedUser"1024"user02");
        
 
        if (jedis != null) {
            jedis.close();
        }
        pool.close();
 
    }
 
}
 
cs





특이하게 봐야 할 곳이 있다면 SortedUser 키 . 

user02의 경우 마지막에 추가했지만 확인해보면 가중치 값으로 인해 중간에 삽입된 것을 확인 할 수 있다.






마지막으로 키 삭제에 대한 코드는 다음과 같다.


jedis.del("key");







참고

http://jdm.kr/blog/202




'Cloud & NoSQL & Middleware > Redis' 카테고리의 다른 글

Redis 명령어  (0) 2018.08.04
Redis Pub/Sub Model  (0) 2018.07.01
MacOS에서 Redis 설치 및 실행  (0) 2018.07.01
Redis 특징(3) - Redis Persistance  (0) 2018.06.29
Redis 특징 (2) - 지원 데이터 타입  (0) 2018.06.29

MacOS에서 Redis 설치


mac에서는 설치유틸리티인 brew를 통해 손쉽게 redis를 설치할 수 있다.




Redis 설치


$brew install redis





Redis 서비스 실행, 중지, 재시작


$brew services start redis

$brew services stop redis

$brew services restart redis



Redis 설정


# Accept connections on the specified port, default is 6379.

# If port 0 is specified Redis will not listen on a TCP socket.
port  6379   [포트번호 변경]

# Warning: since Redis is pretty fast an outside user can try up to
# 150k passwords per second against a good box. This means that you should
# use a very strong password otherwise it will be very easy to break.
#
requirepass password  [주석제거하고 패스워드 입력]

# By default Redis listens for connections from all the network interfaces
# available on the server. It is possible to listen to just one or multiple
# interfaces using the "bind" configuration directive, followed by one or
# more IP addresses.
#
# Examples:
#

# bind 192.168.1.100 10.0.0.1  
bind 127.0.0.1 192.168.0.101   [외부에서 접근 가능하도록 IP 추가 가능]





Redis 실행


$redis-server







Redis 클라이언트


https://redisdesktop.com 에서 클라이언트를 다운받고 쉽게 redis를 사용할 수 있다.




설치


ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null ; brew install caskroom/cask/brew-cask 2> /dev/null



brew cask install rdm






'Cloud & NoSQL & Middleware > Redis' 카테고리의 다른 글

Redis Pub/Sub Model  (0) 2018.07.01
Java에서 Redis 연동 테스트 (jedis)  (0) 2018.07.01
Redis 특징(3) - Redis Persistance  (0) 2018.06.29
Redis 특징 (2) - 지원 데이터 타입  (0) 2018.06.29
Redis 특징  (2) 2018.06.29


Redis Persistance


Redis Persistance 특징을 활용해 데이터를  저장하는 방법은 2가지가 존재한다.



RDB Mode 와 AOF Mode





RDB Mode


1) 정의


특정 시점 또는 반복적으로 메모리에 있는 전체 데이터를 디스크에 저장한다.



2) 장점


- 파일크기가 작아 AOF보다 로딩시간이 빠르다.




3) 단점


- 특정 시점에 데이터를 저장함에 따라 이슈 발생 시 데이터가 유실 될 수 있다.

ex)  13시에 데이터를 백업 하고 13시 30분에 장애가 발생하면 13시에서 13시 30분 사이의 데이터는 복구 불가능하다.


- 바이너리 파일로 백업을 제공한다. 





AOF Mode



1) 정의


명령이 실행될 때마다 기록이 저장된다.


2) 장점


- 서버 장애가 발생해도 데이터 유실이 거의 없다.

- 텍스트 파일로 백업을 제공한다. 따라서 손생이 발생해도 쉽게 복구 가능하다.




3) 단점


- 모든 명령이 기록되기 때문에 파일 크기가 커지고, 데이터 로딩이 느려질 수 있으며, OS의 파일크기 제한으로 장애가 발생할 수 있다.

 * Re-write를 통해 최종 데이터만 기록할 수 있고 파일을 크기를 줄 일 수 있다.






우선순위


-  RDB 와 AOF가 둘다 존재할 경우 redis.conf 설정에 따라 읽어들이는 우선순위가 다르다.


"AppendOnly" 가  yes인 경우 AOF 파일을 읽어 온다.

"AppendOnly" 가  no인 경우  RDB 파일을 읽어 온다.




권고사항


안전한 데이터의 보존을 위해선 RDB, AOF 모두 사용할 것을 권고한다.

또한 데이터를 보관하는 저장소가 있다면 스캐쥴을 통해 주기적으로 데이터 보관 스토리지에 데이터를 저장하는 것을 권고한다.








출처:http://ossian.tistory.com/42





'Cloud & NoSQL & Middleware > Redis' 카테고리의 다른 글

Java에서 Redis 연동 테스트 (jedis)  (0) 2018.07.01
MacOS에서 Redis 설치 및 실행  (0) 2018.07.01
Redis 특징 (2) - 지원 데이터 타입  (0) 2018.06.29
Redis 특징  (2) 2018.06.29
레디스(Redis) 란?  (1) 2018.06.29

+ Recent posts