반응형


스파크(Spark) 작업 중 평소에 잘돌던 잡이 갑자기


특정 노드에서의 문제로 작업이 중단됬거나 제대로 돌지 않았을 경우는 해당 노드의 디스크폴트(disk fault)를 의심해보아야 한다.


최근 잡이 실패해 해당 잡의 로그를 보았더니 다음과 같은 에러가 찍혔다.


Exception in thread "main" org.apache.spark.SparkException: Job aborted due to stage failure: Task 8 in stage 1.0 failed 4 times, most recent failure: Lost task 8.3 in stage 1.0 (TID 374, datanode-10.svr.maker.net):

com.esotericsoftware.kryo.KryoException: java.io.IOException: Stream is corrupted

        at com.esotericsoftware.kryo.io.Input.fill(Input.java:142)

        at com.esotericsoftware.kryo.io.Input.require(Input.java:155)

        at com.esotericsoftware.kryo.io.Input.readInt(Input.java:337)

        at com.esotericsoftware.kryo.util.DefaultClassResolver.readClass(DefaultClassResolver.java:109)

        at com.esotericsoftware.kryo.Kryo.readClass(Kryo.java:610)

        at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:721)

        at org.apache.spark.serializer.KryoDeserializationStream.readObject(KryoSerializer.scala:192)

        at org.apache.spark.serializer.DeserializationStream.readKey(Serializer.scala:169)

        at org.apache.spark.serializer.DeserializationStream$$anon$2.getNext(Serializer.scala:201)

        at org.apache.spark.serializer.DeserializationStream$$anon$2.getNext(Serializer.scala:198)

        at org.apache.spark.util.NextIterator.hasNext(NextIterator.scala:71)

        at scala.collection.Iterator$$anon$13.hasNext(Iterator.scala:371)

        at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)

        at org.apache.spark.util.CompletionIterator.hasNext(CompletionIterator.scala:32)

        at org.apache.spark.InterruptibleIterator.hasNext(InterruptibleIterator.scala:39)

        at scala.collection.Iterator$$anon$13.hasNext(Iterator.scala:371)

        at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)

        at scala.collection.Iterator$$anon$13.hasNext(Iterator.scala:371)

        at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)

        at org.apache.spark.util.collection.ExternalSorter.insertAll(ExternalSorter.scala:209)

        at org.apache.spark.shuffle.sort.SortShuffleWriter.write(SortShuffleWriter.scala:73)

        at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:73)

        at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:41)

        at org.apache.spark.scheduler.Task.run(Task.scala:88)

        at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:214)

        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)

        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)

        at java.lang.Thread.run(Thread.java:748)

Caused by: java.io.IOException: Stream is corrupted

        at net.jpountz.lz4.LZ4BlockInputStream.refill(LZ4BlockInputStream.java:153)

        at net.jpountz.lz4.LZ4BlockInputStream.read(LZ4BlockInputStream.java:117)

        at com.esotericsoftware.kryo.io.Input.fill(Input.java:140)

        ... 27 more


데이터노드에서 com.esotericsoftware.kryo.KryoException: java.io.IOException: Stream is corrupted exception이 발생하며


잡이 정상적으로 돌지 않았다. 그래서 해당 서버를 모니터링 하는 사이트에 들어가서 확인해봤더니 딱히 별다른 이슈가 없었지만 이전에도


상태는 정상이나 disk fault로 비슷한 상황이 발생한 적이 있었기에 시스템팀에 문의해보았더니 역시나 디스크폴트(disk fault)문제였다.


정확히는 하드웨어 폴트는 확인 되지 않고 OS에서만 컨트롤러 및 디스크 장애가 있다고 전달받았다.


따라서 평소에 잘 돌던 작업이 특정노드를 원인으로 돌지않았다면 장비를 의심해보시길!!!

반응형
반응형


Hive external table을 생성하게 되면 테이블을 drop시키더라도 하둡에는 데이터가 남게 되는데요.


