반응형
configuration 의 "dfs.data.dir" 의 값으로 DataNode와 그에 속한 쓰레드를 실행하며 값은space 나 comma 로 분리되고 분리된 갯수 만큼 DataNode를 실행한다. (ServerSocket 을 전달함)

DataNode 생성자에서 서버소켓을 실행, 서버 포트는 "dfs.datanode.port" 의 값으로 시작되며 디폴트는 50010 이고 서버가 갯수 만큼 실행 될 때 +1 씩 포트가 증가한다.

DataNode 가 갖는 쓰레드
1. 자체 Thread : Namenode에 Heartbeat, blockReport 를 보냄
2. DataXceiveServer : ServerSocket 을 전달받아 클라이언트 접속이 있으며 DataXceiver 스레드를 만든다.
3. DataXceiver  : 클라이언트가 보낸 데이터를 읽는다. (in : InputStream, reply : OutputStream)
    1. in.read() : 1 byte 를 읽어서 operation 을 알아낸다.
    operation 이 write block 일 경우
    2. in.readBoolean() : 리포트를 해야할 블럭인지 boolean 값을 읽어낸다.
    3. block.readFields(in) : block id와 block의 길이 len 을 읽는다.
    4. in.readInt() : block 을 복사할 타켓의 갯수를 읽는다.
    5. DatanodeInfo.readFields(in) : 데이터 노드명, 용량, 남은용량, 마지막 업데이트 값을 타겟수만큼 읽는다.
    6. in.read() : 인코딩 타입을 1 byte 읽는다.
    7. in.readLong() : 이후 읽어야할 실제 데이터 길이 len 을 읽는다.

    현재 데이터노드 서버에 파일을 생성하여 outputstream 을 만든다. 
    첫번째는 자신의 데이터 노드 이므로 다음 타겟인 데이터노드와 소켓으로 접속하여 out2 와 in2 를 생성한다.
    1. out2.write(OP_WRITE_BLOCK) : 1 byte 값이 block write operation을 보낸다.
    2. out2.writeBoolean(shouldReportBlock) 으로 리포트 해야할 블럭인지를 보낸다.
    3. block.wirte(out2) : block id와 block의 길이 len 을 쓴다.
    4. out2.writeInt(target.length -1) : 복사해야할 남은 타겟의 갯수를 쓴다.
    5. DatanodeInfo.write(out2) : 루프를 돌면서 남은 데이터노드의 정보를 보낸다.
    6. out2.write(encodingType) : 1 byte 의 인코딩 타입값을 쓴다.
    7. out2.writeLong(len) : 데이터 길이 len 을 쓴다.

    8. in.read(buf, 0, len) : 루프를 돌면서 데이터를 다 읽는다.
    9. out.write(buf,0, len), out2.write(buf, 0, len) : 루프를 돌면서 로컬 파일(out) 과 out2 에 데이터를 쓴다.

    10. out2.flush() : 복사하는 타겟 out2 를 flush 한다.
    11. in2.readLong() : long 값의 WRITE_COMPLETE 를 읽는다. 복사된 타겟이 잘 전달됐는지 확인
    12. LocatedBlock.readFields(in2) : block 을 읽고 DatanodeInfo의 갯수를 읽고 루프돌면서 DatanodeInfo 읽음
                                                     이것으로 복사된 타겟의 정보를 얻을 수 있음
    13. data.finalizeBlock(b) : DataNode 의 속성인 FSDataset 의 dirTree 에 block과 파일을 저장
    14. receivedBlockList.add(b) : Namenode에 보고할 block을 리스트에 저장한다. 
                                               리스트에 저장되면 Datanode 자체쓰레드에서 관련 정보를 Namenode에 보냄
    15. reply.writeLong(WRITE_COMPLETE) : 클라이언트에게 complete 메세지를 보냄
    16. LocatedBlock.write(reply) : block, DatanodeInfo 갯수, 루프를 돌면서 DatanodeInfo.write 를 보낸다.
