- 전체
- Sample DB
- database modeling
- [표준 SQL] Standard SQL
- G-SQL
- 10-Min
- ORACLE
- MS SQLserver
- MySQL
- SQLite
- postgreSQL
- 데이터아키텍처전문가 - 국가공인자격
- 데이터 분석 전문가 [ADP]
- [국가공인] SQL 개발자/전문가
- NoSQL
- hadoop
- hadoop eco system
- big data (빅데이터)
- stat(통계) R 언어
- XML DB & XQuery
- spark
- DataBase Tool
- 데이터분석 & 데이터사이언스
- Engineer Quality Management
- [기계학습] machine learning
- 데이터 수집 및 전처리
- 국가기술자격 빅데이터분석기사
- 암호화폐 (비트코인, cryptocurrency, bitcoin)
NoSQL Redis(레디스)를 어떻게 활용할 수 있을까?
2017.05.30 22:14
Redis(레디스)를 어떻게 활용할 수 있을까?
Redis는 다른 데이터베이스솔루션들과는 다른 방식입니다.
Redis는 메인저장소로는 메모리를 사용하며, 영구적인 저장을 위해서는 디스크를 사용하는대 이 런 데이터 모델은 다소 독특하며, 단일스레드로 구성되어져 있다는 것 이외에도 많은 다른 점들이 존재합니다. 개인적으로 가장 큰 다른 점으로는 Redis의 장점을 취하기 위해서 여러분들의 제품환경에서 Redis를 위한 전환작업을 해줄 필요가 없다는 것입니다. 전에는 불가능했거나 오래된 문제를 해결하기 위해서 Redis를 그냥 추가해 사용하면 됩니다.
Redis로 전환하는 것은 당연히 선택사항입니다. 많은 사용자들이 자신들이 필요한 기능들을 필요로 한다거나 쓰기속도를 향상시키기 위해서 또는 대기시간(지연시간)의 줄이기 위해서 Redis를 메인데이터베이스로 사용하고 있습니다. 하지만 이미 구동되고 있는 어플리케이션에서 전환작업을 한다는 것은 여러분의 예상으로는 아주 큰 작업으로 느껴지실 겁니다.
또한 어떤 종류의 어플리케이션에서는 Redis를 사용하는 것이 적합하지 않을 수 있습니다.
예를들어 Redis의 데이터셋은 메모리보다 클 수 없으며, 만약에 여러분이 BigData를 다루는 어플리케이션이거나 주로 읽기작업을 한다고 하면 Redis는 옳은 선택이 아닐 것입니다.
하지만 제가 Redis를 좋아하는 한가지 이유는 기존의 데이터베이스로는 불가능했거나 너무 느렸던 문제들을 해결하기 위해서 단지 여러분들의 시스템에 추가해주기만 하면 된다는 것이죠. 이 방식은 확장성에 대한 신뢰를 가지고 시작할 수 있으며, 단지 여러분들의 어플리케이션에 새로운 기능을 추가하거나 최적화 하기 위해 사용을 시작할 수 있습니다.
이 블로그 게시물에서는 어떻게 사람들이 Redis를 이미 존재하는 환경에 추가하였는지에 대한 몇 가지 사례를 설명할 것입니다. 저는 사이트 이름이나 정확한 환경설정부분에 대해서는 구체적으로 설명하지 않고, 기본 데이터베이스가 없이 Redis로 해결할 수 있는 문제들을 보여주는 것에 초점을 맞추겠습니다.
가장 최근의 리스트를 보여주기
제가 보여드리는 이 쿼리가 너무 느려서 그런대 고쳐주실 수 있겠습니까?
SELECT * FROM foo WHERE ... ORDER BY time DESC LIMIT 10
보통 웹어플리케이션에서 유저가 추가한 최근 항목을 나열한다거나 그 밖의 최신의 것을 보여주는 경우가 많습니다. 그러나 종종 이 문제는 확장성 문제를 가지고 있습니다.
이런 유사한 문제들은 제가 보여드리는 Redis 패턴을 사용하여 해결할 수 있습니다. 우리는 우리의 고객들로부터 등록된 최신 20개의 코멘트를 보여주기를 원합니다. 또한 최근 코멘트박스 근처에 “Show all” 이라는 링크페이지를 제공하여 20개보다 더 많이 볼 수 있게 할 것이고 pagination 을 통해 시간별 코멘트를 확인할 수 있게 제공할 것입니다.
우리의 데이터베이스 안에 모든 코멘트들이 정렬되어 있고, 그것들은 유일한 ID(자동증가하는) 필드를 가지고 있습니다. 이제 Redis패턴을 사용하면 홈페이지박스와 페이지네이션이 가능한 시간별 코멘트페이지를 간단하게 구현해낼 수 있습니다.
- 매시간 새로운 코멘트는 등록되어지며, 우리는 Redis list 안에 ID를 추가합니다.
: LPUSH latest.comments <ID> - 그리고 주어진 길이만큼 리스트를 잘라내고, Redis는 최근 5000개의 아이템을 저장할 겁니다.
: LTRIM latest.comments 0 5000 - 매시간 최근 코멘트를 가져와야 하는대, 아마 그 함수는 이런식일 겁니다.(가상의코드)
- FUNCTION get_latest_comments(start,num_items):
- id_list = redis.lrange("latest.comments",start,start+num_items-1)
- IF id_list.length < num_items
- id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...")
- END
- RETURN id_list
- END
보시는 것처럼 우리는 간단히 이 문제를 해결했습니다.
Redis에서 최근데이터의 IDs를 지속적으로 업데이트 하고 가져올 수 있습니다.
그러나 우리는 IDs의 저장량을 5000개로 제한설정을 해놨고, Redis시스템이 막 구동되었다면 이러한 IDs가 하나도 존재하지 않을 수도 있겠죠. 그래서 우리의 새로운 Function(함수)에서는 항상 Redis에 먼저 최근 코멘트를 가져오라고 하고 만약에 이 범위를 초과할 때는(*역자*예: 5001개의 코멘트를 달라고했는대 Redis가 5000개밖에 주지않았을 때) 데이터베이스에 접근하여 데이터를 가져옵니다.
우리는 캐시를 “refresh” 할 필요가 없습니다. SQL-DB(혹은 디스크)에 접근하는 일은 고객이 표준범위 이상의(여기서는 5000개를 넘는) 코멘트를 보려고 할 때만 접근하면 됩니다.
여기서 볼 수 있듯이 Redis로 새로운 것을 추가하는 것이 간단하게 이루어 집니다.. 이건 전통적인 cache로는 할 수 없는 작업입니다. 캐시 refresh가 없고, Redis 인스턴스의 정보는 항상 일관성을 유지하고 있죠.
역자*전통적인 데이터베이스를 사용한다면 5000개가 넘었을 때 오래된 데이터를 삭제하고 새로운 데이터를 추가해주는 로직을 따로 작성하지 않아도 된다는 이야기인듯. (관리포인트가 줄어듬)
삭제와 필터링
LREM을 사용하여 코멘트를 삭제하는 것이 가능합니다.
(*역자:이상한 삭제방식을 알려주는대 무슨 말인지 잘 이해가 안됨. 생략하라는거 같은대…)
또한 각각 다른 필터값으로 각각의 리스트를 출력하고 싶을 때가 많을 겁니다. 이 필터값이 많지 않을 경우(카테고리처럼) 단순하게 각각의 필터값에 대한 목록들을 Redis에 저장하면 됩니다.
목록당 5000개로 제한시키더라도 Redis는 아주 작은 메모리로도 수백만개의 데이터를 저장할 수 있어서 상관없습니다. 결국 이건 여러분들의 창의력으로 해결하면 되겠죠!?
순위표와 관련된 문제들
in-DB 방식을 사용하여 실시간으로 업데이트 되는 항목들을 Score 별로 정렬된 리스트를 뽑는다고 하는 건 매우 어려운 일입니다. (성능을 고려할 떄)
고전적인 예로는 온라인게임의 순위표가 되겠네요. 하지만 여러가지의 방식으로 보여질 수 있습니다. 온라인 게임에서는 여러 사용자가 매우 높은 점수를 받게 됩니다. 보통 이런 순위표를 보여주길 원할 겁니다.
- 최고점수 상위 100위의 순위표
- 현재 유저의 세계랭킹
이러한 동작은 Redis를 사용하면 아주 하찮은 일이죠. 분당 수백만 유저의 의해서 수백만개의 순위가 교체된다고 할지라도 말입니다.
이 문장은 한 유저에게서 새로운 점수를 받아 저장합니다.
ZADD leaderboard <score> <username>
Note: 만약 여러분들이 username이 아닌 userID를 원한다면 그렇게 디자인 하세요!
점수에 의한 상위 100명의 유저를 얻기 위해서는 ZREVRANGE leaderboard 0 99.
마찬가지로 현재 유저의 세계순위를 알아내는 건 ZRANK leaderboard <username>.
아주 쉽죠? 추가적으로 더 가능합니다. 해당 유저의 근처의 유저를 함께 보여주는 순위표를 만드는 것 또한 아주 간단하게 할 수 있겠죠?
사용자 투표와 시간에 의한 정렬
위의 순위표의 예제에서 주목할 만한 점은 Reddit, Hacker News와 같은 사이트들이 적절한 순위를 만들어 보여주기 위해서 특정 공식을 이런식으로 사용할 것입니다.
score = points / time^alpha
따라서 뉴스의 유저의 투표수에 비례하여 Score점수가 증가하겠지만, 시간이 지나면 뉴스는 순위 밑으로 떨어질 것입니다. 음, 실제 알고리즘은 여러분들에게 달려있습니다.
예를들어 1000개의 좋은 뉴스들로만 여러분들의 홈페이지에 위치시키고자 한다면 간단하게 구현 가능합니다.
- 매 시간 등록되는 새로운 뉴스들의 ID들을 LPUSH+LTRIM을 사용하여 목록에 넣습니다.
- 그리고 계속적으로 이 최종점수를 계산한다음 ZADD를 사용하여 리스트에 추가하면 됩니다. 이렇게만 해주면 오래된 데이터는 자동으로 리스트에서 삭제될 겁니다.
여기서 중요한 점은 뉴스사이트의 구독자가 점점 늘어난다고 해서 우리 작업자를 더 추가하지 않아도 된다는 것입니다.
아이템에 대한 만료시간 구현
정렬된 리스트를 뿌려주는 또 다른 방법은 시간에 의한 색인일 것입니다. 우리는 단지 UNIX 시간에 의해서 Score를 줄 수 있습니다. 이 방식은 시간에 의해서 색인할 때 사용되어지지만 주목해야 할 것은 바로 우리의 데이터베이스에서 시간이 초과되었을 때 그 항목을 삭제해야 한다는 것입니다.
- 매시간마다 새로운 아이템이 우리의 데이터베이스에 추가됩니다..그리고 이 떄 Score는 Current_time + time_to_live 로 계산되어 정렬됩니다.
- 그럼 백단에서 ZRANGE … WITHSCORES 같은 것을 사용하여 정렬하고 최근 10개의 데이터를 추출할 수 있습니다. 또한 만료시간이 초과한 항목은 삭제됩니다.
Counting Stuff
Redis는 카운팅하기에 아주 적합합니다. INCRBY 와 그 밖의 유사한 명령을 사용하면 말이죠.
여러분들은 어떤 통계나 새로운 유저의 정보를 보여주기 위해서 얼마나 많이 데이터베이스에 접근하고 계십니까? 그러나 이런 쓰기 집약적 작업들이기 때문에 최대한 피해야 합니다. 저 같은 경우는 이런 경우가 참 많았습니다.
음, 좋아요 그렇다면 Redis를 사용하고 신경을 끄세요! 여러분들이 얻고자 하는 Count의 값을 쉽게 얻을 수 있고 원한다면 GETSET을 이용하여 초기화 시킬 수 도 있습니다. 또한 만료시간을 설정할 수도 있습니다.
예를 들어
INCR user:<id>
EXPIRE user:<id> 60
여러분들은 최근 60초안에 얼마나 많이 페이지를 보았는지에 대한 숫자를 가져올 수 있습니다.
*역자* 글쓴이는 이러한 숫자가 20에 도달하면 배너나 알림 같은 것을 보여줄 수 있다고 말한다.
주어진 시간동안의 고유한 N 항목
여기 또 다른 흥미로운 통계에 대한 예가 있습니다. Redis를 사용하면 아주 사소하게 처리할 수 있지만 다른 데이터베이스로는 아주 어려울 것입니다. 이것은 주어진 시간 내에 어떤 자원에 대해서 특정한 유저가 얼마나 많이 방문하였는가에 대한 통계입니다. 예를 들면 저는 온라인 신문에 들어있는 어떤 기사를 접근하는 특정한 유저나 IP주소의 숫자를 알고 싶을 것입니다.
밑에 예제를 사용하여 저는 실시간의 페이지뷰를 얻을 수 있습니다.
SADD page:day1:<page_id> <user_id>
물론 day1 대신에 unixtime, like:time()-(time()%3600*24) 같이 여러분들이 원하는 것으로 사용할 수 있습니다.
몇 명이 접근했는지 알고 싶으세요? 그럼 SCARD page:day1:<page_id> 로 해결할 수 있습니다.
어떤 특정 유저가 해당 페이지에 접근했었는지에 대한 여부를 테스트하길 원하시나요?
SISMEMBER page:day1:<page_id> <user_id>로 해결하면 되겠네요.
*역자* 원문에는 SISMEMBER page:day1:<page_id> 로 되어있는대, 직접 테스트해보니SISMEMBER의 요소로 원하는 user_id값도 넣어주어야 하는 것이 맞다. 특정 유저를 알고싶은거니까 사실 넣어주는게 상식이긴 하다.
실시간 분석, 통계, 스팸 제거.
우리는 단지 몇가지 예제를 공부했지만, Redis 명령어들을 공부하고 원하는 방식으로 데이터 구조를 잘 결합한다면 조금의 노력만으로도 막대한 숫자를 다루는 실시간 분석이나, 스팸퇴치시스템, 또는 서비스의 품질이 사용자에 새로운 정보에 대한 감사함을 전할 수 있습니다.
*역자 마지막줄은 무슨 의미인지 잘모르겠습니다.
원문에는 the quality of service you can provide to user thanks to the new information. 표기되었음.
Pub/Sub
여러분들은 Redis가 막강한 성능의 Pub/Sub 구현을 포함하고 있다는 사실을 아십니까?
Pub/Sub은 사용하기 아주 간단하고, 안정적이며 빠르게 동작합니다. 또한 패턴일치, 채널에 가입/탈퇴 하는 기능이 제공됩니다. 더 많은 정보를 원한다면
Queues
여러분들은 아마도 list push, list pop 같은 Redis 명령들이 Queues에 적합하게 만들어졌는지 알고 있을 것입니다.
하지만 이보다 더 나아가서 Redis는 목록이 비어있다면 list pop의 변형을 막을 것을 할 수 있습니다. Link : http://redis.io/commands/blpop
*역자* BLPOP이 차단된거 같네요~? 무슨 비어있으면 락을 걸고 기다리는 명령같은대…
RPOPLPUSH 요게 좀 흥미로워 보입니다. 오른쪽부터 빼서 왼쪽부터 넣는 ~
Link : http://redis.io/commands/rpoplpush
RPOPLPUSH 이용하면 순서는 그대로 유지하면서도 오래된 데이터를 먼저 꺼낼 수 있어요.
Caching
이 섹션만을 가지고 따로 블로그 포스팅을 할 수 있을 정도로 이 이야기는 좀 방대합니다.
그래서 간단히 언급만 하도록 하겠습니다. Redis는 memcached을 대체하기 위해서 사용될 수도 있습니다. 단순하게 업데이트방식으로 데이터를 저장하고 싶다면 말이죠.
매번 데이터를 갱신시킬 필요가 없습니다. 첫번째 섹션을 참조하세요.
*역자* LPUSH, LTRIM, LRANGE 를 사용하라는 말인거 같습니다.
Redis는 여러분들의 골치거리를 해결해줄 수 있답니다
Redis를 지금 바로 사용하면 여러분들의 고객을 조금 더 행복하게 만들 수 있을 것입니다.
여러분들의 시스템은 보다 덜 복잡해질 것이고, 사이트는 보다 더 반응적일 것이며, 무엇보다 현재 시스템을 교체 하지않고 바로 사용할 수 있다는 것입니다.
새로운 것을 도입하기 위해서 그냥 Redis를 사용하세요. 비싸지도않고, 어렵지도않습니다!
원문 제목 : How to take advantage of Redis just adding it to your stack
원문 링크 : http://antirez.com/post/take-advantage-of-redis-adding-it-to-your-stack.html
출처: http://iamyour.tistory.com/entry/내멋대로-번역Redis를-사용하여-해결할-수-있는-11가지-케이스 [백병아리 날다]
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
댓글 0
| 번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
|---|---|---|---|---|
| 공지 | 오라클 기본 샘플 데이터베이스 | 졸리운_곰 | 2014.01.02 | 86187 |
| 공지 | [SQL컨셉] 서적 "SQL컨셉"의 샘플 데이타 베이스 SAMPLE DATABASE of ORACLE | 가을의 곰을... | 2013.02.10 | 78669 |
| 공지 | [G_SQL] Sample Database | 가을의 곰을... | 2012.05.20 | 95404 |

