Spark Documentation 문서 번역을 한 번 해보려고 한다.

눈가락번역기의 번역 상태가 많이 좋지 않으니 양해 바람.

 

 

 

번역 대상 문서 : https://spark.apache.org/docs/latest/tuning.html

 

Tuning Spark
Spark 튜닝하기

Because of the in-memory nature of most Spark computations, Spark programs can be bottlenecked by any resource in the cluster: CPU, network bandwidth, or memory.
Spark 가 실행하는 대부분 계산이 memory 내에서 일어나기 때문에, Spark 프로그램에서 클러스터가 갖는 자원의 부족은 보틀넥이 될 수 있다. 여기서 말하는 자원이란 CPU나 네트워크 대역폭, 메모리 등을 말한다.
Most often, if the data fits in memory, the bottleneck is network bandwidth, but sometimes, you also need to do some tuning, such as storing RDDs in serialized form, to decrease memory usage.
대부분의 경우, data 가 memory 에 알맞게 들어가는 상황에서는, 네트워크 대역폭이 보틀넥이 된다.

하지만 때때로 RDD 를 직렬화된 포맷으로 저장하거나 memory 사용률 감소하게 만드는 등의 튜닝을 해야 할 필요가 있다.
This guide will cover two main topics: 

이 가이드는 두 가지 주요 주제에 대해 논한다.

data serialization, which is crucial for good network performance and can also reduce memory use, and memory tuning.

1. 데이터 직렬화 : 네트워크 퍼포먼트에 크게 영향을 주는 요인이며 메모리 사용률도 낮출 수 있다.

2. 메모리 튜닝

We also sketch several smaller topics.

Data Serialization
데이터 직렬화

Serialization plays an important role in the performance of any distributed application.

직렬화는 어느 분산 application 에서든 퍼포먼스에 중요한 역할을 한다.

Formats that are slow to serialize objects into, or consume a large number of bytes, will greatly slow down the computation.

객체를 직렬화하는 데 느린 형식이거나 많은 바이트를 소비하는 형식은, 계산을 크게 느리게 할 수 있다.

Often, this will be the first thing you should tune to optimize a Spark application.

종종 이것은 Spark application 의 최적화를 위해 튜닝해야 할 가장 첫번째 부분이다.

Spark aims to strike a balance between convenience (allowing you to work with any Java type in your operations) and performance.

Spark는 퍼포먼스와 편리성(사용자가 어떤 자바 타입을 사용해도 괜찮도록 하는 등) 사이의 균형을 맞추려고 노력한다.

It provides two serialization libraries:
이것은 두 가지 직렬화 lib 를 제공한다.

  • Java serialization: By default, Spark serializes objects using Java’s ObjectOutputStream framework, and can work with any class you create that implements java.io.Serializable.
    Java serialization : 기본적으로 제공됨. Spark 는 Java 의 ObjectOutputStream 프레임워크를 사용하여 객체를 직렬화한다. 그리고 java.io.Serializable 을 상속받은 사용자의 어떠한 클래스를 직렬화 할 때도 마찬가지.
    You can also control the performance of your serialization more closely by extending java.io.Externalizable.
    또한 java.io.Externalizable 을 확장하여 직렬화의 성능을 더 자세히 제어할 수도 있습니다.
    Java serialization is flexible but often quite slow, and leads to large serialized formats for many classes.
    Java 직렬화는 유연하지만 종종 매우 느리다. 그리고 많은 클래스의 경우 큰 직렬화 포맷(??)으로 이어진다 ????
  • Kryo serialization: Spark can also use the Kryo library (version 4) to serialize objects more quickly.
    Kryo serialization : Spark 는 또한 더 빠르게 객체를 직렬화하기 위해 Kryo lib 를 사용할 수 있다.
    Kryo is significantly faster and more compact than Java serialization (often as much as 10x), but does not support all Serializable types and requires you to register the classes you’ll use in the program in advance for best performance.
    Kryo 는 바로 위에서 설명한 Java Serialization 보다 훨씬 더 빠르고 압축률도 좋지만, 모든 Serializable 타입들을 제공하지 않는다. 또한 사용자가 프로그램에 사용할 class 들을 미리 등록해야 사용 가능하다.