반응형
Posted by seungkyua@gmail.com
,
반응형
NameNode 는 RPC 클래스를 통해서 Server 클래스를 동작시킨다.

Server 클래스는 아래의 3개의 내부 쓰레드를 가진다.

1. Listener 스레드 : ServerSocket 을 가지면 클라이언트가 접속할 때 마다 Connection 쓰레드를 생성
2. Connection 스레드 : 클라이언트의 요청 데이터를 받아서 Call 객체를 생성하여 callQueue 에 넣는다.
                                 데이터는 DataInput 으로 부터 읽어 들임
3. Handler 쓰레드 : callQueue로 부터 Call 객체를 받아와 RPC 호출을 실행 시킨다.
                           실제적으로 일을 하는 쓰레드로 conf 객체의 "dfs.namenode.handler.count"  값으로
                           갯수를 결정하며 default 는 10 이다.


클라이언트가 요청할 때 DataInput 으로 읽어들이는 값의 순서
1. id : in.readInt() 로 id 값을 읽음
2. methodName : UTF8.readString(in) 로 메소드 명을 읽음
3. 파라미터 갯수 : in.readInt() 로 파라미터 갯수를 int 값으로 읽음
4. 파라미터 객체를 읽음 : ObjectWritable.readObject(in, objectWritable, this.conf) 로 파라미터 객체 생성에 
                                    필요한 값을 읽음

4번 파라미터 객체를 읽는 순서
1. className : UTF8.readString(id) 로 클래스명을 읽음
                      클래스명은 in.readUnsignedShort() 로 클래스명이 차지하는 byte 수를 읽고 
                      그 클래스명 크기만큼 읽어들임
2. 자기 클래스에 맞는 크기 만큼 읽어 들임.
    - null 이면 NuuInstance 의 readFields(in) 를 읽음
    - 원시타임(char, int, long 등등)은 in.readChar() 등으로 읽음
    - Array 는 in.readInt() 로 배열크기를 읽은 다음 recursive call로 readObject() 를 다시 읽음
    - String 은 UTF8.readString(in) 으로 읽음
    - 그외 객체는 1번으로 읽어들인 클래스명으로 인스턴스를 만들어 객체가 Writable 인터페이스를 구현한
       writable.readFields(in) 로 읽어들임
반응형
Posted by seungkyua@gmail.com
,
반응형
DatanodeInfo 속성은?
1. UTF8 name : <host>:<port> 로 구성된 값
2. long capacityBytes : 총 수용 가능한 bytes 수
3. long remainingBytes : 수용 가능한 남은 bytes 수
4. long lastUpdate : capacityBytes, remainingBytes 값을 세팅한 시간 System.currentTimeMillis()
5. TreeSet blocks : Block 타입의 데이터를 저장

Block 타입의 속성은?
1. long blkid : "blk_" 시작하는 파일명 뒤의 long 값을 저장
2. len : block 파일의 크기

Block 을 write 할 때의 순서
1. out.writeLong(blkid); 
2. out.writeLong(len);

DatanodeInfo 를 write 할 때의 순서
1. name.write(out);
2. out.writeLong(capacityBytes);
3. out.writeLong(remainingBytes);
4. out.writeLong(lastUpdate);

여기서 UTF8 은 어떻게 write 할까?

UTF8 타입의 속성?
1. byte[] bytes : byte 값
2. length : String 을 utf8 bytes 로 변환할 때 char 가 1,2,3 byte 로 변환될 수 있으므로 변환한 String의 길이

UTF8 write 순서
1. out.writeShort(length);
2. out.write(bytes, 0, length);
반응형
Posted by seungkyua@gmail.com
,
반응형
UTF8 타입에는 byte[] 와 length 를 가지고 있다.

1. set(String string) 을 사용하여 string -> byte[] 로 저장할 때 DataOutputBuffer 사용
    String -> charAt(i) 루프를 돌면서 utf8 byte 로 변환하여 DataOutputBuffer 의 byte[] 에 저장 ->
    System.arraycopy로 UTF8 byte[] 에 복사

