승인된 하루의 데이터 대체하기

빅 데이터Beginner
지금 연습하기

소개

지역 행사장은 확정된 방문 기록을 Hive 아카이브에 보관합니다. 승인된 정정은 한 날짜의 확정된 레코드 전체를 대체합니다. 이전 행에 덧붙이는 패치가 아닙니다. 승인된 날짜 중 하나에는 이제 확정된 방문이 두 건 있고, 다른 날짜에는 한 건도 없습니다. 나중에 추가된 방문을 포함하여 나머지 날짜는 모두 그대로 보존해야 합니다.

연습용 테이블에서 추가와 대체를 비교한 뒤, 쓰기 범위를 좁게 제한한 SQL 파일을 저장하고 실제 ORC 아카이브에 실행합니다. 같은 파일을 다시 실행하고 결과도 다시 읽습니다. 환경에는 Hive와 HDFS가 이미 실행 중이며, 서로 독립적인 원본 레코드, 정정 후보, 아카이브가 준비되어 있습니다.

Hive 외부 테이블, WHERE를 사용하는 SELECT, 파티션 열, ORC, 기본 HDFS 경로를 알고 있어야 합니다. 이 실습에서는 정적 대상 파티션과 날짜별 전체 대체를 배웁니다. 모든 작업은 Terminal 탭에서 수행합니다. 65분은 읽기와 일반적인 실수에 대한 대응을 포함한 작성자의 예상 시간입니다.

추가와 대체를 안전하게 비교하기

이 단계에서는 아카이브의 정상적인 하루 데이터를 읽고, 연습용 테이블에서 세 가지 쓰기 범위를 비교합니다. 비교하는 동안 실제 아카이브는 변경하지 마세요.

Terminal을 엽니다. 실습 전체에서 준비된 작업 디렉터리를 사용합니다.

cd /home/labex/project

로컬 venue 디렉터리에는 참조용 CSV 파일과 승인 목록이 있습니다. cat은 파일을 편집하지 않고 내용을 표시합니다.

cat venue/approved-days.txt
2026-10-02
2026-10-03

실제 아카이브에서 대체할 수 있는 날짜는 이 두 날짜뿐입니다. 먼저 정상적인 날짜의 데이터를 읽습니다. Beeline은 SQL을 HiveServer2로 보냅니다. 아래 명령에서 -u는 JDBC 연결 주소, -n labex는 클라이언트 사용자 이름, -e는 SQL 텍스트를 지정합니다. 큰따옴표는 텍스트를 셸 인수 하나로 묶고, 그 안의 작은따옴표는 SQL 값을 구분합니다. DATE '...'는 날짜 데이터 타입을 명시합니다.

beeline -u jdbc:hive2://localhost:10000/default -n labex -e "SELECT * FROM venue_archive.archive WHERE visit_date=DATE '2026-10-04' ORDER BY visit_id;"

시작 알림 아래에 있는 데이터 행을 읽습니다. 이 날짜에는 v4 / Music / 4와 v5 / LateWalk / 2가 있습니다. 나중에 추가된 방문 v5도 유효하므로 보존해야 합니다. 이미지에서 여러 로깅 바인딩에 관한 SLF4J 알림을 출력할 수 있지만, 이는 SQL 오류와 별개입니다. 명령 실행이 끝나고 프롬프트로 돌아올 때까지 기다린 뒤 계속하세요.

이제 취소된 레코드까지 포함한 전체 후보 소스를 살펴봅니다.

beeline -u jdbc:hive2://localhost:10000/default -n labex -e "SELECT * FROM venue_archive.candidate ORDER BY visit_date,visit_id;"

10월 2일에는 c21 / PrintWorkshop / 5와 c22 / Bookbinding / 2가 있으며, 둘 다 confirmed입니다. 10월 3일에는 cancelled 행이 있습니다. 아카이브는 confirmed 행만 저장하므로, 10월 3일의 올바른 대체 집합은 비어 있습니다. 필터링 결과에 날짜가 없다고 해서 그 날짜의 기존 아카이브를 그대로 두라는 뜻은 아닙니다. 승인 여부와 확정 행 필터는 서로 다른 판단입니다.

