일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- Docker
- java11
- eof
- puppeteer
- 자바
- ai
- LangChain
- HTTP
- Spring
- bufferdreader
- 스프링부트
- Apollo
- Mongoose
- redis
- Android
- MapReduce
- restapi
- mongodb
- graphql
- k8s
- mysql
- nodejs
- 조건문
- Scanner
- TCP
- 프로그래머스
- java
- 서버
- 백준알고리즘
- 스프링
- Today
- Total
자라나라 개발머리
[데이터 분산 처리] 맵리듀스(MapReduce) 간단 설명/ Mapper, Reducer 구현해보기 본문
맵리듀스(MapReduce)는 데이터 분산 처리에 활용되는 프로그래밍 모델로서, 대량의 데이터를 세분화해서 각 머신에서 로직을 처리하고, 다시 합쳐 효율적으로 데이터 처리를 할 수 있도록하는 모델입니다.
맵 리듀스는 총 4가지 기능으로 구성되어있습니다.
1. Mapper: 입력 데이터를 받아서 세분화, key-value 쌍으로 변환, 필요한 로직을 적용하여 중간 결과를 생성
2. Reducer: 중간 결과를 받아서 동일한 키를 기준으로 그룹화하고 데이터를 합침
3. Partitioners: 맵 단계에서 생성된 중간(key, value) 쌍을 리듀스 태스크로 분배
4. Combiners: 최적화 도구. output을 로컬에서 미리 집계하여 네트워크 상으로 전송되는 데이터 양을 줄이는 역할
전체적인 흐름은, Mapper가 InputData를 key-value로 세분화(Mapping)한 뒤 특정 로직을 처리합니다. 처리된 데이터를 Partitioner가 각 Reducer로 전달해주고, Reducer를 각 key와 value를 이용해 데이터를 합치고, Combiner를 거쳐 최적화 후 저장 시스템에 저장되거나 반환됩니다.
오늘은 javascript를 이용하여 MapReduce의 핵심이 되는 Mapper와 Reducer를 만들고, MapReduce 구조를 구현해보겠습니다.
예시로는, 맵리듀스 예시로 널리 이용되는 wordcount, 단어 숫자세는 기능을 구현해보겠습니다.
1. interface
// Mapper 인터페이스
class Mapper {
constructor() {}
map(input) {}
}
// Reducer 인터페이스
class Reducer {
constructor() {}
reduce(intermediateResults) {}
}
2. Mapper 구현
각 word를 key, 횟수를 value로 하는 map을 생성합니다.
class WordCountMapper extends Mapper {
map(input) {
const words = input.split(' '); //공백으로 나누기
const wordCountMap = new Map();
words.forEach(word => {
if (wordCountMap.has(word)) {
wordCountMap.set(word, wordCountMap.get(word) + 1); //word가 있으면 해당 value+1
} else {
wordCountMap.set(word, 1);
}
});
return Array.from(wordCountMap.entries());
}
}
3. Reducer 구현
mapper가 만든 데이터를 합치는 연산을 합니다.
class WordCountReducer extends Reducer {
reduce(intermediateResults) {
const reducerInput = intermediateResults.reduce((acc, current) => {
current.forEach(([word, count]) => {
if (acc.has(word)) {
acc.set(word, acc.get(word) + count);
} else {
acc.set(word, count);
}
});
return acc;
}, new Map());
return reducerInput;
}
}
4. MapReduce 구조 사용
// 입력 데이터 (문자열 배열)
const inputData = [
"apple banana apple",
"banana orange",
"orange apple banana"
];
const mapper = new WordCountMapper();
const reducer = new WordCountReducer();
// 맵 함수를 이용하여 중간 키-값 쌍 생성
const intermediateResults = inputData.map(input => mapper.map(input));
// 리듀스 함수를 이용하여 중간 결과 처리
const finalResult = reducer.reduce(intermediateResults);
// 결과 출력
finalResult.forEach((count, word) => {
console.log(`${word}: ${count}`);
});
여기서는, mapper와 reducer를 단일로 사용했습니다. 단일로 사용하면 mapReduce 구조가 데이터 처리에 별 도움이 되지 않습니다.
데이터가 많아질수록 mapper와 reducer의 갯수를 늘려서 사용하면 그제서야 mapReduce구조가 빛을 발합니다.
const mapper1 = new WordCountMapper();
const mapper2 = new WordCountMapper();
const mapper3 = new WordCountMapper();
const reducer1 = new WordCountReducer();
const reducer2 = new WordCountReducer();
// 입력 데이터를 각각의 매퍼에게 전달
const intermediateResults1 = inputData.slice(0, 1).map(input => mapper1.map(input));
const intermediateResults2 = inputData.slice(1, 2).map(input => mapper2.map(input));
const intermediateResults3 = inputData.slice(2, 3).map(input => mapper3.map(input));
// 리듀스 함수를 이용하여 중간 결과 처리
const finalResult1 = reducer1.reduce(intermediateResults1);
const finalResult2 = reducer2.reduce(intermediateResults2);
// 중간 결과를 다시 리듀서에게 전달하여 최종 결과 생성
const finalResult3 = reducer2.reduce(intermediateResults3);
// 중간 결과를 하나로 합치기
const mergedIntermediateResults = [...finalResult1, ...finalResult2, ...finalResult3];
// 최종 결과 생성
const finalResult = reducer2.reduce([mergedIntermediateResults]);
// 결과 출력
finalResult.forEach((count, word) => {
console.log(`${word}: ${count}`);
});
객체로서 3개를 만든 예시를 보였지만, 실제로는 서버가 될 것 입니다. 또한 각 처리를 비동기로 구성하여 코드를 짜야 진정한 MapReduce가 될 것 입니다!
이렇게 해서 간단하게 MapReduce 구조에 대해 알아보고, 간단 예제를 구현해보았습니다. 대용량 데이터 처리 시스템을 설계할 때, MapReduce 패턴을 이해하고 설계한다면 더욱 효율적인 시스템을 만들 수 있을 것 입니다. 읽어주셔서 감사합니다😀
'AI&Data' 카테고리의 다른 글
[LangChain/node.js] LangChain을 활용한 문서 요약(loadSummarizationChain) (0) | 2024.05.25 |
---|---|
[LangChain] LangChain 쌩기초 뜯어보기 (장점, LECL) (0) | 2024.05.12 |