2. toString() 으로 byte[] -> String 으로 리턴할 때 DataInputBuffer 와 DataOutputBuffer 사용
    UTF8 byte[] -> DataInputBuffer 의 byte[] 에 저장 -> 
    DataInputBuffer를 argument로  DataOutputBuffer 의 byte[] 에 저장 (out.write(in)) -> 
    DataOutputBuffer의 byte[] 를 StringBuffer에 append 하여 리턴

여기서.. 의문.. 왜 2 번에서 UTF8 byte[] 를 DataOutputBuffer byte[] 에 arraycopy를 하지 않을까?

간단함.. 그냥 그런 api 를 만들지 않았음.. byte[] 를 받아서 저장하는 것은 DataInputBuffer 에만 존재
DataOutputBuffer 는 DataInputBuffer 를 이용해서 byte[] 를 저장.

중요한 것은 DataOuputBuffer 는 DataOutputStream 을 상속받았지만 DataOutputStream 에는 없는 buffer 기능을 추가하였음. (내부 클래스로 ByteArrayOutputStream 을 상속받은 Buffer 클래스가 존재)

DataInputBuffer 도 DataInputStream 을 상속받있지만 똑같이 buffer 기능을 추가.

반응형
Posted by seungkyua@gmail.com
,
반응형
Safari Javascript Debug Console

defaults write com.apple.Safari IncludeDebugMenu 1
반응형
Posted by seungkyua@gmail.com
,
반응형
ie 인지 판별하는 법

var userAgent = navigator.userAgent.toLowerCase();
var isIE = (/msie/gi.test( userAgent ) && !/opera/gi.test( userAgent ));


로딩 이벤트 등록하기

if (isIE) {
    iframe.attachEvent('onload', 함수명);
} else {
    iframe.addEventListener('load', 함수명, false);
}
반응형
Posted by seungkyua@gmail.com
,
반응형
1. 프로젝트를 만든다.
    프로젝트명 : WindowBasedSample
    프로젝트 생성시 처음 만들어지는 파일은 일종의 엔트리 포인트로 생각한다.
    WindowBasedSampleAppDelegate.h
    WindowBasedSampleAppDelegate.m

2. nib 파일(화면)을 만든다.
    Interface Builder 를 실행하여 View 타입으로 생성하여 WindowBasedSample 프로젝트 디렉토리에 저장한다.
    파일명 : HelloWorldView.xib
    Library 창에서 원하는 view object 를 선택하여 View 창에 드래그&드랍으로 화면을 만든다.

3. HelloWorldView.xib 화면을 연결할 UIViewController 파일을 만든다.
   Xcode 에서 File -> New File 을 선택하고 타입을 UIViewController subclass 로 선택한다.
   파일명 : HelloWorldViewController

4. HelloWorldView.xib 화면과 HelloWorldViewController 를 연결한다.
    HelloWorldView.xib 의 Document 창에서 File's Owner 를 선택하고 Identity Inspector 창을 띄운다.
    class identity 의 클래스에서 HelloWorldViewController 를 선택한다.
    Connections Inspector 창에서 Outlets 의 view 속성을 드래그해서 Document 창의 View와 연결한다.
    
5. WindowBasedSampleAppDelegate.m 에서 HellowWolrdView.xib 를 로딩한다.
    -(void) applicationDidFinishLaunching 메소드에서 자신의 view를 window view 에 세팅한다.

로딩 순서 및 연결고리를 보면.....

1. main.m
2. MainWindow.xib
3. WindowBasedSampleAppDelegate.m
4. HelloWorldView.xib
5. HelloWorldViewController.m



  
반응형
Posted by seungkyua@gmail.com
,
반응형
Class                : 설명이 필요없겠죠.. 우리가 알고 있는 클래스 그 자체입니다.
Class Object      : 클래스에 단 하나밖에 없는 객체로 인스턴스를 만들 때 필요한 정보를 가지고 있는 객체입니다.
                          내부적으로 존재하는 객체로 보시면 되고 Factory Object 라고도 합니다.
                          클래스에서 접근하는 메소드는 사실 클랙스 객체의 메소드로 접근한다고 생각하면 됩니다.
                          클래스 객체는 타입으로는 클래스와 같습니다.
