반응형
iTunes U : Standford CS 193    -> 아이폰 유용한 강좌

iPhone 3 : icon.png
iPhone 4 : icon@2x.png    -> 파일명에 @2x 를 붙히면 자동으로 인식

MFi : Made For iPhone -> 애플의 아이폰 액서서리 커넥트 핀 보장
FSK library :  아이폰 오디오 잭으로 연결한 라이브러리

[iPhoneSDK 3.0]
APNS : Apple Push Notification Service
StoreKit : 앱 내에서의 구매 기능
GameKit
AVFoundation
MapKit : 지도 표시
Core Data : 로컬 데이터 베이스

[iPhoneSDK 4.0]
Multitasking
iAd
GameCenter
Calendar

GCC 4.2 :  컴파일
GDC 4.2 :  디버깅

[메모리 관리]
alloc   : 리테인 카운트 1
retain :  리테인 카운트 +1
release : 리테인 카운트 -1
* 클래스 메소드 (+)를 호출하여 생성한 객체는 autorelease 가 자동으로 호출됨
* 콜렉션에 add 된 객체는 +1, remove 된 객체는 -1, 콜렉션 객체가 소멸되면 포함된 객체도 자동 release 됨. 


[Prefix 의 의미]
UI  : UIKit -> 화면
NS : Foundation (Core Service)
CA : Core Animation
CG : Core Graphics
CV : 
MP : 

1. ADC 가입
     - Agent  : 최초 애플과 계약 모든 릴리즈에 책임 (멤버와 어드민 초청)
     - Admin : 개발자 포털 관리, 프로파일 정보 수정가능 (멤버와 어드민 초청)
     - Member : 장치에 사이드로딩 방식으로 설치 가능
2. 인증서 발급 :  맥의 키체인 접근 프로그램을 통해서 인증서 발급 요청서를 받아 ADC 포털에서 요청
3. 인증서 다운로드
4. Xcode Organizer 에 디바이스 등록
5. App ID 만들기
    - URL의 역순으로 만듦
         ex) com.ahnseungkyu.livecoder
    - *문자를 사용하면 다수의 앱을 지칭할 수 있음
        ex) com.ahnseungkyu.*
    - APN, InAppPurchase, Keychain 공유등을 사용하려면 * 없이
    - 삭제불가
6. 프로비저닝 프로파일 만들기
7. 프로비저닝 등록 및 다운로드


 
반응형
Posted by seungkyua@gmail.com
,
반응형
1. 아이폰 디버깅 방법
2. Instruments 도구에서 메모리 누수 찾는 법 
반응형
Posted by seungkyua@gmail.com
,
반응형
테이블명 : tb_emprelation, 컬럼패밀리 source, target, read

hbase(main):001:0>create 'tb_emprelation', {NAME=>'source'}, {NAME=>'target'}, {NAME=>'read'}

source 컬럼패밀리에 mail 컬럼에 값을 넣을 경우
hbase(main):002:0>put 'tb_emprelation', 'source:email', 'skanddh@gmail.com'
반응형
Posted by seungkyua@gmail.com
,
반응형
HBase eclipse 환경 세팅

1. 새로운 워크스페이스를 만든다.
2.  HBaseEmptyWorkspace.tar.gz 을 다운받아 새로운 워크스페이스에  .metadata 드렉토리를 푼다.
3. 서브버전을 eclipse software install로 설치한다.  (SubClipse Site 에 것을 설치하면 됨)
4. Subclipse 를 설치하면 CollabNet Subversion 을 다운받아 JavaHL을 추가로 설치한다.
    CollabNet Subversion은 /opt/subversion 경로로 설치된다.
5. SVN Repositoty 에서 http://svn.apache.org/repos/asf/hbase/ 를 Root URL로 세팅한다.
6. eclipse 의 Project -> Build Automatically 를 해제.
7. checkout 으로 New Project Wizard 를 선택 ->  Java Project -> HBase-trunk로 프로젝트 이름을 세팅
8. 디폴트 아웃풋 폴더로 PROJECT_HOME/build/eclipse-classes 로 폴더를 생성하여 지정 

9. cmd 로 워크스페이스의 HBase-trunk 폴더로 이동하여 mvn eclipse:eclipse 를 치면 .project 파일이 다시 생성됨


Ant 스트립트

<project name="EmpRelationHadoop" default="compile">

<property name="classes.dir" value="build/classes"/>

<property name="jar.dir" value="build/jar"/>

<property name="library.dir" value="/Users/skanddh/.m2/repository"/>


