ML in Action.. Ch. 1

올해 6월에 쓰고는 처음 포스팅이네요. 그간 직장을 옮기고, 자바 / 클로져 공부하고, 빅데이터 좀 파보고.. 300 줄 이내의 안드로이드 앱 하나 만드니 반년이 갔네요..

12월부터는 머신 러닝 살짝 파보려고 합니다.

매닝의 인 액션 시리즈..  참 좋은 것 같네요..

Part 1   Classification

이 책의 첫 두 파트는 supervised learning.  관리된 러닝은 목표 변수를 규정하고 데이터로부터 배우도록 지시한다.
목표 값의 두 경우.  노미널 : 참/거짓, 물고기, 포유류, 식물 …
실수 : 이 경우 ‘회기’ 라고 불림.  이것은 파트 2 에서 공부한다.
첫번째 파트는 분류 .. 에 촛점을 맞춘다.

7장의 분류 불균형으로 마무리. 다른 클래스들보다 한 클래스의 데이터가 더 많을 경우… 실세계의 문제.

Ch. 1 … Machine learning basics

머신 러닝의 여러 사례. 스팸 필터, 제품 추천, 얼굴 인식..

파이썬 : 머신러닝에 적합.  NumPy : 매트릭스 연산 등 제공.

1.1   What is ML ?

스팸 메일을 제목의 한 단어만 갖고 판단하기는 힘들다. 하지만, 여러 단어의 조합을 보고, 메일 전체의 길이 등 여러 요소를 같이 보면 더 잘 판단할 수 있다. 머신 러닝은 데이터를 정보로 바꾼다.

머신러닝은 컴퓨터 공학, 엔지니어링, 통계, 기타 다른 분야 등의 교차점에 놓여있다. 정치학, 지질학에 적용되기도 한다.

머신러닝은 통계학을 사용한다. 통계학은 회사가 소비자를 속이기 위해 악용되기도 한다.
인간의 동기는 모델링하기 어렵다.  사회 과학에서 60% 가 맞으면 성공적으로 간주된다. 사람 행동의 60%만 예측하면 잘 한 것이다.
항상 맞을 수는 없나?

완전한 모델링이 불가능한 예. 인간은 행복을 최대화 하기 위해 행동하지 않는가? 이것에 근거해 행동을 예측할 수 있는가?  아마도,  하지만 모든 사람의 행복은 다르기 때문에 어렵다.  그러므로, 사람의 행복을 극대화하는 것에 대한 가정이 옳을 지라도 행복의 정의는 너무 복잡하다.
인간 행동을 결정론적으로 모델링하기 어려운 다른 예들이 많다. 이런 문제에 대해서 통계의 몇몇 도구를 사용할 필요가 있다.

1.1.1 Sensors and the data deluge

웹에는 인간으로 부터의 데이터가 있는데, 요즘은 그 외의 데이터가 더 쌓이고 있다. 센서의 기술은 새롭지 않지만, 그것을 웹에 연결하는 것은 새롭다.

지진의 예.  센서.. 핸드폰..  의 3축 magnetometers.  지진 예측에 사용 가능.. 최소 비용.

1.1.2 ML will be more important in the future

향후 10년간 가장 매력적인 직업은 ‘통계학자’ 일 것이다.

1.2   Key terminology

새 분류 시스템. 엑스퍼트 시스템.    분류..

알고리즘을 만들고는.. 훈련시켜야..  또는 배우는 것을 허락해야..  이를 위해 training set 이라는 데이터를 먹여야 한다.
분류에서 타겟 변수는 노미널 값을 받고 회기 작업에서 값은 연속적일 수 있다.
트레이닝 셋트에서 타겟은 알려져 있다. 기계는 특징과 타겟 변수사이의 관계를 찾음으로 학습한다.
타겟 변수는 ‘종’ 이고 노미널 값을 취함으로 이것을 줄일 수 있다.
분류에서 타겟 값은 classes 로 불리고 유한한 개수의 클래스가 있다고 가정한다.

보통은 트레이닝 셋트와 별개의 테스트 세트가 있다. 초기엔 트레이닝 예제가 먹여진다. 이것이 기계학습이 일어날 때이다.
다음에 테스트 셋을 적용한다.  알고리즘이 얼마나 정확한지 추정.

새 분류작업을 한 후 기계가 뭘 학습했는지 알 수 있나?  이것이 knowledge representation 이다.
답은 ‘경우에 따라 다름’ 이다. 어떤 알고리즘은 사람이 읽기 더 좋은 KR 을 갖는다. 이것은 몇개의 법칙으로 표현될 수 있다.
어떤 것은 가능성의 분포 또는 트레이닝 세트로부터의 예 일 수도 있다.
어떤 경우 우리는 엑스퍼트 시스템을 만드는 것 보다 오직 ‘인지 표현’ 에만 관심이 있을 수도 있다.

1.3   Key tasks of ML

이전 예제는 ‘분류’ 에 관한 것.  인스턴스가 어떤 클래스에 들어갈 것이냐.  기계학습의 다른 분야는 ‘회기’ 임.
이것은 수치 예측이다.  이 두가지는 감독된 학습의 예임. 뭘 예측할 지 주어지기 때문에 ‘감독’ 된 것임.
이 반대는 ‘비감독 학습’.  여기선 데이터에 주어진 라벨이나 목표 값이 없다.
비슷한 아이템을 그루핑하는 작업은 ‘클러스터링’ 이라 한다.  비감독 학습에서 데이터를 설명하는 통계학적 값을 찾길 원할 수 있다.
이것은 density estimation 으로 알려져 있다.
다른 예는 많은 특성에서 데이터를 단순화시켜 2, 3차원 형태로 시각화하는 것이다.

1.4  How to choose the right algorithm

노미널, 목표값?. missing value 가 있나? outliers ?  needle in a haystack. ..

1.5  Steps in developing a ML application

> Collect data.
> Prepare the input data.
> Analyze the input data
> Human involvement
> Train and algorithm.  ML
> Test the algorithm
> Use it.

1.6   Why Python?

clear syntax. easy text manipulation

