본문 바로가기
Data

Apache Arrow | LIM

by forestlim 2023. 1. 29.
728x90
반응형

이전에 Python Ray 에 대해 학습하면서 Ray Mulitprocessing 이 빠른 이유가 기본 Python Mulitiprocessing 과 비교했을 때 직렬화 과정의 오버헤드가 없다는 것이었다. 이때 Apache Arrow를 사용한다고 했고, 이 Apache Arrow 가 도대체 어떤 거길래 직렬화 과정을 거치지 않는다는 건지 좀 더 자세히 알아보기 위해 공부했다. 

 

🤔 직렬화(Serialization)란?

객체를 저장하거나 메모리, 데이터베이스 혹은 파일로 옮길 때 필요한 것이 직렬화이다. 직렬화란 객체를 바이트 스트림으로 바꾸는 것, 즉 객체에 저장된 데이터를 스트림에 쓰기위해 연속적인 데이터로 변환하는 것이다. 직렬화의 주된 목적은 객체를 상태 그대로 저장하고 필요할 때 다시 생성하여 사용하는 것이다. 

 

이 직렬화했던 것을 반대로 하는 것이 역직렬화이다. 네트워크나 영구저장소에서 바이트스트림을 가져와서 객체가 저장되었던 바로 그 상태로 변환하는 것. 직렬화하면서 생긴 바이트스트림은 플랫폼에 독립적이다. 즉, 직렬화된 객체는 다른 플랫폼에서 역직렬화가 가능하다.

 

https://www.geeksforgeeks.org/serialization-in-java/

 

🧐 Apache Arrow란?

Arrow는 언어, 플랫폼과 상관없이 메모리 상에서 컬럼 구조로 데이터를 정의하여, CPU 와 GPU 에서 메모리를 빠르게 읽고 쓸 수 있도록 한다. 

 

여러 카산드라, h베이스, 임팔라, 스파크 등 아파치 빅데이터 프로젝트 관련 개발사가 프로젝트에 참여했기 때문에 데이터를 메모리에 빠르게 올릴 수 있을 뿐만 아니라 다양한 플랫폼에서 변환 없이 사용할 수 있다. 

 

 

Apache Arrow는 행(Row) 기반이 아닌 컬럼 기반의 인메모리 포맷으로 Zero-Copy 직렬화를 수행한다.

Zero-Copy 직렬화란 즉, 직렬화라는 과정을 없애버린 것이다. Python 에서 정의한 특정 객체를 다른 플랫폼으로 보내기 위해서 직렬화 과정이 필수였고, 그 플랫폼에서 어떤 걸 보냈는 지 알기 위해서 역직렬화 과정을 무조건 거쳐야 했는데 이 과정을 없애버린 것이다. 

 

Apache Arrow 가 생기기 전에 두개의 서로 다른 어플리케이션이나 라이브러리가 데이터를 전달하는 방법은 서로 데이터를 저장하고 가져가서 변환하는 작업이었다. 예를들어서 .NET Core 라이브러리가 파이썬으로 데이터를 전달하기 위해서는 파일을 쓴다음(e.g. csv, json, Parquet,...) 그 파일을 다시 파이썬에서 읽어야 했다. 양쪽 과정에서 쓰고(serialization) 읽고(deserialization) 하는 과정은 비용이 많이 들어가고 느렸다. 그리고 데이터가 커지면 커질수록 양쪽 모두에게 시간이 오래 걸리는 작업이었다. 

python 저 표정 일할 때 내모습 같다

그렇다면 handshake 와 zero copy 를 이용해 데이터를 바로 전달하는 방법은 없을까?

 

🤩 Apache Arrow: 데이터가 어디있는 지 Arrow( 화살표 ) 로 가리키자!

 

.NET 이 파이썬에게 데이터를 쌓아두고 데이터가 어디있는 지 가리키고 파이썬은 쌓아져 있는 데이터를 변환없이(deserialization) 가져가기만 하면 되는 것이다! 이것이 Apache Arrow 이고 데이터를 HandShake 과정과 Zero Copy 를 통해 바로 전달하는 것이다. 

 

✨ 그렇다면 이 Zero-Copy 를 통해 어떻게 데이터를 전달하는 걸까?