<path id="libraries">

        <fileset dir="${library.dir}">

            <include name="**/*.jar"/>

        </fileset>

    </path>

    <target name="clean">

        <delete dir="build/classes"/>

    <delete dir="build/jar"/>

    </target>


    <target name="compile">

        <mkdir dir="${classes.dir}"/>

        <javac srcdir="src" destdir="${classes.dir}" classpathref="libraries"/>

    </target>


    <target name="jar" depends="compile">

        <mkdir dir="${jar.dir}"/>

        <jar destfile="${jar.dir}/EmpRelationHadoop.jar" basedir="${classes.dir}">

            <manifest>

                <attribute name="Main-Class" value="hbase.RelationCalculator"/>

            </manifest>

        </jar>

    </target>


    <!-- target name="run">

        <java jar="${jar.dir}/EmpRelationHadoop.jar" fork="true"/>

    </target -->


</project>




반응형
Posted by seungkyua@gmail.com
,
반응형
hadoop 의 구성을 보면 Namenode 와 Datanode 가 있다. Namenode 를 일종의 마스터로 보면 Datanode 는 슬레이브로 볼 수 있으며 Namenode 와 Datanode 사이에는 주기적으로 통신을 한다.

Datanode 가 파일 시스템 정보나 기타 헬스체크를 주기적으로 Namenode 로 보내는데 이 때의 통신방법은 RPC 이다.
Namenode 가 기동 될 때 RPC Server 가 같이 기동되며 Namenode 는 DatanodeProtocol 인터페이스를 구현하였기 때문에 Datanode 가 이 메소드를 호출하는 RPC 통신을 하게 된다.

RPC 통신 구현 방법은 간단한데 Datanode 가 적합한 메소드(DatanodeProtocol 메소드 중의 하나)를 호출하면 ipc.Client 클래스를 이용하여 메소드 명,  파라미터 갯수, 루프를 돌면서 (파라미터 타입, 파라미터 값) 을 보내면 -RPC.Invocation클래스를 이용하면 관련 정보를 순서대로 보낸 - Namenode 는 ipc.Server 를 통해서 메소드명, 파라미터 갯수, 루프를 돌면서 (파라미터 타입, 파라미터 값) 을 받아 - RPC.Invation클래스를 이용하면 순서대로 받을 수 있다 - Namenode 의 적합한 메소드(DatanodeProtocol 메소드 중의 하나)를 invoke 한다.
invoke 후에는 리턴 값을 받아서 ipc.Server 를 통해 리턴 클래스명, 리턴 클래스의 값을 Datanode 에 보낸다.
Datanode 는 ipc.Client 를 통해서 리턴 클래스명, 리턴 클래스의 값을 받아 처음에 호출한  메소드의 결과값으로 리턴된다.

RPC의 핵심은 Proxy 클래스와 Reflection API 를 사용한다는 것. 
반응형
Posted by seungkyua@gmail.com
,
반응형
Datanode 는 Proxy.newProxyInstance(...) 로 DatanodeProtocol 인터페이스를 구현한 Proxy 객체를 구해서
다른 데이터노드와 통신한다.

이렇게 되면 DatanodeProtocol 의 메소드를 호출 할 때 마다 Proxy 객체 생성시에 저장된 InvokerHandler.invoke 메소가 호출된다. 결국 중요한 것은  InvokerHandler.invoke  메소드이다. (실제 작업하게 되는 메소드)

ObjectWritable value = (ObjectWritable) CLIENT.call(new Invocation(method, args), address);
return value.get();

Invocation 클래스는 대충 호출할 메소드와 파라미터를 저장한 것이라고 하면 CLIENT 클래스가 중요하다.

CLIENT 가 call 을 호출하면 내부적으로는 다음과 같은 진행을 한다.
1. 쓰레드 타입의 Connection 객체 생성하여 재사용을 위해 Hashtable 에 저장하고 쓰레드를 시작한다.
    Connection 객체에는 InetSocketAddr을 이용하여 DataInputStream 과 DataOutputStream 을 가지고 있다.
2. Call(param) 으로 call 객체를 파라미터만 저장하여 생성
3. call 객체를 Hashtable 에 저장하고 out.writeInt(call.id); call.param.write(out) 와 같이 파라미터를 보낸다.
4. Connection 쓰레드의 run 이 끝나서 결과를 받으르 때까지 타임아웃만큼 기다린다.  call.wait(timeout);
5. Connection 쓰레드의 run 메소드에서 id = in.readInt(); 후 Hashtable 의 call 객체를 remove 한다.
6. in.readBoolean(); 으로 에러여부를 읽고 value.readFields(in); value 값을 읽어 들인다.
7. call 객체에 value 를 세팅하고 call 객체의 notify() 를 호출한 후 Connection 쓰레드를 Hashtable에서
    제거한 후 쓰레드를 종료한다.
반응형
Posted by seungkyua@gmail.com
,
반응형
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
,
반응형
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
,