1.6.1 Executable pseudo-code

풍부한 기본 자료형, 객체 지향, procedual, 함수형 형태로 가능.  정규식 없이 텍스트 다루기.  …

1.6.2 Python is popular

NumPy, SciPy, Matplotlib ==>  Pylab

1.6.3 What Python has that other languages don’t have

Matlab, Mathmatica .. expensive.  Java, C … too many ceremony.

1.6.4 Drawbacks

Not as fast as Java or C.
Boost C++ library,  Python, PyPy.

1.7  Getting started with the NumPy library

Clojure in Action Ch. 1

by Amit Rathore

Preface

복잡성의 두가지
Essential complexity : 원래 복잡한 것.
Accidental complexity : 문제 외의 영역에서 초래된 복잡성.

Chapter 1. Introduction to Clojure

1.1 What is Clojure

1.1.1 Clojure – the reincarnation of Lisp

리스프의 환생.

1.1.2 How we got here

LISt Processing : LISP. 1958년에 설계된 언어.
“code as data” 의 개념.  70~80년대에 인공지능에 많은 투자가 이뤄졌지만, 대부분 실패. 그 오명을 리스프가 지게 됨.
JVM 위의 리슾 개념 : JScheme, Kawa, ABCL  등등.  하지만, 실용적으로 유용한 건 없었슴.
Rich Hickey : 창조자. 는 굉장한 일을 하였다.
클로져는 마침내 살아남은 리슾이 되었다.  –> 리슾의 미래이자 동적 프로그램 언어의 미래.

1.1.3 How this book teaches Clojure

이 책의 철학은 두 기둥에 놓여있다.
> 클로져의 첫번째 원칙을 강조하는 것.
> 그리고, 이러한 원리를 이해하기 위한 실용적인 접근.
많은 코드를 통해 이를 제공할 것이다.
클로져는 새로운 사고를 요구한다.

1.2 Understanding Clojure syntax

신택스는 호불호가 갈린다.
A Clojure expression is either < a symbol > or < a sequence >.
클로져는 배우기 지극히 간단한 언어다. (지랄. 아님) 신택스의 관점에서.. (맞아) 거의 아무것도 없다. (오케이)

1.2.1 XML and parentheses

1.2.2 Lists, vectors, and hashes

클로져는 리슾보다 더 많은 문법이 있지만, 이것이 가독성을 높여준다.
[ 벡터 ]  :  함수의 인수 리스트에 사용.  정수 인덱스 체계.
{ 해시 맵 / 사전 } : { :키 ,  값 }

1.3 The sources of Clojure’s power

1.3.1 Clojure and Lisp

1.3.2 Clojure and functional programming

> immutability, higher-order functions, laziness, concurrency semantics.

1.3.3 Clojure and the JVM

1.3.4 Clojure as a Lisp

AST (abstract syntax tree)
클로져의 런타임은 다른 언어와 다르게 작동한다. JIT 컴파일러 채용.. thanks to the JVM. 코드를 겁나 빠르게 컴파일 / 실행한다.
As alluded to, 암시…  contrive 억지스런, 고안해내다.
The Reader
리더는 소스코드를 AST 구현으로 크로져의 고유 데이터 구조를 이용하여 컨버트한다.
The Macro System
매크로는 클로져 함수. s-expression 을 인수로 받는다. s-expre.. 이 데이터 구조이므로 변형되고 반환가능하고 리턴된 값은 원래 형태로 사용된다.
이러한 코드-변형 매크로는 클로져 ‘위에’  미니 언어를 만들 수 있음.  DSLs (domain specific languages)
Metaprogramming with Macros
코드를 생산하는 코드
모든 클로져 코드는 같은 구조.  크로져 코드를 만들려면 심볼과 다른 데이터 구조를 갖는 클로져 데이터 구조를 만들면 됨.
이러한 신택스 없음과 매크로 시스템은 DSL 에 적합하게 한다.  ==> programmable programming language.
frivolous  천박한
매크로는 메타 프로그래밍의 ‘궁극’의 모습이다.

1.3.5 More advantages of Clojure

Dynamic Language
The REPL

1.3.6 Clojure as a functional language

클로져는 맵 리듀스 같은 higher-order functions 을 장려한다.
Higher-Order Functions

Machine Learning in Action Ch. 1, 2, 3

Part 1 CLASSIFICATION

1. Machine learning basics

Numpy, matrix, array etc

2. Classifying with k-Nearest Neighbors

숫자 인식.. 스킵.

3. Splitting datasets one feature at a time : decision trees

스무고개 ?  예/아니오 만 가능.
가장 보편적인 등급화 기법.  조사 결과 가장 많이 사용되는 ‘기법’.
이메일 분류.. 직원, 하키(친구) 기타는 스팸으로 분류.
콘택 렌즈 분류..

3.1 Tree construction

D. trees
Pro : 싸다, 결과를 사람이 인지하기 쉽다. 값이 빠져도 OK, 상관없는 특성들을 다룰 수 있다.
Cons : Prone to overfitting
숫자 값, niminal values 에 사용.

Information theory ..

데이터를 나눌 첫번째 결정을 설정해야..

createBranch .. 재귀적..
어떻게 데이터셋을 나눌 것인가.  [10/27]

General approach to decision trees
1. Collect : Any method.
2. Prepare :  ~~~

 

 

 

HDFS Architecture Guide

by Dhruba Borthakur

1. Introduction

분산 파일 시스템. 기존 시스템과의 차이점 : highly falut-tolerant , 저가 하드웨어에 디플로이 가능.
HDFS 는 Apache Nutch web search engine project 의 인프라로 만들어짐.
Apache Hadoop subproject.

2. Assumptions and Goals

2.1 Hardware Failure

하드 페일은 예외라기 보다는 ‘표준’ 이다. HDFS 인스턴스는 수백, 수천의 서버로 구성되어 파일 시스템의 데이터를 저장한다.
많은 수의 컴퍼넌트가 있다는 사실, 각 컴퍼넌트가 non-trivial 한 실패 가능이 있다는 것은 HDFS 의 일부 컴퍼넌트가 항상 non-functional 있다는 것을 의미한다.
그러므로, 결함의 발견과 그것의 빠르고, 자동적인 복구는 HDFS 의 코어 설계 목적이다.