이러한 zero-copy 과정은 serialization step 을 없애기 위해 객체를 가지고 작업하는 대신 직렬화된 데이터 자체를 가지고 작업한다. 이렇게 되면 네트워크를 통해 전송될 때에도 serialization 을 거치지 않기 떄문에 훨씬 효율적이며 데이터를 받는 쪽에서도 deserialization 을 하지 않아도 된다. 

 

 

❗️Parquet 과 Arrow 는 또 어떻게 다른가

Parquet 도 알다시피 column based file format 이다. Parquet 이 Arrow 의 원리인가? 그건 아니다. 

다음은 Parquet 의 특성이다. 

 

1. Highly Compressible

.json 또는 .csv file 은 데이터가 압축되어 있지 않은 반면에 parquet 은 데이터를 압축하고 그로 인해 disk 공간을 적게 쓰게 된다. 컬럼 기반이기 때문에 각각의 컬럼들은 low 한 cardinality 를 가지고 있고, 따라서 압축하기에 더 쉽다

 

2. File querying/filter pushdown

불필요한 데이터를 읽기 전에 제거한다. 이러한 과정은 데이터를 로드함에 있어서 시간을 줄여주고 리소스 낭비를 줄여준다. 2개의 컬럼만 필요한데 모든 row 를 스캔하는 과정 같은 것이 없는 것이다. 필요한 컬럼만 읽으면 되는 것이다. 

 

💡Parquet 이 데이터를 압축하는 방법은?

아래 참고에 적어놓은 블로그에서 예시를 잘 정리해주어서 그 부분을 정리해보고자 한다. 

 

동전 뒤집기!

동전을 뒤집은 결과가 다음과 같이 나왔다고 가정해보자

[Head, Head, Head, Head, Tail, Tail, Tail, Head, Tail, Tail]

 

먼저, 이렇게 압축해볼 수 있다. 

[4 x Head, 3 x Tail, Head, 2 x Tail]

이러한 압축 기법 알고리즘을 Run-Length Encoding 이라고 한다. 

 

순서 그대로 나온 결과 모두 저장하는 방식이 .csv 로 저장하는 방법이고, 위 예시처럼 축약해서 저장하는 것이 parquet 파일에서 압축하는 방법 중 하나이다. 

 

만약 더 나아가서 순서가 중요하지 않다면 이렇게도 압축해서 저장할 수 있는 것이다. 

[5 x Head, 5 x Tail]

 

💡Arrow 도 압축이 가능한가?

Parquet 은 위와 같은 방법들로 효과적으로 압축이 가능하지만 결국 parquet 데이터를 읽을 땐 결국 압축해놓은 것을 다시 unpacking 해서 memory 에 올린 후 작업해야 하는 것이다.

 

하지만 Arrow 의 경우는 다르다. Arrow는 memory-mapped format 이다. Arrow 압축에 대한 원리이다. 

“Arrow serialization design provides a ‘data header’ which describes the exact locations and sizes of all the memory buffers for all the columns in a table. This means you can memory map huge, bigger-than-RAM datasets and evaluate pandas-style algorithms on them in-place without loading them into memory like you have to with pandas now. You could read 1 megabyte from the middle of a 1 terabyte table, and you only pay the cost of performing those random reads totalling 1 megabyte.”

 

간단히 말하자면, 디스크에 올라가 있는 전체 데이터에 대해서 메모리에 fully load(1 terabyte) 하는 것이 아닌 것이 아닌 읽고자 하는 데이터만(1 megabyte) 전체 데이터에서 찾아가서 읽는 것(?) 이다. 

 

그렇다면 실제로 코드를 통해 각 기법들에 대한 performance 를 비교해보자.

 

📝 Hands-on: Performance 비교

밑에 블로그에서 한 방법대로 똑같이 따라해보았다. 눈으로 보는 것과 실제로 copy and paste 해서 실행시켜보는 것은 또 다르다.

 

 

 

 

 

 

📚 참고

https://towardsdatascience.com/apache-arrow-read-dataframe-with-zero-memory-69634092b1a

 

Apache Arrow: Read DataFrame With Zero Memory

Theoretical & practical introduction to Arrow file format

towardsdatascience.com

 

728x90
반응형

댓글