일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- redash
- gradle
- Kafka
- Jenkins
- login
- SpringBoot
- 간단
- Cluster
- ec2
- spring
- 머신러닝
- hive
- java
- 예제
- vue
- Zeppelin
- fastcampus
- 자바
- 설정
- Redis
- 로그인
- config
- 젠킨스
- 레디스
- 클러스터
- Docker
- EMR
- 자동
- Mac
- aws
- Today
- Total
코알못
[AWS] 스노우볼을 이용한 데이터 이관 본문
IDC 에 하둡을 구성하여 운영중에 있었으나 디스크 증설, 버전 관리 등 공수가 크고 관리에 어려움이 있어 클라우드 이전을 계획 하였다.
클라우드 이전을 위해서는 약 37TB의 데이터를 이관해야 했으나 현재 IDC에 구축한 하둡의 경우 외부로 나가는 네트워크 망이 1G 로 되어 있으며 해당 망에 부하가 생길시 서비스에 영향을 주는 상황이였다.
hadoop(hdp 2.6) 에 distcp 에 mac map 수(-m), map 당 max bandwidth(-bandwidth) 조절 가능한 옵션이 존재하나 아래 테스트와 같이 해당 옵션이 적용 되지 않았다. (map 하나 투입, 56Mbps 사용하도록 설정 하였으나 200Mbps 를 사용하였다.)
서비스에 영향을 줄수 있는 작업이므로 다른 대안을 검색중 선택한 방안은 AWS 스노우볼을 이용하는 것이였다.
스노우볼은 80G 정도 되는 디스크 장비이며 원하는 장소에 스노우볼을 주문하면 일주일이 소요되어 도착한다.
저자의 경우 하둡이 설치되어있는 서버가 있는 IDC 에 스노우볼을 주문하였으며 일주일뒤에 도착하였다.
스노우 볼에 원하는 IP 를 할당할 수 있어 이슈가 있는 '외부로 나가는 네트워크망' 을 사용하지 않아 서비스에 영향 없이 작업이 가능했다.
내부 IP 네트워크 망은 1G 를 사용하였으며 3시간에 최대 800GB 전송 할 수 있었다.
총 60TB를 옮겨야 하여 약 10일 소요되었다.
스노우 볼은 도착한 시점으로 부터 10일간 사용가능하며 그 이후는 추가 요금이 나가며
이슈 파악 및 데이터 정합성 체크를 제외한 only 데이터 이관 시간만 10일 이였고 총 사용일수는 20일 정도 된다.
우선 스노우볼에 데이터를 전송하기 위해서는 aws cli 명령어를 이용하며
aws cli 명령어를 이용하기 위해서는 해당 명령어를 호출할 중계서버가 필요하다. (aws 에서 제공하는것이 아닌 자체 구축 해야한다.)
중계서버는 IDC 하둡과 같은 IP 대역을 할당 하였으며 아래 3가지 사항이 필요하다.
- aws cli 설치 : 1.16.14 이하 (이상 버전은 스노우볼에서 지원 하지 않음)
- hdfs fuse 설치 (aws cli 로 데이터 전송을 위해서는 리눅스 파일 시스템 경로로 진행해야 하므로 hdfs fuge 를 이용하여 하둡 디스크를 중계서버에 마운트 한다. 설치 방법은 아래 참고)
- 메모리 최대한 많이 (최소 30GB 라고 가이드 받았으나 데이터 이관 속도가 매우 느려 90GB로 증설)
가이드 받은 중계서버 최소 스펙은 아래와 같다.
- MEM 32G / 4core / 디스크 100G /회선은 10Gbps 권장
스노우볼의 경우 데이터 전송시 메모리 캐시에 저장하여 전송하기에 메모리가 클수록 빠르게 전송 가능하다.
데이터 이관에 대한 전체적인 그림은 아래와 같다.
[1차 -> 스노우볼 셋팅은 aws 같이 진행, 그뒤 데이터 이관 작업은 자체적으로 진행] (자체적으로 진행하므로 정확한 소요일 없으나 보통 3일 소요 된다고 함)
[2차 -> aws에서 스노우볼을 가져간뒤 aws 에서 데이터 최종 경로에 이관 진행] (총 3일 소요)
이관을 위해 했던 이슈와 정합성 체크 했던 내용을 아래 정리 하였으니 이관시 참고 하여 도움이 됐으면 한다.
아래 가이드에 따라 재설치를 진행하여 해결 하였다.
Snowball Edge디바이스는 AWS CLI를 1.16.14 이하만 지원을 하고 있기 때문에, AWS CLI를 재설치할 필요성이 있어 보입니다.
AWS CLI는 설치 과정 중 Python 3.6 이상을 필요로 하며, OS 상황에 따라 설치 방법은 다를 수있으나 Amazon Linux2 (CentOS) 기준
sudo yum install -y python3
이후, 설치된 파이썬버전을 기본 값으로 대체해주면됩니다. (sudo ln -s -f /usr/bin/python3.x /usr/bin/python)
Python 설치 이후, 아래 명령어 3개를 입력하여 AWS CLI 1.16.14 버전을 설치합니다.
curl "https://s3.amazonaws.com/aws-cli/awscli-bundle-1.16.14.zip"
-o "awscli-bundle.zip" unzip awscli-bundle.zip sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
재설치 이후, aws --version 을 입력해도 여전히 AWS CLI 2 버전이 명시된다면, 아래 명령어를 통해 경로에 AWS CLI를 다시 추가합니다.
export PATH=/usr/local/bin:$PATH
source ~/.bash_profile
참고 링크(https://docs.aws.amazon.com/cli/v1/userguide/install-linux.html)같이 전달 드리며,
2. fuse 설치 이슈
hdp fuse 패키지를 해당 가이드대로 다운로드 하였으나 cloudera와 Hortonworks 인수하면서 해당 패키지가 유료로 전환되어 다운로드가 불가능 했다.
저자의 경우 인터넷에 돌아다니는 rpm 파일 다운받아서 설치 진행하였으며 차근 차근 없는 파일 인터넷에 다운받아서 정상 설치 완료 하였다.
마운트시 아래와 같은 오류 발생시 버전이 안맞는것으로 다른 버전의 fuge 를 설치한다. (저자의 경우 sudo yum install hadoop-0.20-fuse 로 설치한뒤 hdp2.6과 버전이 안맞아 이슈 발생하였다.)
$ hadoop-fuse-dfs dfs://master-ip:8020 /mnt/hdfs -odebug
INFO fuse_options.c:165 Adding FUSE arg /mnt/hdfs
org.apache.hadoop.ipc.RemoteException: Server IPC version 9 cannot communicate with client version 4
정상적으로 버전 이슈가 발생하지 않은 fuge rpm 파일은 여기서 다운 받았다. 저자의 경우 hdp 버전이 2.6 이다.
주의할점은 하둡 설치된 서버에서 설치하게 되면 하둡 기존 설치된 bin파일 링크가 해지되어 기존 하둡을 사용할 수 없으므로 절대 하둡 설치된 서버를 중계서버로 사용하지 않는다. (복구 하느라 힘들었습니다..)
-- 마운트 디버깅 모드 (마운트된 디렉토리 접속해서 테스트 하며, 로그 확인후 이슈 없으면 ctrl+c 눌러 마운트 종료 > 언마운트 따로 해줘야 마운트 가능하다)
$ mkdir -p /mnt/hdfs
$ chown -R hdfs:hdfs /mnt/hdfs/
$ hadoop-fuse-dfs dfs://master-ip:8020 /mnt/hdfs -odebug
INFO fuse_options.c:165 Adding FUSE arg /mnt/hdfs
org.apache.hadoop.ipc.RemoteException: Server IPC version 9 cannot communicate with client version 4
-- 마운트
$ hadoop-fuse-dfs dfs://master-ip:8020 /mnt/hdfs
-- 언마운트
$ umount /mnt/hdfs
3. aws 메모리 이슈
- 네트워크 1g 모두 사용하지 않는 이슈 발생
- 병렬 처리를 5배(10개 > 50개 동시 실행)로 늘려도 네트워크를 1g 미만으로 사용함
- 병렬 처리를 늘리니 마운트가 해지되기도 함 (다시 언마운트 한뒤 마운트 진행해야함)
- 메모리를 3배(30G > 90G)로 늘리고 10개의 배치 돌렸더니 메모리 모두 사용하고 네트워크도 모두 사용함
- 자원을 충분히 사용하고 있으므로 배치를 50개로 늘릴 필요가 없어 10개의 배치로 진행
- 용량 및 갯수를 확인할 수 있는 방법이 없었음
- 아래 [1] 명령어 쓰면 특정 객체수 이하만 읽을수 있어 정확한 측정이 어려움
- ls 의 option 으로 page-size 가 있는데 기본값이 1000 (최대값)이라 1000개의 객체 이하의 데이터의 정보만 얻을 수 있음
- [2], [3] 둘중 하나 사용하여 스노우볼에 이관된 데이터의 용량, 객체수 확인 하면 되고 저자의 경우 [2] 방식을 사용하여 확인 하였다.
- 용량 확인시 단위 변환(byte > GB)을 툴로 계산하였으나 툴에 따라 데이터 단위 변환 계산 방식이 달라 하둡 데이터 크기는 아래 사이트를 이용한다.
- [1]
$ aws s3 ls s3://<S3bucketName>/<Path>/ --endpoint http://스노우볼IP:8080 --recursive --human-readable --summarize | tail -2
Total Objects: 41
Total Size: 9.0 GiB
[2]
aws s3api list-objects --bucket BUCKETNAME --endpoint http://스노우볼IP:8080 --prefix SUBFOLDER --output json --query "[sum(Contents[].Size), length(Contents[])]"
예시
$ aws s3api list-objects --bucket "버킷명" --endpoint http://스노우볼IP:8080 --prefix "transform/data/" --output json --query "[sum(Contents[].Size), length(Contents[])]"
[
22901629741,
14719
]
[3]
Python Script
#!/bin/python3
import boto3
bucket_name="your-own-dest-seoul"
#prefix="file"
prefix=""
# Create a client
client = boto3.client('s3', region_name='ap-northeast-2', endpoint_url='http://10.10.10.10:8080')
# Create a reusable Paginator
paginator = client.get_paginator('list_objects')
# Create a PageIterator from the Paginator
page_iterator = paginator.paginate(Bucket=bucket_name, Prefix=prefix)
sum_size = 0
count_objs = 0
for page in page_iterator:
for content in page['Contents']:
print(content['Key'], ',', content['Size'])
sum_size += content['Size']
count_objs += 1
# print summary
print("##########")
print("Sum of size: %s, Count of objects: %s "% (sum_size, count_objs))
5. 스크립트 (데이터 이관시 사용한 명령어)
- 이관 스크립트
date2=`date -d "$END_TIME KST" +%Y%m%d`;
cnt=3
logname="default"
if [ -n "$1" ]
then
let date2=$(date -d "$1" +"%Y%m%d");
fi
if [ -n "$2" ]
then
let cnt=$2
fi
if [ -n "$3" ]
then
let logname=$3
fi
for ((i=1;i<=cnt;i++)); do
yyyy=$(date -d "$date2" +"%Y");
mm=$(date -d "$date2" +"%-m");
dd=$(date -d "$date2" +"%-d");
echo "$(date +%Y)-$(date +%m)-$(date +%d) $(date +%H):$(date +%M):$(date +%S) : $yyyy $mm $dd start" >> /root/script/snow/logs/data_move_$logname.log
aws s3 sync /mnt/hdfs/apps/hive/warehouse/test.db/table_A/yyyy=$yyyy/mm=$mm/dd=$dd s3://bucket/transform/test/table_A/yyyy=$yyyy/mm=$mm/dd=$dd/ --endpoint http://snowball-ip:8080
echo "$(date +%Y)-$(date +%m)-$(date +%d) $(date +%H):$(date +%M):$(date +%S) : $yyyy $mm $dd end" >> /root/script/snow/logs/data_move_$logname.log
date2=`date -d "$date2 1 day" +%Y%m%d`;
done
- 이관 스크립트 병렬처리 스크립트
2020-01-01 부터 862일 까지 데이터를 10개로 나누어 병렬 처리 (프로세스 10개)
allday=862
batch=10
startday=20200101
batchperday=$((allday/batch))
remain=$((allday%batch))
for ((i=1;i<=batch;i++)); do
amount=$batchperday
if [ $remain -gt 0 ];then
amount=$(($amount+1))
remain=$(($remain-1))
fi
nohup /root/script/new_snow/data_move.sh $startday $amount $i &>/dev/null &
startday=`date -d "$startday $amount day" +%Y%m%d`;
done
- 용량 체크 스크립트
용량이 매우 크면 나눠서 용량 체크 하는것이 빠르다.
aws s3api list-objects --bucket "bucket" --endpoint http://snowball-ip:8080 --prefix "transform/test/table_A/yyyy=2020/" --output json --query "[sum(Contents[].Size), length(Contents[])]" > /root/script/snow/logs/table_A_2020.log
aws s3api list-objects --bucket "bucket" --endpoint http://snowball-ip:8080 --prefix "transform/test/table_A/yyyy=2021/" --output json --query "[sum(Contents[].Size), length(Contents[])]" > /root/script/snow/logs/table_A_2021.log
aws s3api list-objects --bucket "bucket" --endpoint http://snowball-ip:8080 --prefix "transform/test/table_A/yyyy=2022/" --output json --query "[sum(Contents[].Size), length(Contents[])]" > /root/script/snow/logs/table_A_2022.log
'BIG DATA' 카테고리의 다른 글
[EMR] Glue > Aurora Metastore Migration (0) | 2022.07.12 |
---|---|
[EMR] 해결한 이슈 항목 (0) | 2022.05.27 |
[Redash] Ldap 연동 해보자! (0) | 2022.05.08 |
filebeat에서 다중 logstash 서버로 로그 이동시 한대 재기동시? (0) | 2022.04.29 |
[AWS] EMR(hadoop) - 클러스터 고정 IP 지정 해보자! (0) | 2022.04.28 |