일괄 처리 - 유닉스 도구

Neo·2023년 5월 14일
0

시스템의 유형

  • 서비스(온라인 시스템)

    • 서비스는 클라이언트로부터 요청이 올 때까지 기다림. 요청 하나가 들어오면 서비스는 가능한 빨리 요청을 처리해 응답하며, 응답 시간은 성능 측정의 중요한 지표로 작용함
  • 일괄 처리 시스템(오프라인 시스템)

    • 매우 큰 데이터를 받아 데이터를 처리하는 작업을 수행하고 결과 데이터를 생산. 대개 수 분에서 때론 수 일이 걸리기 때문에 사용자가 작업이 끝날 때까지 대기하지 않으며, 하루에 한번 수행과 같이 반복적인 일정으로 수행. 주요 성능 지표로는 처리량이 대표적임
  • 스트림 처리 시스템(준실시간 시스템)

    • 온라인과 오프라인(일괄) 사이에 있는 준실시간 처리(near-real-time processing). 일괄 처리 시스템과 마찬가지로 요청에 응답하지 않으며 입력 데이터를 소비해 출력 데이터를 생산함. 다만, 일괄 처리 작업은 정해진 크기의 입력 데이터를 대상으로 작동하지만, 스트림 처리는 입력 이벤트가 발생한 직후 바로 작동함

유닉스 도구로 일괄 처리하기

  • 웹 서버가 하나 있고 들어온 요청이 처리될 때마다 로그 파일에 한 줄씩 추가한다고 가정

  • 이를 해석하려면 로그 형식의 정의가 필요함

  • 해석해보면 이 로그는 2015년 2월 27일 UTC 17시 55분 11초에 서버가 클라이언트 IP 주소 216.58.210.78로부터 /css/typography.css 파일에 대한 요청을 받았음을 나타냄

  • 비인증 사용자여서 $remote_user가 하이픈(-)으로 표시됐고, 응답 상태는 200으로 요청은 성공, 응답 크기는 3,377바이트. 웹 브라우저는 크롬 40이며, 파일이 http://martin.kleppmann.com/이라는 URL에서 참조됨

단순 로그 분석

  • 기본 유닉스 도구를 사용해 웹 사이트에서 가장 인기가 높은 페이지 5개를 뽑는다고 해보자
cat /var/log/nginx/access.log | 
 awk '{print $7}' | 
 sort | 
 uniq -c | 
 sort -r -n | 
 head -n 5
  • 여기서 uniq는 중복을 나타내며 -c 옵션은 count 즉, 중복 횟수를 나타내는 옵션, 수행 결과는 아래와 같을 수 있음

연쇄 명령 대 맞춤형 프로그램

  • 위와 같은 유닉스 연쇄 명령을 루비로 작성하면 다음과 같음
counts = Hash.new(0) 
File.open('/var/log/nginx/access.log') do |file|
 file.each do |line|
 url = line.split[6] 
 counts[url] += 1 
 end
end
top5 = counts.map{|url, count| [count, url] }.sort.reverse[0...5] 
top5.each{|count, url| puts "#{count} #{url}" } 
  • 유닉스 연쇄 파이프보다 간결하지는 않지만, 더 읽기 쉬움

정렬 대 인메모리 집계

  • 앞선 루비 스크립트는 URL 해시 테이블을 메모리에 유지하지만, 유닉스 파이프라인에서는 이런 해시 테이블이 없음

  • 고유 URL과 URL 카운트의 크기를 메모리에 담을 수 있다면, 맞춤형 프로그램이 유용할 것임

  • 반대의 경우라면, 정렬 접근법을 사용하는 것이 좋음. 정렬 접근법은 디스크를 효율적으로 사용하는데, 앞서 봤던 "SS테이블과 LSM 트리"에서 설명한 원리와 비슷함

  • 먼저 데이터 청크를 메모리에서 정렬하고 청크를 세그먼트 파일로 디스크에 저장함. 이후, 각각 정렬된 세그먼트 파일 여러 개를 한 개의 큰 정렬 파일로 병합

  • 유닉스의 sort 유틸리티는 메모리보다 큰 데이터셋을 자동으로 디스크로 보내고 자동으로 여러 CPU 코어에서 병렬로 정렬함. 만일 병목이 있다면, 디스크에서 입력 파일을 읽는 속도일 것

유닉스 철학