실제 테이블 세 개가 어디에서 읽고 어디에 쓰는지 확인합니다. DESCRIBE FORMATTED는 열 정의에 저장소 메타데이터를 추가합니다. 각 결과에서 Table Type, Location, InputFormat을 찾으세요. 긴 출력에는 엔진 세부 정보도 있으므로 쓰기 전에 이 필드에 집중합니다.

beeline -u jdbc:hive2://localhost:10000/default -n labex -e "DESCRIBE FORMATTED venue_archive.raw; DESCRIBE FORMATTED venue_archive.candidate; DESCRIBE FORMATTED venue_archive.archive;"

세 객체 모두 EXTERNAL_TABLE입니다. 원본 위치는 hdfs://localhost:9000/user/labex/venue-archive/raw이고, 후보 위치는 /user/labex/venue-archive/candidate로 끝납니다. 두 소스 모두 텍스트 입력을 사용합니다. 아카이브 위치는 hdfs://localhost:9000/warehouse/external/venue_archive.db/archive이며 입력 형식은 OrcInputFormat으로 끝납니다. 로컬 venue/*.csv 파일은 참조용 복사본이며 아카이브가 아닙니다. 제공된 매핑과 소스 파일을 보존하세요.

실제 아카이브를 변경하기 전에 연습용 테이블 두 개를 사용합니다. practice_days에는 날짜 파티션이 있고, practice_whole은 날짜를 일반 열에 저장합니다. 처음에는 원본의 확정된 방문 기록이 들어 있습니다. 다음 명령은 이 연습용 테이블에서만 잘못된 결과를 의도적으로 보여 줍니다.

INSERT INTO는 행을 추가합니다. PARTITION(visit_date='2026-10-02')는 정적 대상 파티션입니다. 날짜 리터럴이 선택된 모든 행의 목적지를 정합니다. 따라서 SELECT는 파티션 열을 제외한 세 열만 반환해야 합니다. 별도의 WHERE 조건이 소스 행을 선택합니다. 대상 날짜를 지정해도 소스가 자동으로 필터링되지는 않습니다.

beeline -u jdbc:hive2://localhost:10000/default -n labex -e "INSERT INTO TABLE venue_archive.practice_days PARTITION(visit_date='2026-10-02') SELECT visit_id,activity,visitors FROM venue_archive.candidate WHERE visit_date=DATE '2026-10-02' AND record_status='confirmed'; SELECT * FROM venue_archive.practice_days WHERE visit_date=DATE '2026-10-02' ORDER BY visit_id;"

결과에는 c21, c22뿐 아니라 기존 v2도 있습니다. SQL은 성공했지만 대체 계약은 충족하지 못했습니다. 같은 정정을 다시 추가하면 중복이 더 늘어납니다.

INSERT OVERWRITE는 대상의 기존 행을 대체합니다. 파티션이 없는 practice_whole 테이블에서는 테이블 전체가 대상입니다. 다른 날짜가 사라지는 것을 확인하세요.

beeline -u jdbc:hive2://localhost:10000/default -n labex -e "INSERT OVERWRITE TABLE venue_archive.practice_whole SELECT visit_id,activity,visitors,visit_date FROM venue_archive.candidate WHERE visit_date=DATE '2026-10-02' AND record_status='confirmed'; SELECT * FROM venue_archive.practice_whole ORDER BY visit_date,visit_id;"

10월 2일의 두 행만 남습니다. 테이블 전체 쓰기가 성공해도 관련 없는 날짜가 조용히 사라질 수 있습니다. 이 연습용 테이블을 전체 원본 소스에서 복원합니다.

beeline -u jdbc:hive2://localhost:10000/default -n labex -e "INSERT OVERWRITE TABLE venue_archive.practice_whole SELECT visit_id,activity,visitors,visit_date FROM venue_archive.raw WHERE record_status='confirmed'; SELECT * FROM venue_archive.practice_whole ORDER BY visit_date,visit_id;"

원래의 다섯 행이 모두 돌아옵니다. 마지막으로 practice_days에서 OVERWRITE와 정적 날짜 파티션을 함께 사용합니다.

beeline -u jdbc:hive2://localhost:10000/default -n labex -e "INSERT OVERWRITE TABLE venue_archive.practice_days PARTITION(visit_date='2026-10-02') SELECT visit_id,activity,visitors FROM venue_archive.candidate WHERE visit_date=DATE '2026-10-02' AND record_status='confirmed'; SELECT * FROM venue_archive.practice_days ORDER BY visit_date,visit_id;"