2.2 Streaming Data Access

HDFS 에서 도는 어플은 자신의 데이터 셑에 접근하는 스트리밍이 필요하다. 그것들은 일반 파일 시스템에서 도는 일반 목적의 어플이 아니다.
HDFS 는 일반 유저 사용이 아니라 배칭 프로세싱에 더 알맞게 설계되었다. 데이터 억세스의 낮은 레이턴시보다 high throughtput of data access 에 집중.
Posix 는 HDFS 에 타게팅된 어플에 필요없는 많은 요구조건을 강요하고 있다.
Posix 의 몇몇 키 영역에서의 의미론은 데이터 처리율을 높이는 데 상쇄되었다.

2.3 Large Data Sets

HDFS 에서 도는 프로그램은 기가 / 테라 바이트의 파일.  그러므로, HDFS는 큰 파일을 지원하도록 튜닝 되었음.
싱글 클러스터에서 높은 최종 데이터 밴드위스 와 수백개의 노드를 지원해야 함. 한 인스턴스에서 수천만개의 파일을 지원해야 함.

2.4 Simple Coherency Model

파일에 대해 “1회 쓰고 – 여러번 읽기” 모델 이 필요. 파일이 생성, 기록, 닫히면 변경이 불필요하다. 이 가정은 데이터 일관성 이슈를 간단히 하고, 높은 데이터 억세스 생산량을 가능케 한다. 맵 리듀스나 웹 크롤러는 이 모델에 완벽히 맞아 떨어진다.
향후 추가-기록 을 지원하는 계획이 있음.

2.5 “Moving Computation is Cheaper than Moving Data”

어플의 요청에 의한 계산은 자료가 가까이에 있으면 효율적이다. 특히, 이것은 데이터가 클때 그렇다. 이것은 네트워크 사용을 최소화하고 시스템 성능을 증가시킨다. 가정은 이렇다. 데이터 가까이 컴퓨테이션을 이동하는 게 데이터를 이동하는 것보다 종종 낫다는…
HDFS 는 이렇게 데이터 가까이 어플리케이션을 가까이 가져가는 인터페이스를 제공한다.

2.6 Portability Across Heterogeneous Hardware and Software Platforms

플랫폼 간 이동이 쉽다.

3. NameNode and DataNodes

HDFS 는 마스터/슬레이브 아키텍쳐.
한개의 네임노드 (마스터 서버) +  여러개의 데이터 노드(보통 클러스터에서 노드당 한개), 노드에 붙은 스토리지 관리.
HDFS는 파일 시스템 namespace 를 노출하여 유저 데이터가 파일에 저장되도록 허용함.
내부적으로 한 파일은 하나이상의 블럭으로 나뉘고 이 블럭들은 데이터 노드들의 세트에 저장.
> 네임노드는 file system namespace operation 을 파일이나 폴더를 열고/닫고/리네임 하듯 함.
또한, 데이터노드에 블럭을 매핑하는 결정을 한다.
> 데이터 노드는 클라이언트로부터의 읽기/쓰기 요청에 대응할 책임이 있음.
데이터 노드는 블락생성/삭제/복제 등을 수행.

이 노드들은 머신에서 돌도록 설계된 소프트웨어의 일부임. 이 머신들은 GNU/Linux .. 보통.
자바로 쓰여짐. 자바를 지원하면 노드들을 돌릴 수 있음. 자바가 포터블성이 좋으므로 여러 머신에서 동작 가능.
전형적인 디플로이는 전적으로 네임노드 소트트웨어를 돌림. 각각의 다른 머신은 한 데이터노드를 돌림.
여러 노드를 한 머신에서 돌리는 것이 구조상 가능하지만 실제로는 적다.

네임노드가 하나인 것은 구조를 간단히 해준다. 이 네임노드는 메타데이터 등을 담는 중재자 역할.
유저 데이터는 네임노드를 통해 ‘절대’ 흐르지 않음.

4. The File System Namespace

기존 파일 구성 체계 지원. 디렉토리 생성 가능.  파일을 생성, 이동, 리네임 등 기존 체계와 비슷.
하지만 유저 쿼타를 구현하지 않음. 하드/소프트 링크 지원 안함.  하지만, HDFS 아키텍춰는 이런 구현을 배제하지는 않음.

네임노드는 파일 시스템 네임스페이스를 유지한다. 파일 시스템 네임공간의 변화는 네임노드에 의해 기록된다. 어플이 복제의 수를 규정. 파일의 복제 갯수는 그 파일의 replication factor 라고 함.  이 정보는 네임노드에 저장됨.

5. Data Replication

HDFS 는 큰 클러스터에 큰 파일을 여러 머신에 안정적으로 저장하게 설계되어 있음. 블락의 연속으로 파일 저장 ;
마지막 블락을 제외한 모든 블락은 같은 크기.
파일의 블락은 fault tolerance 를 위해 복제됨. 블락 크기와 복제팩터은 파일 별로 조절 가능. 어플리케이션이 파일의 복제수를 규정.
복제팩터는 파일 생성시에 규정 가능하고 나중에 바뀔 수 있다.
파일은 한번-쓰고 항상 한 writer 를 갖는다.

네임노드는 모든 블락의 복제에 관해 결정을 내림. 주기적으로 핫빝과 블락 레포트를 데이터노드로 부터 받음.
핫빝의 영수증은 잘 기능한다는 걸 의미.
레포트는 데이터노드의 모든 블락의 리스트를 포함함.

5.1 Replica Placement : The First Baby Steps

복제는 신뢰성/성능에 매우 중요.  복제 최적화는 HDFS의 차별화 요소. 또한 튜닝과 경험 필요.
랙 인식 복제의 목적은 데이터 신뢰성, 가용성, 밴드폭 활용을 향상시키기 위함.
현재 복제 정책의 구현은 이 방향의 첫번째 노력이다. 단기 목표는 제품 시스템에서 검증, 행동 연구, 더 복잡한 정책 연구 등이다.

