Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scala, Spark, Luigi, Shell 개발 가이드 추가 #126

Merged
merged 5 commits into from
Nov 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Luigi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# [Luigi](https://luigi.readthedocs.io/en/stable/#) 개발 가이드

- 태스크 클래스의 이름은 동사구(verb phrase)로 한다.
- 태스크 클래스 이름 뒤에 Task 를 붙이지 않는다.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
- [MariaDB(MySQL)](MariaDB(MySQL).md) - DDL, DML 작성 규칙
- [PHP](PHP)
- [Python3](Python)
- [Scala](Scala)
- [Shell](Shell.md)


### Platform
Expand All @@ -41,3 +43,9 @@
- [iOS](iOS) - Swift, Objective-C 코딩 스타일
- [Qt](Qt.md) - C++, XML 코딩 스타일
- [CMS](CMS.md) - 내부 시스템 개발 가이드


### Frameworks

- [Luigi](Luigi.md)
- [Spark](Scala/Spark.md)
75 changes: 75 additions & 0 deletions Scala/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Scala 코딩 스타일 가이드

Scala 코딩 스타일은 기본적으로 다음 두 문서를 참조한다.
- [The Official Scala Style Guide](https://docs.scala-lang.org/style/)
- [Databricks Scala Style Guide](https://github.com/databricks/scala-style-guide)

두 문서의 코드 스타일 정의에 충돌이 있는 경우 [Databricks Scala Style Guide](https://github.com/databricks/scala-style-guide)를 우선적으로 따른다.

## Tools
위 코드 스타일 가이드의 내용을 모두 숙지하고 있기는 현실적으로 어렵기 때문에, 최대한 적절한 도구의 도움을 받는 것을 원칙으로 한다.

현재 사용 중인 도구는 다음과 같다.

- [Scalafmt](https://scalameta.org/scalafmt/)
- Scala 코드를 정해진 규칙에 따라 Reformating 해준다.
- IDE의 scala formatter 로 설정하여 사용한다.
- [Scalastyle](http://www.scalastyle.org/)
- Scala 코드에서 잠재적으로 문제가 될 수 있는 부분을 검사하여 알려준다.
- IDE의 Code Inspector에서 동작하도록 설정하여 사용한다.

:warning: 설정 가이드
- 최대한 [Databricks Scala Style Guide](https://github.com/databricks/scala-style-guide)를 따르도록 설정하되, 코드베이스의 특성에 따라 예외 항목을 둘 수 있다.
- Scalafmt와 Scalastyle 설정이 충돌하지 않아야 한다.
- Scalafmt를 사용하여 Reformat된 코드가 Scalastyle 설정에서 문제가 되는 코드로 표기되지 않아야 한다.
- Scalastyle에서 `import` 정렬과 관련된 규칙이 있는 경우 Scalafmt에서 이를 따르도록 설정한다.
- Scalastyle의 모든 체크 항목의 level을 `"error"`로 설정한다.
- 에디터 상에서 오류처럼 표기되어야 코드 작성자가 스타일에 맞지 않는 코드를 쉽게 인지하고 수정할 수 있다.

## IDE(Integrated Development Environment)
boridevna marked this conversation as resolved.
Show resolved Hide resolved

IDE로는 [IntelliJ IDEA](https://www.jetbrains.com/idea/)를 사용을 권장한다.

<details><summary>IntelliJ에서 사용가능한 플러그인 및 적용방법</summary>
<p>

#### Plugins

스칼라 코드 개발에 사용되는 플러그인들은 다음과 같다.

- [Scala Plugin](https://plugins.jetbrains.com/plugin/1347-scala/)
- [SBT Plugin](https://plugins.jetbrains.com/plugin/5007-sbt/)
- [Scalafmt Plugin](https://plugins.jetbrains.com/plugin/8236-scalafmt/)

#### Scalafmt 적용

1. [Scalafmt Plugin](https://plugins.jetbrains.com/plugin/8236-scalafmt) 설치
2. (선택) 프로젝트 root에 `.scalafmt.conf` 설정 파일 추가
3. IntelliJ의 `Preferences` 메뉴에서 다음 항목 설정
- `Preferences > Editor > Code Style > Scala`
- (필수) Formatter 목록에서 `scalafmt` 선택
- (권장) 하단 `Scalafmt` 탭에서 `Reformat on file save` 체크
- (권장) 만일 Scalastyle 설정에 import 순서도 정의되어 있다면
- `Imports` 탭에서 `Sort imports (for optimize imports)` 항목 체크
- `scalastyle consistent` 선택

#### Scalastyle 활성화

1. 프로젝트 root에 `scalastyle-config.xml` 설정 파일 추가
2. IntelliJ의 `Preferences` 메뉴에서 다음 항목 설정
- `Preferences > Editor > Inspections`
- `Scala 항목 체크`

</p>
</details>

## 참고자료
Scala 코딩 스타일 가이드
- [The Official Scala Style Guide](https://docs.scala-lang.org/style/)
- [Databricks Scala Style Guide](https://github.com/databricks/scala-style-guide)
- [Spotify Scio Scala Style Guide](https://spotify.github.io/scio/dev/Style-Guide.html)

설정파일
- [apache/spark/scalastyle-cofig.xml](https://github.com/apache/spark/blob/master/scalastyle-config.xml)
- [spotify/scio/scalastyle-config.xml](https://github.com/spotify/scio/blob/master/scalastyle-config.xml)
- [spotify/scio/.scalafmt.conf](https://github.com/spotify/scio/blob/master/.scalafmt.conf)
90 changes: 90 additions & 0 deletions Scala/Spark.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Spark 개발 가이드

Spark Application 개발은 scala 사용을 원칙으로 한다.

## Scala Style Guides
스칼라 코딩 스타일은 [Scala 코딩 스타일 가이드](../Scala)를 참조한다.

## Naming
### Variables
- 기본적으로 변수명은 `camelCase`를 사용한다.
- 다음의 케이스는 예외적으로 `snake_case`를 사용한다.
- `DataFrame/Dataset`을 `case class`에 담아 테이블로 저장하는 경우
- 필드명이 테이블 컬럼이름으로 사용되기 때문에 `case class`의 필드명은 `snake_case`를 사용한다.
- 비슷한 맥락으로, `Column.name`도 SQL코드를 쉽게 작성할 수 있도록 `snake_case`로 작성한다.
- `DataFrame/Dataset/RDD`를 담는 변수명에는 `DF/DS/RDD` postfix를 붙인다.
```scala
val userDF: DataFrame = ...
val bookDS: Dataset[Book] = ...
val bestsellerRDD: RDD[Bestseller] = ...
```
- 하나의 객체를 나타내는 변수명에는 단수형을, 복합 객체를 표현하는 변수명에는 복수형을 사용하되 의미상 중복을 최소화한다.
```scala
val defaultCategory = "comic"
val categories = List("general", "romance", "fantasy", "comic", "bl")

// Don't do this
val categoryList = List("general", "romance", "fantasy", "comic", "bl")
```

### Application
- Spark Application의 이름은 동사구(verb phrase)를 사용한다. `ex) BuildBestseller, BuildRecommend`

## Chained Method Invocations
- chained method 호출은 다음의 경우를 모두 허용한다.
- on a single line
- line length가 100 이내이고 가독성을 헤치지 않는 경우 허용

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

문득 궁금해져서 여쭤보는 건데.. line length를 100 byte로 설정하신 배경이 궁금합니다.

Copy link
Contributor Author

@boridevna boridevna Nov 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nephtyws 요기의 가이드에서 따왔습니다!
https://github.com/databricks/scala-style-guide#linelength

- on multiple lines
- 일반적인 모든 경우
- argument를 받는 method가 한 line에 둘 이상 올 수 없음
```scala

outputDF.write.format("parquet").mode(SaveMode.Overwrite).saveAsTable(output)

outputDF.write
.format("parquet")
.mode(SaveMode.Overwrite)
.saveAsTable(output)

outputDF.write.format("parquet")
.mode(SaveMode.Overwrite)
.saveAsTable(output)

// don't do these
outputDF.write.format("parquet").mode(SaveMode.Overwrite)
.saveAsTable(output)

outputDF.write
.format("parquet").mode(SaveMode.Overwrite)
.saveAsTable(output)
```

## Spark SQL
- 쿼리문이 간결하고 짧은 경우 singleline string 사용
```scala
val teenagerNameDS = spark.sql("SELECT name FROM people WHERE age BETWEEN 13 AND 19").as[Name]
```
- 그렇지 않은 경우 indent와 함께 multiline string 사용, 쿼리문 내 indent는 `1 space` 사용
```scala
val teenagerNameDS = spark
.sql(
s"""
|SELECT
| name // indent 1 space
|FROM people
|WHERE age BETWEEN 13 AND 19
|""".stringMargin
).as[Name]
```

## RDD vs Spark SQL, Dataset, DataFrame API
- 가급적이면 Spark SQL, Dataset & DataFrame API를 사용한다.
- Type Safety, High Level Abstraction
- Spark SQL의 Catalyst Optimizer로 인한 성능 최적화
- Low Level의 세밀한 제어가 필요한 경우 RDD API 사용을 허용한다.

## 참고문서
- [Spark Examples](https://github.com/apache/spark/tree/master/examples/src/main/scala/org/apache/spark/examples)
- [MrPowers/spark-style-guide](https://github.com/MrPowers/spark-style-guide)
- [A Tale of Three Apache Spark APIs: RDDs vs DataFrames and Datasets - When to use them and why](https://databricks.com/blog/2016/07/14/a-tale-of-three-apache-spark-apis-rdds-dataframes-and-datasets.html)
- [Deep Dive into Spark SQL’s Catalyst Optimizer](https://databricks.com/blog/2015/04/13/deep-dive-into-spark-sqls-catalyst-optimizer.html)
19 changes: 19 additions & 0 deletions Shell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Shell 스타일 가이드

기본적으로 [Google Shell Style Guide](https://google.github.io/styleguide/shell.xml)를 따른다.

:warning: 정말 필요한 경우가 아니라면 python과 같은 스크립트 언어사용을 권장한다.

## lining & formatting tools
- [ShellCheck](https://www.shellcheck.net/)
- [shfmt](https://github.com/mvdan/sh#shfmt)

Jetbrains 계열 IDE를 사용한다면 다음의 내장 플러그인에서 사용 가능
- [Shell Script Plugin](https://plugins.jetbrains.com/plugin/13122-shell-script)


## 참고자료
- [Google Shell Style Guide](https://google.github.io/styleguide/shell.xml)
- [GitLab Shell scripting standards and style guidelines](https://docs.gitlab.com/ee/development/shell_scripting_guide/)
- [ShellCheck](https://www.shellcheck.net/)
- [shfmt](https://github.com/mvdan/sh#shfmt)