2015. 3. 24. 00:38

▶ 직렬화 기술 이해

  • 직렬화란 무엇인가?
    컴퓨터 과학, 그중에서 데이터 저장소(data storage)의 맥락에서, 직렬화는 객체의 상태 혹은 데이터 구조를 기록할 수 있는 포맷(예를 들면 파일 또는 메모리 버퍼,  또는 네트워크 연결 링크를 통해 전송될 수 있는 형태)으로 변환하며, 나중에 동일 혹은 다른 컴퓨터 환경에서 재구성할 수 있게끔 하는 절차이다.

    직렬화의 결과로 생성된 연속된 비트 데이터는 원래의 객체와 동일한 의미를 가진 객체를 생성하는데 사용된다. 광범위한 참조를 사용하는 복잡한 객체의 경우,  직렬화 과정이 간단하지 않다. 객체지향 프로그램의 객체들을 직렬화할 경우 객체와 불가분의 관계를 맺는 메소드들은 직렬화 대상에 포함되지 않는다.

    참조 링크 : 위키피디아 - serialization

  • 직렬화는 왜 중요한가?
    직렬화는 인터넷이 보편화된 시대에 빼놓을 수 없는 기술이 되었다. 거의 모든 소프트웨어는 네트워크를 통해 데이터를 주고 받고 있다. 따라서, 프로그램의 구현하는데 필요한 기반 기술 중에서 빼놓을 수 없게 되었다. 게다가 직렬화는 네크워크 의존성이 높은 소프트웨어일 경우, 전체 성능을 좌우할 수도 있는 중요한 기술이다. 

  • 마샬링(marshalling)과의 차이점
    마샬링과 직렬화는 원격 프로시저 호출(remote procedure call)이라는 맥락에서는 대략적으로 비슷한 단어이다, 의도적인 측면에서는 그 의미가 다르다. 
    깊이 얘기해 보자면, 마샬링은 이곳에서 저곳으로 인자(parameter)들을 전달하는 작업이고, 직렬화는 구조적인 데이터를 원시형(primitive) 형태에서 바이트 스트림과 같은 형식을 복사하는 작업이다. 이러한 의미에서 직렬화는 마샬링의 pass-by-value 개념을 구현하는 수단이다.

    참조 링크 : 스택오버플로우 - 직렬화와 마샬링은 어떻게 다른가?

  • 분산 컴퓨팅의 흑역사 (COM and CORBA)
    COM (Component Object Model)컴포넌트 객체 모델 (COM)는 마이크로소프트에 의해 1993 년에 도입된 소프트웨어 컴포넌트에 대한 바이너리 인터페이스(binary interface) 표준이다. 다양한 프로그래밍 언어로 작성된 프로세스 간 통신 및 동적 객체 생성을 가능하도록 하는 기술이다. COM 표준은 OLE, OLE 자동화(automation), ActiveX, COM+, DCOM, 윈도우 쉘, DirectX, UMDF 및 윈도우 런타임 등 여러 가지 다양한 Microsoft 기술 및 프레임 워크의 기초가 된다.

    참조 링크 : 위키피디아 - COM

    CORBA (Common Object Request Broker Architecture)
    Common Object Request Broker Architecture (CORBA)는 Object Management Group(OMG)에 의해 정의된 다양한 플랫폼 상에서 동작하는 시스템 간의 통신을 용이하게 하기 위한 표준이다. CORBA는 서로 다른 운영 체제, 프로그래밍 언어, 컴퓨팅 하드웨어 위에서 동작하는 시스템들이 협업(collaboration)할 수 있게 해준다. CORBA는 캡슐화와 재사용 등 객체지향 프로그래밍과 동일한 설계 목표를 가진다. CORBA를 사용하는 시스템은 객체지향 프로그램일 필요는 없지만, CORBA 자체는 객체지향 모델을 사용한다. CORBA는 분산 객체 패러다임의 사례이다.

    참조 링크 : 위키피디아 - CORBA

  • 직렬화 적용 분야
    직렬화가 적용되는 분야는 구체적으로 다음과 같다.

    파일 저장소 (File storage) :  프로그램 실행 중에 생성된 데이터를 영구 저장소(파일 시스템) 등에 저장한 후, 이후에 프로그램이 다시 실행되었을 때 저장된 데이터를 메로리 상에 객체(혹은 구조체) 형태로 복구해 사용한다.

    네트워크 통신 (Network communication)네크워크 상에 떨어져 있는 프로그램 간에 데이터를 주고 받기 위해 데이터를 직렬화한 후, 패킷(packet)에 담아 전송한다.

    데이터베이스 (Database)복잡한 형태의 객체를 데이터베이스에 저장할 때 직렬화한 문자열 형태로 테이블의 컬럼에 저장하기도 한다.

    웹 환경 (Web environment) : 웹 서버에서 브라우저(클라이언트)로 구조화된 데이터를 전송할 때 직렬화 한 후 -JSON 형식 등- 전달하는 방식이 점차 많이 사용되고 있다.

  • 직렬화 기법 선택 시 고려할 점
    다양한 직렬화 기법(프레임워크)가 존재하며 특정 기술을 선택해서 적용해야만 한다. 직렬화 기법을 선택하는데 활용할 수 있는 기준들은 다음과 같다. 

    단순성 (simple) : 사용하기가 복잡하지 않아야 한다. 직렬화를 위해 추가해야 할 코드가 적거나, 이상적인 것은 기존 코드를 변경하는 작업이 아예 없어야 한다.

    경량 (compact) : 프레임워크(혹은 라이브러리)의 규모가 작아야 한다. 라이브러리 혹은 프레임워크의 크기가 작다는 것(small foot-print)은 시스템에 대한 추가 부담(overhead)가 적어지므로 소규모의 시스템 - 이상적인 것은 안드로이드 같은 모바일 시스템까지-에서 구동될 수 있는 확률을 높다는 것을 의미한다.

    유연성 (flexible) : 다양한 데이터 타입을 직렬화할 수 있어야 한다. 한정된 자료형(숫자 타입, 문자열 타입 등)만 직렬화할 수 있다면, 도입 자체가 불가능하거나, 혹은 개발/테스트 단계에서 뒤늦게 오류를 유발하여 프로젝트 실패의 원인이 될 수도 있다.

    버전지원 (viersioning) : 객체의 데이터 구조는 설계 및 개발, 나아가 유지보수 단계에서 변화할 수 있다. 객체의 구조가 변경되더라도 클래스의 명칭을 변경하지 않고 새로운 버전을 부여할 수 있고, 서로 다른 버전의 객체들을 자동으로 변환(직렬화 및 역직렬화)해주는 기능을 프레임워크에서 제공해 줄 경우, 시스템의 유지관리가 용이해진다.

    속도 (fast) : 처리 속도가 빠르면 빠를수록 좋다!

    확장성 (scalable) : 복잡하거나, 거대한 형태의 데이터를 직렬화 할 수 있어야 한다. 예를 들어 메모리 사용량이 많아, 직렬화 대상 객체가 증가함에 따라 메모리 부족(out of memory)를 유발한다면 심각한 수준의 문제로 인해 직렬화 프레임워크를 사용할 수 없게 된다.

  • 직렬화 데이터 형식
    직렬화된 데이터는 다양한 형식(foramat)으로 표현될 수 있다.

    Binary : 메모리에 저장된 데이터를 최소한의 가공 혹은 가공 없이 바이트의 연속된 형태로 저장하는 방식이나, 사람이 읽기 불편하기 때문에, 데이터의 무결성(integrity)을 검사하기 어렵다.

    JSON (JavaScript Object Notation) : 텍스트 형식이므로 사람과 기계 모두 읽기 가능하다. 다양한 프로그래밍 언어에서 읽고 쓸 수 있기 때문에 널리 사용된다. XML 에 비해 파싱(parsign) 속도가 빠르다. 참조 링크 : 위키피디아 - JSON

    XML (eXtensible Markup Language) : 텍스트 형식이며, JSON에 비해 복잡하다. JSON에 대해 가지는 장점은 스키마(schema)를 적용할 수 있어, 데이터 구조의 무결성을 검사할 수 있다는 점이다. 참조 링크 : 위키피디아 - XML

    YAML (YAML Ain't Markup Language) :  XML에 비해 사람이 읽고 쓰기 쉽도록 고안된 마크업(markup) 언어이다. 문법이 상대적을 단순하고, 가독성이 높게 설계되어 있다. 참조 링크 : 위키피디아 - YAML

  • 구현 기법에 따른 성능 차이
    직렬화는 내부적으로 사용하는 구현 기법에 따라 속도가 달라진다. 다음에 나열된 순서대로 점차 처리 속도가 느리다.

    Native memory copying using C operations : 객체가 할당되어 있는 메모리 영역 자체를 복사하기 위해 C 함수를 사용한다.

    “Unsafe” operationsUnsafe Java 는 본래 자바 코어 개발자들이 low-level 프로그래밍 하기 위해 만든 API이다. JNI(Java Native Interface) 와 비슷하거나 유사한 수준의 성능을 내는 자바 코딩 기술이며 자바의 캡슐화 기반의 보안을 무시할 수 있다는 장점 등이 있어서 몇몇 라이브러리에서 사용되었다. 참조 링크 : Unsafe Java

    Ignore object introspectionintrospection 은 reflection과 유사한 기술이다. 다만, introspection 은 자바의 instanceof 연산자 처럼 객체의 타입 정보만 조회하는 것이고, reflection 은 메타 정보 조회 뿐 아니라, 객체에 대한 조작 기술까지를 의미한다.

    Direct object-object copying : 자바 코드로 객체 내의 모든 멤버 변수를 복사하는 로직을 구현하는 것이다.


  • "성능"! 왜 성능이 가장 중요한가?
    앞서 다양한 직렬화 프레임워크 중에서 한가지를 선택하기 위한 다양한 지표를 제시하였으나 , 가장 중요한 평가 기준은 성능이다. 성능은 왜 중요한가? 성능이 바로 '비용(cost)'에 직결되기 때문이다. 비용은 소프트웨어의 성패를 좌우하는 매우 중요한 요소이다.

    CPU 비용 : 메모리에 존재하는 바이너리 형태의 객체를 디스크 등에 저장할 수 있는 형태 (텍스트 등)로 저장하기 위해서는 변환(transform) 처리 과정이 필요하며, 반대의 처리 또한 필요하다. 객체를 스캔(scan)하고, 데이터 타입을 문자열로 변환하거나 반대의 작업은 CPU 자원을 소모하는데다가 데이터 형식(format)이 복잡할수록 긴 시간을 소모한다.

    메모리 비용 : 변환 작업을 수행하는 과정에서 임시 버퍼(temporary buffer)를 할당하고, 네트워크를 통한 송수신 과정에서 스트림 처리 등에 따른 공간 할당이 필요하다. 메모리 및 각종 통신 자원을 할당하고 해제하는 일은 상당히 많은 자원을 소모하는 작업이므로 보다 적은 메모리를 사용하는 것이 좋다. 

    네크워크 비용 : 직렬화를 수행하는 대다수의 프로그램 혹은 시스템은 네트워크를 통해 데이터를 주고 받게 된다. 네트워크 송수신에 있어서 패킷(packet)의 크기가 커질수록 전체 성능은 떨어진다.


▶ 직렬화 프레임워크 개요

  • JDK (Serializable)
    • 프로그래밍하기 가장 쉽고, Serializable 인터페이스를 이용해 별도의 라이브러리 없이 즉시 사용할 수 있다.
    • 클래스를 릴리즈(release)한 후에는 구현을 변경하기 어려워 유연성(flexibility)을 감소시킨다.
    • C++, 파이썬(python)등 다른 언어로 구현된 프로그램과 데이터를 교환(exchange)할 수 없다.
    • 기본 연산자의 취약점(hole)으로 인해 불변 값이 손상되거나, 비정상적인 접근이 발생할 수 있다.
      (invariant corruption and illegal access)
    • 커스터마이징(customization)이 불가능하고, 소스 코드를 수정할 수 있어야 한다.

  • Java externalization
    • 객체를 저장(persist) 및 복구(restore)하는 Externalizable 인터페이스를 구현해 직접 직렬화를 구현한다.
    • 인스턴스의 컨텐츠를 저장하고 복구하는 역할을 수행하는 클래스를 구현해야 한다.
    • 클래스의 구조가 변경될 때 마다, 읽고 쓰는 코드를 수정해야 한다.

      

  • Google GSON
    • 자바 객체를 JSON으로 변환하거나 반대의 작업을 수행하는 자바 라이브러리.
    • 직렬화된 객체의 소스 코드를 필요로 하지 않는다.
    • 커스텀 표현(custom representatives)을 지원한다.

       

  • Jackson
    • 고성능, 인간공학적 JSON 프로세서 자바 라이브러리
    • 광범위한 커스터마이징 툴 지원
    • 혼합 어노테이션 (Mix-in annotations)
    • 실체화된 인터페이스 (Materialized interfaces)
    • 다양한 데이터 포맷 : JSON, CSV, Smile(binary JSON), XML, YAML

  • BSON for Jackson
    • 바이너리 인코딩된 JSON (Binary encoded JSON)
    • 몽고 DB의 주된 데이터 교환 포맷 (Main data exchange format for MongoDB)
    • 확장 프로그램 작성 가능 (Allows writing custom extensions)

  • Protocol buffers
    • 구조적인 데이터를 확장가능하며 효율적인 포맷을 변환하는 방법 제공
    • 구글 내부에서 대부분의 내부 RPC 프로토콜과 파일 포맷에 Protocol Buffers를 사용 중.
    • Java, C++, Python 지원

  • Kryo
    • 빠르고 효율적인 객체 그래프 직렬화 자바 프레임워크
    • 구글 코드 상의 오픈 소스 프로젝트
    • 자동화된 깊고 얕은 복사/복제 (Automatic deep and shallow copying/cloning)
    • 소스 클래스에 대한 코드 작성 요건이 거의 없음
      (Doesn’t put requirements on the source classes in most cases)

▶ 성능 비교 분석


Posted by 곽중선
2015. 3. 16. 22:45

로깅(logging)은 "비 기능 요구사항(Non Functional Requirement)"에 속한다. 그러나 고객의 요구 여부에 상관없이 로그 출력 기능은 프로그램 개발 중 디버깅 및 개발 완료 후 문제 발생 시 원인 분석을 위해 좋은 프로그램이 필수적으로 갖추어야 하는 요구조건에 속한다.


로깅이란 무엇인가? How To BeAProgrammer 발췌


로그 기록(logging)이란 정보를 제공하는 일련의 기록인 로그(log)를 생성하도록 시스템을 작성하는 활동을 말한다. 프린트 줄 넣기(printlining)는 간단한, 보통은 일시적인, 로그를 생성하기만 한다. 완전한 초보자들은 프로그래밍에 대해 아는 것에 한계가 있기 때문에 로그를 이해하고 사용해야 한다. 시스템 설계자들은 시스템의 복잡성 때문에 로그를 이해하고 사용해야 한다. 로그가 제공하는 정보의 양은, 이상적으로는 프로그램이 실행되는 중에도, 설정 가능해야 한다. 일반적으로 로그 기록은 다음의 이점이 있다.

  • 그는 재현하기 힘든 (예를 들어, 개발 완료된 환경에서는 발생하지만 테스트 환경에서는 재현할 수 없는) 버그에 대한 유용한 정보를 제공할 수 있다.
  • 로그는, 예를 들어, 구문(statement)들 사이에 걸리는 시간과 같이, 성능에 관한 통계와 정보를 제공할 수 있다.
  • 설정이 가능할 때, 로그는 예기치 못한 특정 문제들을 디버그하기 위해, 그 문제들을 처리하도록 코드를 수정하여 다시 적용하지(redeploy) 않아도, 일반적인 정보를 갈무리할 수 있게 한다.


    자바에서 로그를 출력하는 방법

    초보자들은 System.out.print() 메소드를 이용해 실행 중 다양한 입출력 및 변수 값들을 출력한다. System.out.println 명령은 출력되는 로그의 양(혹은 수준)을 조절할 수가 없고, 표준출력(standard out)을 통해 출력하는 것은 로그를 파일 등에 저장하기도 불편하고 성능 면에서도 낮은 편에 속한다.


    자바 개발자를 위한 로깅 라이브러리는 이미 다양하게 개발되어 있기 때문에 직접 로그 출력 기능을 개발하는 것은 무의미하다. 다만, 다양한 라이브러리 중에서 적합한 것을 고르는 안목이 필요하다. 


    널리 쓰이는 로그 출력 라이브러리

    다양한 오픈 소스 로그 라이브러리가 존재하지만, 그 중에 널리 쓰이는 것들이 있기 마련이다.

    • java.util.logging
      JDK(Java Development Kit) 1.4 버전부터 자바에 포함된 표준 로그 API 이다. 별도의 라이브러리를 추가할 필요가 없다는 점이 장점이나, 다른 것들이 더 많이 사용되는 이유는 아마도 제공하는 기능이 가장 적다는 이유 때문일 것이다.
      Java Doc 혹은 Java Logging API - Tutorial 사이트를 참조하길 바란다.

    • Apache Commons logging
      아파치 재단(Apache Foundation)이 웹 서버(Apache Web Server)나 톰캣(Apache Tomcat) 서버만 제공하는 것이 아니다. 오히려, 아파치 재단에서 제공하는 다양한 오픈 소스 자바 라이브러리들이 아파치 재단의 영향력을 잘 보여준다. 그중에서 Commons 라이브러리는 프로그램의 기초를 단단히 다지고자 하는 학생에서는 멋진 도서관이다. Commons 라이브러리 중에서 로그 출력 기능을 제공하는 라이브러리가 Commons Logging 이다. Apache Commons logging 공식 홈페이지를 참조하길 바란다.

    • Log4j
      재밋는 사실은 아파치 재단에서 제작되는 로그 라이브러리가 하나 더 있다는 점이다. log4j 는 로그 라이브러리 중에서 가장 성공적이고 널리 사용된 라이브러리일 것이다. (공식 통계는 없지만....) Log4j 공식 홈페이지는 역시 아파치 사이트 중 하나이다. 참고로 Log4j version 2 부터는 JAVA 6 이상을 필요로 한다.

    • Logback
      Log4j를 만드신 분은 Ceki Gülcü 인데, Log4j를 만들어 놓고 더 좋은 라이브러리를 새로 만들게 된 것이 logback 이다. 오픈 소스 진영은 이렇듯 "창조적 파괴"가 빈번히 일어나기 때문에, 이미 잘 알고 있거나 오래도록 쓰고 있던 기술이 있더라도 항상 더 나은 기술이 나오지는 않았는지 살펴보는 주의력이 필요하다. 자칫 뒤떨어지기 마련이다. Logback 홈페이지는 다른 라이브러리에 비해서 매뉴얼이 상세한 편이다. 그만큼 제공하는 기능이 많다는 점은 확실히 부담스럽다.

    • 세상의 모든 로그 라이브러리
      남들이 쓰지 않는 특이한 것에 관심이 있다면 거의 모든 오픈 소스 로그 라이브러리 목록 : 
      Open Source Logging in Java 을 참고하면 된다.

    로그 라이브러리를 갈아끼울 수는 없을까?
    컴퓨터에 설치된 소프트웨어는 언제나 지우고 다른 제품을 설치할 수 있다. 그렇다면, 로그 라이브러리도 필요에 따라 갈아끼울 수는 없을까? 이런 생각을 하는 사람들이 분명 있다. 앞서 설명한 바와 같이 오픈 소스 진영에서 계속 새로운 라이브러리가 나오고 있으니 말이다.
    로그 라이브러리를 갈아 끼울 수 있게 만드려면 무엇이 필요할까? 혹은 어떤 선행 조건이 필요한가? 전기 콘센트에는 TV, 냉장고, 세탁기, 그외에 다양한 전자제품을 연결할 수 있다. 콘센트와 플러그가 호환만 된다면 말이다. 플러그는 제품에 붙어 있지만, 콘센트는 항상 벽에 붙여 있다. 이렇듯 프로그램에서 콘센트 역할을 하는 모듈과 플러그 역할을 하는 모듈을 분리하면 언제든 기능을 교체할 수 있다.

    그래서 콘센트 역할 - 이것을 디자인 패턴에서 사드(facade) 패턴이라고 한다 -을 하는 라이브러리가 나오게 되었고 SLF4J 라고 한다. SLF4J 자체는 로그를 출력하는 기능을 제공하는 것이 아니다. (콘센트가 있다고 저절로 냉장고가 생기는게 아닌 것처럼...) 하지만, 다양한 로그 라이브러리를 골라가며 쓰고 싶다면 한번쯤 공부해볼 만한 기법이다. 실제로 다양한 오픈 소스 제품들이 SLF4J를 활용하고 있다.


    그외에 읽을만한 거리...

    로거(logger)쯤은 이미 잘 활용하고 있기에 끝까지 한 달음에 읽었다면 다음 글들도 한 번 읽어보시길 권한다.

    logback을 사용해야 하는 이유

    아키텍처 설계: Logback을 활용한 Remote Logging


    SLF4J 로깅 처리


    Logging framework logback

    Posted by 곽중선
    2015. 2. 20. 14:15
    소프트웨어 개발자가 알아야할 기본 지식들을 정리한 문서들입니다.
    일부 완성되지 못한 문서들이 있으나 계속 업데이트될 예정입니다.


    Posted by 곽중선
    2015. 2. 20. 14:04


    0. 컴퓨터 시스템

    1. API (Application Programming Interface)

    2. 라이브러리 (Library)

    3. API vs. Library

    4. 프레임워크 (Frameworks)

    5. 통합개발환경(IDE : Integred Development Environment)

    6. 지속적인 통합 (continuous integration)

    7. 소셜 코드 공유

    .... and more

    Posted by 곽중선
    2015. 2. 20. 14:01



    • 소프트웨어 기술 요소
    • 학사 커리큘럼에서 익힐 수 있는 것들
    • 전공 필수와 선택, 우선 순위는?
    • 소프트웨어 개발자 직무의 다양성과 변화
    • 소프트웨어 개발자 직무별 필수 기술 요소
    • 직무 유형별 필수 기술 정리
    • 학생으로서 공부해야 할 것들


    Posted by 곽중선