대규모 HDFS 인스턴스는 여러 랙에 걸쳐 분산된다. 다른 랙의 두 노드사이의 통신은 스위치를 통해야 한다. 대부분의 경우 같은 랙 머신간의 네트웤 밴드폭은 다른 랙 사이보다 크다.

네임노드는 각 데이터노드가 속한 랙 아이디를 ‘하둡 랙 인지(Awareness)’ 에서 정하는 프로세스에 따라 결정한다.
간단하지만 최적은 아닌 정책이 복제를 유니크한 랙에 둔다.
이것은 랙 전체가 페일날 때 데이터 유실을 예방하고 데이터 읽기작업에 여러 랙으로부터의 밴드폭을 허용한다.
이 정책은 복제를 골고루 분산시켜 콤포넌트 실패에 로드 발란스를 쉽게 한다. 하지만, 이 방법은 쓰기작업이 여러 랙에 블락을 옮기는 것을 막아야하기 때문에 쓰기 비용을 늘린다.

일반적인 경우 복제계수가 3이면 HDFS의 원칙은 하나를 로컬랙의 한 노드에 놓고, 다른 건 다른 랙의 노드에, 세번째는 다른 랙의 다른 노드에 놓는다.
랙 페일의 가능성은 노드 페일보다 훨씬 적다. 이 원칙은 데이터 신뢰도와 가응성을 해치지 않는다.
하지만, 3개가 아닌 2 랙에 분리되어 있어 데이터 읽을 때의 밴드폭은 줄여준다. 또한, 랙에 골고루 분산시키지는 않는다.
이 원칙은 데이터 신뢰성과 읽기 성능을 떨어뜨리지 않으면서 쓰기 퍼포먼스를 향상시킨다.

여기서 기술된 현재의 디폴트 원칙은 진행 중임.

5.2 Replica Selection

글로벌 밴드폭 소비와 읽기 레이턴시를 최소화하기 위해 HDFS 는 리더에 가장 가까운 복제본으로부터 읽어야 한다?.
리더 노드와 같은 랙에 복제본이 있으면 그놈이 읽기 요청을 만족하는 것이 바람직함. 클러스터가 여러 데이터 센터로 펼쳐지면 로컬 데이터센터에 있는 복제본은 어느 원격 복제본보다 우선된다.

5.3 Safe Mode

시작 시 네임노드는 ‘안전 모드’ 로 들어간다. 이때 복제 작업 없음. 네임노드가 Heartbeat & Blockreport 메시지를 데이터노드로부터 받는다. 블락레포트는 한 데이터노드가 호스팅하는 블록들의 리스트를 담고 있다. 각 블럭은 복제본의 정해진 최소 수를 갖고 있다.
블락은 네임노드에 최소개수가 체크인하면 안전하게  복제됐다고 간주된다. 안전하게 복제된 복제본의 일정 퍼센트가 체크인하고 (추가 30초 ) 후에 안전모드에서 나온다. 그리고나서 정해진 숫자 이하의 블락을 갖는 데이터블록을 결정한다.
그리고나서 네임노드는 이 블락을 데이터노드에 복제한다.

6. The Persistence of File System Metadata

HDFS namespace 는 네임노드에 의해 저장된다.
네임노드는 현재 파일 시스템 메타데이터의 변화를 끊임없이 기록하기 위해 EditLog라 불리는 트랜잭션 로그를 사용한다.
예를 들어 새로운 파일을 생성할 때 네임노드는 이것을 가리키는 에딧로그에 레코드를 삽입한다. 복제 팩터를 바꾸는 것도 비슷.
네임노드는 수정로그 저장에 로컬 호스트 OS 파일 시스템을 이용한다.
파일 블록의 맵핑을 포함한 파일 시스템 이름공간 전체는 FsImage 라는 파일에 저장된다.
이 파일 역시 네임노드의 로컬 파일 시스템에 파일로 저장된다.

네임노드는 전체 파일 시스템 이름공간의 이미지와 파일 블록맵을 ‘메모리’에 띄운다. 이 키 메타데이터 아이템은 작게 설계되어 4기가의 램도 충분하다.
네임노드가 기동할 때 FsImage 와 EditLog 를 디스크에서 읽고 EditLog로 부터의 모든 트랜잭션을 FsImage의 인-메모리 객체에 적용하고 이 새로운 버전을 디스크의 새로운 FsImage 로 플러시아웃 한다.
그리고나서 기존의 EditLog 를 (반영이 되었으므로) 없앤다.
이 과정을 ‘체크포인트’ 라고 한다.
현재 구현에서는 체크포인트는 네임노드가 기동할 때만 일어난다. 향후에는 주기적으로 할 계획이다.

데이터 노드는 HDFS 데이터를 로컬 파일시스템에 저장한다. 데이터노드는  HDFS 에 대해 모른다.
단지 파일의 블럭을 로컬 파일 시스템에 저장할 뿐이다. 모든 파일을 같은 디렉토리에 생성하지 않는다. 대신, ‘자기발견 heuristic’ 을 사용하여 디렉토리당 최적의 파일 수를 결정하고 적당히 하위 디렉토리를 만든다. 모든 파일을 같은 디렉토리에 놓는 것은 적합하지 않다. (파일 시스템 문제)
데이터노드가 기동시 로컬 파일 시스템을 스캔하고 데이터 블록의 리스트를 만들고 이 레포트를 네임노드에 보낸다.
이것은 ‘블럭 레포트’ 이다.

7. The Communication Protocols

모든 HDFS 통신은 TCP/IP 위에 놓여진다. 클라이언트는 네임노드 머신위에 TCP 포트 연결을 확보하여 네임노드와 ClientProtocol 을 통신한다.
데이터노드는 네임노드와 ‘데이터노드 프로토콜’ 을 이용하여 소통한다.
RPC (remote procedure call) 추상화는 클라이언트 / 데이터노드 프로토콜 양쪽을 랩핑한다.
설계상, 네임노드는 어떤 RPC 도 초기화하지 않는다. 대신 데이터노드나 클라이언트에 의해 요청된 RPC 에 응답할 뿐.

