다형성

다형성이란 타입정보를 매개변수화 함으로써 인터페이스의 재사용을 높인다.
https://twitter.github.io/scala_school/ko/type-basics.html

1 제네릭 클래스 (Generic Classes)

값만 넘길 수 있도록 정의된 함수는 보통의 함수가 되고, 구체적 타입과 값을 넘겨야 하는 경우 일반적(제네릭) 함수가 된다

제네릭은 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입 체크를 해주는 기능이다.
즉, 클래스 내부에서 사용할 데이터 타입을 나중에 인스턴스를 생성할 때 확정하는 것을 제네릭이라 한다.

(C++ / JAVA 에서도 제네릭 메서드가 존재) http://devbox.tistory.com/entry/Java-%EC%A0%9C%EB%84%A4%EB%A6%AD
자바 개념이 있어서 그런지 스칼라 문서들은 다 대충 설명한다.
입문자라면 자바에서 개념을 찾는 것이 편하다.
JAVA

class Person<T>{
    public T info;
    // p1 일시 데이터 타입은 String이된다.(인스턴스 생성시 String 제네릭 생성) 
    // p2 일시 데이터 타입은 StringBuilder이 된다. 
}
public class GenericDemo {
    public static void main(String[] args) {
        Person<String> p1 = new Person<String>();
        Person<StringBuilder> p2 = new Person<StringBuilder>();
    }
}

스칼라

class Stack[T] {
  var elems: List[T] = Nil
  def push(x: T) { elems = x :: elems }
  def top: T = elems.head
  def pop() { elems = elems.tail }
}
2 다형성 메소드 (Polymorphic Methodes)
def dup[T](x: T, n: Int): List[T] =
3 가변성 (타입 가변성) (Type Variance)

위 예제에서 Stack[T] 가 Stack[Char] 의 인스턴스에는 Stack[Char] 만 가능한 제약을 해결하기 위해 도입

3-1 순가변자 (Covariant)

순가변자는 타입 파라미터가 하위 타입을 포괄하도록 함으로써 타입 파라미터의 호환 범위를 넓혀준다.

class X[+T]
// 순가변적 파라미터 T가 선언된 타입을 상속했다면, 언제나 scala.Nothing 타입(모든 타입의 최하위 타입)을 타입 파라미터로 사용할 수 있다.
val x: X[String] = new X[Nothing]   // legal
val x: X[String] = new X[Object]    // illegal
3-2 역가변자 (Contravariant)

역가변자는 타입 파라미터가 상위 타입을 포괄하도록 함으로써 타입 파라미터의 호환 범위를 넓혀준다

class Y[-T]
// new Y 임을 주목
val y: Y[String] = new Y[Nothing]   // illegal
val y: Y[String] = new Y[Object]    // legal
타입경계 Type Boundaries

타입 파라미터의 가변성과는 별도로, 타입 파라미터의 범위를 한정해 타입간 포함 관계를 제약해야 할 때가 있다.

  • 상위 타입 경계의 경우, 타입 파라미터 T가 반드시 타입 A의 하위 타입이어야 한다면 ‘T <: A’

  • 하위 타입 경계의 경우, 타입 파라미터 T가 반드시 타입 A의 상위 타입이어야 한다면 ‘T >: A’로 표현해 이 관계를 지정할 수 있다.

타입 가변성 & 경계 (Type Variance & Boundaries)

타입 가변성은 타입 파라미터가 허용하는 타입의 범위를 확장 하지만 이것만 가지고 범위를 제한 할 수 없다.
아래는 한계점을 설정해줘야 하는데 가변성&경계를 이용해 범용성을 높인 예제