이런 이유로 같은 이름으로 테이블을 재생성했을 경우 기존의 데이터가 그대로 들어있는 것을 보실 수 있습니다.


그래서 hdfs명령으로 하둡데이터를 삭제하고 싶은데 권한 문제로 삭제되지 않습니다...


rmr: DEPRECATED: Please use 'rm -r' instead.

rmr: Failed to move to trash: hdfs://server-txa001.svr.maker.net:8020/user/hive/warehouse/oasis.db/specific_pub_and_area: Permission denied by sticky bit setting: user=irteam, inode=specific_pub_and_area

Command failed with exit code = 1


따라서 external 테이블은 drop시키기 전에 alter명령어로  테이블의 external속성을 변경해주고 drop시켜주어야 합니다.


먼저 desc formatted 테이블명 으로 데이터가 하둡어디에 저장되어있는지 확인합니다.


[server-txa001.svr.maker.net: 8020] > desc formatted specific_pub_and_area;

Query: describe formatted specific_pub_and_area



보시면 Location이 하둡에 저장된 데이터 경로입니다.

해당 Table Parameters를 보시면 EXTERNAL옵션이 TRUE로 되어 있는 것을 보실 수 있습니다.


이 상태에서는 아무리 테이블을 drop시켜도 데이터가 남아있게 됩니다.

따라서 alter table specific_pub_and_area set tblproperties('EXTERNAL'='FALSE'); 명령어로 옵션을 변경해주셔야 합니다.


이렇게 변경하고 desc formatted 테이블명 명령어로 보시면 EXTERNAL옵션이 FALSE로 변경된 걸 확인하실 수 있습니다.


이 상태에서 drop table {테이블명} 을 해주시게 되면 하둡에 있는 데이터들도 삭제되는 것을 확인 하실 수 있습니다.

반응형
반응형

최근 SUPERSET(슈퍼셋)작업을 진행 중 impala(임팔라)를 사용하면서 경험했던 내용에 대해 정리해보려고 한다.


impala(임팔라)와 hive(하이브)는 hive metastore(하이브 메타스토어)를 공유하며 impala는 metatdata를 캐시를 해서 관리하기때문에 빠른 성능을 보여주지만 hive에 의해서 메타데이터가 변경되었을 때 해당 캐시를 리프레쉬해주는 invalidate metadat명령이나 refresh명령어를 사용해서 캐시를 갱신해주어야 한다.

 When you create a table, load data, and so on through Hive, you do need to issue REFRESH or INVALIDATE METADATA on an Impala node before executing a query there.
The REFRESH and INVALIDATE METADATA statements are not needed when the CREATE TABLE,INSERT, or other table-changing or data-changing operation is performed through Impala.
These statements are still needed if such operations are done through Hive or by manipulating data files directly in HDFS, but in those cases the statements only need to be issued on one Impala node
rather than on all nodes. See REFRESH Statement and INVALIDATE METADATA Statement for the latest usage information for those statements.

By default, the metadata loading and caching on startup happens asynchronously, so Impala can begin accepting requests promptly. 

참고 : Components of the Impala Server



hive shell(하이브쉘)에서 다음과 같은 테이블이 있다.

hive> show tables;
OK
acedmp_custom
specific_pub_and_area3
test_table

hive shell에서 보면 specific_pub_and_area 테이블이 없다. drop시켰기 때문 (이전에 있었는데 drop시킨후 show tables 명령어)

but impala shell로 접근해서 보면 hive에서 spcific_pub_and_area테이블을 드랍시켰음에도 불구하고 테이블이 나타난다...

[svr.maker.net:21000] > show tables;
Query: show tables
+------------------------+
| name                   |
+------------------------+
| specific_pub_and_area  |
| specific_pub_and_area3 |
| test_table             |
+------------------------+



그래서 drop시켜보려고 하면 이미 hive metastore에는 존재하지 않는다고 나온다...