행은 여섯 개입니다. 원래의 10월 1일, 정정된 10월 2일의 두 행, 원래의 10월 3일, 10월 4일의 두 방문이 있습니다. 기존 v2는 사라졌습니다. 실제 아카이브에 필요한 쓰기 범위가 바로 이것입니다.

Beeline이 잘못된 테이블 이름을 보고하면 SQL이 의도한 객체를 찾지 못한 것입니다. 이미 익숙한 아래 읽기 전용 명령으로 철자를 확인한 다음, 수정한 명령을 다시 실행합니다. 파일 경로 오류는 pwd와 ls venue로 조사하고 위의 cd 명령으로 돌아갈 수 있습니다. 오타를 고치려고 테이블을 다시 만들거나 환경 설정을 다시 실행하지 마세요.

beeline -u jdbc:hive2://localhost:10000/default -n labex -e "SHOW TABLES IN venue_archive;"

이 단계를 검사하기 전에 연습용 파티션의 10월 2일에 정확히 c21과 c22만 있고, 전체 테이블 연습용 데이터는 원래 다섯 행으로 복구되었으며, 실제 아카이브에는 여전히 원래 데이터가 있는지 확인하세요.

확정된 레코드가 있는 승인 날짜 대체하기

이 단계에서는 실제 10월 2일 대체 작업을 저장하고 실행합니다. Terminal의 /home/labex/project에서 계속합니다.

실제 테이블 venue_archive.archive는 visit_date DATE 파티션을 사용하는 외부 비트랜잭션 ORC 테이블입니다. 원본과 후보 소스는 서로 독립적인 외부 쉼표 구분 텍스트 테이블입니다. 승인된 아카이브 날짜만 대체할 수 있습니다. 소스 파일 편집, 테이블 정의나 위치 변경, 파티션 매핑 변경, 추가 날짜 생성, 전체 아카이브 재구축은 허용되지 않습니다. 10월 1일과 4일은 원래 데이터 및 기존 HDFS 파일을 보존해야 합니다. 동일한 행을 다시 쓰는 것도 승인 범위를 벗어납니다.

쓰기 전에 실제 파티션 목록과 열 구조를 살펴봅니다. SHOW PARTITIONS는 등록된 날짜 파티션을 나열하고, DESCRIBE는 일반 열 다음에 파티션 정보를 표시합니다.

beeline -u jdbc:hive2://localhost:10000/default -n labex -e "SHOW PARTITIONS venue_archive.archive; DESCRIBE venue_archive.archive;"

네 날짜는 10월 1일부터 4일까지입니다. 일반 열은 visit_id STRING, activity STRING, visitors INT이고, visit_date DATE는 파티션 열입니다. 이 매핑과 ORC 형식을 유지하세요.

같은 작업을 살펴보고 수정하고 반복할 수 있도록 SQL을 편집 가능한 파일로 저장합니다. nano는 Terminal 안의 텍스트 편집기입니다. 다음 명령은 현재 작업 디렉터리의 replace-approved-days.sql을 엽니다. 새 파일이므로 처음에는 편집 영역이 비어 있습니다.

nano replace-approved-days.sql

다음 SQL 다섯 줄을 셸 프롬프트가 아니라 nano에 입력하세요. 작은따옴표는 SQL 값을 구분하고 세미콜론은 문을 끝냅니다. 마지막 세미콜론 뒤에 빈 줄을 추가하지 말고 멈추세요. nano가 저장할 때 끝의 줄바꿈을 넣습니다.

INSERT OVERWRITE TABLE venue_archive.archive
PARTITION(visit_date='2026-10-02')
SELECT visit_id,activity,visitors
FROM venue_archive.candidate
WHERE visit_date=DATE '2026-10-02' AND record_status='confirmed';

화살표 키로 수정할 문자로 이동합니다. Home과 End는 현재 줄의 시작과 끝으로 이동합니다. Backspace는 커서 왼쪽 문자를, Delete는 커서 위치의 문자를 지웁니다. 그 자리에 올바른 텍스트를 입력하세요. nano 아래쪽의 ^는 Ctrl을 뜻합니다. Ctrl+O로 저장합니다. File Name to Write에서 표시된 파일 이름을 유지하고 Enter를 누르세요. 이어서 Ctrl+X로 나갑니다. 셸 프롬프트가 돌아올 때까지 기다리세요. SQL은 편집기에 입력하고 다음 명령들은 셸 프롬프트에서 실행합니다.

