개발자

데이터 수집 시스템 조언 부탁드립니다..

2023년 04월 27일조회 653

안녕하세요. 현재 데이터분석가 인턴으로 회사에 들어간지가 한달이 조금 넘었습니다. 현재 회사에서 분석이 아닌, 직접 데이터를 수집하는 작업을 하고 있습니다. 제가 분석만 하다보니, 데이터를 수집하고 저장하는 작업을 처음해보고 사수도 따로 없다보니 조언을 구할 곳이 없어서 이렇게 게시물로 조언을 요청드립니다.. 지식이 부족해 다소 어렵게 설명을 드려도 이해 부탁드리며, 제 글을 보고 “저 친구는 왜 저렇게 비효율적으로 하지? 이렇게 하면 좋을텐데”라는 생각이 드신다면 바로 댓글이나 쪽지 부탁드립니다. 제가 처음 올려봐서 쪽지 기능이 있나 모르겠네요.. 먼저, 간단하게 제가 진행하고 있는 데이터 수집 절차를 설명드리겠습니다. 1. 컬럼이 한개인 4GB가 조금 넘는 데이터를 수집 코드에 불러와야 한다. 해당 데이터에는 도메인 주소가 담겨 있다. 2. 내 수집 코드는 불러온 데이터를 한행씩 조회하면서 수집을 진행한다. 3. 한 행에 있는 도메인 주소에 순서대로 http 접속을 해서 해당 도메인 주소가 사전에 설정한 특정 조건을 만족하면, 해당 도메인 주소와 사이트에 접속해서 추출한 정수형 값을 DB에 저장한다. 4. 즉, 4기가의 데이터를 불러와 한 행씩 조회해가면서 실시간으로 데이터를 db에 수집하는 코드다. 5. 24시간 동안 코드를 돌리는 수집 예상 기간은 3개월 정도이다. 다음으로는 조금 구체적인 진행 사항을 말하겠습니다. 밑에서부터 길어지니, 바쁘신 분들은 위에 주요 절차만 보시고 조언 주시면 감사하겠습니다. 1. 파이썬만 사용할 줄 알기 때문에, 파이썬을 사용하여 class로 만들어 수집 코드를 짰다. 2. 데이터의 양이 많아서 메모리 부족 오류가 빈번하게 나타나, 하둡과 아파치 스파크를 이용해봤다. 내가 조회할 데이터 파일을 하둡 HDFS에 업로드 한다음에, 아파치 스파크 클러스터를 구축했다. 그리고, pyspark 모듈을 이용해 파티션을 나눠 데이터를 불러왔다. 파티션으로 받아온 값을 리스트로 변환하여 순서대로 해당 도메인 주소로 접속하는 반복문을 진행하면서 데이터를 수집했다. 즉 파티션으로 데이터를 쪼개서 1번 파티션부터 n번 파티션까지 각각 파티션 내부에 도메인 주소 리스트가 반복문을 진행된다고 보면 된다. 각 파티션이 다른 파티션으로 전환되는 과정도 반복문으로 처리했다. 하나의 파티션 마다 내가 만든 class(도메인 리스트를 인자로 받는다)가 한번씩 실행된다고 보면 된다. 3. 수집 속도가 너무 느려서 class에 있는 수집 메소드를 멀티 스레드 방식을 이용해서 수정해주었다. 수집 속도가 매우 빨라졌다. 4. 기존에는 aws의 클라우드 db(dynamo db)를 사용했지만, 과금 문제로 인해 로컬에 db를 설치하기로 했다. 쓰기 속도가 매우 빠른 redis db를 선택했다 5. 위에서 설명한 반복문을 돌면서 조건에 일치한 도메인 주소와 정수 값은 한 행씩 redis db에 key(도메인주소) value(정수값) 형식으로 저장하도록 코드를 만들었다. 이 과정도 class 내부에 포함되어 있다. 6. redis는 on memory db이기 때문에 대용량 데이터를 영구적으로 저장하고 분석하기에 적합하지 않다고 판단해서 1시간마다 redis에 있는 데이터를 postgresql db로 옮겨주는 코드를 따로 만들었다. postgresql db에 미리 redis에서 옮겨갈 테이블을 생성해두었다. redis의 key였던 도메인 이름을 첫 번째 필드에 프리이머리 키로 저장했고 value인 정수 값을 2번 째 필드에 값으로 넣어줬다. 그리고, 마지막 필드에는 자동으로 데이터가 저장될 때, 현재 시간이 넣어지게 테이블을 만들었다. 총 3개의 열로 구성된 테이블에 1시간에 한번씩 redis에 저장해두었던 데이터가 옮겨간다고 생각하면 된다. 7. 처음 redis에 데이터를 저장할 때 ttl을 설정해서 1시간 10분이 지나면 redis db에서 데이터가 자동으로 소멸되도록 설정했으며, 만약 postgresql에 중복된 데이터가 들어간다면 자동으로 무시하고 다음 작업을 진행하도록 테이블 설정을 해줬다. 즉, 실시간으로 데이터가 수집되고 자동으로 시간이 지나면 데이터가 소멸되는 redis db에서 1시간마다 한번 postgresql로 옮겨주는 코드를 따로 만들었다. 8. 수집 코드를 spark-submit 명령문으로 실행해주었다. spark-submit 명령어 앞에 nohup을 해줘서 백그라운드에서 코드가 실행되게 해줬고, 로그 결과를 따로 파일을 만들어 저장되도록 했다. 그리고 파이썬 실행 파일 내에서도 로그를 입력하는 코드를 만들어서, 도메인의 http 접속이 성공했는지의 여부를 로그 파일에 실시간으로 입력되도록 했다. 예를 들어, http 접속이 잘 된 도메인 주소는 로그에 “INFO 도메인 주소: success” 이렇게 기록하고, 타임아웃 에러, 접속 에러, redirect 오류, db 저장 오류는 모두 종류별로 예외 처리해서 로그에서 기록되도록 코드를 구성했다. 파이썬에서 자체적으로 로그를 기록한 파일은 수집코드를 실행하면서 파티션이 전환될 때마다 하나씩 생성된다. 이제 이렇게 제가 실행할 코드는 24시간 내내 수집을 진행하는 코드 하나와 1시간에 한번 데이터를 옮겨주는 스케줄러 코드로 총 2개가 됩니다. 저는 이 코드와 수집 환경을 만들기 위해 모두 도커를 활용하였으며, 사용한 컨테이너와 부가 설명은 다음과 같습니다. spark-master: 하둡과 스파크 클러스터를 구축하는 컨테이너로 standalone모드로 spark-summit 명령어로 파이썬 파일을 실행해주었다. --conf 옵션으로 메모리, 하트비트 간격, 파티션 수 를 지정해주었다. 스파크와 하둡을 처음 사용해봐서 약간의 개념만 있는 상태에서 돌려보니 아직도 세부 설정을 제대로 이해하지 못했다. 결국 worker를 1개 생성해서 파이썬 파일을 처리하도록 하였다. 현재 대다수의 오류가 이 컨테이너에서 발생한다. redis: spark-master에서 실시간으로 실행되고 있는 수집 코드에서 선별된 데이터들이 redis 컨테이너에 있는 redis db에 저장된다. postgresql: 1시간에 한번 redis에 있는 데이터를 옮기기 위해 postgresql 컨테이너를 생성했다. schduler: 1시간에 한번 postgresql 컨테이너에서 작동하고 있는 postgresql db에 redis 데이터를 옮겨주기 위한 스캐줄러 코드를 실행할 컨테이너다. redis-monitor: 실시간으로 redis db를 모니터링 하기 위해 redis-monitor 컨테이너를 생성하여 웹에서 모니터링 툴인 Redis-Stat에 접속한다. postgre-monitor: 마찬가지로, 실시간으로 postgresql db를 모니터링 하기 위해 생성한 컨테이너로 웹에서 Pgadmin4를 사용할 수 있다. 이렇게 총 6개의 컨테이너를 생성하여 내 수집 코드를 실행했는데, 여기서 많은 문제가 발생했습니다. 제가 가진 의문과 문제를 나열하자면 다음과 같습니다. 1. 먼저, 수집 코드를 실행한 다음에 스케줄러 코드를 실행해주었는데, (서로 독립된 컨테이너에서 실행) 두 코드가 DB에 동시에 접속할 때, 충돌이 일어날 가능성이 있지 않을까? 2. 수집 코드를 실행하고 몇분이 지나면 터미널이 먹통이 되고, 코드가 더 이상 실행이 안되는 일이 빈번하게 발생한다. 너무 많은 자원을 사용하고 있어서 그런건가.. 컴퓨터 사양이 안좋아서 그런건가 원인을 잘 모르겠다.. 3. spark-submit 로그를 보면 내 노트북에서는 안그러는데, 대용량 파일을 불러오는 과정에서 파티션 별로 데이터를 정리할 때 오류가 빈번하게 발생한다 . executor가 통신이 안된다는 경고 메세지도 자주 나오고, 특히, Remote RPC client disassociated 라는 오류가 가장 많이 나온다. 내 컴퓨터보다 높은 사양의 클러스터를 구축하려고 해서 그런가. 검색해보니 네트워크 문제이거나, 컨테이너에 할당한 자원을 초과해서 그런거라고 한다. 대용량 데이터를 불러오는 다른 방법을 강구해봐야되나 고민하고 있다. “그래서 요점이 뭐야” 라고 물어보신다면, 저는 현직에서 활동하고 계신 데이터 엔지니어, 백앤드 개발자 분들이 제 글을 본다면 “아니 굳이 왜 그렇게 하지? 이렇게 쉬운 방법이 있는데” 또는 “저기서 이렇게도 해봤나?, 이러면 안정적으로 코드를 돌릴 수 있을텐데”라는 반응으로 갈릴 것 같다고 생각합니다.

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.
profile picture
익명님의 질문

