반응형
레디스의 처리 성능을 증대시키는 방법은?
- 결론) 복제와 샤딩을 통해서 처리 성능을 증대 시킬 수 있음.
- 그럼, 복제와 샤딩에 대해서 간단히 알아볼께요 ^^;
- 복제
- 클라이언트가 어느 노드에 접근하더라도 동일한 데이터를 읽을 수 있도록 데이터를 각 노드에 복제하여 저장하는 것을 말함.
- 샤딩
- 데이터를 특정 조건에 따라 나누어 저장하는 것.
- ex) 처리 데이터가 9개 있다고 가정할 때, 3대(A,B,C)의 노드를 사용하여 샤딩을 수행한다고 가정하면,
- 1~3 데이터는 A 노드
- 4~6 데이터는 B 노드
- 7~10 데이터는 C 노드
- 다시말해서, 각각의 데이터를 분할 저장하는 것을 샤딩이라고 함.
- ex) 처리 데이터가 9개 있다고 가정할 때, 3대(A,B,C)의 노드를 사용하여 샤딩을 수행한다고 가정하면,
- 샤드(Shard)란?
- 위의 예시처럼 3개의 노드를 사용하여 데이터를 분할 저장할 때, 각 노드를 샤드라고 부름.
- 만약, 각 샤드가 복제를 사용하여 여러개 의노드로 구성될때에도 하나의 샤드로 취급함.
- 데이터를 특정 조건에 따라 나누어 저장하는 것.
- 복제
- 그럼, 복제와 샤딩에 대해서 간단히 알아볼께요 ^^;
- 예시
- A란 서버가 1초에 처리할 수 있는 요청을 10이라 가정하면, 이때 서비스를 위해서 필요한 성능이 50이어야 한다면 어떤 방안이 있을까 한번 5초간 생각해보자?^^ ...마음속으로^_____^; (1초...2초...3초...4초.. 5초...stop!)
- 첫째, A 서버를 5배가 되는 성능 서버로 바꿈.
- 전통적인 관계형 데이터 베이스에서는 가능
- but, 레디스는 해당이 안됨.
- 단일 스레드로 동작하기 때문에 하나의 레디스 인스턴스가 사용할 수 있는 최대 CPU의 개수는 하나임.
- 즉, 처리 성능을 높이기 위해서 CPU를 추가하는 것은 성능 향상에 큰 도움이 되지 못함.
- 여기서 잠깐!, 레디스가 정말로 단일 스레드인지 확인해볼까요? ^^;
-
- 엥, 명령어를 보니깐 멀티 스레드네요 ? 무려 스레드가 4개...ㄷㄷ;;
- but, 결론부터말씀드리면, 실제적으로 데이터 처리에 사용하는 스레드는 한개입니다. 근거는 아래와 같습니다. ^^;
- Redis 스레드를 처리하는 파일은 bio.h 와 bio.c 이고 bio.h 를 보면 다음과 같은 코드를 볼 수 있습니다.
- 엥, 명령어를 보니깐 멀티 스레드네요 ? 무려 스레드가 4개...ㄷㄷ;;
-
- 첫째, A 서버를 5배가 되는 성능 서버로 바꿈.
- A란 서버가 1초에 처리할 수 있는 요청을 10이라 가정하면, 이때 서비스를 위해서 필요한 성능이 50이어야 한다면 어떤 방안이 있을까 한번 5초간 생각해보자?^^ ...마음속으로^_____^; (1초...2초...3초...4초.. 5초...stop!)
- BIO_NUM_OPS는 몇개의 잡큐(개별 하나당 스레드)를 만들 것인지에 대한 내용.
- BIO_CLOSE_FILE, BIO_AOF_FSYNC, BIO_LAZY_FREE를 보면, 뭔가 데이터 처리를 안할것 같이 보이네요... ^^; 실제로도 데이터 처리를 안합니다.
- bio.c 소스파일을 까봤더니, 크게 두 가지 함수가 존재하네요. ^^;
- bioCreateBackgroundJob 함수
- 작업 큐에 작업을 넣는 함수
- bioProcessBackgroundJobs 함수
- 실행하는 함수
- bioCreateBackgroundJob 함수
void *bioProcessBackgroundJobs(void *arg) {
struct bio_job *job;
unsigned long type = (unsigned long) arg;
sigset_t sigset;
/* Check that the type is within the right interval. */
if (type >= BIO_NUM_OPS) {
serverLog(LL_WARNING,
"Warning: bio thread started with wrong type %lu",type);
return NULL;
}
/* Make the thread killable at any time, so that bioKillThreads()
* can work reliably. */
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_mutex_lock(&bio_mutex[type]);
/* Block SIGALRM so we are sure that only the main thread will
* receive the watchdog signal. */
sigemptyset(&sigset);
sigaddset(&sigset, SIGALRM);
if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
serverLog(LL_WARNING,
"Warning: can't mask SIGALRM in bio.c thread: %s", strerror(errno));
while(1) {
listNode *ln;
/* The loop always starts with the lock hold. */
if (listLength(bio_jobs[type]) == 0) {
pthread_cond_wait(&bio_newjob_cond[type],&bio_mutex[type]);
continue;
}
/* Pop the job from the queue. */
ln = listFirst(bio_jobs[type]);
job = ln->value;
/* It is now possible to unlock the background system as we know have
* a stand alone job structure to process.*/
pthread_mutex_unlock(&bio_mutex[type]);
/* Process the job accordingly to its type. */
if (type == BIO_CLOSE_FILE) {
close((long)job->arg1);
} else if (type == BIO_AOF_FSYNC) {
redis_fsync((long)job->arg1);
} else if (type == BIO_LAZY_FREE) {
/* What we free changes depending on what arguments are set:
* arg1 -> free the object at pointer.
* arg2 & arg3 -> free two dictionaries (a Redis DB).
* only arg3 -> free the skiplist. */
if (job->arg1)
lazyfreeFreeObjectFromBioThread(job->arg1);
else if (job->arg2 && job->arg3)
lazyfreeFreeDatabaseFromBioThread(job->arg2,job->arg3);
else if (job->arg3)
lazyfreeFreeSlotsMapFromBioThread(job->arg3);
} else {
serverPanic("Wrong job type in bioProcessBackgroundJobs().");
}
zfree(job);
/* Lock again before reiterating the loop, if there are no longer
* jobs to process we'll block again in pthread_cond_wait(). */
pthread_mutex_lock(&bio_mutex[type]);
listDelNode(bio_jobs[type],ln);
bio_pending[type]--;
/* Unblock threads blocked on bioWaitStepOfType() if any. */
pthread_cond_broadcast(&bio_step_cond[type]);
}
}
- 결론, 즉 Redis에서 데이터를 처리하는 스레드는 싱글. 나머지 스레드들은 부가적인 것으로 볼 수 있습니다. 해당 스레드들에 대해서는 뒤에서 설명할 기회가 있으면 설명드리겠습니다. ^^; (직접 Redis 소스를 까보셔도 공부가 될것 같습니다. 저도 공부가 많이 되네요;;)
- 둘째, 동일한 사양의 시스템을 추가 하는 것. 5배가 되도록...
- NoSQL에서 사용하는 통상적인 스케일 아웃방식.
- Redis는 스케일 아웃을 처리하기 위한 방법으로 2가지 기법을 제공함.
- 읽기분산을 위한 복제(Replication)
- 쓰기분산을 위한 샤딩(Sharding)
결론
- 복제와 샤딩을 통해서 레디스의 처리 성능을 증대시킬 수 있음.
- 복제와 샤딩에 대해서 대략적인 용어 정리는 하고 있어야 할 것 같음.
- 추후에 기초적인 복제와 샤딩에 대해서 좀더 자세하게 알아보려고 함.
- 오늘의 명언 한마디
- 협상에서 갑과 을이란 없다. -최철규, 김한솔지음, "협상은 감정이다." 중에서...
- 상대적으로 지위가 높은 사람이 "갑"이 되고, 힘없는자가 "을"이되어 갑이 을에게 일방적인 요구를 하는 것이 갑을 관계다. 하지만, 협상은 한사람이 일방적으로 요구하고 다른 사람은 복종하기만 하는 자리가 아니다.
- 갑이 을과 "협상"을 하고 있다는 것은 갑도 무엇인가 을에게 원하는 것이 있다는 뜻이다.
- 그래서 아무리 "을"의 위치에 있는 사람이라도 갑이 필요로 하는 "가치"를 줄 수 있다면, 갑을 관계는 "파트너"관계로 바꿀 수 있다.
- 결국 "을"이 스스로를 어떤 위치에 두느냐가 중요하다.
- 협상에서 갑과 을이란 없다. -최철규, 김한솔지음, "협상은 감정이다." 중에서...
- 오늘의 영어 한마디
- 질문) That music is horrible!
- 끔찍한 음악이군!
- 응답) I agree.
- 맞아.
- 해설
- horrible은 "끔찍한" 단순히 무섭다는 것뿐만아니라, 극도의 혐오감을 나타낼 때 쓰는 표현.
- "소름끼치다" 라고 해석하는 경우가 많음.
- 그밖의 표현으로 awful, uncomfortable 등이 있음.
- horrible은 "끔찍한" 단순히 무섭다는 것뿐만아니라, 극도의 혐오감을 나타낼 때 쓰는 표현.
- 질문) That music is horrible!
728x90
300x250
'좋아하는 것_매직IT > 9.redis' 카테고리의 다른 글
26.Redis, 레디스 복제에 대해서 알아볼까요? 단일 복제는 ? ^^ (0) | 2021.01.15 |
---|---|
25.Redis, 레디스에서 말하는 복제에 대해서 전반적으로 정리해 보면? (0) | 2021.01.15 |
23.Redis, 레디스 공유객체에 대해서 알아볼께요. (0) | 2021.01.15 |
22.Redis, 레디스문자열 구현에 대해서 알아볼께요. (0) | 2021.01.14 |
21.Redis, 레디스 인코딩 중 셋 데이터 인코딩 에 대해서 알아볼께요.^^ (0) | 2021.01.14 |