2017년 우버에서 자기들이 사용하는 hoodie를 공유했다.


https://eng.uber.com/hoodie/





이게 개념적으로 kappa 아키텍처 (보통 우리가 쓰는 lamba 아키텍처의 다음 버전, incremtal )으로

HDFS에 metadata, index, data를 Spark 라이브러리로 구현한 오픈 소스(https://github.com/uber/hudi)이다.


스키마 이슈를 풀기 위해 avro를 사용하고 컬럼 기반의 최적화된 성능을 보장하기 위해 parquet를 사용다. 읽을 때는 컬럼 단위로 읽으니 Scan에 최적화된 Parquet, 저장할 때는 스키마 이슈없고 row단위로 저장하는 Avro를 사용한다. 컴파일 병렬화, 쿼리 병렬화, HDFS의 파일 이슈(쿼터)를 해결하기 위해 HDFS 블록 크기로 저장한다.


저장할 때 데이터를 정확히 partition 단위로 저장하고, HDFS 블록 크기만큼 채워서 저장한다. 그런식으로 계속 저장한다. 데이터의 변경은 bloom filter로 미리 저장한 위치를 빨리 찾도록 변경된 데이터를 추가하는 방식을 사용하고 있다. 


compaction은 시간제한이 걸려 있고 몇 분마다 비동기로 진행한다. 이때 compaction과 변경이 걸리면 이슈가 되니 lock을 zookeeper로 걸어 사용한다. 




유투브 발표 자료.








그리고 2018년 7월에 하나의 블로그를 올려놨다.

https://eng.uber.com/uber-big-data-platform/


나름 kappa 아키텍처 기반임에 틀림없다. 





중요한 포인트는 증분 데이터를 append함으로서 최종 값과 증분 값 모두 읽을 수 있다는 점이다. 





Posted by 김용환 '김용환'


스크립트에서 현대 디렉토리를 지정하기 위해 다음과 같은 스크립트를 많이 사용한다. 


my_root=$(cd $(dirname $(readlink $0 || echo $0))/../;/bin/pwd)



그런데 맥에서 이런 에러가 발생했다.


dirname: illegal option -- b




bash에서 $0이 스크립트 경로를 알려주는 것이라 알고 있긴 하지만... 사실 보장하지 않는다.

완벽히 보장하는 bash script를 개발하려면 BASH_SOURCE를 사용하길 바란다.



SCRIPT_PATH=${BASH_SOURCE[0]}

my_root=$(cd $(dirname $(readlink ${SCRIPT_PATH} || echo ${SCRIPT_PATH}))/../;/bin/pwd)




Posted by 김용환 '김용환'


앤서블의 호스트 지정 패턴

플레이북의 host 매개 변수에 보통 단일 호스트 또는 그룹을 지정하는데..

hosts: web

단일 호스트 또는 그룹을 지정하는 대신 패턴을 지정할 수도 있다. 이미 all 패턴을 봤었다. all  패턴은 알려진 모든 호스트들에 대해 플레이를 실행할 것이다.

hosts: all

콜론을 사용해 두 그룹의 합집합을 지정할 수 있다. 다음처럼 모든 dev 머신 및 staging 머신을 지정할 수 있다.

hosts: dev:staging

\콜론과 앰퍼샌드(:&)를 사용하여 교집합을 지정할 수 있다. 예를 들어 staging 환경에서 모든 데이터베이스 서버를 지정하려면 다음처럼 지정할 수 있다.

hosts: staging:&database


표 9-1은 앤서블이 지원하는 패턴을 보여준다. 정규식 패턴은 항상 물결 기호(~)로 시작한다.



액션

사용 예시

모든 호스트

all

모든 호스트

*

합집합

dev:staging

교집합

staging:&database

배제

dev:!queue

와일드카드

*.example.com

번호로 지정한 서버의 범위

web[5:10]

정규식

~web\d+\.example\.(com|org)





앤서블은 여러 패턴 조합을 지원한다. 예를 들면 다음과 같다.

hosts: dev:staging:&database:!queue




또한 호스트의 임의 조합을 예시처럼 지정할 수 있다. $ ansible-playbook -l 'staging:&database' playbook.yml


Posted by 김용환 '김용환'


ansible-vault 커맨드 간단 정리



커맨드

설명

ansible-vault encrypt file.yml

일반 텍스트 파일인 file.yml을 암호화한다

ansible-vault decrypt file.yml


암호화된 file.yml 파일을 해독한다

ansible-vault view file.yml

암호화된 file.yml 파일의 내용을 출력한다

ansible-vault create file.yml

암호화된 새로운 파일 file.yml을 생성한다

ansible-vault edit file.yml

암호화된 파일 file.yml 파일을 수정한다

ansible-vault rekey file.yml

암호화된 파일 file.yml의 암호를 변경한다




앤서블 2.4 버전부터는 커맨드 라인에서 --vault-id를 사용해 볼트 암호 사용을 권장하고 있다.


암호가 ~/password.txt 텍스트 파일에 저장되어 있고 --vault-id 플래그를 사용해 암호 파일의 위치를 ansible-playbook 에게 전달한다.

ansible-playbook --vault-id ~/password.txt secrets.yml


암호화 파일을 해독하려면 --vault-id @prompt 플래그를 사용한다.

ansible-playbook --vault-id @prompt secrets.yml



앤서블 2.4 버전 이전에는 앤서블 실행시 하나의 볼트 암호만 사용할 수 있었었지만 2.4 버전 이후부터 다중 볼트 암호를 사용하여 지원해 --vault-id를 여러 번 제공할 수 있다. 그러나 --vault-id 옵션은 Ansible 2.4 이전 버전을 지원하지 않는다.

여러 볼트 암호가 제공된 경우 기본적으로 앤서블은 커맨드 라인에서 제공된 순서대로 각 볼트 암호를 시도하여 볼트 내용을 해독할 것이다.

예를 들어 특정 파일에 읽은 'dev' 암호를 사용해 'prod' 암호를 입력하라는 메시지를 표시하려면 다음과 같이 사용할 수 있다.

 

ansible-playbook --vault-id dev@dev-password --vault-id prod@prompt secrets.yml



자세한 정보는 https://docs.ansible.com/ansible/latest/user_guide/vault.html에..



Posted by 김용환 '김용환'



sbt test를 실행하다 다음과 같이 종료 에러가 나면.. (Intellij에서는 이상이 없다)



19/01/17 22:16:40 ERROR Utils: uncaught error in thread spark-listener-group-streams, stopping SparkContext

java.lang.InterruptedException

at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.reportInterruptAfterWait(AbstractQueuedSynchronizer.java:2014)





build.sbt에 다음 파일을 추가한다.


fork in run := true 


로 수정한다. info 로그를 error로 처리하는 것이 맘에 들지 않지만 .. 작동은 된다.





Intellij와 sbt를 함께 사용하고 있기 떄문에 그럴 수 있는데.


console 커맨드를 사용해 scala 코드를 실행하면 SBT와 동일한 가상 시스템에서 코드가 실행된다. 상황에 따라 System.exit 호출이나 종료되지 않은 스레드와 같이 SBT가 중단될 수 있다. 


테스트 결과 JVM이 종료되면 SBT를 다시 시작해야 하는 상황을 피하기 위해 JVM을 포크하는 fork in run := true를 추가한다.

Posted by 김용환 '김용환'




SparkSession을 종료하지 않으면 아래와 같은 에러가 발생할 수 있다. 




Driver stacktrace:

19/01/17 19:42:45 INFO DAGScheduler: Job 1 failed: count at FirstSparkSample.scala:21, took 0.194101 s

Exception in thread "main" org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 2.0 failed 1 times, most recent failure: Lost task 0.0 in stage 2.0 (TID 22, localhost, executor driver): java.lang.NoSuchMethodError: net.jpountz.lz4.LZ4BlockInputStream.<init>(Ljava/io/InputStream;Z)V




SparkSession을 stop하는 코드를  추가한다.


sparksession.stop()

Posted by 김용환 '김용환'



    

- name: copy index.html

  copy:

    src: files/index.html

    dest: /usr/share/nginx/html/index.html

    mode: "0644"

    

    

mode 매개 변수를 0으로 시작하지 않거나 문자열로 인용하면 앤서블은 이 값을 8진수가 아닌 10진수로 해석하고 예상한 대로 파일 사용 권한을 설정하지 않는다. 자세한 내용은 깃허브(http://bit.ly/1GASfbl)를 참조한다.







'Ansible-Puppet-Chef' 카테고리의 다른 글

앤서블의 호스트 지정 패턴  (0) 2019.01.19
ansible-vault 간단 커맨드  (0) 2019.01.19
[ansible] copy mode 주의사항  (0) 2019.01.14
ansible-galaxy  (0) 2019.01.14
[ansible] ubuntu 16에 no_proxy가 안먹는 이슈가  (0) 2019.01.09
ansible 설치 (virtualenv)  (0) 2018.12.18
Posted by 김용환 '김용환'



깃허브 사용자인 bennojoy가 작성한 ntp 롤을 설치하고 싶다고 가정하자. 이는 시간을  NTP 서버와 동기화하도록 호스트를 설정하는 롤이다.


다음 설치 커맨드로 롤을 설치할 수 있다.



$ ansible-galaxy install --roles-path ./roles bennojoy.ntp


결과는 다음과 같다.


- downloading role 'ntp', owned by bennojoy

- downloading role from https://github.com/bennojoy/ntp/archive/master.tar.gz

- extracting bennojoy.ntp to /Users/samuel.kim/dev/commerce/111/roles/bennojoy.ntp

- bennojoy.ntp (master) was installed successfully

'Ansible-Puppet-Chef' 카테고리의 다른 글

ansible-vault 간단 커맨드  (0) 2019.01.19
[ansible] copy mode 주의사항  (0) 2019.01.14
ansible-galaxy  (0) 2019.01.14
[ansible] ubuntu 16에 no_proxy가 안먹는 이슈가  (0) 2019.01.09
ansible 설치 (virtualenv)  (0) 2018.12.18
[ansible] lineinfile  (0) 2018.07.05
Posted by 김용환 '김용환'

sqoop 성능 튜닝

hadoop 2019.01.11 18:33



sqoop에서 무거운 DB덤프 잡을 빨리 하려면 다음 옵션을  고려하길 바란다. 확실히 빨라진다. 10분 배치를 1분대로..



1)  mapper 메모리는 크게


           -Dmapreduce.map.memory.mb=(크게, 그러나 적절하게) -Dmapreduce.map.java.opts=-Xmx(크게, 그러나 적절하게)



2) mapper 개수는 많이 


        --num-mappers (크게, 그러나 적절하게)                                                