8. Robustness

HDFS 의 주된 목적은 실패가 나더라도 데이터를 안정적으로 저장하는 것.
3가지 실패.

8.1 Data Disk Failure, Hearbeats and Re-Replication

각 데이터노드는 네임노드에게 핫빗 메시지를 주기적으로 보냄. 네트워크 파티션은 데이터노드의 섭셋이 네임노드와 연결을 잃게 할 수 있다. 네임노드는 최근에 핫빗을 안 보낸 데이터노드를 죽은 것으로 간주하고 더 이상의 IO 를 보내지 않는다. 죽은 노드에 기록된 데이터는 HDFS 에서 접근할 수 없다. 데이터노드의 죽음은 블럭의 복제 팩터가 내려가게 한다. 네임노드는 끊임없이 어떤 블락이 복제가 필요한 지 추적한다.
재-복제의 필요성이 여러 이유에 의해 제기된다 : 데이터노드가 접근불가,
복제본이 상한경우, 하드 디스크 페일 또는 복제 팩터 증가.

8.2 Cluster Rebalancing

HDFS 구조는 데이터 재균형 계획과 호환됨. 이것은 데이터노드의 빈 공간이 어느 레벨 이하로 내려가면 자동으로 다른 데이터노드로부터 옮겨온다.  어떤 파일에 대해 갑자기 높은 요구가 생기면 스킴은 동적으로 추가의 복제를 생성하고 클러스터의 다른 데이터와 재-균형할 수 있다.
이런 재균형은 아직 ‘미 구 현’ ..

8.3 Data Integrity

데이터노드로부터 가져온 블락이 손상되었을 가능성이 있다.  원인은 스토리지 이상, 네트워크 부실, 소프트웨어 버그.
클라이언트는 첵섬을 구현한다.
클라이언트가 HDFS 파일을 생성하면 각 블럭의 첵섬을 계산하여 HDFS 네임 공간에 히든 파일로 저장한다.
클라이언트가 데이터를 받을 때 확인.
틀리면 그 블럭을 다른 복제본에서 가져온다.

8.4 Metadata Disk Failure

FsImage & EditLog 는 중앙 데이터 구조임. 이 파일이 망가지면 HDFS 인스턴스가 기능 정지하게 됨.
이런 이유로 네임노드는 이 파일들을 여러 카피 유지하도록 함.
이 파일이 수정되면 각각의 복사본이 싱크되게 함.
이런 싱크 작업은 초당 트랜잭션 정도를 줄일 수 있다.
하지만, 메타데이터가 큰 것은 아니기 때문에 이런 성능저하는 수용할 만 하다.
네임노드가 재 시작할 때 최근의 파일들을 이용한다.

HDFS 클러스터에서는 네임노드 머신이 페일나는 한 지점이다. 네임노드가 페일나면 매뉴얼 작업이 필요하다.
현재, 자동 재시작과 네임노드의 페일오버시 다른 머신으로 이전은 지원되지 않는다.

8.5 Snapshots

특정 시간의 데이터의 카피 저장을 지원.  쓰임은 타임머쉰.. 에러 나기 전 시간으로 되돌림.  향후 기능.

9. Data Organization

9.1 Data Blocks

HDFS 는 큰 파일을 지원하기 위해 설계 되었음. 호환되는 어플은 큰 데이터 세트를 다룬다.
이 어플들은 데이터를 한번 쓰지만 한번 이상 읽고 이러한 읽기는 스트리밍 속도를 만족하는 것이 필요하다.
HDFS는 1번쓰고 여러번 읽는 개념을 지원한다. 전형적인 블럭 사이즈는 64 메가 바이트.
그러므로 64씩 잘라지고 다른 데이터 노드에 자리잡는다.

9.2 Staging

파일을 생성하라는 클라이언트 요청은 네임노드에 즉시 닿지 않는다.
실제로, 초기에 HDFS 클라이언트는 파일 데이터를 임시 로컬 파일에 캐시한다.
어플 쓰기는 이 임시 로컬 파일에 투명하게 redirect 된다.
로컬 파일이 블럭 사이즈만큼 데이터를 쌓게 되면 클라이언트는 네임노드에 컨택한다.
네임노드는 파일 이름을 파일시스템 위계에 넣고 데이터블럭을 잡는다.
클라이언트 요청에  네임노드는 데이터노드의 아이디와 최종 데이터 블록을 갖고 응답한다. 그리고나서 클라이언트는 임시파일에서 데이터 블럭을 지운다.
파일이 닫히면, 남은 데이터는 데이터노드로 옮겨진다. 그리고, 클라이언트는 네임노드에 파일이 닫혔다고 한다.
이때, 네임노드는 영구 공간에 파일생성 작업을 커밋한다.
파일이 닫히기전에 네임노드가 죽으면 파일은 잃어버린다.

위의 접근방식은 어플의 특성을 고려하여 세심히 설계 되었다. 이 어플들은 파일에 대해 스트리밍 쓰기가 필요하다. 클라이언트가 클라이언트 측 버퍼링 없이 원격파일에 직접 쓰면 네트워크 속도와 congestion in the network 는 작업에 상당히 영향을 준다.
이 접근은 선례가 없지 않다.  초기의 분산 파일 시스템은 성능을 향상시키기 위해 클라이언트 캐싱을 이용했다.
POSIX 요구는 더 높은 성능을 위해 relaxed ..

9.3 Replication Pipelining

클라이언트가 파일을 쓸 때 로컬 파일에 먼저 쓴다.
복제 계수가 3일 때를 가정.
로컬 파일이 데이터로 가득 차면, 클라이언트는 네임노드로 부터 데이터노드 리스트를 갱신한다.
이 리스트는 그 블록의 복제물을 보관할 데이터노드를 갖고 있다.
그럼 클라이언트는 그 블록을 첫번째 데이터노드에 플러시 한다.
첫번째 데이터노드는 데이터를 작은 조각(4KB)으로 받기 시작해서 로컬 저장소에 쓰면서 그 부분을 두번째 데이터노드에 전달한다.
두번째 노드는 똑같이 세번째 노드에 전달한다.
마침내 세번째 노드가 저장소에 보관한다.
데이터 노드는 파이프라인의 이전 노드에서 데이터를 받고 다음 노드로 넘겨준다.
그러므로 데이터는 한 데이터 노드에서 다음으로 파이프라인 된다.