[svr.maker.net:21000] > drop table specific_pub_and_area;
Query: drop table specific_pub_and_area
ERROR: AnalysisException: Table oasis.specific_pub_and_area no longer exists in the Hive MetaStore. Run 'invalidate metadata oasis.specific_pub_and_area' to update the Impala catalog.
CAUSED BY: TableLoadingException: Table oasis.specific_pub_and_area no longer exists in the Hive MetaStore. Run 'invalidate metadata oasis.specific_pub_and_area' to update the Impala catalog.

여기에 대해서는 impala가 hive metastore를 어떻게 관리하는지 이해할 필요가 있다!(todo)



그래서 invalidate metadata oasis.specific_pub_and_area 명령어를 수행해주어야 impala에도 변경된 내용이 반영된다. 

(refresh oasis.specific_pub_and_area;) 명령어로는 테이블 삭제 생성까지 여부는 반영되지 않는다. 

[svr.maker.net:21000] > invalidate metadata oasis.specific_pub_and_area;
Query: invalidate metadata oasis.specific_pub_and_area

Fetched 0 row(s) in 0.16s
[svrmaker.net:21000] > show tables;
Query: show tables
+------------------------+
| name                   |
+------------------------+
| specific_pub_and_area3 |
| test_table             |
+------------------------+

새로운 테이블이 create됬을 때도 똑같이 해주어야한다.



hive쿼리로 hive테이블에 데이터를 밀어넣어보았다. (밑의 내용은 임의로 수정된 내용임을 말씀드립니다..)

hive> select * from specific_pub_and_area limit 10;
OK
20190320       3339487      Test신문    8888      Test_신문_Below      PAG     333     67
20190320      4449485      Test신문    7777      Test_신문_Below      PAG     14844   103335
.
.
.
(생략)
Time taken: 0.29 seconds, Fetched: 10 row(s)

hive> select count(*) from specific_pub_and_area;
OK
4794



impala shell에서 select를 해보면???

[svr.maker.net:21000] > select count(*) from specific_pub_and_area;
Query: select count(*) from specific_pub_and_area
+----------+
| count(*) |
+----------+
| 0        |
+----------+
Fetched 1 row(s) in 2.03s

[svrmaker.net:21000] > refresh oasis.specific_pub_and_area;
Query: refresh oasis.specific_pub_and_area2

Fetched 0 row(s) in 0.18s
[svrmaker.net:21000] > select count(*) from specific_pub_and_area;
Query: select count(*) from specific_pub_and_area2
+----------+
| count(*) |
+----------+
| 4794     |
+----------+
Fetched 1 row(s) in 1.21s

실제로 hive metastore에 테이블이 추가되거나 데이터가 insert되었을 때 invalidate metadata db.tablename 을해주면 모든 

경우에대해서 impala shell에서도 접근 가능하다.



하지만 invalidate metadata는 refresh에 비해 부하가 크므로 실제 데이터가 insert되었는지에 대한 확인만을 위한거면 refresh명령어로 갱신해주도록하자.

INVALIDATE METADATA and REFRESH are counterparts: INVALIDATE METADATA waits to reload the metadata when needed for a subsequent query, 
but reloads all the metadata for the table, which can be an expensive operation, especially for large tables with many partitions. 
REFRESH reloads the metadata immediately, but only loads the block location data for newly added data files, 
making it a less expensive operation overall. If data was altered in some more extensive way, 
such as being reorganized by the HDFS balancer, use INVALIDATE METADATA to avoid a performance penalty from reduced local reads. 
If you used Impala version 1.0, the INVALIDATE METADATA statement works just like the Impala 1.0 REFRESH statement did, while the Impala 1.1 REFRESH 
is optimized for the common use case of adding new data files to an existing table, thus the table name argument is now required.

The table name is a required parameter [for REFRESH]. To flush the metadata for all tables, use the INVALIDATE METADATA command. 
Because REFRESH tablename only works for tables that the current Impala node is already aware of, when you create a new table in the Hive shell, 
enter INVALIDATE METADATA new_table before you can see the new table in impala-shell. Once the table is known by Impala, 
you can issue REFRESH table_name after you add data files for that table.

참고 : invalidate와 refresh에 대한 자세한 내용



