Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file removed redis/week05/taejun/.gitkeep
Empty file.
137 changes: 137 additions & 0 deletions redis/week05/taejun/ACL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
## ACL (AccessControl)

- Redis 6.0버전부터 사용가능하다.
- User마다 다른 Password와 권한을 줄 수 있다.
- ACL List를 통해서 부여받은 제한을 확인 가능하다.

```bash
ACL List
# default라는 user는 active 되어있고 패스워드가 없으며
# 모든 카테고리 enable,모든 pubsub enable, 모든 key pattern enable
"user default on nopass ~* &* +@all"
```

- 기본적인 설정은 redis.conf에 저장된다.
- 파일 분리도 가능하다.

```bash
# redis.conf에 acl파일의 위치를 지정해주면 된다.
aclfile <path-to-acl-file>

# redis.conf의 aclfile 설정에 저장되있는 설정을 Load한다.
ACL LOAD

# 초기 파일의 형태와 달라졌을 때 (ACL SET USER, ...) 해당 설정은 메모리에 위치하게 된다.
# 이걸 ACL파일에 다시 저장하여 메모리와 설정을 동기화 시킨다.
ACL SAVE
```


### Connection 제어

- redis.conf 혹은 cli상에 파라미터를 통해서 설정을 넘길 수 있다.
- Redis Server는 여러개의 NetworkInterface를 가질 수 있다.
- 여러 IP중에 어떤 IP로 들어오는 요청만 받을 것인지 설정한다.
- Client의 접근을 관리 할 수 있다.
- 특정 IP만 Ciient에게 허용하기 떄문에 보안을 높일 수 있다.
- Network대역폭환경에 맞게 제한하여, 성능최적화도 가능하다.

### Password

- 1개이상 지정 가능하다.
- 추가 삭제 모두 가능하다.
- SHA256으로 해시되어있다.
- 2가지 방식이 있다.
- ACL이전처럼 Node에 직접 Password를 매핑
- requirepass

```bash
# 명령어를 통한 전달
CONFIG SET requirepass <password>

# -a옵션을 통한 접근
redis-cli -a <password>

# 우선 접근 후 AUTH
redis-cli

# username 명시적 지정
AUTH <user-name> <password>

# username은 default로 가정된다.
AUTH <password>
```

- redis.conf에 저장
- ACL 기능을 사용
- nopass: 비밀번호 없이 접근 가능
- resetpass: 비밀번호 초기화
- nopass에 대한 권한도 사라지게 된다.
- 새로운 비밀번호를 부여하기 전까지는 아무도 접근 할 수 없다.

### protectedMode

- Redis를 운영할 것이라면 사용하는 것이 권장된다.
- Password를 입력하지 않았다면, local(127.0.0.1)에서 접근 하는것만 허용된다
- 일종의 이중장치라고 볼 수 있다.

### Command제어

- redis-command를 통해서, 이름을 변경하거나 활성화 / 비활성화가 가능하다.
- redis.conf에서 변경이 간으하다.
- CONFIG GET을 통해서 보거나, CONFIG SET을 통해서 변경하는 것은 불가능하다.
- 세밀한 설정을 통해서 보한 강화가 가능하다.
- ex) CONFIG SET과 같은 설정변경은 매우 위험한데, ACL을 통해서 특정 User의 접근을 Disable할 수 있다.
- command이름도 변경 가능하다.
- 예를들어서 다른 기능과 함께 사용되는 command가 변경되면 같이 설정해주어야한다.
- ex) REPLICAOF, CONFIG가 변경되면 sentinel.conf도 변경되어야한다.
- rule은 왼쪽 → 오른쪽 순서로 적용된다.

