멀티플렉싱 서버의 구현에 있어서 가장 대표적인 방법 : select()


select함수를 사용하면 한곳에 여러 개의 file descriptor를 모아놓고 동시에 이들을 관찰할 수 있다.

*파일 디스크립터의 관찰은 소켓의 관찰로 해석할 수 있다.

파일 디스크립터에 대한 관찰을 하는 데 사용되는 것이 fd_set형 변수이다. 이는 0과 1로 표현되는, 비트단위로 이뤄진 배열이다.

이러한 자료형으로 각 file descriptor에 대해 세 가지에 대해서 관찰을 한다.

- read buffer 관련

- write buffer 관련

- exception 관련


이러한 관찰범위를 select 함수에 fd_set 변수를 선언하여 변수의 주소값을 넘겨준다.

관심없는 관찰에 대해선 NULL을 넘겨주면된다.


select의 parameter를 살펴보면 다음과 같다.



readfds 는 read buffer 즉, '수신된 데이터의 존재여부'에 관심 있는 file descriptor 정보를 모두 등록해서 그 변수의 주소 값을 전달한다.

writefds 는 write buffer 즉, '블로킹 없는 데이터 전송의 가능여부'에 관심 있는 file descriptor 정보를 모두 등록해서 그 변수의 주소 값을 전달한다.

exceptfds는 exception 즉, ' 예외상황의 발생여부'에 관심있는 파일 디스크립터 정보를 모두 등록해서 그 변수의 주소 값을 전달한다.


※readfds, writefds, exceptfds는 모두 서로 다른 fd_set 형 변수이다.



관찰 대상이되는 파일 디스크립터의 수를 나타내는 nfds에 대해서 알아보자.

여기서 주의해야할 것은 관찰 대상이 되는 file descriptor의 정확한 개수를 넘기는 게 아니라

'가장 큰 file descriptor의 값 + 1' 을 select의 가장 첫번째 인수로 넘겨준다는 것이다.

이 의미는 fd_set형 배열을 nfds만큼 순회하면서 값이 1인 file descriptor를 캐치한다는 것이다.


Q. 관찰을 원하지 않는 file descriptor의 변화를 감지할 수 있지 않은가?

우리는 fd_set형 변수에서 관심있는 file descriptor를 1로 set한다. 그리고 이 fd_set 변수는 초기화하는 데 사용되고

이 변수를 또다른 fd_set형 변수를 선언하여 복사해준다. 

그래서 매번 select 하기 전에 원래의 fd_set(1)으로 초기화한다. 그 다음, select의 fd_set 자리에는 복사한 fd_set(2)형 변수의 주소값을 넘겨준다.

select는 fd_set의 1로 셋팅된 것으로 관찰 대상인 file descriptor를 판별하는데 매번 초기화를 안 해주면 들어갈 때마다 값이 바뀌기 때문에 관찰대상이 계속 바뀌어 의미가 없어진다.



Select함수는 변화를 감지하기 위한 목적이 있다. 그래서 세 가지 관찰범위에 대해서 변화가 일어나지 않으면 반환을 하지 않는다. 이러한 infinite blocking 상태에 빠지지 않게 하기 위해서 설정한 timeout 시간을 초과하면 0을 반환하도록 한다.


실패하면 -1을 반환하고 성공 시, 변화가 일어난 file descriptor의 수를 반환한다.









사전 준비: JDK 설치 및 JAVA_HOME 환경 변수 설정

sudo apt-get update

sudo apt-get -y install openjdk-8-jdk


echo $JAVA_HOME

아무것도 안 뜨거나, echo $JAVA_HOME 이 그대로 뜨면

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64


1. Apache Spark Project의 공식 내려 받기 페이지에 접속

https://goo.gl/DLvWLR



2. Package type 선택

이미 하둡을 설치했다면 해답 하둡 버전에 맞는 유형을 선택할 수 있다.


3. Spark 다운로드


cd $HOME/Downloads

tar -xvf spark*

rm spark*tgz            -------내려받은 스파크 tgz 아카이브를 삭제


4. 압축을 해제한 스파크 디렉터리를 Downloads에서 bin/sparks 로 옮긴다.


cd $HOME                ------ 홈 디렉터리로 이동

mkdir -p bin/sparks    ------ bin/sparks 디렉터리 생성

mv Downloads/spark-* bin/sparks    ------압축 해제한 스파크 디렉터리를 Downloads에서 bin/sparks로 옮긴다.


5. 심볼릭 링크 생

cd %HOME/bin

ln -s sparks/spark-2.4.0-bin-hadoop2.7 spark    ------ 심볼릭 링크 생성


심볼릭 링크는 리눅스에서 여러 버전의 프로그램을 관리하는 데 매우 유용하다.

~/bin 폴더에서 tree -L 2 명령을 실행해 보자.

spark 폴더가 실제로는 sparks 디렉터리의 다른 폴더를 가리키는 심볼릭 링크인 것을 볼 수 있다.


이처럼 심볼릭 링크를 사용하는 이유는 스파크 루트 폴더를 항상 동일한 방식을 참조할 수 있기 때문이다.

다른 버전의 스파크를 사용하려면 단순히 심볼릭 링크가 다른 버전의 설치 디렉터리를 가리키도록 변경하면 된다.


이제부터는 이 $HOME/bin/spark 디렉터리를 spark root로 칭한다.


+ Recent posts