10 Accessability

HDFS 는 어플에서 여러가지 방법으로 접근 가능하다.  네이티브는 자바 API 제공.
이것에 대한 C 래퍼 또한 가능.   HTTP 브라우저 가능.
WebDAV 프로토콜을 통하는 방법은 개발 중.

10.1 FS Shell

HDFS 는 사용자 데이터를 파일/ 디렉토리로 구성한다. 사용자 인터페이스를 위해 쉘 제공.
다른 쉘과 비슷.
스크립트 언어 지원 위해 필요.

10.2 DFSAdmin

Command set..  HDFS cluster 관리용
관리자 만의 용도.

10.3 Browser Interface

전형적인 HDFS 설치는 TCP 포트를 통한  ‘네임스페이스’를 노출시키는 웹서버를 구성한다.
이것을 통해 브라우징 하면서 내용을 확인할 수 있다.

11. Space Reclamation

11. 1 File Deletes and Undeletes

어플이나 사용자에 의해 파일이 삭제되면 바로 삭제 되지 않음.
휴지통으로 이동.
이동한 파일은 정해진 시간만큼 존재.
완전히 삭제된 후 네임노드는 HDFS 이름공간에서 파일을 삭제.
파일의 삭제는 그에 할당된 블락들을 해제시킴.
파일의 삭제와 빈공간의 증가 사이에는 시간 차이가 존재함.

파일이 휴지통에 있는 동안은 복구 가능.
복구하려면 휴지통으로 가서 복구 해야 함. 여기에는 최종본만 있음.
복구하는 규칙 :: 현재의 정책은 6시간 이상 경과한 파일을 지우는 것.
향후에는 여러 옵션을 적용할 수 있을 것이다.

11.2 Decrease Replication Factor

복제 계수가 줄어들면 네임노드가 지워질 여분의 복제분을 선택한다.
다음번의 핫빗 이 이 정보를 데이터노드에 전달.
데이터 노드가 블럭을 지우고 자유 공간이 증가.  역시 시간차이가 존재.

 

 

몽고 디비 MongoDB The Definitive Guide.. Ch. 4 : Querying

1. Introduction to find [p45]

> db.user.find () >> 컬렉션의 모든 값.
> db.user.find({“username: : “joe”, “age” : 27}) > And 조건절이 됨.

Specifying Which Keys to Return

두번째 인자에 받고 싶은 키를 전달.. 통신량과 일을 줄임. 아이디 키는 항상 리턴.
> db.users.find({}, {“username” : 1, “email” : 1})
키를 제외시킬 때는 0 전달. 아이디를 제외하는 것도 가능.
> db.users.find({}, {“username” : 1, “_id” : 0})

Limitations

쿼리는 상수여야 함. (코드의 일반 변수) 즉, 다큐먼트의 다른 키의 밸류값을 가질 수 없음.
이런 쿼리는 $where Queries … 에서 설명.

2. Query Criteria

보다 다양한 조건. range, or clauses, negation .

Query Conditionals [p47]

“$lt” “$lte” “$gt” “$gte”   “$ne” not equal.  (ne : 모든 타입에 적용 가능)
> start = new Date(“03/04/2007”)
> db.users.find({“registered” : {“$lt” : start}})

OR Queries

“$in” “$or” “$nin”

> db.raffle.find({“ticketNo” : {“$in” : [725, 23, 39]}})
> db.users.find({“user_id” : {“$in” : [345, “steve”]}}) >> 스키마를 변경했을 때 여러 타입 혼용 가능.

“$in” 은 단일 키에서 OR 쿼리 가능. 여러 키를 대상으로는 “$or” 필요.

$not

meta conditional  >> 제외시킬 때.

Rules for Conditionals

조건식은 ‘내부 다큐’, 업데이트 문은 ‘외부 다큐’.
조건식은 단일키에 여러번 적용가능.. 업데이트문은 한번만 가능.

3. Type-Specific Queries

여러가지 타입과 특별한 거동.

null

널은 자신과 매치. 존재하지 않는 것도 매치. 어느 키가 널인지 확인하려면 그 키가 존재하는지도 확인해야함.
> db.c.find({“z” : {“$in” : [null], “$exists” : true}})

Regular Expressions

> db.users.find({“name” : /joe/i })  >> case insensitive matching.
몽고디비 Perl Compatible Regular Expression (PCRE)  사용.
정규식은 자신과 매치.. 정규식을 넣으면 그대로 인식.

Querying Arrays

$all

하나 이상의 요소와 매칭하는 어레이 검색 시. 순서는 무관.
> db.food.find({fruit : {$all : [“apple”, “banana”]}})
한 요소만 넣으면 그냥 검색한 것과 동일.
어레이를 검색하면 순서, 요소 수 등이 완전히 일치해야 검색이 나옴.
키.인덱스 로 찾을 수도 있음.
> db.food.find({“fruit.2” : “peach”}) >> 과일의 3번째 요소가 ‘배’ 를 찾음.

$size

> db.food.find({“fruit” : {“$size” : 3}})  >> 어레이 크기가 3인 요소.
크기의 영역을 주어 검색은 불가.. 대신 “size” or “number” 등을 같이 사용하는 것은 가능
> db.food.update({“$push” : { “fruit” : “apple”}, “$inc” : {“number” : 1}})  >> 이렇게 하고
> db.food.find({“size” : {“$gt” : 3 }})  >> 이렇게 영역 검색할 수 있음.

The $slice operator

> db.blog.posts.findOne(criteria, {“comments” : {“$slice” : 10 }})
음수는 마지막에서부터.
[23, 10] >> 23개는 스킵하고 24번째부터 34번째까지 10개 리턴.
따로 지정되지 않으면 모든 키의 값들 리턴.  다른 명령어와는 좀 다른 액션.

