2019년 10월 21일 월요일

ORC 파일 포맷 v1 자세히 보기

Background
2013년 1월, Hive의 속도 향상과 아파치 하둡에서의 데이터 효율성을 높이기 위해 ORC 파일을 만들었다. 높은 처리 속도와 파일 사이즈 크기를 줄이는 데에 목표를 둔 것이다.

ORC Specification
현재 ORC 파일은 2가지 릴리즈 버전이 있다.
 - ORC v0 : Hive 0.11에서 릴리즈되었다.
 -  Hive 0.12 와 ORC 1.x로 릴리즈되었다.

현재는 ORC v2를 위한 작업 중에 있다.

지금까지 매우 간단한 ORC 소개를 해보았고,
이제 본격적으로(?) ORC v1에 대해서 보자.

ORC Specification v1

Motivation

Hive의 RCFile이 원래 수년간 하둡에서 테이블 데이터를 저장하는 표준 포맷이었으나, RCFile은 각 컬럼을 시멘틱 없이 binary blob으로써만 처리한다는 한계점이 있었다. 그래서 Hive 0.11과 함께 Optimaized Row Columnar (ORC) 파일이라는 새로운 파일 포맷을 추가했다. 
ORC는 타입 정보를 함께 저장하며 이용했다. ORC는 타입 정보를 이용한 경량화된 압축 기법들을 사용했고 그럼으로써 드라마틱한 압축 효과를 볼 수 있었다. 여기서 말하는 경량화된 압축 기법이라 함은 사전 인코딩, 비트 패킹, 델타 인코딩, 연속 길이 인코딩(run length encoding)이었으며 추가적으로 일반적인 압축 방법(zlib, snappy) 또한 적용할 수 있다. 그러나 이런 저장공간 절약은 이점 중 하나에 불과하다.
ORC는 projection을 지원하여 어떤 컬럼을 선택하여 읽기를 요청하든 필요한 만큼만 읽어들여 원하는 컬럼값을 얻을 수 있다. 더 나아가 ORC file은 경량 인덱스(10,000 row 또는 전체 파일에 있는 컬럼에 대한 최소 최대값을 포함)를 포함하고 있다.
ORC file structure




이후의 순서는 ORC 파일 내용을 읽기 위한 순서와 연결해서 생각하면 이해하기 쉽다.

1. File Tail : 파일을 뒤부터 읽어서 필요한 메타데이터를 사용
2. Compression : 압축별 헤더를 통해 skip 가능하도록
3. Stripes : 실제 데이터 부분

File Tail (파일의 끝부분)

HDFS는 파일 쓰기 이후에 데이터 변경을 지원하지 않으므로 ORC는 파일의 끝에 top level index를 저장했다. 
먼저 알아야할 것이 ORC의 메타데이터들은 Protocol Buffer를 사용하여 저장된다. file tail은 아래와 같이 구성되어 있다. 오른쪽 정보는 해당 메타데이터를 표현하는 protobuf meesage type이다.

 - 암호화된 stripe 통계 : list of ColumnarStripeStatistics
 - stripe 통계 : Metadata
 - footer : Footer
 - postscript : PostScript
 - psLen : byte

PostScript

ORC file에서 가장 처음 읽게 되는 정보라고 생각하면 된다. 나머지 파일의 어떤 부분을 어떻게 읽어야할지에 대한 기본 정보를 포함한다. 그러므로 Postscript는 압축되지 않는다.

 - footerLength
 - compression
 - compressionBlockSize
 - version 
 - metadataLength
 - magic // the fixed string "ORC"

*version : 이 파일을 읽을 수 있는 Hive 최소 버전을 sequence로 나타낸다. ex) [0,12] : 0.12 버전 이상

Footer

파일의 바디에 대한 레이아웃 정보를 포함한다.

 - headerLength
 - contentLength
 - (repeated) stripes // Stripe Information
 - (repeated) types // Type Information
 - (repeated) metadata // UserMetadataItem
 - numberOfRows
 - (repeated) statistics // ColumnStatistics
 - rowIndexStride
 - writer
 - encryption
 - stripeStatisticsLength

*Stripe Information : 각각의 stripe는 하나의 row가 나눠지는 일은 없도록 데이터를 포함시킨다. 그리고 stripe는 크게 3개의 섹션 indexes, data, stripe footer로 나눠진다.
*Type Information : ORC 파일 내 모든 row는 같은 스키마를 가져야한다. 그리고 tree 구조로 나타냄으로써 map, struct 같은 계층적인 타입으로 표현할 수 있다.
ORC column structure
*User Metadata : 사용자가 임의로 key/value pair를 추가할 수 있다.
*Column Statistics : 파일내 모든 컬럼별 통계 정보를 저장하는데, writer가 타입별로 미리 정의된 유용한 정보를 기록한다. 대부분의 primitive 타입은 최소, 최대를 포함하고 숫자 형태는 sum까지 저장한다.

Metadata

 - (repeated) stripeStats // StripeStatistics
* StripeStatistics는 ColumnStatistics Set

즉 metadata에는 stripe level에서의 컬럼별 통계 정보를 포함한다.  데이터 조건절에 대한 stripe별 평가 지표로 사용될 수 있다.

Compression

ORC file writer에 일반 압축 코덱(zlib or snappy)를 선택하면, Postscript를 제외한 모든 부분이 해당 코덱으로 압축된다.
그러나 ORC 요구사항 중엔 이런게 있다.
 'reader는 전체 stream을 압축 해제하지 않고도 필요 없는 데이터(압축된)를 스킵할 수 있어야 한다' 
그래서 ORC는 아래와 같이 청크별로 데이터를 압축하며 3 bytes의 헤더를 붙인다. 압축된 후가 더 크다면 원래 정보를 그대로 저장하며 isOriginal 비트에 체크한다.
compression chunk default size는 256K이긴 하나, writer에서 해당 값을 선택할 수도 있다. chunk가 커지면 압축률은 좋아지겠지만 더 많은 메모리를 사용할 것이다. 지정된 청크 사이즈는 Postscript에 기록되므로 그에 맞는 적절한 크기의 버퍼를 통해 데이터를 read할 수 있다. Reader는 압축된 청크를 해제하더라도 지정된 청크 사이즈보다는 커지지 않을 것이라는 걸 알고 있기 때문에.

compression streams

Stripes

ORC 파일 바디는 stripe들로 구성되어 있다.
ORC 파일에서 각각의 컬럼은 여러개의 stream들을 통해 파일 내에 나란히 저장된다.

예1) integer column 같은 경우엔, PRESENT, DATA 라는 2개의 스트림으로 표현된다. PRESENT 는 데이터가 null이 아닌지를 표현하는 하나의 비트 표현이고, DATA는 null이 아닌 데이터를 기록한다. 모든 컬럼의 값이 null이 아니라면 PRESENT 스트림은 생략될 수 있다.

예2) binary data를 저장하기 위해서는 PRESENT, DATA, LENGTH를 사용한다. LENGTH 말 그대로 각 값의 크기(length)를 저장한다.

Stripe 구조는 아래와 같다.

 - index streams
 - data streams
 - stripe footer

* index streams : row group index, bloom filter index

Stripe Footer