Class Method    : 클래스 객체에서 접근가능한 메소드입니다. 인스턴스가 없어도 클래스 객체로 직접 접근 가능
                          합니다.
Instance            : 클래스 객체로 부터 생성되어 메모리에 할당된 객체입니다.


@interface Artist : NSObject
{
    NSString *name;      // instance variable
    static int age;        // class varialbe
}
- (NSString *) name;   //  instance method
@end


#import "Artist.h"

@implementation Artist

- (NSString *) name    //  instance method
{
    return name;
}
- (void) init             //  instacne variable 초기화
{
   name = @"ASK";
}
+ (void) initialize   // class variable 초기화
{
     static BOOL initialized = NO;
    if ( ! initialized )
    {
 
         age = 20;
         initialized = YES;
     }
}
@end

반응형
Posted by seungkyua@gmail.com
,

Flex Troubleshooting

Flex 2010. 9. 9. 14:24
반응형
Flex 로 웹 프로그래밍을 할 때... 특히 게시판과 같은 시스템을 만들 때 고려할 점~~

1. Flex 위에 게시물 상세정보(HTML) 이 보여줘야 한다.
   (1층 : Flex, 2층 : HTML 상세정보)
2. 상세정보를 스크롤 할 때 상세정보 내용이 스크롤 되면서 상단위 플렉스 영역을 침범하면 안된다. 
3. 게시물을 작성할 때 javascript 에디터나 ActiveX 컨트롤을 사용한 에디터를 사용한다.
4. 게시물 저장 버튼을 클릭할 때 확인 메세지가 레이어로 떠야 한다.
    (1층 : Flex, 2층 : ActiveX, 3층 : Flex 레이어 팝업)
5. Flex 의 로딩시점과 ActiveX의 로딩시점이 꼬이지 않게 정확한 로딩 순서를 보장해야 한다.
6. 포커스 처리
    (처음 창이 뜰 때와 탭등으로 포커스 이동 등)
7. Drag & Drop 기능을 사용할 때 잔상이 안남게 하는 방법
8. swf 로딩을 이용한 모듈과의 LocalConnection 사용 시 자주 끊길 수 있는 문제

적어도 이 정도를 고려하지 않으면 Flex 로 HTML 내용을 저장하는 게시판 만들 생각하지 마세요..

근데.. 저희는 해결했습니다.. ^^
반응형
Posted by seungkyua@gmail.com
,

Telnet, Proftp 설치

Linux/Ubuntu 2010. 8. 14. 23:57
반응형
텔넷은 설치가 쉬었는데.. Proftp 는 정말 삽질 많이 했습니다..^^

//----------------------------------------
//--  Telnet 설치
//----------------------------------------
# sudo apt-get install xinetd
# sudo apt-get install telnetd

//------- telnet을 xinetd에 추가
# vi /etc/xinetd.conf
defaults
{
}

service telnet
{
   disable = no
   flags = REUSE
   socket_type = stream
   wait = no
   user = root
   server = /usr/sbin/in.telnetd
   log_on_failure += USERID
}

//------- xinetd 재시작
# service xinetd restart

문제가 발생하면 다음의 로그를 보면 됩니다.
# tail -f /var/log/syslog

//----------------------------------------
//--  Proftpd 설치
//----------------------------------------
# sudo apt-get install proftpd

화면에 standalone 과 xinetd 선택이 나오면 xinetd 를 선택합니다.

//------- proftpd을 xinetd에 추가
# vi /etc/xinetd.conf

service ftp
{
   disable = no
   flags = REUSE
   socket_type = stream
   wait = no
   user = root
   server = /usr/sbin/proftpd
   log_on_success += DURATION USERID
   log_on_failure += USERID
   nice = 10
}

//------- xinetd 재시작
# service xinetd restart

//------- 방화벽 열기
# sudo ufw allow 21/tcp


반응형
Posted by seungkyua@gmail.com
,