Querying on Embedded Documents

임베디드 다큐 쿼리의 두가지 방법 : 전체 다큐 / 각각의 키/밸류값.  >> 각각 쿼리하는 게 더 맞는 것 같네..
{ “Embeded” :  {“keyA” : “SomeValue”, “keyB” : “TheValue” }}  >> 이런 경우 다른게 끼어들거나 순서가 바뀌어도 쿼리 불능.
{“Embeded.keyA” : “Some”, “Embeded.keyB” : “blabla” }  >> 이렇게 하면 스키마가 바뀌어도 쿼리 가능.

이런 “도트” 노테이션으로 하위 문서에 접근 가능… 하지만, 도큐먼트 키에 “도트” 를 쓸 수 없다는 제약.

범위를 지정할 때… $elemMatch  –> group criteria.
> db.blog.find({“comments” : {“$elemMatch” : {“author” : “joe”, “score” : {“$gte” : 5 }}}})
임베디드 다큐 쿼리조건에서 다수의 키 사용 시… 에만 필요함.

4. $where Queries

검색이 애매한 경우 $where 절 사용하여 자바스크립트 구문을 실행하면 거의 모든 쿼리 가능. (함수형 언어 특성 ? )
어떤 두 키에 대한 값이 같은 것을 검색하는 경우.
> db.foo.find({“$where” : fundtion() {
for (var current in this) {
for (var other in this) {
if (current != other && this[current] == this[other]) { return true; }  } }
return false;
}});
스트링으로 처리 가능.
> db.foo.find({“$where” : “this.x + this.y == 10”})
느리므로 꼭 필요할 때만 사용.  각 다큐먼트는 BSON 에서 자바스크리트 객체로 컨버트 된 다음 ‘웨어’ 구문을 수행한다.
인덱스 사용 불가.
복잡한 쿼리를 하는 다른 방법은 ‘맵리듀스’..

5. Cursors