Stripe footer는 각 컬럼별 인코딩 정보와 stripe 내 stream에 대한 위치를 포함한 정보를 가지고 있다.
 - (repeated) streams // Stream
 - (repeated) columns // ColumnEncoding
 - writerTimezone
 - (repeated) encryption

*Stream : 각각의 스트림 정보를 설명하기 위해, 스트림별로 종류(kind), columm id, size in bytes를 저장한다.




2019년 6월 26일 수요일

Hive 3.x의 새로운 변경 1. Managed Table vs External Table

Hive 3.x을 고려한다면 알아야할 변경 사항 1. Table Type

Managed Table 과 External Table


처음에 Hive 3.0이 나오면서 새로운 기능들에 초점을 맞추어 읽었고, (확실히 Hortonworks에서 Hive 개발을 많이 하는 가보다) Hive 3.0에 추가된 몇가지만 소개하면 아래와 같습니다.

  • Execution engine changes : Hive default engine으로서 Tez가 자리 잡다.
  • Design changes that affect security : 주요 권한 모델로 Ranger를 사용.
  • HDFS permission changes : Ranger를 안 쓴다면 HDFS ACL를 사용한다는 데 뭐가 바뀐건지는..
  • Transaction processing changes : 2에서 제공하던 transactional 기능과 성능 및 사용성 향상
  • Query execution of batch and interactive workloads : 뭔가 신기해보이는데 아직 잘 모르겠..

(위 내용은  HDP3 에서 hive 내용을 참고했습니다.)


 그런데 막상 적용하려고 보니 "기존에 제공하던 기능들이 여전히 잘 동작하느냐?" 가 관건이었고, 그 중에서도 테이블에 관한 변화에 대해서는 Hive 3을 고려할 때 가장 우선이 되어야할 내용이라고 생각했습니다.

 추가된 기능 상세 내용보다는 Hive 2와 비교해서 어떤 점이 달라졌고, 그래서 Hive 3을 쓰려면 무엇을 고려해야 하는지에 초점을 맞춰서 살펴보았습니다.

A. Managed Table의 default는 transactional(ACID)이며, ORC fileformat을 갖는다.

 - 기본 설정으로 사용할 경우, insert 뿐 아니라 row 단위의 update/delete가 가능하며 파티션별 트랜잭션으로 작업을 수행(isolation)합니다.

 - file format을 ORC외의 타입을 설정하면 insert_only로 지정됩니다.
 -- insert_only도 insert와 select 시에 실행 중인 것과 실패(aborted)된 트랜잭션을 고려하여 작업을 수행합니다.

 - transactional=true가 기본값으로 설정되며, managed table로서 사용하는 경우 변경할 수 없습니다.


B. Hive는 managed table에 대한 모든 제어 권한을 갖는다.

 - Managed table에 대한 데이터를 Hive를 통해서만 접근, 변경할 수 있습니다.
 -- 만약 Hive를 지나쳐서 data에 직접 접근하고 싶다면, external table을 사용하거나 Druid나 HBase 같은 storage handler를 사용해야 합니다.


아래 표는 Hive에서 사용하는 테이블 타입별 ACID 지원 여부와 필요로 하는 스토리지 포맷과 주요 SQL 처리에 대해 나타내고 있습니다.

Table TypeACIDFile FormatINSERTUPDATE/DELETE
Managed: CRUD transactionalYesORCYesYes
Managed: Insert-only transactionalYesAnyYesNo
Managed: TemporaryNoAnyYesNo
ExternalNoAnyYesNo


C. Managed table의 Owner는 Hive이다.


 - 위의 설명을 보면서, Insert-only transactional 을 보고 Hive 2에서 쓰던 일반 테이블과 비슷하겠구나 생각했었는데 이게 또 같지가 않았습니다.
 -- HDP 에서 2.x와 3.x의 테이블 타입의 차이점을 잘 설명하고 있습니다.

HDP 2.xHDP 3.x
Table TypeACID v1FormatOwner (user) of Hive Table FileTable TypeACID v2
ExternalNoNative or non-nativehive or non-hiveExternalNo
ManagedYesORChive or non-hiveManaged, updatableYes
ManagedNoORChiveManaged, updatableYes
non-hiveExternal, with data delete*No
ManagedNoNative (but non-ORC)hiveManaged, insert onlyYes
non-hiveExternal, with data delete*No
ManagedNoNon-nativehive or non-hiveExternal, with data delete*No

 - 위의 내용을 종합해서 보면, ORC 외의 native format (parquet, avro, rcfile 등)을 사용하는 managed table 중에서 hive가 아닌 외부 사용자(non-hive)를 통해서 데이터를 적재하던 테이블은 external table이 되어야 한다는 내용을 볼 수 있습니다.

 - external table로 사용해야 한다고 하더라도 with data delete*라고 해서 external.table.purge=true 테이블 프로퍼티를 사용하면 delete를 통해 HDFS에서의 삭제까지도 연결해서 사용 가능하도록 하고 있습니다.
-- https://issues.apache.org/jira/browse/HIVE-19981
-- 이 표 또한 HDP 문서인만큼 여기에선 문제가 없겠지만, 해당 JIRA를 보면 master에만 merge가 되었고 Fix Version에 4.0.0만 표기가 되어있습니다.
-- 즉 Apache Hive를 사용할 사람이라면 어느 버전에서 사용 가능할지 추가 확인이 필요합니다. 또한 이런 내용들(4.0.0에서나 반영될 수 있는 이슈와 버그)을 체크하여 patch 대상을 관리해야할 것으로 보입니다.



References
 - https://docs.hortonworks.com/HDPDocuments/Ambari-2.7.1.0/bk_ambari-upgrade-major-ppc/content/hive_post_upgrade_tasks.html
 - https://docs.hortonworks.com/HDPDocuments/HDP3/HDP-3.0.1/using-hiveql/content/hive_hive_3_tables.html
 - https://docs.hortonworks.com/HDPDocuments/HDP3/HDP-3.0.1/hive-overview/content/hive-apache-hive-3-architectural-overview.html

2018년 2월 9일 금요일