답변 2

인기 답변

김병수님의 프로필 사진

전반적으로 구축하신 아키텍처가 머리 속에 잘 그려지지 않네요 @.@ 가능하시면 아키텍처를 이미지 링크로 공유하시거나 diagrams or miro 등의 툴로 표현하시면 서로 같은 뷰를 그릴수 있을듯합니다 텍스트로만 표현하면 서로 생각이 다른 사람들이 다른 아키텍처를 상상할 수 있기 때문입니다 아키텍처 얘기 시에는 같은 뷰를 바라보는게 효과적인 커뮤니케이션 할 수 있는 방법이더라구요 완전 새로운 아키텍처를 제안하기 전에 문제라고 표현하신 3가지 내용을 먼저 파고들면 왜 새로운 아키텍처를 구축해야하는지 더 명확한 근거가 생길수 있을듯합니다 댓글로 서로 핑퐁하면서 적당한 구조를 찾아가면 좋을듯합니다~~ 1. 수집 코드는 redis write 작업을 행하고 스케줄러 코드는 독립된 컨테이너에서 redis read 작업을 행하는데 충돌이 발생하지 않을까?라고 질문해 주셨는데, 충돌이라고 표현하신 부분이 data consistency를 말씀하시는 걸까요? redis cluster를 구축하셨다면 어떻게 구축하셨냐에 따라 대답이 달라지지만 single instance라면 strong consistency를 유지하니 걱정하지 않으셔도 됩니다 제가 이해한 부분이 맞는지 알려주시며 좋겠습니다 2. 4g 데이터를 하둡에 저장하고 한 컨테이너에서 멀티스레드로 파티션된 4g 데이터를 불러온다면 아마도 로딩 과정에서 이슈가 생긴것 같습니다 멀티 컨테이너에서 파티션된 4g 데이터를 부르지 않는 이상, 한 스레드에서 4g 모든 데이터를 로드하는 것과 차이가 없는것 같습니다 수집 코드에서 데이터 로드 이외 코드는 주석처리하시고 테스트해보시면 예상한 가설이 맞는지 확인 할 수 있을 듯합니다 테스트 해 보시고 알려주시면 좋겠네요 ^^ 3. 저도 관련 내용을 찾아보니 메모리 관련 이슈일 것으로 판단됩니다 파티션된 4g 데이터가 어느정도 사이즈인지 모르지만 이 데이터 또한 메모리에 적재되기에 컨테이너 메모리 사이즈에 영향을 많이 받을 듯합니다;; 파티션한 데이터 사이즈와 컨테이너 메모리 사이즈가 어떤지 궁금합니다~~ 우선 위에 3가지 이슈에 대해 명확한 원인이 무엇인지 같이 파악해봐요~~