| 분류 | 규칙 | 설명 |
| --- | --- | --- |
| 사용자 활성화/비활성화 | on, off | on: 사용자 활성화, off: 사용자 비활성화 (이미 인증된 연결은 계속 작동) |
| 명령어 접근 제어 | +<command>, -<command> | +<command>: 특정 명령어 허용, -<command>: 특정 명령어 거부. Redis 7.0부터 서브커맨드 차단 가능 (예: `-config |
| 카테고리별 접근 제어 | +@<category>, -@<category> | +@<category>: 특정 카테고리의 모든 명령어 허용, -@<category>: 특정 카테고리의 모든 명령어 거부. 예: @admin, @set, @sortedset 등 |
| 키 패턴 제한 | ~<pattern>, %R~<pattern>, %W~<pattern> | ~<pattern>: 특정 패턴의 키 접근 허용. Redis 7.0부터 읽기/쓰기 키 패턴 (%R~, %W~) 지원 |
| Pub/Sub 채널 접근 제어 | &<pattern>, allchannels, resetchannels | &<pattern>: 특정 패턴의 Pub/Sub 채널 접근 허용. allchannels는 모든 채널 허용, resetchannels는 채널 패턴 목록 초기화 |
| 비밀번호 설정 | ><password>, #<hash>, nopass, resetpass | ><password>: 비밀번호 추가, #<hash>: SHA-256 해시 값으로 비밀번호 추가. nopass: 비밀번호 없이 접근 허용, resetpass: 비밀번호 목록 초기화 |
| 선택기 설정 | (<rule list>), clearselectors | Redis 7.0부터 사용 가능. (<rule list>): 새 선택기 생성 및 규칙 매칭, clearselectors: 모든 선택기 삭제 |
| 사용자 초기화 | reset | resetpass, resetkeys, resetchannels, allchannels, off, clearselectors, -@all을 포함하여 사용자를 초기 상태로 재설정 |
- 카테고리: 명령어의 집합

```bash
# 모든 카테고리목록을 보여준다.
ACL CAT
```

- @read: 데이터를 읽는 명령어의 집합
- @write: 데이터를 쓰는 명령어들의 집합
- @dangerous: 보안이나, 데이터 무결성에 영향을 줄 수 있는 명령어 집합

### Command 실행환경 제어

- 7버전부터, Command가 실행될 수 있는 환경도 제어가 가능하다.
- Redis Server가 실행중일 때 변경되면 위험한 설정은 실행불가능하게 막았다.
- redis.conf에 설정 가능하다.
- 위험한 설정을 실행중에 변경 하는 것을 enable / disable / 로컬에서만 허용 등의 설정이 가능하다.
- no | yes | local의 설정이 가능하다.

```bash
enable-protected-configs no # CONFIG SET, CONFIG REWRITE, CONFIG RESETSTAT, ...
enable-debug-command no # DEBUG SETFAULT, DEBUG RELOAD, DEBUG OBJECT, ...
enable-module-command no # MODULE LOAD, MODULE UNLOAD, MODULE LIST, ...
```

### User 생성 및 삭제

```bash
# 유저 생성
#(user-name: tj, password: password, 접근가능 Key Pattern: cached:*, pubsub: *, dangerous 카테고리 제외)
ACL SETUSER tj on >password ~cached:* &* +@all -@dangerous

# 유저 삭제
ACL DELUSER

# 유저 ACL 목록 조회
ACL GETUSER <user-name>
```
158 changes: 158 additions & 0 deletions redis/week05/taejun/Replication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
## Redis Replication이란?

- Sentinel, Clustering을 제외 했을 때, 간편하게 구성할 수 있는 고가용성(HA)확보 방법이다.
- Replica는 Master와 연결이 끊어질 때마다 재연결을 시도한다.
- master의 상태에 상관없이 항상 정확한 Replica를 얻기위해서 노력한다.
- 멀티 마스터구조의 replica는 불가능하다.
- write연산은 master에서, read연산은 Replica에서 수행해야한다.
- Master는 N개의 Replica를 가질 수 있다.
- Replica의 Replica도 가질 수 있다. (특정환경에서 유리)
- Replica Chaning, Replica Cascading …
- Master의 복제연산에 대한 부하를 분산할 수 있다.
- 지리적 분산 환경에서, 가까운 ReplicaNode끼리 복제를 수행하여 네트워크 성능을 최적화 할 수 있다.
- 각각의 네트워크에서 수행될 것이기 떄문에 대역폭 최적화 관점에서도 유리하다.
- RDB는 Replicaion과정에서 주로 사용되지만, AOF는 사용되지 않는다.
- RDB옵션을 꺼두어도, Replicaion이 Enable되있으면 RDB저장이 수행된다.
- diskless옵션을 키면 RDB가 저장되지 않는다.

### 복제 Case

```bash
(1) Master와 Replica가 잘 연결되어 있을 때 - ReplicaionBuffer를 이용한 명령어 전달
(2) Master와 Replica의 연결이 끊어졌을 때 - 부분 재동기화 시도
(3) 부분 재동기화가 불가능 할 때 - 전체 재동기화 시도
```

### 부분 재동기화

- 연결이 끊어질 때마다 매번 RDB 스냅샷 파일을 전송하는 것은 매우 비효율적이다.
- Master는 Connection 유실에 대비하여, BacklogBuffer라는 메모리공간을 둔다.
- 이 곳에는, Replica에 전달할 Command들을 저장해둔다.
- BacklogBuffer Size에 대한 설증은 redis.conf에서 구성가능하다.
- ReplicaNode는 재연결이 되었을 때, MasterNode에게 자신의 ReplicaionId와 Offset을 전달한다.
- 충분한 Backlog가 없거나, 알 수 없는 ReplicaionId를 참조하는 경우 재동기화가 발생한다.

### 전체 재동기화

1. RDB 스냅샷 생성: 전체 재동기화 과정의 첫 단계로, 마스터 인스턴스는 자신의 전체 데이터셋에 대한 스냅샷을 생성한다.
2. RDB 스냅샷 전송: 생성된 스냅샷은 복제 인스턴스로 전송한다. 네트워크 대역폭과 데이터 크기에 따라 시간이 소요될 수 있다.
3. 명령어 스트림 전송 재개: 스냅샷 전송 후, 마스터 인스턴스는 복제 인스턴스에 데이터셋 변경 사항을 반영하는 명령어 스트림의 전송을 재개한다.

### Command

```bash
# 복제 프로세스 시작
REPLICAOF <master-ip> <master-port>

# Master와 ReplciaNode가 연결되어 있을 때, 동기화 수행 (ReplicaNode가 내부적으로 수행)
# 기존에 Sync명령어가 존재했으나, 부분 재동기화를 지원하지 않는관계로 PSYNC가 사용된다.
PSYNC <replicaion-id> >offset>

# 설정 적용
CONFIG SET masterauth <master-node-password>
CONFIG REWRITE
```

- REPLICAOF명령어를 수행하는 RedisServer가 Replica가 되는 것이다.
- 기본적인 Password를 사용해서, 데이터를 복제 할 때는 masterauth옵션에 패스워드를 입력해야한다.
- masterauth를 통해서, Replica가 master에 접근한다.
- CONFIG REWRITE를 통해서, 설정을 적용시킨다.

### 과정

```
(1) REPLICAOF를 통해서, 복제 연결을 시도한다.
(2) MasterNode에서는, fork()를 통해서 자식 Process를 생헝 한 후 RDB Snapshot을 생성한다
(3) MaserNode에서 수행된 DataSet의 변경은 RESP형태로 Master ReplicationBuffer에 저장된다.
(4) RDB파일이 생성 완료되었다면, ReplicaNode에게 소켓통신을 통해서 diskless하게 전달된다.
(5) Replica는 받아온 RDB를 디스크에 저장한다.
(6) Replica에 저장되어있던 모든 내용을 삭제한 후, RDB파일을 이용하여 데이터를 로딩한다.
(7) Replica과정동안 Buffering됐던 데이터를 Replica에 전달하여 수행시킨다.
```

- RDB Snapshot은 Redis 전체의 복사본이다.
- RDB와 ReplicaionBuffer 두가지 방법을 사용하는 이유는 효율성 + 일관성의 목적이다.
- RDB: 초기 DataSet을 제공하기 위해서 사용된다.
- ReplicaionBuffer: 실시간으로 데이터를 추적하는데 사용된다.


### 비동기 (기본)

- 유실이 발생할 수 있다
- Client와 Master간의 Command 및 응답이 선행된다.
- 그 이후에 Master와 ReplicaNode간의 통신이 수행된다.
- ReplicaNode와의 통신 이전에 Master의 비정상적인 종료의 경우 유실이 발생할 수 있다.
- Replica 속도가 굉장히 빠르기 떄문에, 유실이 빈번하게 발생하지는 않는다.

### 동기

- WAIT명령을 수행한다.
- 지정된 수의 Replica가 Write명령을 받을 때 까지 대기한다.
- 데이터의 내구성은 향상시키지만, 성능을 저하시키게된다.
- 동기방식이 CP시스템을 보장하지는 않는다. (Consistency - Partition Tolerance)
- 여전히 데이터 유실의 가능성은 있다는 것을 의미한다.
- 장애발생 및 설정에 따라서 달라질 수 있기 떄문이다.

### Replicaion ID

```
> INFO Replication

# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:277a883084000887a988cdfc32dff307444957e5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:723
slave_priority:100
slave_read_only:1
connected_slaves:0
master_fail_over_state:no-failover
master_replid:277a883084000887a988cdfc32dff307444957e5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

```

- RandomString값을 가지며, Offset과 쌍으로 유지된다.
- ReplicaionId가 같다는 것은 같은 DataSet을 구성하고 있다는 것을 의미한다.
- ReplicaNode는 ReplicaitonConnection이 맺어지면 Master의 ReplicaionId를 상속받는다.
- Replication상태를 추적하는데 사용된다.
- INFO REPLICAION 을 통해서 Replica상태를 파악 할 수 있다.
- Offset은 Replica에서 마지막으로 동기화된 Master의 Offset을 나타낸다.
- Offset이 같으면 정확하게 일관성이 유지된 상태인 것이다.
- Secondary ReplicaionId는 Replica가 Master로 승격했을 떄를 구분하기 위함이다.
- 새로운 Master가 선출 되면 새로운 ReplicaionId를 생성하게 된다.
- 이전 Master노드의 ReplicationId는 SecondaryReplicaionId가 된다.
- 단순히 Network문제로 인해서, 승격이 결정되고 이전 Master가 그대로 동작하고있다면 같은 DataSet을 가지고있다는 사실을 위반하게된다.

### Replica에서의 Expire

- ReplicaNode는 스스로 Key를 Expire시키지 않는다.
- MasterNode가 Key를 만료시키거나, LRU를 통해서 제거될 때 까지 기다린다.
- Master는 Expire가 된다면 ReplicaNode에게 DEL명령을 전달한다.
- 일관성이 깨질 수 있다.
- Master의 DEL명령어가 전달되지 않는다면?
- 읽기작업시 자체적인 논리적 시계를 사용하여, 만료되었다고 판단되는 데이터는 반환하지 않을 수 있다.
- Master와는 독립적으로 동작하는 시계이며, Expire된 Key를 추적한다.
- Master의 DELETE명령어를 대체할 자체적인 프로세스는 가지고 있지 않다.
74 changes: 74 additions & 0 deletions redis/week05/taejun/SSL&TLS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
### SSL/TLS

- 버전 6부터 지원을 시작했다.
- 두가지 모두 암호화를 위한 인터넷 보안 프로토콜
- SSL은 1996년 이후로 업데이트 되지 않고있다.
- 두가지용어가 혼용되어 사용되고 있다.
- TLS 1.0, 1.1은 안전하지 않다고 판단되고있고 1.2사용이 권장된다.
- Redis는 Network를 통해서 빠르게 데이터를 주고받는데, 이 과정에서 평문일 경우 문제가 생길 수 있다.

### SSL/TLS 설정 Enable

- 기본적으로는 Disable되어있다.
- SSL개발 라이브러리가필요하다.
- Redis빌드를 해주어야한다.

```bash
make BUILD_TLS=yes
```

- Server와 Client가 동일한 인증서를 사용한다.
- TLS port를 설정해주어야한다.

```bash
# 일반 포트 비활성화
port 0

# TLS 연결만 허용
tls-port 6379
```


### 명시적으로 Server 실행시키기

```bash
./src/redis-server --tls-port 6379 --port 0 \
--tls-cert-file ./tests/tls/redis.crt \
--tls-key-file ./tests/tls/redis.key \
--tls-ca-cert-file ./tests/tls/ca.crt
```

### cli를 통한 접근

```bash
./src/redis-cli --tls \
--cert ./tests/tls/redis.crt \
--key ./tests/tls/redis.key \
--cacert ./tests/tls/ca.crt
```

### Replicaion에서의 TLS

- Client와의 설정이 Replicaion에도 똑같이 적용된다.
- MasterNode 설정
- tls-port 정의되어있어야 한다.
- tls-auth-clients(Optional)를 통해서, Client에게 인증서를 요구 할 수 있다.
- ClientNode 설정
- tls-replicaion을 enable해야 한다.
- ReplicaionNode → MasterNode로의 통신이 TLS로 연결된다.

### Sentinel에서의 TLS

- Sentinel은 Redis의 네트워크 구성을 상속받는다.
- 설정한 모든내용은 Sentinel에게도 전파된다.
- Sentinel ←→MasterNode간의 연결 시, tls-replicaion을 통해서 지원할 지 여부를 결정한다.
- enable되어있으면 Sentinel과의 연결도 tls-port에 매핑된 포트로 TLS로 되어야한다는 것이다.

### Cluster에서의 TLS

- tls-cluster 옵션이 enable되어있다면, cluster-bus간의 통신도 tls를 통해서 이루어진다.

### 고려해 볼 점

- Read / Write에 암호화, 복호화를 수행하는 통신계층이 추가되는 것이다.
- 결과적으로 Instance 하나 당 처리량은 줄어든다.
Loading