실행하기 전에 저장한 내용을 읽습니다.

cat replace-approved-days.sql

문의 두 날짜를 모두 확인합니다. 정적 대상과 소스 필터는 모두 10월 2일이어야 합니다. 정정은 c21과 c22를 모두 포함한 전체 확정 집합입니다. 기존 방문 ID를 대조하거나 개별 행을 업데이트할 필요가 없습니다.

Beeline의 -f는 파일에서 SQL을 읽습니다. 저장한 파일을 실행합니다.

beeline -u jdbc:hive2://localhost:10000/default -n labex -f replace-approved-days.sql

그런 다음 아카이브를 사용하는 입장에서 네 날짜 전체를 읽습니다.

beeline -u jdbc:hive2://localhost:10000/default -n labex -e "SELECT visit_date,visit_id,activity,visitors FROM venue_archive.archive ORDER BY visit_date,visit_id;"

여섯 행이 나와야 합니다. 10월 2일에는 c21 / PrintWorkshop / 5와 c22 / Bookbinding / 2가 있고 v2는 없습니다. 10월 3일에는 아직 기존 v3가 남아 있습니다. 10월 1일의 v1, 10월 4일의 v4와 v5는 변경되지 않았습니다.

Beeline 연결에서 사용자는 labex입니다. HiveServer2는 서비스 사용자 hive로 저장소에 쓰므로 새 ORC 파일의 소유자는 hive:bigdata일 수 있습니다. 소유권이나 권한을 변경할 필요가 없습니다. HDFS NameNode는 별도의 서비스 계정 hdfs로 실행됩니다.

SQL 문에 구문 오류가 있으면 cat으로 저장한 파일을 살펴보고 nano replace-approved-days.sql로 다시 여세요. 화살표 키로 Beeline 오류에 표시된 문을 찾습니다. 다른 SQL 줄은 유지하면서 필요에 따라 테이블 이름, 날짜, 따옴표, 세미콜론을 수정하세요. Ctrl+O, Enter로 저장하고 Ctrl+X로 나갑니다. -f를 다시 실행하기 전에 파일을 다시 읽으세요. 이 승인 날짜에 실수로 행을 추가했다면 같은 올바른 파티션 덮어쓰기가 오래된 행과 중복 행을 제거합니다. 이 복구는 승인 날짜에만 적용되며 보호된 날짜를 재구축할 권한을 주지 않습니다.

빈 레코드 집합으로 대체하고 파일 다시 실행하기

이 단계에서는 승인된 10월 3일 파티션을 비우고, 완전한 정정 파일을 두 번 실행하여 아카이브에 행이 누적되지 않는지 확인합니다. Terminal의 /home/labex/project에서 계속합니다.

취소도 정정입니다. 승인 목록에 10월 3일이 있지만 그날의 후보에는 확정된 방문이 없습니다. 먼저 소스 선택을 실행합니다.

beeline -u jdbc:hive2://localhost:10000/default -n labex -e "SELECT visit_id,activity,visitors FROM venue_archive.candidate WHERE visit_date=DATE '2026-10-03' AND record_status='confirmed';"

데이터 행이 없습니다. 올바른 최종 아카이브에도 이 날짜의 행이 없어야 합니다. 쓰기를 건너뛰면 기존 v3가 남습니다.

같은 파일을 다시 엽니다. 기존 10월 2일 문은 유지하세요. 문 하나를 추가하는 것이며 첫 번째 문을 다시 복사하지 않습니다.

nano replace-approved-days.sql

아래쪽 화살표 키로 첫 번째 문의 세미콜론 뒤에 있는 빈 줄까지 이동하고, 필요하면 End로 그 줄의 끝으로 갑니다. 그 빈 줄에서 Enter를 한 번 눌러 문 사이에 빈 줄 하나를 두세요. 그런 다음 아래의 새 다섯 줄만 입력합니다. 마지막 세미콜론 뒤에 빈 줄을 추가하지 말고 멈추세요. 중단된 편집을 재개한다면 먼저 이 10월 3일 문이 이미 있는지 확인하세요. 중복해서 추가하지 말고 기존 문을 수정합니다.