[ 결 론 ] 

hive쿼리를 통해 hive metastore에 데이터베이스나 테이블이 생성되거나 삭제되었을 때는 

impala에서 invalidate metadata db.tablename 명령어를 주어야 다시 캐싱된다.

but 테이블에 새로운 데이터만 hive쿼리에 의해 insert되었을 때는 refresh db.tablename으로 갱신해주도록 하자.

impala에서 생성한 테이블이나 데이터는 hive에서 별다른 명령어 없이 확인 가능하다.


반응형
반응형

스파크(SPARK)가 설치된 서버에서 스파크 버전이 확인 하고 싶을 떄


spark-submit --version


으로 확인할 수 있다.


감사합니당 :)


반응형
반응형

최근 hive와 impala query를 만지게 되면서 hive udf를 impala에 등록할 일이 생겼는데


hive에서 udf를 등록할 때의 명령어가 먹지 않아 약간의 삽질을 하였다.


사용한 udf는 string을 입력받아 잘게 쪼개어 다시 string을 반환하는 역할이었다.


[ Hive UDF create command ]

hive> create function ad_get as 'com.data.udf.AdGet' using jar 'hdfs:///user/hive/lib/hive-udf.jar';

ad_get => hive에서 udf로 사용할 명칭
com.data.udf.AdGet => jar에서 udf로 등록할 클래스명칭

hdfs:///user/hive/lib/hive-udf.jar => jar hdfs path



[ Impala UDF create command ] 

Impala는 hive udf create 명령과는 다르게 해당 udf의 return 타입과 input타입을 명시해 주어야 한다.

create function ad_get(string, string, string) returns string location 'hdfs:///user/hive/lib/hive-udf.jar' symbol='com.data.udf.AdGet';


ad_get(string, string, string) => impala에서 udf로 사용할 명칭(string arg 3개를 입력 받는다)

returns string => 리턴타입 지정

symbol='com.data.udf.AdGet' => jar에서 udf로 등록할 클래스명칭

location 'hdfs:///user/hive/lib/hive-udf.jar



impala에 해당 명령어로 udf를 등록한 후 show functions 명령을 내려 보면 잘 등록되었는지 확인이 가능하다.


감사합니다:)


반응형
반응형

하둡 클러스터를 운영하다보면 데이터 노드마다 데이터 분포의 불균형 상태가 생길 수 있는데 이 때 실행시켜주어야 하는 작업이 '밸런서(balancer)'이다.


밸런서(balancer)에 대한 내용을 포스팅 해보겠다. 해당 내용은 '하둡 완벽 가이드(4판)'을 정리한 내용이다.


[ 하둡 밸런서 ] 

하둡 클러스터는 시간이 지남에 따라 데이터노드 사이의 블록의 분포는 불균형 상태가 될 수 있고 불균형 상태의 클러스터는 맵리듀스의 지역성(locality)에 영향을 받게 되므로 자주 사용되는 데이터노드에 큰 부하를 주게 된다. 따라서 불균형 상태가 되지 않도록 해야 한다.


밸런서란?

밸런서 프로그램은 블록을 재분배하기 위해 사용률이 높은 데이터노드의 블록을 사용률이 낮은 데이터노드로 옮기는 하둡 데몬이다. 블록 복제본을 다른 랙에 두어서 데이터 유실을 방지하는 블록 복제본 배치 정책은 그대로 고수한다. 밸런서는 클러스터가 균형 상태가 될 때까지 블록을 이동시킨다. 여기서 균형 상태란 각 데이터노드의 사용률(노드의 총 가용 공간과 사용된 공간의 비율)이 클러스터의 사용률(클러스터의 총 가용 공간과 사용된 공간의 비율)과 비교하여 지정된 임계치 비율 이내일 때를 의미한다. 


밸런서는 다음과 같이 실행할 수 있다.

start-balancer.sh


-threshold 인자에는 클러스터의 균형 상태를 의미하는 임계치 비율을 지정한다. 이 플래그는 선택사항이며, 지정하지 않으면 임계치는 10%다. 클러스터에는 오직 하나의 밸런서만 실행될 수 있다. 


