목록으로

Programming Notes

Car-ffeine, 23만 잔의 데이터를 DB에 맛있게 담아내는 비법

안녕하세요! 우테코 Car-ffeine 팀의 제이입니다. 저희 서비스는 사용자에게 유용한 정보를 제공하기 위해, 공공 API로부터 방대한 데이터를 가져와 데이터베이스에 저장하는 과정을 거칩니다. 마치 커피 원두를 로스팅하고 분쇄하여 맛있는 커피를 추출하는 과정과 같죠. 문제는...

안녕하세요! 우테코 Car-ffeine 팀의 제이입니다. 저희 서비스는 사용자에게 유용한 정보를 제공하기 위해, 공공 API로부터 방대한 데이터를 가져와 데이터베이스에 저장하는 과정을 거칩니다. 마치 커피 원두를 로스팅하고 분쇄하여 맛있는 커피를 추출하는 과정과 같죠. 문제는 이 원두, 즉 데이터의 양이 상당하다는 겁니다. 약 23만 건에 달하는 데이터를 효율적으로 저장하는 것은 저희 팀의 중요한 과제였습니다.

공공 API는 한 번에 최대 9,999개의 데이터만 제공하기 때문에, 23번이나 API를 호출해야 했습니다. 처음에는 단순하게 데이터를 하나씩 데이터베이스에 삽입하는 방식을 사용했지만, 예상대로 시간이 너무 오래 걸렸습니다. 마치 에스프레소를 한 방울씩 추출하는 것처럼 비효율적이었죠. 그래서 저희 팀은 (누누, 박스터, 키아라와 함께!) 이 과정을 개선하기 위해 다양한 방법을 시도했습니다. 누누의 깊이 있는 분석과 꼼꼼함 덕분에 많은 아이디어를 얻을 수 있었습니다.

데이터 저장, 어떻게 하면 더 빠를까?

저희는 먼저 데이터베이스에 연결하는 과정에서 불필요한 오버헤드가 발생하는 것을 줄이기 위해 노력했습니다. 예를 들어, JDBC 연결을 매번 생성하고 닫는 대신, Connection Pool을 활용하여 연결을 재사용하도록 변경했습니다. 마치 미리 따뜻하게 데워놓은 에스프레소 머신처럼, 필요할 때 즉시 연결을 사용할 수 있도록 한 것이죠.

다음으로는 데이터베이스에 데이터를 삽입하는 방식을 개선했습니다. 기존에는 데이터를 한 건씩 삽입하는 방식 대신, PreparedStatement를 사용하여 SQL 쿼리를 미리 컴파일해두고, 파라미터만 변경하여 반복적으로 실행하는 방식으로 변경했습니다. 이는 마치 미리 레시피를 준비해두고 재료만 바꿔가며 요리하는 것과 같습니다.

하지만 이것만으로는 충분하지 않았습니다. 23만 건이라는 데이터 양은 여전히 부담스러웠죠. 그래서 저희는 Batch Insert 방식을 도입했습니다. 여러 개의 데이터 삽입 쿼리를 하나의 트랜잭션으로 묶어서 한 번에 실행하는 방식입니다. 이는 마치 여러 잔의 커피를 한 번에 추출하는 것과 같습니다.

특히, Batch Insert를 사용할 때, Batch Size를 적절하게 조절하는 것이 중요했습니다. 너무 작은 Batch Size는 잦은 네트워크 통신을 유발하고, 너무 큰 Batch Size는 메모리 부족을 일으킬 수 있기 때문입니다. 여러 번의 테스트를 통해 최적의 Batch Size를 찾아냈습니다.

뿐만 아니라, 데이터베이스의 인덱스 설정도 꼼꼼하게 확인했습니다. 자주 사용되는 컬럼에 적절한 인덱스를 설정하여 데이터 검색 속도를 향상시켰습니다. 마치 잘 정리된 커피 원두 보관함처럼, 필요한 데이터를 빠르게 찾을 수 있도록 한 것이죠.

마지막으로, 데이터 변환 과정에서 발생하는 병목 현상을 해결하기 위해 스트림 API를 활용했습니다. 데이터를 순차적으로 처리하는 대신, 병렬 스트림을 사용하여 데이터를 분산 처리함으로써 전체 처리 시간을 단축했습니다. 이는 마치 여러 명의 바리스타가 동시에 커피를 만드는 것과 같습니다.

마치며

이러한 노력 덕분에 저희는 데이터를 데이터베이스에 저장하는 시간을 획기적으로 단축할 수 있었습니다. 초기에는 몇 시간이나 걸리던 작업이, 이제는 몇 분 만에 완료됩니다. 23만 잔의 데이터를 맛있게 담아내는 비법을 찾은 셈이죠.

이번 경험을 통해 저희는 데이터베이스 성능 최적화의 중요성을 다시 한번 깨달았습니다. 앞으로도 지속적인 개선을 통해 사용자에게 더 나은 서비스를 제공할 수 있도록 노력하겠습니다. Car-ffeine 팀의 여정은 계속됩니다!