INSERT OVERWRITE TABLE venue_archive.archive
PARTITION(visit_date='2026-10-03')
SELECT visit_id,activity,visitors
FROM venue_archive.candidate
WHERE visit_date=DATE '2026-10-03' AND record_status='confirmed';

Ctrl+O, Enter로 저장하고 Ctrl+X로 나갑니다. 셸 프롬프트에서 저장된 파일 전체를 읽습니다.

cat replace-approved-days.sql

정확히 두 문이 있는지 확인하세요. 기존 10월 2일 문 다음에 새 10월 3일 문이 와야 합니다. 각 문의 정적 대상과 소스 필터는 모두 그 문의 승인 날짜를 지정해야 합니다. 잘못된 부분이 있으면 nano로 같은 파일을 다시 열고 영향받은 줄만 고친 뒤 저장하고 다시 살펴보세요.

이 완전한 저장 파일을 처음으로 실행합니다.

beeline -u jdbc:hive2://localhost:10000/default -n labex -f replace-approved-days.sql

빈 선택 결과를 사용하는 정적 덮어쓰기는 대상 파티션의 기존 행을 제거합니다. 해당 날짜의 등록은 유지됩니다. 빈 파티션에 물리적 파일이 존재하는지는 저장소 엔진이 결정합니다. 직접 CSV나 ORC 자리표시자 파일을 만들지 마세요.

등록된 날짜와 전체 결과를 읽습니다.

beeline -u jdbc:hive2://localhost:10000/default -n labex -e "SHOW PARTITIONS venue_archive.archive; SELECT visit_date,visit_id,activity,visitors FROM venue_archive.archive ORDER BY visit_date,visit_id; SELECT COUNT(*) FROM venue_archive.archive WHERE visit_date=DATE '2026-10-03';"

네 파티션이 모두 계속 표시됩니다. 전체 결과에는 v1, c21, c22, v4, v5의 다섯 행이 있습니다. 10월 3일의 개수는 0입니다. 승인 목록에 날짜가 두 개 있다고 해서 비어 있지 않은 파티션이 두 개여야 하는 것은 아닙니다.

이제 수정하지 않고 같은 저장 파일을 다시 실행합니다.

beeline -u jdbc:hive2://localhost:10000/default -n labex -f replace-approved-days.sql

아카이브 읽기를 반복합니다.

beeline -u jdbc:hive2://localhost:10000/default -n labex -e "SELECT visit_date,visit_id,activity,visitors FROM venue_archive.archive ORDER BY visit_date,visit_id; SELECT COUNT(*) FROM venue_archive.archive;"

같은 다섯 행이 남고 전체 개수는 5입니다. 제공된 소스에 대해 반복 가능한 대체이며, 중복을 추가하지 않습니다. 반복 실행으로 승인된 파티션 파일은 다시 생성될 수 있지만, 대상이 아닌 날짜의 원래 파일은 건드리지 않아야 합니다.

익숙한 HDFS 명령으로 원본 소스를 살펴볼 수 있습니다. 여기서 -cat은 정확한 원본 파일을 읽으며 파생된 ORC 아카이브를 읽는 것이 아닙니다.

hdfs dfs -cat /user/labex/venue-archive/raw/raw.csv

여전히 원래의 v2와 v3가 들어 있습니다. 파생 아카이브를 변경해도 원시 이력은 다시 쓰지 않습니다. 후보와 승인 목록도 제공된 상태로 유지해야 합니다. SQL 파일을 작업 디렉터리에 보관하세요. 검사는 현재 Hive 데이터, 정의, 작업 범위, 보호된 파일을 관찰하며 임의의 저장 SQL을 실행하지 않습니다. 실제 반복 실행과 결과 읽기가 저장한 작업의 자체 점검입니다.

요약

추가, 테이블 전체 대체, 정적 파티션 대체를 비교했습니다. 그런 다음 승인된 하루의 전체 데이터를 대체하고, 유효한 빈 집합 대체를 적용했으며, 같은 저장 SQL을 다시 실행해도 행이 누적되지 않음을 확인했습니다. 독립적인 원시 이력과 다른 아카이브 날짜는 그대로 보존되었습니다.