NiFi Clustering과 HA(High Availability)


  NiFi Clustering으로 찾아보면 Zero_master Clustering이라는 문구를 가장 쉽게 마주치게 됩니다. 1.0.0 버전에서부터 적용한 방식으로, 간단히 설명하면 ZooKeeper를 활용해서 내부적으로 Cluster Coordinator를 선정하여 NiFi의 flow를 클러스터된 노드들 모두 동일하게 유지합니다.
  Zero-master라 함은, Cluster Coordinator가 떠있는 노드가 SPOF가 되는 것이 아니라 또다시 다른 Cluster Coordinator를 띄울 리더를 선출하기 때문에, 마스터 역할만을 하는 노드가 별도로 존재하지 않기 때문입니다.

  그래서 처음에 쉽게 생각했습니다.
  'NiFi Clustering을 통해서 작업도 쉽게 분배하고, HA도 이룰 수 있겠구나.' 라고...

  결과는 둘 다 아니었습니다?
  HDFS, Hive, Spark 같이 처음부터 distributed 환경에서 쓰도록 만들어진 Application을 너무도 쉽고 당연하게 접할 수 있어서, 막연히 비슷하게 생각했던 것 같습니다.


  먼저, NiFi Clustering.

  3개의 노드를 하나의 클러스터로 구성을 하고, 그 중 하나의 노드의 UI에 접근을 해서 작업을 정의한다고 생각해 봅시다. 간단하게 아래와 같은 flow로 작성을 했습니다.
  ExecuteSQL -> ConvertAvroToORC -> PutHDFS
  그러면, 3개의 NiFi 노드에 동일하게 해당 flow가 생성이 됩니다. 그리고 작업을 전부 시작시켜 봅시다. 첫 번째 Processor(ExecuteSQL)가 폭주(?!)하지 않도록 적당한 schedule을 넣어 실행시켜 보겠습니다. 3개의 노드에서 모두 같은 SQL을 수행을 할 것이고, 그 결과 파일을 각자의 노드로 가져와서 ConvertAvroToORC 작업을 수행한 후에 해당 flowfile의 이름대로 HDFS에 파일을 put 할 것입니다. 즉 같은 파일이 3개가 HDFS에 쌓이게 되겠죠. (?)
  NiFi를 Single 노드로 쓸 때와 같이 작업을 정의하게 되면, 클러스터링된 NiFi는 각각의 노드에서 모두 같은 작업을 수행하게 됩니다. 사실 문서에도 해당 내용을 나와 있습니다. 클러스터링이 된다고 했지, 작업 분배를 자동으로 해 준다고는 안 했으니까요. (작업 분배가 필요하다고도 나와 있습니다.)
  그래서, NiFi 클러스터링에서는 작업 분배가 필요하고, 보통 아래와 같은 추가적인 Data flow 정의가 필요합니다.

  1) Kafka와 같은 queue로부터 작업을 시작 (ex. ConsumeKafka, ConsumeJMS)
  2) Nifi의 remote group이나 HAProxy처럼 Nifi Clustering 앞 단에서 분배해서 시작
  3) Data source를 바꿀 수 없는 경우 (대부분), 해당 데이터를 가져와야 할 processor를 On Primary Node로 설정한 후, 1,2와 같은 방법을 통해 작업을 재분배

  어쨌든 작업을 분배했으니 클러스터링해서 사용하는 의미를 찾을 수 있습니다. 우리는 처리해야 할 data에 비해서 cpu core도 부족하고, NiFi JVM에게 할당한 메모리도 넉넉치 못한 서버라서, 어쩔 수 없으니까요. 하지만 클러스터링이 곧 HA는 아닙니다.


  그러면 이제 HA (High Availability)

  NiFi를 3개의 노드로 클러스터링을 했으니까, 노드 하나가 죽어도 NiFi는 다음 리더를 선출해서 남은 노드들 중에서 Cluster Coordinator(및 Primary Node)를 시키면서 클러스터링을 유지해 나갑니다. NiFi UI를 통해서 현재 클러스터링 상태가 2/3 으로 바뀌는 것을 볼 수 있습니다. 그러니까 HA라고 할 수 있을까요.

  이번에도 이미 안 될 거라고 말했는데요.. NiFi도 클러스터링이 된다고 했지, HA는 된다고 한 적이 없습니다. 아마도 Failover가 안된다는 것이 조금 더 정확한 표현일 지 모르겠습니다.
  되는 것부터 보면, 하나의 노드가 떨어져나간 클러스터링의 상태에서도 Primary node를 zookeeper를 통해 새로 선정하게 될 것입니다. 그러면 위에서 말한 어느 방법이더라도 작업 분배에는 이상이 없습니다.

   문제는 이미 분배된 작업(및 data)인데요. 죽은 노드에서 돌던 작업들은 그 노드의 NiFi 프로세스를 되살리기 전까지는 그냥 사라져버린다고 볼 수 있습니다. 돌고 있는 노드들이 뭔가 조치를 해줄 수도 없고, 분배된 작업만 수행하는 입장에서는 솔직히 무슨 문제가 있는 지도 모릅니다.
  이 점은 정의해 놓은 flow가 복잡하고 오래 걸리는 작업일 수록, 그리고 데이터가 빠지지 않고 다 들어오는 것이 중요할 수록, 그리고 시간 제약이 있는 데이터일수록 문제가 크다는 생각을 합니다.
  어떤 이유에서 죽었는 지는 모르겠지만 해당 노드의 NiFi를 되살리면 NiFi의 ContentRepository, FlowFileRepository가 힘을 발휘해서 이어서 작업을 할 수는 있습니다.
  죽은 노드에서의 작업을 온전히 재수행이라도 시키기 위해서는 해당 노드의 NiFI를 어떻게든 되살리는 것 말고는 답이 없습니다.



  그래서

  ...
  '그래서'라고 부제목을 달고 보니, 답도 없으면서 무얼 위해 이렇게 장황하게 썼는가라는 생각이 드는 순간입니다. 저는 모르겠습니다. 비슷한 고민을 하는 Nifi 개발자가 Confluence에 던진 제안이 있는데 보면 요약해보면, Repository 를 HDFS와 같은 외부의 distributed 환경에 저장을 하고, failover 시 활용할 수 있도록 하면 HA를 할 수 있을 것이라는 내용입니다.(https://cwiki.apache.org/confluence/display/NIFI/High+Availability+Processing)

  NiFi 적용을 고려 중이시라면, 위 내용을 알고 접근하시면 좋을 것 같다는 생각에 글을 남깁니다. 긴 글 읽어주셔서 감사합니다. (사실은 넋두리..)

2018년 1월 28일 일요일

Hive LLAP (Interactive SQL) 이란?

참고 : https://cwiki.apache.org/confluence/display/Hive/LLAP

LLAP

Live Long And Process라고 Hive 2.0에서 추가된 기능이다.


Overview

Hive는 최근 수년 내에 커뮤니티의 활발한 활동의 결과(Tez와 Cost-based-optimization) 덕에 상당히 빨라질 수 있었다.  Hive가 다음 단계로 나아가기 위해서는 아래와 같은 것들을
필요했다.
 - Asynchronous spindle-aware IO
 - Pre-fetching and caching of column chunks
 - Multi-threaded JIT-friendtly operator pipelines

LLAP는 hybrid 실행 모델을 제공한다. 그 것은 HDFS Datanode와 직접적으로 통신하는 long-lived daemon과 긴말하게 통합된 DAG 기반 framework로 이뤄진다.
캐시, pre-fetching, 쿼리 프로세싱, 접근 관리와 같은 기능들이 daemon에서 수행된다. 또한 작은(짧은) 쿼리들은 대개 daemon에서 직접 수행되며, 무거운 작업은 일반적인 YARN 컨테이너를 통해 수행된다.

Persistent Daemon

캐싱과 JIT 최적화, 그리고 시작 비용을 없애기 위해, daemon이 클러스터의 worker 노드에서 돌고 있다. 해당 daemon은 I/O, 캐싱, query fragment execution을 수행한다.
 - Stateless
 - Recovery/resilency
 - Communication between nodes

Execution Engine (실행 엔진)

LLAP는 기존의 프로세스 기반의 Hive execution 모델에서 수행되므로, 기존 Hive의 확장성과 다재다능함(versatility)을 그대로 유지한다.
 - The ademons are optional. LLAP가 배포되어 동작 중인 상태에서도 Hive는 LLAP 없이 수행될 수 있다.
 - External orchestraction and execution engines. LLAP는 MapReduce나 Tez 같은 실행 엔진이 아니다. LLAP의 모든 작업 수행은 기존의 Hive 실행 엔진(Tez와 같은)에 의해 스케줄되고 관리된다. LLAP 지원 수준은 각자의 실행 엔진에 따라 다르다. 현재는 Tez를 지원하며, MapReduce는 계획에 없다.
 - Partial execution. LLAP daemon에 의해 수행 된 작업 결과는 쿼리에 따라 Hive 쿼리 결과의 일부를 구성하거나 외부 Hive 작업에 전달 될 수 있다.
- Resourece Management. 여전히 YARN이 리소스 할당 및 관리를 책임진다. JVM 메모리 설정의 한계를 피하기 위해 큰 작업(group by, joins)을 위한 버퍼나, 캐시된 데이터들은 off-heap에 저장된다. 이 방법은 작업 부하에 따라 추가적인 리소스 사용을 가능케 한다.

Query Fragment Execution

부분 실행을 위해 LLAP 노드들은 "쿼리 조각(query fragments)"들을 나누어 수행하도록 되어 있다. 여기서 쿼리 조각은 필터, projection, 데이터 변형, 부분 취합, 정렬, bucketing, hash join/semi-join 등의 작업이 될 수 있다.
 - Parallel execution. 하나의 LLAP 노드는 여러 쿼리 조각을 병렬처리 할 수 있다.
 - Interface. 유저는 LLAP 노드들에 client API를 통해 직접 접근이 가능하다.


I/O



Caching

LLAP daemon은 입력 파일의 메타 데이터 뿐 아니라, 데이터 자체도 캐시한다. 메타데이터와 인덱스 정보는 자바 객체로 프로세스에 저장되며, 캐시된 데이터는 off-heap에 저장된다.
 - Eviction policy. 캐치 교체 정책은 테이블 스캔을 통한 작업부하 분석을 통해 조정된다. 기본적으로는 LRFU와 같은 정책이 사용되며, pluggable하다.
 - Caching granularity. Column-chuck의 크기가 캐시의 데이터 단위가 된다. 이것으로 프로세싱 오버헤드와 스토리지 효율성 간의 조정이 가능하다. 파일 포맷과 실행 엔진에 따라 해당 청크의 세분성(granularity)가 정해진다.

Workload Management

YARN을 통해 작업 부하에 따른 자원을 관리한다. 실행엔진이 YARN으로부터 할당 받은 자원을 LLAP나 Hive executor를 새로 띄우기 위해 위임할 수 있다.

ACID Support

LLAP는 transactions을 인지한다. 테이블의 정상적인 상태를 위해 수행되는 델타 파일에 대한 머지가 일어난 후에 데이터 캐싱이 수행된다.
여러 버전이 가능하며 그 중에 사용될 버전을 선택하여 캐시를 요청할 수 있다. 이것으로 얻는 장점은 머지를 비동기로 수행하고 한번에 데이터를 캐시할 수 있다는 점이다.

Security

LLAP 서버는 태생적으로 파일 단위보다도 더 세분화된 레벨의 access control이 가능하다. 데몬이 처리 중인 컬럼과 레코드를 알고 있기 때문에 이런 오브젝트에 대한 정책 적용이 가능하다.

Monitoring

LLAP 모니터링에 대한 설정은 Slider가 사용하는 templates.py에 들어있다. (resources.json, appConfig.json, metainfo.xml)
LLAP Monitor Daemon은 LLAP 데몬과 마찬가지로 YARN 컨테이너에서 수행되며, 같은 port로 리슨하고 있다.
LLAP Metrics Collection Server는 모든 LLAP daemon들로부터 주기적으로 JMX metric 정보를 수집한다.

HDP 기준) Ambari Tez view를 통해 쿼리 수행 현황을 파악할 수 있다.