// 타입 변수 A를 순가변자로 어노테이션해서 하위 타입을 포용할 수 있도록 변경
class Stack[+A] {
  // 하지만 push 메소드의 파라미터가 역가변자 위치 <<< 이건 먼말인지 확인하라
  //  A를 그대로 사용할 경우 컴파일 오류
  // 새로운 타입 변수 B를 도입해서 push 메소드의 타입을 A와 분리하는 한편, A와 B 간에 타입 경계 관계를 설정해 두 타입 간에 연결이 유지
  def push[B >: A](elem: B): Stack[B] = new Stack[B] {
    override def top: B = elem
    override def pop: Stack[B] = Stack.this
    override def toString() = elem.toString() + " " +
                              Stack.this.toString()
  }
  def top: A = sys.error("no element on stack")
  def pop: Stack[A] = sys.error("no element on stack")
  override def toString() = ""
}
상위타입 경계

http://docs.scala-lang.org/ko/tutorials/tour/upper-type-bounds.html
타입 파라미터와 추상타입의 타입
상위 타입 경계 T <: A
타입 변수 T를 선언하면서 서브타입 A를 참조

trait Similar {
  def isSimilar(x: Any): Boolean
}
case class MyInt(x: Int) extends Similar {
  def isSimilar(m: Any): Boolean =
    m.isInstanceOf[MyInt] &&
    m.asInstanceOf[MyInt].x == x
}
object UpperBoundTest extends App {
  // 여기
  // 상위 타입 경계 어노테이션이 없었다면 메소드 findSimilar에서 isSimilar 메소드를 호출할 수 없었을 것
  def findSimilar[T <: Similar](e: Txs: List[T]): Boolean =
    if (xs.isEmpty) false
    else if (e.isSimilar(xs.head)) true
    else findSimilar[T](e, xs.tail)
  val list: List[MyInt] = List(MyInt(1)MyInt(2)MyInt(3))
  println(findSimilar[MyInt](MyInt(4), list))
  println(findSimilar[MyInt](MyInt(2), list))
}
하위타입 경계

http://docs.scala-lang.org/ko/tutorials/tour/lower-type-bounds.html
상위 타입 경계 T >: A
T나 추상 타입 T가 타입 A의 슈퍼타입

 


https://community.hortonworks.com/articles/42027/rdd-vs-dataframe-vs-sparksql.html



특정 Spark 데이터 처리 작업 부하에 대해 RDD 대 DataFrame 대 SparkSQL의 성능 비교


결론 :  데이터 프레임이 짱. 데이터셋은 진보중.


RDD가 DataFrames 및 SparkSQL보다 우수한 성능을 발휘했다고 나오는데 DataFrame 및 SparkSQL 테스트를 위해 RDD 에서 데이터 프레임으로 변환하는 과정때문이라고 Comment 로 지적. databricks 에서 SparkSQL csv reader 를 사용했다면 비교가 다를 것이라고 지적. 



아파치 문서마다 DataFrame에 RDD 보다 뛰어난 메모리와 쿼리 옵티마이져가 있기 때문에 데이터 프레임이 빠르다.

파일이 json 이라면 바로 데이터 프레임으로 읽을 수 있으면 RDD 보다 높은 성능을 보일 것...



http://www.agildata.com/apache-spark-rdd-vs-dataframe-vs-dataset/



RDD 주된 단점은 자바 직렬화 사용. (대부분 kryo 를 빠른 대안으로 사용)


데이터 프레임은 Spark 1.3 에서 Spark 성능과 확장성을 개선하고자 project Tungsten 이니셔티브 의 일부로 새로운 데이터프레임 API 를 도입했다.

데이터 프레임은 스키마 개념을 도입하여 자바 직렬화를 사용하는 것보다 spark의 스키마를 관리하고 노드간에 데이터를 전달하는 방식을 훨씬 더 효율적으로 허용한다.

Spark 가 바이너리 형식의 오프힙저장소로 데이터를 직렬화 한다음 오프 힙메모리에서 직접 많은 변환을 수행하여 개별 개체를 구성하는 것과 관련된 가비지 수집 비용을 피할 수 있으므로 단일 프로세스에서 계산을 수행할 때 장점이 있다.(데이터를 인코딩하기 위해 자바 직렬화를 사용할 필요가 없음)


자바로 DataFrame 또는 Dataset API 를 채택하기전에 스칼라로 전환하는 것을 고려해야 한다.

자바로 작성을 해야 하면 bean 을 완벽히 준수 해야 한다.