밸런서는 클러스터가 균형 상태가 될 때까지 수행된다. 더 이상 블록을 이동시킬 수 없거나 네임노드와 통신이 단절될 수 있기 때문에 표준 로그 디렉터리에 로그파일을 생성하고 재분배 작업이 순환될 때마다 기록을 남긴다. 아래는 작은 클러스터에서 아주 짧은 시간 동안 밸런서를 실행한 결과다.


밸런서는 클러스터에 부담을 주는가???

밸런서는 클러스터에 과도한 부하를 주지 않고 클러스터를 사용하는 다른 클라이언트에 방해가 되지 않기 위해 백그라운드로 실행되도록 설계되었다. 밸런서는 한 노드에서 다른 노드로 블록을 복제할 때 필요한 대역폭을 제한할 수 있다. 기본값은 1MB/s지만 hdfs-site.xml 파일의 dfs.datanode.balance.bandwidthPerSec 속성에 바이트 단위로 값을 지정하면 대역폭을 변경할 수 있다. (대역폭을 늘린 순 있겠지만 늘리게 되면 클러스터에 미치는 영향이 커질 수 있음을 주의하자.)


실제로 경험상 밸런서를 실행하면 생각보다 수행시간이 오래걸린다.(20대 하둡 클러스터 기준) 하루 이상은 걸렸던 걸로 기억한다.


읽어 주셔서 감사합니다.

반응형
반응형

HDFS 네임노드의 파일시스템 이미지와 에디트 로그에 대한 내용은 하둡을 운영하기 위해 기본적으로 알아야 할 내용이기에 정리해본다.


해당 내용은 '하둡 완벽 가이드(4판)'을 정리한 내용이다.


파일시스템 이미지와 에디트 로그


[ 네임노드의 파일시스템 메타데이터 관리 방법 ]

파일시스템의 클라이언트가 쓰기 동작(파일 생성이나 이동)을 하면 일단 에디트 로그에 해당 내역이 기록된다. 네임노드는 파일시스템의 메타데이터를 인메모리(in-memory, 파일과 메모리 양쪽에 데이터를 유지하는 방식)로 관리하는데, 에디트 로그를 먼저 변경한 후 메모리상의 메타데이터도 변경한다. 클라이언트의 읽기 요청에는 인메모리 데이터만 사용된다. 


[ 에디트 로그 ]

에디트 로그는 개념적으로 단일 개체지만 디스크에는 다수의 파일로 관리된다. 각 파일을 세그먼트라고 하며 접두사 edits와 트랜잭션 ID를 의미하는 접미사로 구성되어 있다. 한번에 하나의 파일만 쓰기를 위해 열린다. 네임노드는 쓰기 동작이 끝날 때마다 성공했다는 결과를 클라이언트에 알려주기 전에 에디트 로그를 플러시(flush)하여 동기화시킨다. 네임노드는 여러 개의 디렉터리에 에디트 로그를 기록할 수 있기 때문에 변경 내역을 모든 에디트 로그 복제본 파일에 플러시하고 동기화한 후에 성공했다는 것을 알려주어야 한다. 이는 어떠한 기계적 결함에도 데이터가 손실되지 않도록 하기 위함이다. 


[ fsimage 파일 ]

각각의 fsimage파일은 파일시스템 메타데이터의 완전하고 영속적인 체크포인트다(fsimage 파일의 접미사는 파일시스템 이미지의 마지막 트랜잭션을 나타낸다). 파일시스템에서 쓰기 동작이 있을 때마다 fsimage 파일을 변경하지는 않는데, fsimage 파일이 기가바이트 크기로 커지면 성능이 매우 느려지기 때문이다. fsimage 파일을 바로 갱신하지 않더라도 하둡의 장애복구능력이 저하되는 것은 아니다. 만약 네임노드에 장애가 발생하면 먼저 fsimage를 메모리에 로드하고 에디트 로그파일에서 특정 지점 이후에 발생한 변경 내역들을 메모리에 반영하여 파일시스템의 메타데이터를 최신의 상태로 복원할 수 있기 때문이다. 