Web Services

) 기본적인 metrics 정보는 15002(default) 포트를 통해 web UI를 제공한다.

HIVE-9814 introduces the following web services:
JSON JMX data - /jmx
JVM Stack Traces of all threads - /stacks
XML Configuration from llap-daemon-site - /conf 
HIVE-13398 introduces the following web services:
LLAP Status - /status
LLAP Peers - /peers 


SLIDER on YARN Deployment

LLAP can be deployed via Slider, which bypasses node installation and related complexities (HIVE-9883).




참고하면 더 좋은 slideshare

https://www.slideshare.net/Hadoop_Summit/llap-longlived-execution-in-hive


Tunings

https://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.6.2/bk_hive-performance-tuning/content/ch_hive-perf-tuning-intro.html











2018년 1월 27일 토요일

LRFU (Least Recently/Frequently Used) 이란?

LRFU (Least Recently/Frequently Used)

Adaptive Cache Replacement Policy


캐시를 통해 데이터 처리 성능 향상의 꾀하는 경우에 캐시를 어떻게 유지하고 새로 교체해줄 것인 가에 대한 정책 중에 LRFU라는 게 있어서 찾아보는 중이다.
해당 기법을 본 건 LLAP Caching 부분을 읽다가 였다. (https://cwiki.apache.org/confluence/display/Hive/LLAP)

그 전에 알면 좋을 주요 교체 알고리즘으로 FIFO, LRU, LFU가 있다.
간단히 소개하면 아래와 같다.

FIFO (First In, First Out)
 - 가장 오래된 정보를 삭제한 자리에 새로운 정보를 저장하는 식이다.

LRU (Least Recently Used)
 - 가장 오래 사용되지 않은 정보를 교체한다.

LFU (Least Frequently Used)
 - 가장 빈도수가 적게 사용된 정보를 교체한다.

문제는 LRFU인데, 검색해보면 생각보다 나오는 내용이 없다.


먼저 wikipedia에서 Cache replacement policies를 찾아봤는데, 비슷한게 있었다.
그 내용을 살펴보면 아래와 같다.
https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_Frequent_Recently_Used_(LFRU)_[11]

LFRU (Least Frequent Recently Used)

LFU와 LRU의 장점을 합친 교체 정책으로써, 정보 중심 네트워크(Information-Centric Networking, ICN), 컨텐츠 전송 네트워크(CDN), 일반적인 형태의 분산 네트워크와 같은 캐시 어플리케이션에 적합하다. 
LFRU에서는 캐시가 2 부분으로 나눠지는데, privileged와 unprivileged 파티션으로 불린다. privileged 파티션에선 LRU를 적용하고, unprivileged 파티션에는 ALFU(거의 LFU?)를 적용한다는 것으로 예를 들면 다음과 같다. 
먼저, unprivileged에서 적은 횟수로 사용된 정보를 버리고, privileged 파티션에서 가장 오래된 정보가 unprivileged로 이동한다. 그리고 새로운 정보가 privileged의 빈자리로 들어온다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

위와 같은 내용이었는데, 문제는 순서가 다르다. LRFU가 아니라 LFRU인데.
그래서 조금 더 찾아봤더니 96년도에 서울대에 쓴 논문이 검색된다. 
LRFU (Least Recently/Frequently Used) Replacement Policy: A Spectrum of Block Replacement Policies (1996)

내용을 요약해보면 아래와 같다. 이 논문에서 block을 하나의 저장 및 교체 단위로 본다.

LRFU (Least Recently/Frequently Used)

LFU는 작업량의 추세를 반영할 수 없다. 예를 들면, 예전에는 자주 쓰이다가 현재는 안 쓰이는 block과 최근에 들어서야 점점 더 많이 쓰이기 시작한 block이 있을 때, 전자를 교체 대상으로 삼을 것이다. 구현 관점에서 보면, 보통 Priority queue가 사용되므로 시간 복잡도는 O(log n)을 나타낸다.
반면 LRU는 가장 최근에 남아있는 데이터에 대한 빈도만을 통해 선택을 해야 한다. 결과적으로 제대로된 빈도수 확인이 안될 수 있다. 하지만 다른 정책에 비해 패턴에 의한 변화를 줄 수 있는 형태이며 매우 효율적으로 동작한다. 하나의 연결 리스트로 구현할 수 있으므로, 시간 복잡도는 상수 O(1)이다.

두 가지의 장점을 합쳐 과거의 모든 block의 빈도(frequency)와 최신성(recency)을 둘다 보고 교체 대상을 선정할 수 있도록 하는 것을 Least Recently/Frequently Used(LRFU)라고 부를 것이다. 가중치에 따라 해당 정책은 스펙트럼의 형태로 나타나며 시간 복잡도는 O(1)과 O(log n)의 사이가 될 것이다.
LRFU 정책은 CRF(Combined Recency and Frequency)라는 값을 통해 해당 블럭의 재사용성을 판단하며, 가장 작은 값의 block이 교체 대상이 된다.

자세한 CRF 계산 과정은 논문에서 확인할 수 있다.
그 중 인상적인 부분은 CRF를 계산하기 위한 공식에서 사용되는 F(x)의 parameter인 λ의 범위를 0과 1사이에서 선택하며, 그 값에 따라 LFU와 LRU의 스펙트럼 어딘가에 위치하게 된다는 점이었다.
F(x) = (1/2) ^(λx)

또한 상관관계가 있는 기간(correlated period)을 하나로 묶어 계산할 수 있는 형태에 대한 계산 변형도 가능하다. Database 시스템에서는 data access에 대한 frequency와 recency보다는 상위 작업인 transaction 레벨에서 미래 예측이 더 용이하다고 보고, Gc(x)을 정의해서 사용할 수 있도록 한다.

CRF의 계산을 매번 가지고 있는 전체 block에 대해 수행하는 이슈는, 자료구조 heap을 통해 피해갈 수 있도록 상세한 Implementation 가이드를 포함한다. 결과적으로 Implemetation은 가중치에 따라 연결 리스트와 heap(Priority queue)로 나뉘어 계산된다고 볼 수 있다.

작업량(workload)의 특성에 따라 parameter λ와 c를 변형하여 addaptive 정책을 구성할 수도 있다.



2017년 8월 9일 수요일

Refactoring Techniques

Refactoring Techniques


.Composing methods

..extract method, inline method, extract variable, inline temp, replace temp with query, split temporary variable, remove assignments to parameters, replace method with method object, substitute algorithm

.Moving Feature between

..move method, move field, extract class, inline class, hide delegate, remove middle man, introduce foreign method, introduce local extension

.Organizing Data

..selfencapsulate field, replace data value with object, change value to reference, change reference to value, replace array with object, duplicate observered data, change unidirectional association to bidirectional, change bidirectional association to unidirectional, replace magic number with symbolic constant, encapsulate field, encapsulate collection, replace type code with class, replace type code with subclasses, replace type code with state/strategy, replace subclass with fields

.Simplifying Conditional Expression

..decompose conditional, consolidate conditional expression, consolidate duplicate conditional fragments, remove control flag, replace nested conditional with guard clauses, replace condional with polymorphism, introduce null object, introduce assertion

.Simplifying Method Calls

..rename method, add parameter, remove parameter, seprate query from modifier, parameterize method, replace parameter with explicit methods, preserve whole object, replace parameter with method call, introduce parameter object, remove setting method, hide method, replace constructor with factory method, replace error code with excetpion, replace exception with test

.Dealing with Generalization

..pull up field, pull up method, pull up constructor body, push down method, push down field, extract subclass, extract superclass, extract interface, collapse hierarchy, form template method, replace inheritance with delegation, replace delegation with inferitance


.Big Refactorings(추가)

..Tease Apart Inheritance, Convert Procedural Design to Objects, Separate Domain from Presentation, Extract Hierarchy


reference :
(1) Refactoring techniques
https://refactoring.guru/refactoring/techniques
  Martin Fowler's refactoring 예시로 쓰였던 코드들을 가지고, refactoring techniques를 적용과정을 step by step 확인할 수 있다.
  각각의 technique에 대해 Why, Benefit, How로 정리되어 있으며, 가장 하단에 Live Example로 차근차근 볼 수 있다. (Internet Explorer에서는 안될 수도)


(2) 대규모 리팩토링 (Big Refactorings)
http://wiki.gurubee.net/pages/viewpage.action?pageId=1507354
 구루비에서 한글로 작성된 내용이다. 읽어보진 않았지만 다른 Refactoring technique에 대해서 다루고 있는 것 같다. Big Refactoring에 대한 내용까지 포함하고 있어서 추가했다.


Linux Performance 기초


Netflix Techblog

what do you check in the first minute?

https://medium.com/netflix-techblog/linux-performance-analysis-in-60-000-milliseconds-accc10403c55

Tutorials

https://medium.com/netflix-techblog/netflix-at-velocity-2015-linux-performance-tools-51964ddb81cf

2017년 5월 28일 일요일

[Time Series Analysis] Symbolic Aggregate Approximation (SAX) 이란?

[Time Series Analysis]
Symbolic Aggregate approXimation 또는 Symbolic ApproXimation을 줄여 SAX라 한다.

먼저 SAX에 대한 개괄적인 설명은 아래와 같다.
(느낌이 잘 오지 않는데, Creating SAX을 보면 이해가 될 것이다.)

  SAX는 시계열(time series) data에 대해 time window로 나누고, 차원 축소를 하여 나타내는 하나의 방법이다.
  클러스터링, 분류(classification), 인덱싱(index) 등의 고전적인 데이터 마이닝 기법에서, 잘 알려진 표현방법인 DWT(Discrete Wavelet Transform), DFT(Discrete Fourier Transform) 만큼 좋으면서, 저장 공간은 적게 필요로 하는 것이 바로 SAX 이다.
  게다가, 생물정보학 또는 텍스트마이닝 분야에서 쓰이는 풍부한 자료 구조를 활용 가능할 뿐 아니라, 현재 데이터 마이닝 작업과 관련된 많은 문제에 대한 솔루션을 제공한다. (그렇다고 한다.)



Creating SAX


- Time series 형태의 Input이 들어오면, 계단형의 데이터 형태로 단순화한다. 이것을 PAA로 변환한다고 표현한다. (Piecewise Aggregate Approximation)

- 시간에 따른 곡선형 표현에서 계단형 모습을 바뀌게 된 것(PPA)을 텍스트 형태로 다시 기호화 한다. ex)aabbbccb 이런 형태로 표현된 것을 SAX라 한다.