스칼라 + Spark 1.6.0 을 사용하여 코드를 제작하는 경우 DataFrame API 가 가장 안정적인 옵션이며 현재 가장 우수한 성능 제공

데이터를 직렬화 할때 Dataset API 는 JVM 표현(객체)와 Spark 의 내부 바이너리 형식 사이를 변환하는 인코더 개념을 가지고 있다. Spark 에는 바이트 코드를 생성하여 오프 힙 데이터와 상호 작용하고 전체 개체를 비 직렬화 할 필요없이 개별 특성에 대한 필요시 액세스를 제공한다는 점에서 매우 진보된 기본 제공 인코더가 있다.




databrics 사에서 DataFrame 소개

https://databricks.com/blog/2015/02/17/introducing-dataframes-in-spark-for-large-scale-data-science.html


오늘, 우리는 더 많은 사람들이 큰 데이터 처리를 더욱 쉽게 할 수 있도록 고안된 새로운 DataFrame API를 발표하게 된 것을 기쁘게 생각합니다.




위의 차트는 실행중인 그룹 단위의 런타임 성능을 단일 시스템 ( 소스 코드 https://gist.github.com/rxin/c1592c133e4bccf515dd ) 에서 1,000 만 개의 정수 쌍으로 비교합니다 . Scala와 Python DataFrame 연산은 모두 JVM 바이트 코드로 컴파일되어 실행되기 때문에 두 언어간에 차이가 거의 없으며 바닐라 Python RDD 변형은 5 배, Scala RDD 변형은 2 배의 성능을 보입니다.


Spark 1.3 의 일부로 출시 

Spark 1.6 에서 안정화?

https://spark.apache.org/releases/spark-release-1-6-0.html

http://www.itworld.co.kr/news/97513

Spark 2.0 에서 많은 발전...

'오픈소스 > Spark' 카테고리의 다른 글

[Spark] SQL and DataFrame  (0) 2017.04.10
[Spark] Overview  (0) 2017.01.25



스칼라에서는 다음과 같은 정규식 연산자가 지원됩니다.


. - 개행 문자를 제외한 모든 단일 문자와 일치합니다.


$ - 줄 끝과 일치합니다.


^ - 줄의 시작과 일치합니다.


[...] - 대괄호 안에있는 단일 문자와 일치합니다.


[^ ...] - 대괄호 안에있는 문자를 제외한 모든 단일 문자와 일치합니다.


\\A - A로 시작하는 문자열과 일치합니다.


re * - 선행 표현의 0 번 이상 일치


re + - 이전 것 중 하나 이상을 찾습니다.


re ? - 선행 표현의 0 또는 1 발생과 일치합니다.


re {n} - 선행 표현의 정확히 n 번 일치


re {n,} - 선행 표현식이 n 회 이상 일치합니다


re {n, m} - 선행 표현의 n 번 이상 m 번 일치


x | y - x 또는 y와 일치합니다.


(re) - 정규 표현식을 그룹화하고 일치하는 텍스트를 기억합니다.


(? : re) - 일치하는 텍스트를 기억하지 않고 정규식을 그룹화합니다.


(?> re) - 백 트랙킹없이 독립적 인 패턴과 일치합니다.


\\w - 단어 문자와 일치합니다.


\\W - 단어가 아닌 문자와 일치합니다.


\\s - 공백과 일치합니다. [\t \n \r \f]와 동일합니다.


\\S - 비 공백 문자와 일치합니다.


\\d - 숫자와 일치합니다. [0-9]와 같습니다.


\\D - 비 일치와 일치합니다.


\\A - 문자열 시작 부분과 일치합니다.


\\Z - 문자열의 끝과 일치합니다. 개행 문자가 있으면 개행 직전과 일치합니다


\\z - 문자열의 끝과 일치합니다.


\\G - 마지막 경기가 끝난 지점을 알려줍니다.


\\n - 캡처 그룹 번호 "n"에 대한 역 참조


\\b - 바깥 괄호가있을 때 단어 경계를 찾습니다.


\\B- 단어 경계와 일치합니다.


\\n, \\t, 등 .- 개행 문자, 캐리지 리턴, 탭 등과 일치합니다.


\\Q - 모든 문자를 \\E까지 이스케이프 (인용)합니다.


\\E - \\Q로 시작하는 인용 끝



스파크 SQL


소개


각 레코드의 필드 구성에 대해 모두 알고 있을 경우 스파크 SQL 을 더 쉽고 효과적으로 불러오고 쿼리를 쓸 수 있다.


스파크 SQL 주요 기능 3가지

1. DataFrame 추상화 클래스 제공

2. 다양한 구조적 포맷의 데이터를 읽고 쓸 수 있다 (JSON, Hive, 파케이(parquet)

3. 내부 JDBC/ODBC 나 외부 Tableau (태블루) 같은 BI 툴 등을 써서 스파크 SQL 을 통해 SQL 로 데이터를 질의 할 수 있다.


SchemaRDD

Row 객체의 RDD 

각 아이템은 Record 를 의미

RDD 와 유사해 보이지만 내부적으로는 좀더 효율적인 방법으로 저장하고 Scheme 이점 활용한다

RDD 에서 제공되지 않는 Operation 도 제공

DataFrame은 이전버젼(1.0~1.2)에서 쓰이는 SchemaRDD가 진화한 것

SchemaRDD 로 코딩되어 있어도 1.3이상에서는 DataFrame으로 쓰는것과 같다.

Dataset 은 SQL 의 최적화된 실행 엔진의 이점을 이용하여 RDD (강력한 타이핑, 람다기능)의 이점을 제공하는 Spark 1.6 에서 추가된 새로운 인터페이스.


그외

1. 스파크 SQL 은 하둡의SQL 엔진인 apache Hive 를 포함하거나 또는 포함하지 않고서 빌드가 가능하다.

2. 하이브 의존성 충돌은 주의 해야한다. spark-hive_2.10, spark-sql_2.10

-> SQLContext 는 스파크 SQL의 기능을 제공하지만 하이브에 의존하지는 않는다.

3. HiveQL 은 스파크 SQL 을 쓰기위해 추천하는 질의 언어




구조


그림1

아래는 스파크의 전체 구조입니다.

우리는 본 문서에서 SQL 에 대해서 살펴볼 예정입니다. 

아래 그림2에서 Spark SQL 구조에 대해서 알아봅시다.


그림2

스파크 SQL 의 적용

Hive, JSON, Parquet 등으로 수집된 Spark SQL 을 태블루 등이 JDBC 등을 이용하여 질의 하는 내용이다.



그림3

다음 그림은 스파크SQL의 다른 세부 구조를 보여줍니다.



즉 API, RDD, DATA Source 가 아키텍쳐에 포함되어 있다.



DataFrame

1 큰 클러스터 단일 노드 클러스터에서 페타 바이트에 킬로바이트 크기의 데이터를 처리 할 수 있는 능력.

2 다른 데이터 형식 (아 브로, CSV, 탄성 검색, 카산드라) 및 스토리지 시스템 (HDFS, HIVE 테이블, MySQL은, 등)을 지원합니다.

3 스파크의 SQL 촉매 최적화 (트리 변환 프레임 워크)을 통해 기술 최적화 및 코드 생성의 주.

4 쉽게 스파크 코어를 통해 모든 빅 데이터 툴과 프레임 워크와 통합 할 수 있습니다.

5 파이썬, 자바, 스칼라, 및 R 프로그래밍을위한 API를 제공합니다.



Databricks 의 데이터 프레임 소개

https://databricks.com/blog/2015/02/17/introducing-dataframes-in-spark-for-large-scale-data-science.html



 DataFrame은 JSON 파일, Parquet 파일, 하이브 테이블을 비롯하여 가장 많이 사용되는 형식의 데이터를 읽는 것을 지원합니다. JDBC를 통해 로컬 파일 시스템, 분산 파일 시스템 (HDFS), 클라우드 스토리지 (S3) 및 외부 관계형 데이터베이스 시스템에서 읽을 수 있습니다. 또한 Spark SQL의 외부 데이터 소스 API 를 통해 DataFrames를 확장하여 타사 데이터 형식이나 소스를 지원할 수 있습니다. 기존의 타사 확장 프로그램에는 Avro, CSV, ElasticSearch 및 Cassandra가 이미 포함되어 있습니다.

대규모 데이터 과학을위한 Spark의 DataFrames 소개

데이터 소스에 대한 DataFrames의 지원으로 응용 프로그램은 서로 다른 소스의 데이터 (데이터베이스 시스템에서 페더 레이 티드 쿼리 처리라고 함)를 쉽게 결합 할 수 있습니다.예를 들어, 다음 코드 스 니펫은 S3에 저장된 사이트의 텍스트 트래픽 로그를 PostgreSQL 데이터베이스와 조인하여 각 사용자가 사이트를 방문한 횟수를 계산합니다.


users = context.jdbc(“jdbc:postgresql:production”, users”)
logs = context.load(“/path/to/traffic.log”)
logs.join(users, logs.userId == users.userId, left_outer”) \
.groupBy(“userId”).agg({“*”: count”})

DataFrame에 대한 계산이 시작되기 전에 Catalyst Optimizer 는 DataFrame을 구축하는 데 사용 된 작업을 실제 계획으로 컴파일하여 실행합니다. 옵티마이 저는 조작의 의미 및 데이터 구조를 이해하므로 계산 속도를 높이기 위해 지능적인 결정을 내릴 수 있습니다.



DataFrame 성능





예제>

scala> val sqlcontext = new org.apache.spark.sql.SQLContext(sc)

scala> val dfs = sqlContext.read.json("employee.json")

scala> dfs.show()

scala> dfs.select("name").show()

scala> dfs.groupBy("age").count().show()



참조

1 http://spark.apache.org/docs/latest/sql-programming-guide.html

2 Lerning Spark 서적

3 http://www.w3ii.com/ko/spark_sql/spark_sql_quick_guide.html



'오픈소스 > Spark' 카테고리의 다른 글

Spark RDDs vs DataFrames vs SparkSQL  (0) 2017.06.18
[Spark] Overview  (0) 2017.01.25

스칼라가 자바보다 매력적인 이유

https://gist.github.com/mkaz/d11f8f08719d6d27bab5

https://www.toptal.com/scala/why-should-i-learn-scala

https://www.quora.com/Why-is-Scala-better-than-Java  답변 링크 

'Programming > Scala' 카테고리의 다른 글

[Scala] 정규표현식  (0) 2017.04.28
[Scala] 스칼라는 무엇이며 왜 만들어 졌나 (일문번역)  (0) 2017.02.02
[Scala] Overview  (0) 2017.01.25

기존데이터 : mediawiki / mysql   -->  tistory


어떻게 해야 잘 옮겼다고 소문날까..

하아 귀찮아..

mediawiki 가 문서 작성은 좋은데 호스팅을 해야 하는 단점이..

'기타' 카테고리의 다른 글

옛날 옛적에 중딩 개발자 한명이 살았는데..  (0) 2017.02.02
문서 작성은 참 어렵다.  (0) 2017.01.30
tistory  (0) 2017.01.19
소소한 일상 첫 포스팅  (0) 2017.01.19

https://www.joinc.co.kr/w/Site/Development/Forum/manager/gitserver

reset 과 revert 차이점


reset - 이전 상태로 삭제하고 되돌아간다. (되돌아갈 commit 로그에서 마우스 오른쪽 클릭..)  / 머큐리얼의 strip 과 같음. (Using mode 옵션에서 Hard 선택시..)

revert - 이전 내용은 그대로 두고 되돌아가는  commit 을 자동 실행한다. 

(이미 push 를 했다면 revert 를 아니면 reset 을 하면 좋을꺼 같음.)


'소스버젼관리' 카테고리의 다른 글

[Git] gitignore 적용 설정이 정상 반영 안될때  (0) 2017.02.09

+ Recent posts