안녕하세요! Combiner 공급업체로서 저는 최근 MapReduce 작업에서 Combiner가 스레드로부터 안전하려면 무엇이 필요한지에 대해 많은 질문을 받았습니다. 그래서 저는 이 블로그 게시물에서 여러분을 위해 그 내용을 분석해 볼까 생각했습니다.
먼저, MapReduce 작업의 맥락에서 Combiner가 무엇인지 빠르게 요약해 보겠습니다. Combiner는 매퍼의 출력이 리듀서로 전송되기 전에 로컬 집계를 수행하는 데 사용할 수 있는 선택적 함수입니다. 이를 통해 네트워크를 통해 전송되는 데이터의 양을 크게 줄여 전체 작업 실행 속도를 높일 수 있습니다.
이제 가장 큰 질문은 Combiner가 스레드로부터 안전하기 위한 요구 사항은 무엇입니까?
입력과 출력의 불변성
스레드 안전 결합기의 기본 요구 사항 중 하나는 입력 및 출력의 불변성입니다. 여러 스레드가 동시에 Combiner에 액세스할 때 우리는 이들 중 어느 것도 다른 스레드에 영향을 미칠 수 있는 방식으로 데이터를 수정하는 것을 원하지 않습니다.
예를 들어 Combiner에 대한 입력 데이터가 변경 가능한 경우 한 스레드가 값을 읽거나 처리하려고 시도하는 동안 다른 스레드가 값을 변경할 수 있습니다. 이로 인해 일관성 없는 결과가 발생할 수 있습니다. 마찬가지로 Combiner의 출력도 변경할 수 없어야 합니다. 다른 스레드에서 여전히 사용 중인 Combiner의 출력을 MapReduce 프레임워크의 다른 부분이 수정하기 시작하면 모든 종류의 문제가 발생할 수 있습니다.
단어 수 계산 MapReduce 작업을 수행하고 있다고 가정해 보겠습니다. 매퍼는 키가 단어이고 값이 개수인 키-값 쌍을 출력합니다. Combiner는 각 단어에 대해 이러한 개수를 집계합니다. 키-값 쌍이 변경 가능한 경우 다른 스레드가 해당 단어의 총 개수를 계산하려고 시도하는 동안 스레드가 개수 값을 변경할 수 있습니다. 이로 인해 최종 개수가 잘못될 수 있습니다.
원자적 연산
원자적 연산은 스레드 안전 결합기의 또 다른 중요한 측면입니다. 원자적 작업은 마치 즉시 수행되는 것처럼 시스템의 나머지 부분에 나타나는 작업입니다. Combiner의 컨텍스트에서 원자성 작업은 여러 스레드가 서로 간섭하지 않고 공유 데이터에 대한 작업을 수행할 수 있도록 보장합니다.
예를 들어 Combiner에서 값을 집계할 때 원자 증가 또는 추가 작업을 사용해야 합니다. 자바에서는원자정수클래스는 정수에 대한 원자적 연산을 제공합니다. 개수를 추적하기 위해 일반 정수 변수를 사용하는 대신 다음을 사용할 수 있습니다.원자정수. 이렇게 하면 여러 스레드가 동시에 개수를 증가시키려고 할 때 작업이 원자적으로 보장되고 일관성 없는 결과가 발생하지 않습니다.
다시 단어 수의 예를 들어보겠습니다. 각 단어의 개수를 추적하기 위해 일반 정수를 사용하는 대신 다음을 사용할 수 있습니다.원자정수. 스레드가 특정 단어의 개수를 늘리려고 할 때 다음을 호출할 수 있습니다.증분AndGet()의 방법원자정수. 이 방법은 원자적이므로 여러 스레드가 동시에 카운트를 증가시키려고 해도 작업이 올바르게 수행됩니다.
동기화 메커니즘
때로는 원자적 작업만으로는 충분하지 않을 수 있으므로 스레드 안전성을 보장하기 위해 동기화 메커니즘을 사용해야 합니다. 동기화를 사용하면 한 번에 하나의 스레드만 액세스할 수 있도록 공유 리소스에 대한 액세스를 제어할 수 있습니다.
Java에서는 다음을 사용할 수 있습니다.동기화됨동기화된 메서드나 블록을 생성하는 키워드입니다. 예를 들어, Combiner가 다음과 같은 공유 데이터 구조를 가지고 있다면해시맵집계된 값을 저장하기 위해 동기화된 블록을 사용하여 단 하나의 스레드만 액세스할 수 있도록 할 수 있습니다.해시맵한 번에.