PAA (Piecewise Aggregate Approximation)

Pros:
계산이 매우 빠르다.
다른 접근방법들만큼 효과적이다. (경험적으로)
임의의 길이에 대한 질의도 처리 가능하다.
Can support any Minkowski metric
Supports non Euclidean measures
간단! 명료!
Cons:
그려보면 알겠지만, 썩 만족스럽지 못한 형태로 보인다.


Symbolic ApproXimation

- PAA처럼 시계열 데이터를 조각으로 구분하여 표현한다.
- PAA에서는 표현한 측정치 대신 y축 또한 구간을 심볼로 표현한다. (텍스트 형태).

Symbol Mapping/SAX Computation.


PAA로 표현되는 y값에 대해 정규식을 통해 적절히 구간을 분류하여 구간별로 Symbol을 Mapping한다.

2017년 5월 3일 수요일

CentOS7 바뀐 기본 command (service, netstat, ifconfig

  바뀌거나 말거나 redirect 되어 있거나, yum install을 통해서 해결할 거라면 상관 없지만, deprecated된 데는 이유가 있을 테니 새로운 걸 사용해보려고 하면 찾아보기 귀찮기도 하고 헷갈린다. 그래도 왠지 그러고 싶다ㅋㅋㅋ

  개인적으로 자주 쓰는 명령어부터 하나씩 적어 놓으면 좋을 것 같다. 워낙 피상적으로만 쓰다보니 얼마나 될까 싶기도 하지만..


service postgresql status
  --> systemctl status postgresql

  : service가 systemctl(시스템 콘트롤러)가 되면서 동사가 들어간다고 생각하니 이해하기 편했다.

netstat -anop
  --> ss -anop

  : 내가 쓰던 옵션들은 ss에 다 살아있다.

ifconfig
  --> ip addr



Deprecated Linux networking commands and their replacements 관련 링크 :
  https://dougvitale.wordpress.com/2011/12/21/deprecated-linux-networking-commands-and-their-replacements/
  여기 들어가면 아래 command 관련해서 자세히 볼 수 있다.
  arp, ifconfig, iptunnel, iwconfig, nameif, netstat, route


2017년 5월 2일 화요일

PostgreSQL JDBC 버전 정책 변경 (9.4.xxxx to 42.x.x)


어떤 이유에서 PostgreSQL JDBC를 받으려고 하다가 버전이 갑자기 변경된 걸 보고 찾아보게 되었다. 왜 그럴까 궁금했다.

JDBC Release Notes를 보면, 2017-02-20부터 버전이 확 달라졌음을 알 수 있다.
Version 42.0.0 (2017-02-20)
Version 9.4.1212 (2016-11-02)

원문 내용 : https://jdbc.postgresql.org/documentation/faq.html
그에 대한 답변 중 일부만 간추리면 아래와 같다.

1. 새로운 버전 정책

  1.1 왜 9.4.xxxx 에서 42.x.x로 바뀌었는가?

    a) 해당 버전 PostgreSQL 서버의 버전 호환성 외의 기능만으로도 업데이트가 생기게 되어 더이상 서버의 릴리즈 스케줄과 같이 갈 필요가 없다.

    b) 서버 버전과 일치하는 JDBC를 써야할 것 같은 혼란에 빠진다. 예를 들면,  9.4.xxxx JDBC는 PostgreSQL 8.2 이상을 모두 지원한다.

    c) bug fixes, feature fixes를 구분하기 위해 Semantic Versioning이 더 적절했다.

  1.2 그럼 42라는 숫자는?

    그냥 랜덤이긴 한데, 당분간 서버 버전이랑 겹칠 일이 없을 만큼 큰 숫자기도 했다. 서버 42 버전은 2049년에나 나올 거니까.

    혹자는 42가 삶과 우주, 모든것에 대한 답이라고도 했고.
    (이런 농이 있는 줄 처음 알았네요. https://namu.wiki/w/42)

2017년 5월 1일 월요일

Hadoop(hdp) 클러스터 구성하기 using virtualbox (CentOS7)

0. Virtual Box 설치

https://www.virtualbox.org/wiki/Downloads

사용 버전 :
  VirtualBox 그래픽 사용자 인터페이스
  버전 5.1.22 r115126 (Qt5.6.2)

설치파일 : VirtualBox-5.1.22-115126-Win.exe

1. Virtual Box Image 생성


새로 만들기 (Redhat 64)
메모리  : 3333MB
디스크 용량 : 20GB

VM 네트워크 설정

  설정 > 네트워크 > 어댑터1
    - 다음에 연결됨 : NAT 네트워크
    - 이름 : NatNetwork (기본설정)

  그 외 설정에 대한 간략한 설명 링크 : http://frontjang.info/entry/VirtualBox의-NAT과-NAT-네트워크


2. CentOS 7 설치


설치 디스크 :
CentOS-7-x86_64-DVD-1611.iso


CentOS Install Options
  Keyboard Layout
    - Korean(101/104 key compatible)
    - English(US)

  Installation Destination
    - Automatic Partition

  Network & Host Name
    - enp0s3 enabled
    - hostname : node1, node2, node3


3. 네트워크 설정

node1, 2, 3에 대해서 아래와 같이 설정을 적용한다. IPADDR은 각자 다름.

command line : 

[root@node1 ~]# vi /etc/sysconfig/network-scripts/ifcfg-enp0s3

변경 내용 :
BOOTPROTO="static" #from dhcp
...(중략)
IPADDR="10.0.2.11" # (1), (2) 참고
PREFIX="24" # (1) 참고
GATEWAY="10.0.2.2" # (1) 참고
DNS1="168.126.63.1" # KT DNS Server 1
DNS2="168.126.63.2" # KT DNS Server 2

참고내용 :

(1) In NAT mode, the guest network interface is assigned to the IPv4 range 10.0.x.0/24 by default where x corresponds to the instance of the NAT interface +2. So x is 2 when there is only one NAT instance active. In that case the guest is assigned to the address 10.0.2.15, the gateway is set to 10.0.2.2 and the name server can be found at 10.0.2.3.


(2) examples
  node1 : 10.0.2.11
  node2 : 10.0.2.12
  node3 : 10.0.3.13

command line : 

[root@node1 ~]# systemctl restart network
[root@node1 ~]# ip addr
[root@node1 ~]# vi /etc/hosts

변경 내용 :
10.0.2.11 node1
10.0.2.12 node2
10.0.2.13 node3


  - 난 설정이 제대로 안 먹혀서 헤매다가 reboot 하고 나서 됐다..ㄷㄷ


4. host - guest 접속 설정

NAT Network만으로 사용하고자 한다면,
host에서 guest ip에 직접 접근할 수 없으므로, 포트포워딩 규칙을 이용해야 한다.

파일 > 환경설정 > 네트워크 > NAT 네트워크 > NatNetwork > 포트포워딩 > 규칙 추가

vm에 직접 접속하는 것보다 익숙한 shell client로 접속하려고 일단 22(ssh) 를 연결했다.























5. Ambari Server 설치

(참고 : https://docs.hortonworks.com/HDPDocuments/Ambari-2.1.0.0/bk_Installing_HDP_AMB/content/_download_the_ambari_repo_lnx7.html)

Ambari 서버가 될 노드에서 아래 순서로 진행한다.

1. root 로그인

2. Donwload Ambari reository
(CentOS7 을 minimal로 설치해서, wget이 없었다. yum install wget)

[root@node1 ~]# wget -nv http://public-repo-1.hortonworks.com/ambari/centos7/2.x/updates/2.1.0/ambari.repo -O /etc/yum.repos.d/ambari.repo

3. yum install ambari-server


Set Up the Amabari Sever

https://docs.hortonworks.com/HDPDocuments/Ambari-2.1.0.0/bk_Installing_HDP_AMB/content/_set_up_the_ambari_server.html


DB 준비

ambari 및 service의 metadata 저장소로 PostgreSQL을 쓸 것이다.

  PostgreSQL 설치
    ...

  jdbc 연결
    ambari-server setup --jdbc-db=postgres --jdbc-driver=/path/to/your/postgres/driver.jar

  hive metadata table 생성
    create user hive with password 'hive';
    create database hive owner = hive;

  설정 변경 (pg_hba.conf)

    파일 내용 :
# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
local   all   postgres                                     peer
# IPv4 local connections:
host    all   postgres             127.0.0.1/32            ident
# IPv6 local connections:
host    all   postgres             ::1/128                 ident
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local   replication     postgres                                peer
#host    replication     postgres        127.0.0.1/32            ident
#host    replication     postgres        ::1/128                 ident
local  all  ambari,mapred,hive md5
host  all   ambari,mapred,hive 0.0.0.0/0  md5
host  all   ambari,mapred,hive ::/0 md5
  설정 변경 후 PostgreSQL 재시작
    systemctl restart postgresql

ntpd 설치

https://www.cmsfactory.net/node/11424


Start the Amabri Server

[root@node1 ~]# ambari-server start


 Connect to Ambari (http://node01:8080)

host PC에서 chrome을 쓰는게 편할 것 같아서, node01에 대해 port 8080만 위에서 한 것처럼 포트포워딩을 연결했다. 이런 식으로 많이 쓰일 것 같으면, NAT Network 외에 네트워크 어댑터가 추가하는 게 나을 것 같은데, 아직 모르겠으니 그냥 두는 걸로..

Installing, Configuring, and Deploying a HDP Cluster

https://docs.hortonworks.com/HDPDocuments/Ambari-2.1.0.0/bk_Installing_HDP_AMB/content/ch_Deploy_and_Configure_a_HDP_Cluster.html



설치된 모습..

  나중에라도 서비스들을 추가할 수 있어서 일단 몇 개만 깔았다.
























2017년 4월 20일 목요일

[Machine Learning] 4. Supervised Learning - Classification

Classification

  - Predictive modeling for categorical or discrete values (or class)
  - 각 케이스에 해당하는 그룹을 판별한다.
      . 광고 메일에 대한 반응(답장 여부)
      . 어떤 수술 방법에 대해 적합한 환자인지
      . 신용 평가가 좋은지 나쁜지(또는 등급)
  - training data로 model을 생성하고, 예측에 대한 평가는 그 외의 data로 수행한다.
      . 주로 training data/testing data를 구분하여 수행한다.
  - Classification models
      . Decision Trees
      . Neural Networks
      . Support Vector Machine
      . Discriminant Analysis
      . Logistic regression
      . K-nearest neighbor


이번 글에서는 Logistic regression에 대해 주로 다룰 것이다.
(후에 Decision Tree, Neural Network, Support Vector Machine을 다룰 예정)


Logistic Regression

식을 쓰려다가 막막해서 wiki를 찾아봤는데, 설명이 잘 되어 있다.
(우씨 떄려칠까 그냥)

https://ko.wikipedia.org/wiki/%EB%A1%9C%EC%A7%80%EC%8A%A4%ED%8B%B1_%ED%9A%8C%EA%B7%80

wiki page에서 4. 모델 피팅 내용 전까지 보면 된다.
이후에 모델 피팅 방법으로 wiki에 제시된 것과 다르게, Gradient descent method를 통해 계산할 것이다. (컴퓨터가)


R 코드 예시 :
> testdata = read.table('buytest.txt',sep='\t',header=T)
> lgstResult = glm(RESPOND~X1+X2+X3+X4+X5+X6+X7+X8+X9+X10,
             family=binomial(), data=testdata)


Logistic Regression도 마찬가지로 이전 글(http://justkook.blogspot.kr/2017/04/machine-learning-3-supervised-learning.html)에서 설명한 것처럼 한번만 수행하는 것이 아니라, 가장 적합한 모델을 생성하기 위해서 X Variable을 선택하는 방법이 필요하다.
(Backward Elimination, Forward Selection, Stepwise Selection)


Model Comparison

문제는 Logistic regression은 Linear Regression과 다르게, R-square 또는 p-value가 없어서 모델을 비교하는 다른 방법이 필요하다.

그렇기 때문에 data를 3가지로 분류해서 사용한다.
  - Training data : Regression Model 생성 시 활용
  - Validation data : Model Comparison 에 활용
  - Testing data : 선택된 모델(final model)에 대한 검증 시 활용

Training Dataset을 정할 때 유의할 점이 있다.
  - 전체 data set을 대표할 수 있도록 random sample
  - 매우 희귀한 reponse를 찾는 모델을 다룰 경우, 충분한 관측치가 포함되어야 한다.
      . stratified sampling : random sample로 불충분한 경우에는 일정 비율을 맞춰 데이터를 샘플링 하기도 한다.

Model Comparison in Classification
  - Accuracy
  - Lift chart
  - Profit chart
  - ROC curve (AUROC)
  - K-S statistics


Confusion Matrix

                       predicted class
                         0              1
actual  0    True Negative   False Positive
class    1   False Negative   True Positive


  - Accuracy = true positive / actual positive
  - Error = 1- accuracy
  - Sensitivity = true positive / (false positive + true positive)
  - Specificity = true negative / (true negative + false positive)


Lift Chart
  - Cumulative table


Profit Chart
  : 해당 차트를 통해, cut-off value를 선택

ROC Curve
  - ROC stands for Receiver Operating Characteristic

Graph of ROC
y = True positives
x = False Positives ( 1 - Specificity )

, 그리고 AUROC (Area Under ROC)
AUROC는 linear regression에서의 r-square와 비슷한 값으로
회귀식 에 대한 신뢰도라고 생각할 수 있다.

[Machine Learning] 3. Supervised Learning - Regression

빅데이터에서의 Regression 회귀분석에 주로 쓰이는 기호/용어가 있다.

y = Θ0 + Θ1X1 + ... + ΘpXp
  = ΘTX + ε

... (기호 못 쓰겠다.. gg)
(Θ는 회귀계수를 나타내는 vector (1xN matrix)
(ΘT는 theta transpose)

회귀식은 hypothesis라 하여 아래와 같이 나타낸다.
hΘ(x) = ΘTX

Cost function = mean squared error
J(Θ) = 1/2m x Σ( hΘ(x) - yi )^2
Find Θ which minimizes J(Θ)

비용함수 J(Θ)의 최소값을 찾기 위한 방법에는 크게 2가지가 있다.
1. Normal Equation : 미분해서 0이 되는 값 구하기
2. Gradient descent method

가장 큰 차이점은 Normal Equation의 경우 시간복잡도가 O(p^3)
Gradient descent method가 O(p^2)이다.
데이터가 크면 선택의 여지 없이 Gradient descent method를 써야할 것이다.


Linear Regression
p-value를 통해 유효한 feature 및 그에 대응하는 Coefficients 를 통해 선형 회귀식을 도출한다.

여러가지 Variable 중 선택하는 방법엔 크게 4가지가 있다.

  - All Subsets
      : 모든 경우의 수(2^k) 수행해보기
  - Backward Elimination
      : 모든 변수를 포함한 회귀식을 수행한 뒤, 원하는 유효 수준(p-value)기 되지 않는 변수를 하나씩 삭제한다.
  - Forward Selection
      : Backward와 반대로 변수를 하나씩 넣어보고 가장 유효한(작은 p-value) 변수를 하나씩 추가한다.
  - Stepwise Selection
      : Forward Selection, Backward Elimination을 한번씩 수행한다.

계산 비용은 예측 가능한대로다.
All Subsets > Stepwise > Forward > Backward

일반적으로 Stepwise를 쓰나, 계산이 많은 경우 Backward를 수행한다.




[Machine Learning] 2. Pre-processing (Preparation)

Big Data Analytics에 있어서, 상당 부분 시간이 소요되는 부분은
사실 분석보다는 분석을 위한 준비 단계(데이터 수집+데이터 정제)이다.








참조 :


최근 관련 시장을 보면, Paxata, Datameer, Alteryx와 같은 툴 뿐 아니라, IT 기업에서 다양한 가치와 경험을 내걸고 출시하고 있는 솔루션들이 많다. 
 ex. ETL(AWS Glue), Data Preparation(Google DataPrep)


Data Preparation이라는 무슨 작업일까?

data 정제 및 분석에 알맞은 형태로 변환이라는 넓은 범위에서 보면 상당히 다양하다.

 - missing value 제거 
 - 데이터 추가 (ex. Timestamp field)
 - type 확인하기 (ex. number, string, categories, etc)
 - replace values
 - split values with delimiter
 - data scaling : 분석 모델에 따라 필요한 경우가 많다. 
     (ex. log(x), sqrt(x), 1/x, x^2, exp(x), 표준화(X-μ/σ)
 - dummy variables(indicator variable) 
     . 범주형 data에 대해 필드를 추가하여 0 or 1로 나타냄.


Machine Learning Series에서는 이 정도로만 다루고 넘어가도록 하자.

[Machine Learning] 1. Introduction

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[Machine Learning Series]
1. Introduction (4/20 upload)
2. Preprocessing (4/20 upload)
3. Supervised Learning - Regression (4/20 upload)
4. Supervised Learning - Classification (4/20 upload)
5. Supervised Learning - Neural Network
6. Supervised Learning - Decision Trees
7 Supervised Learning - Support Vector Machine
8. Unsupervised Learning - Clustering
9. Association Analysis - Text Mining
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Machine Learning

What is machine learning?
내가 좋아하는 단어를 포함하는 정의로 하면,
예제 데이터 혹은 과거 데이터를 이용하여, 요구 성능을 최적화하는 것! 
Optimize a performance criterion using example data or past experience.


분석 프로세스
Selection : 다양한 source로부터 data를 수집
Pre-processing : data 클린징
Transformation : 분석을 위한 format으로 데이터를 변경
Machine Learning/Data Mining
Interpretation/Evaluation : 의미 있는 결과를 도출


Machine Learning Tasks
 - Association Analysis 
     : 연관성 분석 (ex. 목요일 밤, 마트에서 맥주를 사고 나면, 기저귀를 같이 산다.)

 - Supervised Learning
     : training/sample data에 y값에 대한 결과가 존재
     . Classification 
         : 분류 (ex. 스팸인지 아닌지, 신용등급 평가)
     . Regression/Prediction
         : 분류를 포함한 다양한 회귀분석 기법 (ex. 중고차의 가격 예측)

 - Unsupervised Learning
    : y가 없는 data에 대한 분석
     . Clustering
       
 - Reinforcement Learning
     . Decision making
 - Deep Learning

2017년 3월 10일 금요일

2017년 3월 9일 목요일

AllFusion ERwin Data Modeler 7

AllFusion ERwin Data Modeler 7 를 이용해서
Logical Model, Physical Model을 개발/관리


개발 DB는 PostgreSQL 이었는데, MySQL.erwin_fe-template으로 별문제가 없어서 그냥 쓰기로 했다.


Logical Model
Format > Display Level >







Physical Model

2016년 12월 7일 수요일

JVM 메모리를 넘는 Huge Excel 파일 입출력

https://poi.apache.org/spreadsheet/limitations.html

  위의 링크 내용 중 메모리에 관한 내용만을 추리면 아래와 같다.


- - - - - - - - - - - -

디폴트 POI 클래스들을 쓰는 것만으로는 memory의 한계가 있다. 
그러므로 매우 큰 Excel 파일을 읽거나 쓰려고 한다면 Out of memory를 만나게 될 것이다.
Main memory에 Excel 처리를 위한 객체를 올려서 작업하는 스타일 때문인데, 이것을 극복하기 위한 방법이 있다.

* 매우 큰 파일을 쓰기 위한 SXSSFWorkbook이 있다. 이것은 data를 streaming으로 쓸 수 있도록 도와준다.

* 매우 큰 파일을 읽기 위해서는XLSX2CSV 을 참고해 볼 수 있다. Excel 파일을 streaming 형태로 읽을 수 있도록 하며, 읽어들이는 정보의 한계가 있으므로 필요할 경우 수정해서 사용할 수 있다.

- - - - - - - - - - - -

  위의 내용 중 매우 큰 Excel 파일 읽기에 대한 경험이 있다. 소스 코드(XLSX2CSV)를 참고로 하여, Excel(XLSX)를 파싱하면서 몇가지 문제가 겪었다.

  일단 Excel(XLSX) 파일은 XML 파일들과 그 외 메타데이터를 포함한 압축파일이다. (그래서 .xlsx 파일을 확장자만 .zip 파일로 변경하면 압축해제를 할 수 있기도 하다.)
  아무튼 XLSX2CSV 예제는 엑셀을 XML 형태로 읽어 들여 element 별로 처리를 해서 데이터를 읽도록 되어 있다.
  XML Parsing 라이브러리를 사용해서 streaming으로 읽기 작업을 처리할 수 있게 된 것인데, 그러면서 생긴 제약이 Excel에서 비어 있는 셀에 대해서 xml이 비어있을 수 있는 문제가 발생하게 된다. 그래서 실제로 사용하면서 필요했던 내용들을 어떻게 보면 하드코딩 방식으로 때워가며 사용했었다.

  가장 일반적인 형태로 xml의 element가 비어 있는 시나리오가 3가지가 있었고, 그러한 상황에 대처하기 위해 method를 추가하는 식으로 작업을 했다.

  매번 재작업하기 보다는 미리 정리해놓고 사용할 수 있었으면 좋겠다는 생각이 들어서 github repository에 올려놓았다.

https://github.com/sungpeo/large-xlsxtocsv


Java finalizer

GC 공부하면서 Finalize에 대한 설명을 들었는데,
난 그게 뭔지 여태 몰랐던 거였음. 소름.

link : http://www.javatpoint.com/difference-between-final-finally-and-finalize


There are many differences between final, finally and finalize. A list of differences between final, finally and finalize are given below:
No.finalfinallyfinalize
1)Final is used to apply restrictions on class, method and variable. Final class can't be inherited, final method can't be overridden and final variable value can't be changed.Finally is used to place important code, it will be executed whether exception is handled or not.Finalize is used to perform clean up processing just before object is garbage collected.
2)Final is a keyword.Finally is a block.Finalize is a method.