You can switch to using Kryo by initializing your job with a SparkConf and calling conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer").

SparkConf 를 사용하거나 conf.set 옵션을 추가 후, job 을 초기화하여 Kryo 를 사용하도록 만들 수 있다. 

This setting configures the serializer used for not only shuffling data between worker nodes but also when serializing RDDs to disk.

이 설정은 워커 노드 사이에 데이터 셔플링 뿐 아니라 RDD 가 disk 에 직렬화로 쓰여질 때 Kryo 를 이용하여 직렬화 하도록 설정한다.

The only reason Kryo is not the default is because of the custom registration requirement, but we recommend trying it in any network-intensive application.

Kryo 가 기본값이 아닌 유일한 이유는 사용자 지정 등록 요구때문이다.

하지만 우리는 어느 네트워크 집약적인 application에서든 Kryo 를 사용하길 권장한다.

Since Spark 2.0.0, we internally use Kryo serializer when shuffling RDDs with simple types, arrays of simple types, or string type.

Spark 2.0.0 버전 이후로, 간단한 타입, 간단한 타입의 배열, string 타입을 갖는 RDD 를 셔플할 때 내부적으로 Kryo 를 사용한다.

Spark automatically includes Kryo serializers for the many commonly-used core Scala classes covered in the AllScalaRegistrar from the Twitter chill library.

Spark 는 Twitter chill lib 의 AllScalaRegistrar 에 포함된, 널리 흔하게 사용되는 핵심 Scala 클래스들을 위해 Kryo 직렬화 lib 를 내장하고있다.

To register your own custom classes with Kryo, use the registerKryoClasses method.

사용자가 만든 class 를 Kryo 를 사용하도록 등록하려면, registerKryoClass 메소드를 사용하라.

val conf = new SparkConf().setMaster(...).setAppName(...)
conf.registerKryoClasses(Array(classOf[MyClass1], classOf[MyClass2]))
val sc = new SparkContext(conf)

The Kryo documentation describes more advanced registration options, such as adding custom serialization code.

Kryo 문서에서 더 자세한 등록 옵션에 대해 설명한다. 예를 들어 커스텀 직렬화 코드 추가하는 방법 등.

If your objects are large, you may also need to increase the spark.kryoserializer.buffer config.

만약 사용자의 객체 크기가 크다면, spark.kryoserializaer.buffer 설정을 증가할 필요가 있을 것 같다.

This value needs to be large enough to hold the largest object you will serialize.

이 값은 사용자가 직렬화 하는 가장 큰 객체를 수용하기 위해 충분히 커야 할 필요가 있다.

Finally, if you don’t register your custom classes, Kryo will still work, but it will have to store the full class name with each object, which is wasteful.

마지막으로, 사용자가 자신의 커스텀 클래스를 등록하지 않는다면, Kryo 는 물론 동작하겠지만, 각 객체 별로 모든 클래스 이름을 저장할 것이며 이것은 낭비이다.

Memory Tuning
메모리 튜닝하기

There are three considerations in tuning memory usage:

메모리 사용률을 튜닝하는 데 세 가지 고려해야 할 점이 있다.

the amount of memory used by your objects (you may want your entire dataset to fit in memory),
the cost of accessing those objects,
and the overhead of garbage collection (if you have high turnover in terms of objects).

1. 사용자 객체에 의해 사용되는 메모리 양 (사용자는 아마도 모든 데이터가 memory 에 딱 맞는 크기이길 원할것이다.)

2. 1번 객체들에 접근하는 데 드는 비용