java.util.HashMap 가져오기; 공용 클래스 MyCombiner { 개인 HashMap<String, Integer> countMap = new HashMap<>(); 공개 무효 결합(문자열 키, int 값) { 동기화됨(this) { if (countMap.containsKey(key)) { countMap.put(key, countMap.get(key) + value); } else { countMap.put(키, 값); } } } }
이 예에서는결합하다메서드는 동기화됩니다. 즉, 한 번에 하나의 스레드만 이 메서드를 실행할 수 있습니다. 이는 다음을 보장합니다.해시맵스레드로부터 안전한 방식으로 액세스 및 수정됩니다.
전역 상태 피하기
스레드로부터 안전한 프로그래밍에 있어서 전역 상태는 악몽이 될 수 있습니다. Combiner가 여러 스레드에 의해 수정될 수 있는 전역 변수나 공유 리소스에 의존하는 경우 경쟁 조건 및 기타 스레드 안전 문제가 발생할 가능성이 매우 높습니다.
대신, Combiner의 상태를 가능한 한 로컬로 유지하려고 노력해야 합니다. 각 스레드에는 작업에 필요한 데이터의 자체 복사본이 있어야 하며 결과는 마지막에 안전한 방식으로 스레드에 결합되어야 합니다.
예를 들어 전역 변수를 사용하는 대신해시맵집계된 값을 저장하려면 로컬을 사용할 수 있습니다.해시맵각 스레드마다. 모든 로컬 집계가 완료되면 이러한 로컬 집계를 병합할 수 있습니다.해시맵스레드에서 - 안전한 방식으로.
스레드 안전성 테스트
테스트는 Combiner가 스레드로부터 안전한지 확인하는 데 필수적인 부분입니다. 일관된 결과를 생성하는지 확인하려면 여러 스레드를 사용하는 다양한 시나리오에서 Combiner를 테스트해야 합니다.
스레드 안전성을 테스트하는 한 가지 방법은 다중 스레드 테스트 프레임워크를 사용하는 것입니다. 예를 들어, JUnit을 사용하여 다중 스레드 테스트 케이스를 작성할 수 있습니다. Combiner를 동시에 호출하는 여러 스레드를 생성한 다음 출력이 올바른지 확인할 수 있습니다.
또한 FindBugs 또는 IntelliJ IDEA에 내장된 정적 분석 도구와 같은 도구를 사용하여 코드에서 잠재적인 스레드 안전 문제를 감지할 수도 있습니다. 이러한 도구는 공유 변수에 대한 비원자적 작업을 사용하거나 공유 리소스에 대한 액세스를 적절하게 동기화하지 않는 것과 같은 일반적인 실수를 식별할 수 있습니다.
당사의 결합기 제품
컴바이너 공급업체로서 당사는 스레드 안전을 염두에 두고 설계된 다양한 고품질 컴바이너를 제공합니다. 우리의12채널 패시브 헤드엔드 결합기그리고24채널 패시브 헤드엔드 결합기스레드 안전이 중요한 MapReduce 작업에 적합합니다. 이러한 결합기는 최신 기술을 사용하여 제작되었으며 최고 수준의 성능 및 신뢰성을 충족하는지 확인하기 위해 엄격한 테스트를 거쳤습니다.
귀하가 MapReduce 작업을 위한 안전한 스레드 결합기를 찾고 계시다면 우리는 귀하의 의견을 듣고 싶습니다. 소규모 개발자이든 대기업이든 상관없이 우리는 귀하에게 적합한 솔루션을 제공합니다. 귀하의 특정 요구 사항에 대해 주저하지 말고 연락하여 대화를 시작하십시오. 귀하의 필요에 가장 적합한 Combiner를 찾고 MapReduce 작업이 원활하고 효율적으로 실행되도록 도와드리겠습니다.
참고자료
- 톰 화이트. “하둡: 확실한 가이드.” 오라일리 미디어, 2015.
- 브라이언 괴츠 외. "실제로 Java 동시성." 애디슨 - 웨슬리 프로페셔널, 2006.