“다른 방법으로 데이터 처리가 필요할 때 정원 호스와 같이 여러 다른 프로그램을 연결하는 방법이 필요하다. 이것은 I/O 방식이기도 하다.”
-- 유닉스 파이프를 발명한 더그 맥일로이(Doug McIlory)

  • 1978년에 기술된 유닉스 철학은 아래와 같음
  1. 각 프로그램이 한 가지 일만 하도록 작성하라. 새 작업을 하려면 기존 프로그램을 고쳐 새로운 “기능”을 추가해 프로그램을 복잡하게 만들기보다는 새로운 프로그램을 작성하라.

  2. 모든 프로그램의 출력은 아직 알려지지 않은 다른 프로그램의 입력으로 쓰일 수 있다고 생각하라. 불필요한 정보로 출력이 너저분해서는 안 된다. 입력 형식으로 엄격하게 열을 맞춘다거나 이진 형태를 사용하지 마라. 대화형 입력을 고집하지 마라.

  3. 소프트웨어를 빠르게 써볼 수 있게 설계하고 구축하라. 심지어 운영체제도 마찬가지다. 수 주 안에 끝내는 것이 이상적이다. 거슬리는 부분은 과감히 버리고 새로 구축하라.

  4. 프로그래밍 작업을 줄이려면 미숙한 도움보단 도구를 사용하라. 도구를 빌드하기 위해 한참 둘러가야 하고 게다가 사용 후 바로 버린다고 할지라도 도구를 써라.

  • 자동화, 빠른 프로토타이핑, 증분 반복, 실험 친화, 큰 프로젝트를 청크로 나누어 처리하기와 같은 방법은 오늘날의 애자일 및 DevOps와 매우 흡사함

  • bash와 같은 유닉스 쉘을 통해 작은 프로그램들을 가지고 놀랄 만큼 강력한 데이터 처리 작업을 쉽게 구성할 수 있음. 이런 프로그램 중 다수는 다른 그룹에서 만들어졌지만, 유연하게 조합할 수 있음 어떻게 이런 결합성을 부여할 수 있었을까?

동일 인터페이스

  • 특정 프로그램이 다른 프로그램과 연결되려면 두 프로그램이 같은 입출력 인터페이스를 사용해야 한다는 의미

  • 유닉스에스의 인터페이스는 파일(정확히는 파일 디스크립터)임. 파일은 단지 순서대로 정렬된 바이트의 연속으로 매우 단순해서, 같은 인터페이스로 실제 파일, 프로세스 간 통신 채널, 장치 드라이버, 소켓 등 다른 여러 가지 것을 표현할 수 있게함

  • 물론 유닉스 인터페이스가 완벽하다는 의미는 아님. 로그 분석 예제에서는 URL을 추출하기 위해 {print $7}을 사용했지만, 가독성이 좋지는 않음. 이상적으로 하자면 {print $request_url}과 비슷한 형식일 것임

로직과 연결의 분리

  • 유닉스 도구의 다른 특징으로는 표준 입력(stdin)과 표준 출력(stdout)을 사용한다는 점임

  • 파이프는 한 프로세스의 stdout을 다른 프로세스의 stdin과 연결하며, 이때 중간 데이터를 디스크에 쓰지 않고 작은 인메모리 버퍼를 사용해 프로세스 간 데이터를 전송함

  • 필요한 경우라면 직접 파일을 읽고 쓸 수도 있지만, 쉘은 유닉스 접근법을 통해 파일의 경로를 신경쓰지 않고 stdin과 stdout만으로 입력과 출력을 연결할 수 있음.

  • 이러한 형태를 느슨한 결합(loose coupling)이라고 하며, 프로그램에서 입출력을 연결하는 부분을 분리하면 작은 도구로부터 큰 시스템을 구성하기가 훨씬 수월함

  • 하지만 몇 가지 제약사항이 존재

    • 프로그램이 여러 개의 입력을 받거나 여러 개의 출력이 필요할 때는 불가능하지는 않지만 까다로움

    • 프로그램의 출력을 파이프를 이용해 네트워크와 연결하지는 못함

    • 프로그램이 파일을 직접 열어 읽고 쓰거나 서브프로세스로 다른 프로그램을 구동하거나 네트워크 연결을 한다면 프로그램의 I/O는 그 프로그램 자체와 서로 묶이게 됨 (무슨 말일까...)

투명성과 실험

  • 유닉스 도구가 성공적인 이유 중 하나는 진행 상황을 파악하기가 쉽기 때문

    • 유닉스 명령에 들어가는 입력 파일은 일반적으로 불변으로 처리됨. 다양한 명령을 수행하더라도 입력 파일에는 손상을 주지 않음

    • 어느 시점이든 파이프라인을 중단하고 출력을 파이프를 통해 less로 보내 원하는 형태의 출력이 나오는지 확인할 수 있음(디버깅에 유용)

    • 특정 파이프라인 단계의 출력을 파일에 쓰고 그 파일을 다음 단계의 입력으로 사용할 수 있음(전체 파이프라인을 다시 시작하지 않고 다음 단계에서부터 재시작할 수 있음)

  • 유닉스 도구는 단순하며, 유용함. 특히 실험용으로 매우 좋음

  • 유닉스 도구를 사용하는 데 가장 큰 제약은 단일 장비에서만 실행된다는 점임. 이 점에서 하둡과 같은 도구의 필요성이 대두됨

0개의 댓글