spark scala 코딩을 할때 datetime에 관련된 코딩을 한다면 아래 내용은 필수!!!
sbt build를 사용하기 때문에 libraryDependencies가 필요하다.

build.sbt에 아래와 같이 추가 
    libraryDependencies ++= Seq( 
      (...)
      "joda-time" % "joda-time" % "2.10.5",
      "org.joda" % "joda-convert" % "1.8.1"
    ),

joda-time만 설치하면 아마도 아래와 같이 WARN이 발생하니 org.joda도 함께 라이브러리에 추가

class org.joda.convert.fromstring not found - continuing with a stub

소스코드

  • 소스코드를 보면 DateTime, Days, DateTimeFormat을 이용
  • string을 DateTimeFormat.forPattern을 이용해 DateTime으로 변환
  • Days.daysBetween을 이용해 두개의 DateTime간의 날짜 차이를 계산
  • 오늘 날짜 DateTime 가져오기
  • 30일전 DateTime 생성하기
  • 두개의 DateTime의 차이 milliseconds 계산
"org.scalatest" %% "scalatest" % "3.0.1" % "test",
"org.scalacheck" %% "scalacheck" % "1.13.4" % "test",
"com.holdenkarau" %% "spark-testing-base" % "2.3.0_0.9.0" % "test"

sbt 테스트

  • 아래 명령어를 입력하면 Test 전체를 수행한다
sbt assembly
  • 아래 명령도 전체를 Test를 수행
sbt
> test
  • build하지 않고 테스트만
sbt test
  • 특정 테스트만 실행하기 (build를 따로 할필요가 없음)
 sbt "testOnly package.TestClass"

test를 진행할때마다 잘보면 아래와 같이 뜨는데... 테스트 마다 Session을 생성하는듯 (매우느림)

20/02/28 12:18:33 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
20/02/28 12:18:34 WARN SparkContext: Using an existing SparkContext; some configuration may not take effect.

이때 Spark의 경우 Session을 생성을 해야하기 때문에 sbt tool에 들어가서 test를 하면 매번 Session을 생성해서 불필요한 시간을 사용하게 된다.

Spark Test Sample

Project Main Modules:

참고

SparkSessionWrapper

  • SparkSessionWrapper를 생성하는 이유는 SparkSession을 시작/중지하는 비용이 크기 때문에
  • SparkSession을 하나 생성해서 빠르게 코드 수행이 가능하다.
  • trait은 java에서 interface를 생각하면 된다. 사용하기 위해서는 with를 통해 확장이 가능하다.
  • 여기서 lazy를 사용하는 이유는 정의된 spark의 변수가 처음 사용될때 코드가 실행되도록
    • that a val is executed when it is defined
    • a lazy val is executed when it is accessed the first time.
  • getOrCreate의 메소드는 SparkSession이 있으면 가져오고, 없으면 새로 생성하는 메소드

Lazy Example

null을 골라내서 개수

join

print 하는 방법

데이터 읽기/쓰기

spark로 프로젝트할때 python? scala? 고민을 하게되는데, 이때 가장 큰 고민은
scala의 경우에는 build하는 sbt, maven을 사용을 해야하는 점이다.
python을 사용하는 사람은 보통 build하는데 익숙하지 않다. 그래서 package의 dependencies를 관리하는게 매우 번거로움
그래서 찾다가보니 proejct를 처음 시작할때 도움을 주는 툴이 있었다.

http://www.foundweekends.org/giter8/

$ mkdir <project_root>
$ sbt new scala/scala-seed.g8

위 명령을 실행하고 나면 해당 디렉토리에 아래와 같은 파일들이 생긴다

build.sbt  project  src

이렇게 제공하면 툴도아니지... 이미 여러개의 template이 존재한다.

Template

$ sbt new scala/scala-seed.g8 --branch myBranch 
$ sbt new holdenk/sparkProjectTemplate.g8
  • sparkProjectTemplate
  • 위 템플릿을 입력하면 아래와 같이 프로젝트 이름, organization, package, library 설정이 가능하다
  • 참고로 project의 이름은 package 이름에 organization + project_name이 되기 때문에 -을 쓰면 에러 발생
This is a g8 template for building a skeleton Spark project.

name [sparkProject]:

build 테스트

  • inputFile.txt에 단어 몇개를 입력하고 아래와 같이 명령어를 입력하면
sbt "run inputFile.txt outputFile.txt"
  • outputFile.txt의 디렉토리에 결과가 생긴다