커서를 이용, find 로부터 결과를 받음.
쉐에서 커서를 만드려면, 다큐를 컬렉션에 넣고, 쿼리를 하고, 결과를 로컬변수에 할당.
> var cursor = db.collection.find();
> whild (cursor.hasNext()) { obj = cursor.next();  //  do stuff   ….  }
## cursor.hasNext() ::   cursor.next() .. fetch.
커서 클래스에서 foreach.. 루프 제공.
find 를 부르면 즉시 수행하지 않고 쿼리를 통해 질문할 때 수행함.
> var cursor = db.foo.find().sort({“x” : 1}).limit(1).skip(10);  # 이때는 수행 안함.
> cursor.hasNext()  # 이때 쿼리가 서버로 보내짐.  쉘은 처음 100개 혹은 4메가를 가져와서 디비 억세스가 잦지 않도록 함.
이 결과를 다 소진한 다음 쉘은 다음 결과를 가져옴.

Limits, Skips, and Sorts [57]

Avoiding Large Skips

Advanced Query Options

Getting Consistent Results

6. Cursor Internals

fk

MongoDB & Python Niall O’Higgins Ch 3, 4

Ch 3. Common MongoDB and Python Patterns

A Uniquely Document-Oriented Pattern : Embedding

RDBMS 의 join 과 같은 역할.
임베디드 다큐도 다큐와 똑같이 작업 가능.
한 키의 다수의 임베디드 다큐는 특히 유용. 즉, 값이 어레이인 속성. ;; 문법에 맞고 매우 유용한 구조.
일-다 관계 표현하는 자연스런 방식. 또는 부모-자식 관계.
한 유저의 ‘여러’ 이메일.. 일반디비에서는 2개의 테이블. 그리고, ‘조인’
몽고에서는 키와 상응하는 이메일들의 어레이..
[.] 기호를 통해 하위 값 가져오기 가능.  즉, dbh.users.find_one( { “emails.email” : “abc@kin.com” } ) .. 이런식.

이 외에도 $pull, $push .. 제공.. atomic append, removal of  sub – documents…
어떤 이메일이 더이상 유효하지 않을 때.. 다큐를 찾아서, 고쳐서, 업데이트 .. 해야하지만,  번거롭고 레이스를 불러올 수 있음.
섭-다큐의 3가지 주 작업 : 삭제, 삽입, 수정..

dbh.users.update ( { “username” : “thename” } ,
{ “$pull” : { “emails” : { “email” : “erse@the.com” } } } , safe=True)

이 소스는 다큐를 찾아내서 어레이에서 atomic fashion 으로 제거하여 레이스 원천봉쇄.
쿼리로 $pull 을 이용 가능.  예를 들어 어떤 조건이 맞는 모든 섭-다큐를 지울 때..
즉.. dbh.users.update ( {“username” : “thename”},
{ “$pull” : { “emails” : { “primary” : { “$ne” : True }}}, safe=True)

atoms 를 갖는 어레이에 적용 가능.  임베디드 다큐 ‘만’ 갖고는 작동 안함.

푸쉬는 어레이에 요소 atomically 추가할 때 사용. 끝에 추가하는 것만 가능.  <어레이의 처음에 추가하거나 임의의 장소에 넣는 업데이트 기능은 없음>
조건문이 없어서 간단함.

new_email = {“email”:”fooemail4@exmaple4.com”, “primary”:False}
dbh.users.update({“username”:”foouser”},
{“$push”:{“emails”:new_email}}, safe=True)
==> # 기존의 섭 다큐를 업데이트..  => positional operator [ $ ] 를 통해 가능.
예 :: {“$set”:{“emails.$.primary”:False}}, safe=True)
>>*<< 업서트 에서 사용 불가, first matched element 에서만 가능.

__ Page 29 __
<1> 임베딩 관련 작업 시, 다큐, 섭-다큐의 성능을 아는 것이 중요. 쿼리에 의해 다큐먼트가 불려오면 섭 다큐 등 모두가 메모리에 로딩됨.
즉, 임베디드 데이터를 가져오는 데 추가의 자원이 필요 없다.. (인코딩 cpu 같은 거 제외하고)
최상위 다큐먼트가 가용상태면 섭-다큐는 즉시 가용함.  이것을 ‘조인’에서는 여러 테이블을 읽으므로 성능이 떨어짐.
<2> 몽고에는 크기 제한이 있지만, 버전 따라 커지고 있음. 1.8 은 16메가.  시간에 따라 커지는 데이터가 아니고서는 충분함.
댓글을 다는 경우.. 한 다큐에 있을 때.
__ To embed , or not to embed. _ _ _ _ _ ^^
임베딩의 대안 >> 다큐를 분리된 컬렉션에 저장.  어플에서 조인하는 코드 구성.
보통 >>> 다 : 다  관계는 이렇게 조인..
보통 >>> 일 : 다  관계는 임베드.

Fast Lookups : Using Indexes in MongoDB [p31]

인덱스의 역할은 관계형디비와 크게 다르지 않음.  두가지 제공 : Btree indexes & geospatial indexes.
Btree 는 MySQL 등과 유사.  관계형 시스템에서는 빨리 찾기 위해 인덱스 이용, 몽고에서는 의미상 인덱스를 컬렉션의 특정 속성에 사용.
몽고는 여러 필드로 인덱스 확장 가능. (a.k.a. compound indexes)  한개 이상의 속성에 기반하여 쿼링하는 것을 미리 알고 있을 경우에 유용.
예 > 성, 이름으로 쿼링할 때.
몽고에서 비트리 인덱스는 “방향”을 가질 수 있음.  컴파운드 인덱스에서만 유용. 성능을 위해 쿼리와 소팅의 방향이 매칭되야 함.
비트리 인덱스는 데이터에 앞서 인덱스를 업데이트해야 하므로 쓰기 퍼포먼스에 타격. 인덱스를 조심히 선택해야 함.
Superfluous indexes를 피할 것.
인덱스는 스토리지도 차지함.   메모리 역시.   전형적인 <시간 대 공간 트레이드 오프> 시나리오임..
비트리는 컬렉션에 특별한 제한을 가할 때도 사용.
비트리는 값이 어레이인 경우도 지원. 어레이의 각 아이템은 인덱스에 적당히 저장되서 다큐의 빠른 조사가 가능. 태깅 기능에 유용.
비트리는 임베디드 다큐도 지원.   예> 이메일을 섭 다큐로 지정하고 인덱스로 사용할 때.
서버 쪽 소팅 퍼포먼스에도 중요. 4메가 이상의 결과에 대해 소팅하려고 할 대 소트 키에 인덱스를 지정해야 함.  개발시에는 예상치 못한 거대한 실제 데이터에 대해 쿼리할 때 예외를 발견하는 것을 간과하기 쉽다.

파이 몽고 드라이버로 인덱스 생성.
Collection.create_index()  # method  single-key OR compound (튜플) indexes 생성.
dbh.users.create_index([(“first_name”, pymongo.ASCENDING), (“last_name”, pymongo.ASCENDING)]) # 리스트로 인덱스 생성 예.
인덱스에는 자동 이름이 붙지만 커스텀 네이밍 가능
dbh.users.create_index([(“first_name”, pymongo.ASCENDING), (“last_name”, pymongo.ASCENDING)], name = “myIndex_name”) # 커스텀 이름.

인덱스를 만들면 기본으로 디비를 ‘잠군다’. 큰 컬렉션에서 시간이 걸리므로. 백그라운드에서 생성 가능. 당연히 시간은 좀 더 걸리지만 디비가 ‘가용’ 상태.
dbh.user.create_index(“username”, background-True)

Unique constraint..  unique=True
유니크 옵션은 몽고에서는 관계디비와는 다름.  첫번째를 제외하고 중복 요소 제거.. dropDups = True

인덱스 제거는 쉽다. drop_index() method.

Collection.index_information() # Python .. 인덱스 조사.   Dictionary 리턴.  인덱스 이름 = 키, 밸류 = 또다른 딕셔너리.
이 딕셔너리는 key ..로 불리는 ‘키’ 를 포함. 인덱스 방향 포함한 원래 인덱스 specifier.   create_index에 넘겨진 것.   옵션들도 포함.

Location-based Apps with MongoDB : GeoSpatial Indexing [p33]

Points of interest (POI)

몽고는 Gustavo Niemeyer 가 개발한 geohasing 알고리즘 사용.
현재로서는 포인트-베이스 쿼링만 가능.
$near $within $box $circle $polygon (MongoDB v 1.9)
GPS 좌표만 가능 (-180 ~ 180 )
파이썬 딕셔너리는 순서가 없으므로 bson.SON 을 이용할 것.

인덱스는 하나의 위치인덱스만 포함 가능.. 다른 것과 같이 컴파운드 인덱싱 가능.

$near :: 기본으로 100개 결과 리턴. 최대값 지정 (5도 정도가 적당) 1도 = 69마일.
$nearSphere $centerSphere :: radian.

Code Defensively to Avoid KeyErrors and Other Bugs [p37]

Update-or-Insert: Upserts in MongoDB

save() : _id 없이 실행하면 새로운 다큐 삽입, _id 가 있으면 업데이트.  ;; 업서트 ..

업데이트는 두가지 경우를 각각 수행함. 문서가 있으면 업데이트 하고, 없으면 새로 만든 후에 업데이트를 실행함.

Atomic Read-Write-Modify : MongoDB’s findAndModify [p40]

업데이트 결과를 가져올 때.. 레이스 컨디션 회피 명령어.

Fast Accounting pattern

점수, 랭킹 계산의 경우.. 데이터 크고, 빠르게 계산 필요.

 

 

Ch 4. MongoDB with Web Frameworks

Pylons 1.x and MongoDB

WSGI-based web frameworks. 2005 09.  v1.0 at 2010
“one-size-fits-all”  < — > Pylon
So modular.. easy to add MongoDB

Pyramid and MongoDB

Pylons 2.0 ..
scaffold ..

Django and MongoDB

Mango..
10gen .. sample app.

2013. 2. 23.