각 fsimage 파일은 파일시스템에 존재하는 모든 디렉터리와 파일의 아이노드(inode)정보를 직렬화한 파일이다. 각 아이노드는 파일이나 디렉터리 메타데이터의 내부 구조를 나타내며 파일의 복제 수준, 변경 및 접근 시간, 접근 권한, 블록 크기, 파일을 구성하는 블록 집합과 같은 정보를 가지고 있다. 디렉터리에는 파일과 달리 변경 시간, 권한, 할당 크기와 같은 메타데이터 정보가 저장되어 있다.


블록이 실제 저장된 데이터노드에 대한 정보는 fsimage 파일에 기록되지 않는다. 대신 네임노드는 매핑 정보(어떤 블록이 어느 데이터노드에 저장되어 있는지)를 메모리에서 따로 관리한다. 네임노드는 클러스터에 데이터노드가 추가될 때마다 블록 목록에 대한 정보를 데이터노드에 요청하여 매핑 정보를 구성하며, 주기적으로 네임노듣의 블록 매핑 정보를 최신 상태로 갱신한다. 


읽어주셔서 감사합니다. 포스팅을 마치도록 하겠습니다:)



반응형
반응형

HDFS에서 데이터가 어떻게 쓰여지는지에 대한 프로세스에 대해서 정리하도록 하겠습니다.


해당 내용은 '하둡 완벽 가이드(4판)'을 정리한 내용입니다.


[ HDFS 파일 쓰기 상세 ]

1. 클라이언트는 DistributedFileSystem의 create()를 호출하여 파일을 생성합니다.

2. DistributedFileSystem은 파일시스템의 네임스페이스에 새로운 파일을 생성하기 위해 네임노드에 RPC 요청을 보냅니다. 이때 블록에 대한 정보는 보내지 않습니다. 네임노드는 요청한 파일과 동일한 파일이 이미 존재하는지, 클라이언트가 파일을 생성할 권한을 가지고 있는지 등 다양한 검사를 수행합니다. 검사를 통과하면 네임노드는 새로운 파일의 레코드를 만들고, 그렇지 않으면 파일 생성은 실패하고 클라이언트의 IOException이 발생합니다. DistributedFileSystem은 데이터를 쓸 수 있도록 클라이언트에 FSDataOutputStream을 반환하고 읽을 때와 마찬가지로 FSDataOutputStream은 데이터노드와 네임노드의 통신을 처리하는 DFSOutputStream으로 래핑됩니다.

3. 클라이언트가 데이터를 쓸 때 DFSOutputStream은 데이터를 패킷으로 분리하고, 데이터 큐라 불리는 내부 큐로 패킷을 보냅니다.  DataStreamer는 데이터 큐에 있는 패킷을 처리하고 먼저 네임노드에 복제본을 저장할 데이터노드의 목록을 요청합니다. 데이터노드 목록에 포함된 노드는 파이프라인을 형성하는데, 복제 수준이 3이면 세 개의 노드가 파이프라인에 속하게 됩니다.

4. Datastreamer는 파이프라인의 첫 번째 데이터노드로 패킷을 전송하고 첫 번째 데이터 노드는 각 패킷을 저장하고 파이프라인의 세 번째(마지막) 데이터노드로 전달합니다.

5. DFSOutputStream은 데이터노드의 승인 여부를 기다리는 ack큐라 불리는 내부 패킷 큐를 유지하고 ack큐에 있는 패킷은 파이프라인의 모든 데이터노드로부터 ack 응답을 받아야 제거됩니다. 

6. 데이터 쓰기를 완료할 때 클라이언트는 스트림에 close() 메서드를 호출합니다. 이 메서드는 데이터노드 파이프라인에 남아 있는 모든 패킷을 플러시(flush)하고 승인이 나기를 기다립니다.

