6. 마덜 컴퍼니의 역작 엄친아.com 을 만들 예정입니다
서비스 오픈 준비 step 1
기획에서 나온 내용들
• 엄친아.com은 엄마 친구 아들의 일상을 담은 영상을 서비스 한다
• 첫 페이지에는 엄친아와 관련된 영상 20개를 조회수 순서로 보여주자
• 엄친아 자랑코너(사진 게시판)
• 기타 이것 저것 좋은 기능
27. 그래서 점진적 적용
WAS inst.
Service
UI
Guava
검색 API
Service
Guava
회원 API
Service
Guava
메시징 API
Service
Guava
채팅 API
Service
Guava
Reverse
Proxy
ACL
WAS inst.
Service
UI
Guava
안된다더니 했네!!
feat. 사장님
29. Reverse Proxy(HA Proxy) 적용 – ACL
frontend api-server-http
bind *:80
log global
option httplog
option http-keep-alive
acl impl_done url_beg /search /member
use_backend micro_group if impl_done
default_backend legacy_group
backend legacy_group
server legacy_01 127.0.0.1:9081 check inter 5000 maxconn 10000
…
backend micro_group
server micro_api_01 127.0.0.1:8081 check inter 5000 maxconn 10000
…
ACL
레거시
마이크로 서비스(구현 완료)
30. Proxy 설정
WAS inst.
Service
UI
Guava
검색 API
Service
Guava
회원 API
Service
Guava
메시징 API
Service
Guava
채팅 API
Service
Guava
Reverse
Proxy
ACL
WAS inst.
Service
UI
Guava
Legacy
Micro
Service
32. Issue 발생
고객센터 불만
영상의 제목을 바꿨는데 모바일에서는 안 바뀌네요!
영상의 조회수가 늘었다가 줄었다가 해요!
새로 올린 동영상이 보였다 안보였다 해요!
서비스가 좋아지게 바꾼거라며!! 이럴꺼면 왜 바꿨냐?
33. WAS inst.
Service
UI
Guava
원인
MySQL
WAS inst.
Service
UI
Guava
WAS inst.
Service
UI
Guava
1분전
캐시 데이터
5분전
캐시 데이터
9분전
캐시 데이터
LoadingCache<String, JsonObject> cache = CacheBuilder.newBuilder()
.maximumSize(100)
.expireAfterWrite(10, TimeUnit.MINUTES)
LoadingCache<String, JsonObject> cache = CacheBuilder.newBuilder()
.maximumSize(100)
.expireAfterWrite(30, TimeUnit.SECONDS) ????
34. 아키텍처 변화 V2.0
Private cache에서 Shared cache로
MySQL
Redis
WAS inst.
Service
UI
Jedis
WAS inst.
Service
UI
Jedis
WAS inst.
Service
UI
Jedis
Load balancer
35. Shared cache – Jedis + Redis 적용
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxTotal(30);
config.setBlockWhenExhausted(true);
JedisPool pool = new JedisPool(config, “192.168.0.101 ...
...
Jedis jedis = pool.getResource();
KeyManager key = new KeyManager...
String mainPageVideoList = jedis.get(key.get(“mainPage”));
JsonParser jsonParser = new JsonParser();
JsonObject mainPageVideoListJson = (JsonObject)jsonParser.parse(mainPageVideoList
);
String to JsonObject
Connection Pool
키 생성 로직
37. 개별 서비스에서 생성한 캐시 키가 충돌하면 장애
Issue
캐시에 저장된 데이터의 키 충돌
Redis
WAS inst.
like 검색
Jedis
WAS inst.
전문검색
Jedis
search:먹방
{hit:{}…}
search:먹방
<html>…
38. 공통 라이브러리 배포 – Jedis + 키 생성
public class CacheManager {
private void initializePool() {
…
public class CacheKeyMaker implements KeyMaker {
public String makeKey(String serviceName, String key) {
return serviceName + “:” + key;
…
String serviceName = “fullTextSearch”;
String searchKeyword = “먹방”;
CacheManager cacheMnager = CacheManager.getInstance();
JsonObject mainPageVideoListJson = cacheMnager.get(serviceName, searchKeyword);
키 생성 규칙
39. 아키텍처 변화 V2.1
Cache-lib.jar 배포
MySQL
Redis
WAS inst.
Service
UI
Cache-lib
WAS inst.
Service
UI
Cache-lib
WAS inst.
Service
UI
Cache-lib, Jedis
Load balancer
44. MS
아키텍처 변화 V2.5
MySQL
M
WAS inst.
Service
UI
Cache-lib, Jedis
WAS inst.
Service
UI
Cache-lib, Jedis
WAS inst.
Service
UI
Cache-lib, Jedis
M M
S S
Redis Cluster
Load balancer
47. 우리도 캐시 쓰게 해주세요
feat. Python
Redis Cluster
NER API
NER
Python,
redis-py
키 생성 규칙 WAS inst.
Service
UI
Java,
Jedis
키 생성 규칙
48. 캐시 서버좀 공유합시다
feat. 김책임
Redis Cluster
NER API
NER
Python,
redis-py
키 생성 규칙
WAS inst.
Service
UI
Cache-lib,
Jedis
검색 API
게시글검색
Node.js,
ioredis
키 생성 규칙
Daemon
영상인덱싱
PHP,
Predis
키 생성 규칙
WAS inst.
모바일
PHP,
Phpredis
키 생성 규칙
Batch
랭킹
Java,
Lettuce
키 생성 규칙
API 1
Service 1
Python,
redis-py
키 생성 규칙
API 2
Service 2
Python,
redis-py
키 생성 규칙
API 3
Service 3
Python,
redis-py
키 생성 규칙
API 4
Service 4
Python,
redis-py
키 생성 규칙
헐!
49. 할일과 고민
캐시 클러스터를 모든 개발팀에 오픈하자
• 굿 아이디어!
오픈 전 고민들
• 사람은 누구나 실수를(flushdb, config set)
• 각 언어에 대한 라이브러리 검토 및 버전관리
• maxclients 1024??
• 키 생성 규칙이 변경되면?
• 개발자의 영원한 숙제 버전 관리!!
50. 라이브러리 버전
feat. 김책임
Redis Cluster
NER API
NER
Python,
redis-py
키 생성 규칙
WAS inst.
Service
UI
Cache-lib,
Jedis 2.8
검색 API
게시글검색
Node.js,
ioredis
키 생성 규칙
Daemon
영상인덱싱
PHP,
Predis
키 생성 규칙
Batch
랭킹
Cache-lib,
Lettuce
키 생성 규칙
51. HTTP 기반 Cache API
S
M
WAS inst.
Service
UI
HttpClient
M M
S S
Redis Cluster
Cache API
Service
Cache-lib, Jedis
52. 장단점
장점
• 클라이언트 라이브러리
• 접근 제어 / Command 제어
• 유연성
단점
• Web API 추가 리소스 필요
• 라이브러리 대비 성능저하(Throughput/Latency)
• 관리 포인트 증가
53. Webd.is? 직접 구현?
Webdis?
HTTP 기반 Cache API
S
M M M
S S
Redis Cluster
Custom API?
Service
Cache-lib, Jedis
curl -XPUT http://host/cache/set -d ‘hello world… '
54. HTTP 기반 Cache API 구조
Zookeeper
S
M M M
S S
Redis Cluster
Cache API
Armeria
Netty
Zookeper
Service
Lettuce
57. HA Proxy 적용 – 다중 인스턴스
frontend api-server-http
bind *:80
log global
option httplog
option http-keep-alive
default_backend cache_api
backend cache_api
option httpchk GET /path
option http-keep-alive
server cache_api-01 127.0.0.1:9081 check inter 5000 maxconn 10000
server cache_api-02 127.0.0.1:9082 check inter 5000 maxconn 10000
server cache_api-02 127.0.0.1:9083 check inter 5000 maxconn 10000
Cache API
서버01~03
66. 메시지 번호와 읽은 사용자의 사용자 번호 저장
메시지 읽음처리
두 가지 구현 방법 중 Line의 구현 방법
“msg:readcount:39929:21021”
39929
92943
30233
1355549
사용자 번호 메시지 번호
읽은 사용자 번호
Data(Hash)Key
68. 이벤트 이름과 사용자 번호에 데이터 저장
기간이 정해진 이벤트
ExpireAt or select <db번호> flushdb
“event:hotsummer:21021”
viewBroad 3
viewVod 7
liveUp 2
addFavorite 1
Data(Hash)Key
사용자 번호
이벤트명 횟수