2016-12-08 1 views
0

나는 PHP (간단한 GET 서비스로 작성된)의 속도를 높이기 위해 RDBMS 접근에서 Redis로 옮기기로 결정했다. 나는 테이블을 많이 가지고 내 관계형 데이터베이스의 필드의 많은이 작업을 수행하는 방법에 대한 연구와 고려의 주를 지출 나는 레디 스 이러한 구조를 만든 : {nameOfTable:clientID:itemID}을 등 예를Redis와 엄청난 양의 키

SET clientSubjects:1:1 bigJSONStringHere1 
SET clientSubjects:1:2 bigJSONStringHere2 
SET clientSubjects:1:3 bigJSONStringHere3 

SET clientSubjects:2:1 bigJSONStringHere4 
SET clientSubjects:2:2 bigJSONStringHere5 
SET clientSubjects:2:3 bigJSONStringHere6 

에 대한

약 2,000 만 명의 고객이 있으며, 각각 약 4-10 개의 과목이 있으므로 약 1 억 5 천만 개의 키가 있습니다. 모든 클라이언트의 주제를 찾으려면 특정 클라이언트로부터 요청을받을 때마다 SCAN을 사용해야합니다. 나는 문제를 직면하는 나는 명령을, 레디 스에

scan 0 match clientSubjects:{someID}:* count 100 반환 모든 클라이언트를로드 완료되면 :

1) "7241728" 
2) (empty list or set) 

그리고를 ... 내 결정은 레디 스 스토리지에 키의 총 수를 찾아로 사용했다 COUNT 인수

local keyspace = redis.call("info", "keyspace") 
local keysCount = keyspace:match("keys=(%d+),") 
local result = redis.call("SCAN", 0, "match", "clientSubjects:" .. ARGV[1] .. ":*", "count", keysCount) --ARGV means I pass clientID to lua script 

그래서 모두가 그것을 실행하기 위해 약 3 초를 필요로하는 것을 제외하고 잘 작동 : 같은

이 보인다! 하지만 몇 밀리 초가 필요합니다 ... 어떻게해야합니까?

+0

친애하는 Dasha, 질문은 여러 가지 이유로 닫힐 수 있지만 호기심 때문에, 왜 redis가됩니까? 예 : 몽고는이 유스 케이스에 아주 잘 맞아야한다. –

+0

@AlexBlex 메모리에 데이터를 저장하는 캐시 시스템이 필요하기 때문에 – Daria

+1

충분합니다. 가장 확실한 충고는 메모리에 맞는지 확인하고 느린 로그에보고 된 내용을 확인하고 정확한 문제를 해결하는 방법을 묻는 것입니다. 일반적으로 세트를 사용하여 클라이언트별로 주제를 그룹화하는 것이 좋습니다. –

답변

1

2,000 만개의 레코드를 사용하면 모든 데이터 구조와이를 쿼리하는 다양한 방법을 저장하기 위해 엄청난 양의 메모리가 필요합니다.

예를 들어 모든 고객의 주체를 찾으려면 주제 또는 ID 값이 clientSubjects:{clientID} 인 목록 또는 목록이 있어야합니다.

다른 쿼리에 맞게 다른 데이터 구조를 사용해야하며 SCAN과 같은 것을 사용하지 않는 것이 좋습니다. 최적이 아니기 때문입니다.

내 생각에 인덱스가 잘 배치 된 관계형 데이터베이스가 더 적합 할 것이므로 인덱스가 일반적으로 메모리에 저장되어 디스크로 다시 떨어질 수 있으므로 많은 시간과 비용을 절약 할 수 있습니다.

Redis는 모든 데이터를 메모리에 저장해야하므로 다른 쿼리 유형을 해결하기 위해 더 많은 데이터 구조를 추가 할 경우 비용이 많이 듭니다.

관련 문제