3) split-by와 $CONDITIONS



--split-by id : 쪼개는 컬럼 이름

$CONDITIONS : 내부 튜닝 값




https://sqoop.apache.org/docs/1.4.2/SqoopUserGuide.html


If you want to import the results of a query in parallel, then each map task will need to execute a copy of the query, with results partitioned by bounding conditions inferred by Sqoop. Your query must include the token $CONDITIONS which each Sqoop process will replace with a unique condition expression. You must also select a splitting column with --split-by.

For example:

$ sqoop import \
  --query 'SELECT a.*, b.* FROM a JOIN b on (a.id == b.id) WHERE $CONDITIONS' \
  --split-by a.id --target-dir /user/foo/joinresults

Alternately, the query can be executed once and imported serially, by specifying a single map task with -m 1:

$ sqoop import \
  --query 'SELECT a.*, b.* FROM a JOIN b on (a.id == b.id) WHERE $CONDITIONS' \
  -m 1 --target-dir /user/foo/joinresults





4) --boundary-query <sql 문>


전체를 덤프를 뜨려고 하면 속도가 통 나지 않는다. split-by id를 사용할 때 index가 있는 id를 기반으로 경계문을 전송하면 빠르게 쿼리 결과를 받을 수 있다.


Posted by 김용환 '김용환'



spark 애플리케이션-haoop(yarn)  연동 잡을 실행하던 중에 


애플리케이션을 종료하려면.. 스파크 스케줄러(또는 hadoop 스케줄러)에서 


인스턴스 id인 application_11123123131321을 얻은 후,


yarn 커맨드의 kill 커맨드에 인스턴스 id를 추가한다.  



yarn application -kill application_11123123131321 





Posted by 김용환 '김용환'