build

  • sbt assembly를 하면 test가지 포함해서 실행해준다.

# 목표
es code분석이 필요해짐에 따라 es 소스를 intellij에 가져와서 debugging해보자.

# 가이드 문서
es버전 6.6이상에서 7.5이하면 아래 가이드 처럼 하면되는데,
https://www.elastic.co/kr/blog/how-to-debug-elasticsearch-source-code-in-intellij-idea 

7.5이상이라면, 아래 풀리퀘를 참고하여 변경된 부분만 원복해서 위와 같은 가이드로 진행하면 된다.
https://github.com/elastic/elasticsearch/pull/48188/files

 

Switch to debug with server=n by atorok · Pull Request #48188 · elastic/elasticsearch

Before this change one needed to re-start debugging several times, as we launched multiple JVMs in debug mode. With this option the IDE has the option to re-launch and listen for connections again ...

github.com


# 진행

1. es 소스 로컬에 가져오기.

git clone https://github.com/elastic/elasticsearch.git
cd elasticsearch 
git checkout --track origin/7.1


2.  gradle설치하고, java 설치하고, JAVA_HOME 설정하기.

((gradle 설치))
   * mac에서는 gradled은 homebrew로 간단하게 설치가되고
     window에서는 gradle홈피가서 zip파일 다운로드받아서 풀고, 환경변수, path만 잡아주면 됨.

((java 설치))
   * java는 es7.1기준 12가 필요해서, java12 설치함.
   . bash_profile에 java home설정해주고 source ~/.bash_profile
     vi ~/.bash_profile

export JAVA_HOME=/library/java/JavaVirtualMachines/jdk-12.0.2.jdk/Contents/Home
export PATH=${PATH}:$JAVA_HOME/bin


   * java 설치 파일 url : https://www.oracle.com/java/technologies/javase/jdk12-archive-downloads.html

 

Java Archive Downloads - Java SE 12

WARNING: These older versions of the JRE and JDK are provided to help developers debug issues in older systems. They are not updated with the latest security patches and are not recommended for use in production. For production use Oracle recommends downlo

www.oracle.com


3. ./gradlew idea
   * 일단 terminal에서 es repository를 클론해온 elasticsearch 디렉터리로 가서 ./gradlew idea 를 실행
   * 이거 해놓고 intellij에서 import해야 자연스럽게 gradle project import가 편해지는 듯.

4. intellij 열어서, import project > gradle 체크 하고 > 오픈.

5. intellij에 gradle auto enable 이런거 뜨면 ok 체크 해주고, 

6. intellij > file > project setting 가서 jdk 12로 변경해주기.
   * platform setting > sdk에서 jdk12 설치한 거 홈으로 잡아주고,
   * project setting > project에서 project sdk를 jdk12로 잡아주기.

7. 소스 폴더 distribution>build.gradle에서 xpack.security.enabled'를 false로 바꿔줘야 localhost에서 rest api사용가능함.

8. intellij 터미널에서 ./gradlew run --debug-jvm 실행.
   * 하다가 뻑나면 ./gradlew clean하고, ./gradlew idea하고 다시 실행.

9. 아래와 같이 run#start가 뜨면 된건데, 이때 intellij>run>attach to process를 누르고 방금 빌드완료한 snapshot넣어주면,
    디버깅 준비 완료!!
    ============-> 98% EXECUTING [33m 6s]
    > :distribution:run#start

10. 이제 break point 걸어서, localhost:9200/_cluster/settings 등등 api날려보면서 코드 디버깅 할 수 있음.

  • vi에서 indentation을 맞추는게 생각보다 까다롭다. 어떤 툴을 써서 각자의 코드에 맞게 수정을 한다던지...
  • how-do-i-fix-the-indentation-of-an-entire-file-in-vi 에서 indentation 파일 전체를 하는방법이 있다.
  • 참고로 gg는 파일 첫번째 줄로 이동, G는 파일 맨끝으로 이동, ==은 indentation 아래는 이명령어의 조합을 사용
파일 전체 들여쓰기
gg=G    

To indent the all the lines below the current line  
\=G

# To indent the current line

To indent n lines below the current line  
n==

For example, to indent 4 lines below the current line  
4==

To indent a block of code, go to one of the braces and use command  
\=% 
  • 이렇게 하면 들여쓰기가 자동으로 맞춰지는 무슨 기준으로 맞춰지는걸까...
  • indent-multiple-lines-quickly-in-vi 에 상당히 자세하게 나와있다 이후에 한번 살펴보자

+ Recent posts