커리어리 AI 봇님의 프로필 사진

안녕하세요! 데이터 수집 작업은 데이터 분석을 위한 가장 기본적이면서 중요한 작업 중 하나입니다. 따라서 효율적인 데이터 수집 절차를 구성하는 것은 매우 중요합니다. 여러 가지 방법이 있지만, 여기에 몇 가지 제안을 드리겠습니다. 1. 데이터베이스의 쿼리 기능을 이용하여 데이터 검색하기 일일히 한 행씩 불러오는 대신, 데이터베이스의 쿼리 기능을 이용하여 필요한 데이터를 검색하는 방법이 있습니다. 이렇게 하면 데이터베이스 내에서 데이터를 직접 가져오기 때문에 불필요한 데이터 전송을 줄일 수 있습니다. 예를 들어, "WHERE"절을 사용하여 특정 조건에 맞는 행을 검색하거나 "ORDER BY"절을 사용하여 정렬된 결과를 가져올 수 있습니다. 이렇게 하면 일정한 검색 범위를 지정하여 속도를 향상시킬 수 있습니다. 2. 멀티스레딩을 이용하여 병렬 처리하기 한 행씩 조회하면서 처리하는 것은 시간이 오래 걸리는 작업입니다. 따라서 멀티스레딩을 이용하여 병렬 처리를 하면 작업 시간을 줄일 수 있습니다. 각 스레드는 데이터를 분할하여 작업하고, 작업이 완료되면 결과를 메인 스레드로 보내어 저장합니다. 이렇게 하면 데이터 처리 속도가 크게 향상됩니다. 3. 필요한 데이터만 수집하기 4GB가 넘는 데이터를 모두 수집하는 것은 많은 시간과 자원이 소요됩니다. 따라서 필요한 데이터만을 수집하여 처리하는 것이 좋습니다. 예를 들어, 수집 대상 도메인 주소를 미리 필터링하여 검색 범위를 줄일 수 있습니다. 4. 크롤링 작업 중 오류 처리하기 데이터 수집 작업에서 가장 자주 발생하는 문제는 크롤링 작업 중 오류가 발생하는 것입니다. 따라서 코드 내에 오류 처리를 반드시 포함시켜야 합니다. 예를 들어, 서버 응답 시간 초과 오류, 인증 오류, 404 오류 등에 대한 처리를 미리 구현해두어야 합니다. 5. 로그를 남겨 디버깅하기 크롤링 작업 중 오류가 발생하는 경우, 로그를 남겨 디버깅하기 쉽도록 코드를 작성하는 것이 좋습니다. 이렇게 하면 오류 발생 시 로그를 살펴보면서 문제를 파악하고 해결하는 데 도움이 됩니다. 6. 데이터 저장소 선택하기 크롤링 작업에서 수집한 데이터를 어떤 형식으로 저장할 것인지 결정하는 것도 중요합니다. 데이터 저장소로는 RDBMS, NoSQL 등이 있으며, 데이터 저장 목적에 따라 적절한 저장소를 선택해야 합니다. 데이터 저장소를 선택할 때는 처리량, 처리 속도, 가용성, 확장성 등을 고려해야 합니다. 7. 데이터 정제하기 크롤링 작업에서 수집한 데이터는 종종 불완전하거나 중복된 데이터가 포함되어 있을 수 있습니다. 이런 경우 데이터 정제 작업이 필요합니다. 예를 들어, 중복 데이터를 제거하거나 불완전한 데이터를 보완하여 데이터의 품질을 향상시킬 수 있습니다. 8. 데이터 무결성 검사하기 크롤링 작업에서 수집한 데이터가 저장소에 제대로 저장되었는지 검사하는 것도 중요합니다. 데이터 무결성 검사를 통해 데이터 저장 과정에서 발생할 수 있는 문제를 미리 파악하고 예방할 수 있습니다. 9. 보안과 개인정보 보호하기 크롤링 작업을 수행하는 도중에는 보안과 개인정보 보호에 대한 문제도 고려해야 합니다. 예를 들어, 접근 권한이 필요한 사이트에 접근할 때는 로그인 정보를 안전하게 처리하고, 수집한 데이터를 저장할 때는 보안 정책을 준수하여 데이터 누출을 방지해야 합니다. 위의 조언들을 고려하면 효율적인 데이터 수집 시스템을 구성할 수 있습니다. 이제 데이터 수집 작업을 보다 효율적으로 수행할 수 있을 것입니다.

커리어리 AI 봇의 답변을 평가해 주세요!

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!