3. GC 의 오버헤드,부하 (객체 관점에서 high turnover 가 높을 때)

여기서 말하는 high turnover 는 "특정 시간 동안 생성된 객체들 중에서 사용되지 않는 객체들이 많은 상황" 이라고 함.

그래서 메모리가 가득 차고, GC 가 청소하러 출동하고...

By default, Java objects are fast to access, but can easily consume a factor of 2-5x more space than the “raw” data inside their fields.

기본적으로, Java 객체는 빠르게 접근할 수 있지만, 내부 필드의 원시 데이터보다 2~5배 더 많은 공간을 소비하기 쉽다. (their fields 가 뭔지 모르겠는데 아래 설명보면 아하 하게 됨)

This is due to several reasons:
이것은 다음과 같은 이유들 때문이다.

  • Each distinct Java object has an “object header”, which is about 16 bytes and contains information such as a pointer to its class.
    각기 다른 Java 객체들은 object header 를 갖고 있는데 이것은 16바이트이고 그 클래스를 가리키는 포인터 같은 정보를 포함하고 있다.
    For an object with very little data in it (say one Int field), this can be bigger than the data.
    굉장히 작은 데이터, 이를테면 int 단 하나만 갖는 객체의 크기는, 내부에 있는 int 데이터보다 객체 크기가 훨씬 크다.
  • Java Strings have about 40 bytes of overhead over the raw string data (since they store it in an array of Chars and keep extra data such as the length), and store each character as two bytes due to String’s internal usage of UTF-16 encoding.
    Java String 은 실제 내부 문자열 데이터와 더불어 약 40바이트만큼의 추가 오버헤드를 갖고 있다. 왜냐면 Chars 의 배열도 저장해야하고, length 같은 추가 정보도 계속 갖고 있어야 하기 때문에. 또한, String 의 내부 UTF-16 인코딩의 사용으로 인해, 문자열의 각 character 는 2 바이트로 저장된다.... 영어 진짜 마음에 안 듦...
    Thus a 10-character string can easily consume 60 bytes.
    따라서, 10개 글자를 갖는 문자열이 60바이트나 소비할 수 있다.
  • Common collection classes, such as HashMap and LinkedList, use linked data structures, where there is a “wrapper” object for each entry (e.g. Map.Entry).
    HashMap 이나 LinkedList 같은 일반적인 collection 클래스들은 각 항목 당 "wrapper" 객체가 있는 linked 데이터 구조를 사용한다.
    This object not only has a header, but also pointers (typically 8 bytes each) to the next object in the list.
    이 객체는 header 뿐만 아니라, 다음 리스트의 객체를 가리키는 pointer (일반적으로 각 포인트 당 8바이트) 도 갖고 있다.
  • Collections of primitive types often store them as “boxed” objects such as java.lang.Integer.
    primitive 타입의 Collections 들은 종종 java.lang.Integer 같은 "boxed" 객체로 저장된다.

This section will start with an overview of memory management in Spark, then discuss specific strategies the user can take to make more efficient use of memory in his/her application.
이 세션에서는 Spark 에서의 메모리 관리 개요부터 시작할 것이다. 그 후, 사용자들이 그들의 application 내 메모리를 더 효율적으로 사용하도록 취할 수 있는 몇가지 전략에 대해 논의해본다.
In particular, we will describe how to determine the memory usage of your objects, and how to improve it – either by changing your data structures, or by storing data in a serialized format.
특히, 사용자 객체의 메모리 사용률을 어떻게 판별하는지, 그리고 그것을 어떻게 개선할지 설명 할 것이다. 예를 들면 데이터 구조를 바꾼다거나, 직렬화 포맷으로 데이터를 저장한다거나...
We will then cover tuning Spark’s cache size and the Java garbage collector.

그 후, Spark 캐시 크기와 Java GC 튜닝에 대해 다룰 것이다.

 

 

 

 

 

 

+ Recent posts