root@97bd8fbf6f8d:/usr#redis-benchmark======PING_INLINE======100000requestscompletedin2.79seconds# 만 개의 명령을 처리하는 데 걸린 시간 2.79초50parallelclients# 50개의 클라이언트 동시 연결3bytespayload# 저장 데이터의 크기 3바이트keep alive:1# 클라이언트 연결 유지 상태 정보hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no0.00%<=0.4milliseconds0.08%<=0.5milliseconds2.13%<=0.6milliseconds10.04%<=0.7milliseconds25.00%<=0.8milliseconds43.93%<=0.9milliseconds63.18%<=1.0milliseconds78.15%<=1.1milliseconds87.81%<=1.2milliseconds93.52%<=1.3milliseconds96.47%<=1.4milliseconds98.01%<=1.5milliseconds98.73%<=1.6milliseconds99.11%<=1.7milliseconds99.33%<=1.8milliseconds99.45%<=1.9milliseconds99.54%<=2milliseconds99.92%<=3milliseconds99.98%<=4milliseconds100.00%<=4milliseconds35842.29requestspersecond# 초당 처리된 명령 수======PING_BULK======100000requestscompletedin2.71seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no54.86%<=1milliseconds99.78%<=2milliseconds99.98%<=3milliseconds100.00%<=3milliseconds36954.91requestspersecond======SET======100000requestscompletedin2.87seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no65.98%<=1milliseconds99.96%<=2milliseconds100.00%<=2milliseconds34867.50requestspersecond======GET======100000requestscompletedin2.83seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no66.07%<=1milliseconds99.98%<=2milliseconds100.00%<=2milliseconds35360.68requestspersecond======INCR======100000requestscompletedin2.82seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no66.94%<=1milliseconds99.99%<=2milliseconds100.00%<=2milliseconds35486.16requestspersecond======LPUSH======100000requestscompletedin2.87seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no64.74%<=1milliseconds99.95%<=2milliseconds99.99%<=3milliseconds100.00%<=3milliseconds34806.82requestspersecond======RPUSH======100000requestscompletedin2.87seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no64.67%<=1milliseconds99.87%<=2milliseconds99.99%<=3milliseconds100.00%<=3milliseconds34867.50requestspersecond======LPOP======100000requestscompletedin2.89seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no65.48%<=1milliseconds99.92%<=2milliseconds100.00%<=3milliseconds100.00%<=3milliseconds34602.07requestspersecond======RPOP======100000requestscompletedin2.91seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no64.82%<=1milliseconds99.96%<=2milliseconds100.00%<=2milliseconds34399.72requestspersecond======SADD======100000requestscompletedin2.94seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no0.00%<=-33milliseconds0.03%<=-32milliseconds0.04%<=0milliseconds58.66%<=1milliseconds99.55%<=2milliseconds99.98%<=3milliseconds100.00%<=3milliseconds34013.61requestspersecond======HSET======100000requestscompletedin2.96seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no61.09%<=1milliseconds99.89%<=2milliseconds100.00%<=2milliseconds33726.81requestspersecond======SPOP======100000requestscompletedin2.74seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no64.93%<=1milliseconds99.94%<=2milliseconds99.99%<=3milliseconds100.00%<=3milliseconds36496.35requestspersecond======LPUSH(neededtobenchmarkLRANGE)======100000requestscompletedin2.88seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no63.70%<=1milliseconds99.95%<=2milliseconds100.00%<=2milliseconds34698.12requestspersecond======LRANGE_100(first100elements)======100000requestscompletedin3.45seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no47.14%<=1milliseconds99.90%<=2milliseconds100.00%<=2milliseconds28993.91requestspersecond======LRANGE_300(first300elements)======100000requestscompletedin5.92seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no0.01%<=1milliseconds97.25%<=2milliseconds99.96%<=3milliseconds100.00%<=3milliseconds16889.04requestspersecond======LRANGE_500(first450elements)======100000requestscompletedin7.05seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no0.00%<=1milliseconds84.77%<=2milliseconds99.68%<=3milliseconds99.96%<=4milliseconds100.00%<=4milliseconds14176.35requestspersecond======LRANGE_600(first600elements)======100000requestscompletedin8.47seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no0.00%<=-32milliseconds0.00%<=-31milliseconds0.02%<=-30milliseconds0.03%<=0milliseconds0.04%<=1milliseconds20.78%<=2milliseconds97.89%<=3milliseconds99.84%<=4milliseconds99.94%<=5milliseconds99.99%<=6milliseconds100.00%<=6milliseconds11800.80requestspersecond======MSET(10keys)======100000requestscompletedin3.03seconds50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no49.40%<=1milliseconds99.90%<=2milliseconds100.00%<=2milliseconds32959.79requestspersecond
성능 측정 세부 설정
50 바이트와 1,024바이트의 데이터를 문자열, 리스트, set 데이터형으로 저장하고 읽어내는 데 걸리는 시간 측정 결과를 진행률을 제외하고 출력
데이터의 크기가 20배 정도 늘었으나 읽기와 쓰기 횟수는 10% 정도 차이 밖에 나지 않는다.
백만 개의 키를 문자열 데이터로 추가하는 테스트 명령
root@97bd8fbf6f8d:/usr#redis-benchmark-tset-n1000000-r1000000======SET======1000000requestscompletedin29.68seconds# 백만 개의 데이터를 입력하는 데 약 29초 소요50parallelclients3bytespayloadkeep alive:1hostconfiguration"save":3600 13001006010000hostconfiguration"appendonly":nomulti-thread:no0.00%<=-32.8milliseconds0.00%<=-32.7milliseconds0.00%<=-32.6milliseconds0.00%<=-32.5milliseconds0.00%<=-32.4milliseconds0.00%<=-32.3milliseconds0.00%<=-32.2milliseconds0.00%<=-32.0milliseconds0.00%<=0.4milliseconds0.01%<=0.5milliseconds0.52%<=0.6milliseconds4.87%<=0.7milliseconds18.67%<=0.8milliseconds39.65%<=0.9milliseconds60.82%<=1.0milliseconds77.10%<=1.1milliseconds87.37%<=1.2milliseconds93.07%<=1.3milliseconds96.13%<=1.4milliseconds97.75%<=1.5milliseconds98.59%<=1.6milliseconds99.03%<=1.7milliseconds99.28%<=1.8milliseconds99.43%<=1.9milliseconds99.51%<=2milliseconds99.87%<=3milliseconds99.99%<=4milliseconds100.00%<=5milliseconds100.00%<=5milliseconds33697.26requestspersecond# 초당 3만 3천개 이상의 데이터를 저장
JSON Web Token의 약자로 전자서명 된 URL-safe (URL로 이용할 수 있는 문자로만 구성된)의 JSON
전자서명(Signature)은 JSON의 변조를 체크할 수 있게 되어 있다.
속성 정보(Claims)를 JSON 데이터 구조로 표현한 토큰으로 RFC 7519 표준
서버와 클라이언트 간 정보를 주고 받을 때 HttpRequest header에 JSON 토큰을 넣은 후 서버는 별도의 인증 과정없이 헤더에 포함되어 있는 JWT 정보를 통해 인증한다. 이때 사용되는 JSON 데이터는 URL-safe 하도록 URL에 포함할 수 있는 문자만으로 만든다.
HMAC 알고리즘을 사용하여 비밀키 또는 RSA를 이용한 Public Key / Private Key 쌍으로 서명할 수 있다.
Base64 인코딩의 경우 "+", "/", "="이 포함되지만 JWT는 URI에서 파라미터로 사용할 수 있도록 URL-Safe 한 Base64url 인코딩을 사용한다.
2. JWT 구조
Claims를 userId, username으로 하고, JWA 알고리즘 SHA-256으로 암호화
서버는 클라이언트에서 요청을 받을 때 마다, 해당 토큰이 유효하고 인증되었는지 검증을 하고, 사용자가 요청한 작업에 권한이 있는지 확인하여 작업을 처리
서버에서는 사용자에 대한 세션을 유지할 필요가 없다. 즉, 사용자가 로그인되어 있는지 여부를 신경 쓸 필요가 없고, 사용자가 요청을 했을 때 토큰만 확인하면 되므로 세션 관리가 필요 없어서 서버 자원과 비용을 절감할 수 있다.
정보 교류
JWT는 두 개체 사이에서 안정정있게 정보를 교환하기에 좋은 방법
정보가 서명이 되어있기 때문에 정보를 보낸이가 바뀌진 않았는지, 또 정보가 도중에 조작되지 않았는지 검증을 할 수 있다.
* UI Layer, REST API 서버를 따로 두는 경우 JWT를 사용
* 하나의 End Point가 아닌 Mobile / Web 등의 multiple EndPoint 환경이라면 통합적인 인증 / 인가 환경을 제공하기 위해 JWT를 사용
* Third Party에게 public하게 open 한 REST EndPoing가 존재하는 경우 해당 Third Party의 인증 인가를 관리하기 위해 JWT 사용