7. 모든 패킷이 완전히 전송되면 네임노드에 '파일 완료' 신호를 보냅니다. 네임노드는 DataStreamer를 통해 블록 할당 요청을 받았기 때문에 파일의 블록이 어떻게 구성되어 있는지 이미 알고 있으며, 최소한의 블록 복제가 완료되기를 기다렸다가 최종적으로 성공 신호를 반환합니다. 


[ 데이터를 쓰는 도중 데이터노드 장애 발생시 ]

1. 파이프라인이 닫히고 ack큐에 있는 모든 패킷은 데이터 큐 앞쪽에 다시 추가됩니다.

2. 이렇게 하면 다운스트림(downstream)노드가 실패해도 패킷이 하나도 유실되지 않고 정상 데이터노드는 네임노드로 부터 새로운 ID를 다시 받습니다.

3. 장애가 발생한 데이터노드가 나중에 다시 복구되면 불완전한 블록은 삭제됩니다. 

4. 장애 데이터노드는 파이프라인에서 제거되고, 정상인 나머지 두 데이터노드로 새로운 파이프라인을 구성하고 블록의 남은 데이터는 파이프라인의 정상 데이터노드로 전송됩니다.

5. 네임노드는 해당 블록이 불완전 복제(under-replicated)라는 것을 인식하고 있으므로 나중에 다른 노드에 복제본이 생성되도록 조치하고 후속 블록을 정상적으로 처리합니다. 


감사합니다. 포스팅을 마치도록 하겠습니다:)


반응형
반응형


오늘은 하둡 서버 장비를 구성할 때 디스크 RAID를 사용하는 것은 어떤지에 대해 포스팅하도록 하겠습니다.


해당 내용은 '하둡 완벽 가이드(4판)'의 내용을 정리한 것입니다.


[ 하둡(Hadoop) 장비에 RAID를 사용하는 것은 어떨까? ] 

HDFS 클러스터는 데이터노드 저장소로 RAID(Redundant Array of Independent Disks)를 사용하더라도 얻을 수 있는 이익이 거의 없다(메타데이터의 손상을 막기 위해 네임노드의 디스크에 RAID를 사용하는 것은 권장한다). HDFS는 각 블록을 여러 대의 노드에 복제하는 기능을 제공하므로 RAID 장치가 지원하는 중복성(redundancy)은 필요하지 않다.


더욱이 성능 향상을 위해 흔히 사용하는 RAID 스트라이핑(RAID 0) 방식은 HDFS 블록을 모든 디스크에 라운드 로빈(round-robin, 순차 순환) 방식으로 배열하는 HDFS의 JBOD(Just a Bunch Of Disks) 방식보다 더 느리다는 것이 밝혀졌다. 'RAID 0'의  읽기와 쓰기 동작은 RAID 배열의 가장 느린 디스크 속도에 의해 제한받기 때문이다. 반면 JBOD는 각 디스크가 독립적으로 동작하므로 디스크 동작의 평균 속도는 가장 느린 디스크보다 빠르다. 실제 환경에서 디스크의 성능은 같은 기종이라도 종종 큰 편차를 보인다. 야후 클러스터에서 수행한 벤치마크에서 JBOD는 'RAID 0'보다 Gridmix에서는 10%, HDFS 쓰기에서는 30% 정도 빨랐다.


마지막으로, 만약 JBOD 환경에서 디스크 하나가 고장나면 HDFS는 고장난 디스크 없이도 계속 동작할 수 있지만, RAID는 하나의 디스크 고장이 전체 디스크 배열을 불능 상태로 만들 수 있다. 

----------------------------------------------------------------------------------------------------


하둡 장비에서 RAID를 굳이 사용할 필요가 없다고 생각했지만(하둡 내부에서 replication factor를 보통은 3으로 설정 유지하기 때문) RAID 스트라이핑 방식도 더 성능이 안좋다는 것을 인지하게 되었다. 네임노드 서버의 디스크에만 RAID를 구성하면 될 것 같다.


오늘 포스팅도 끝~!!!

반응형

+ Recent posts