김정현
Redis Cache세션 및 Clustering 테커톡을 준비하며 자료를 조사하다 보니, 생각보다 자세하게 설명된 자료가 많이 없었습니다.
Redis Cluster에서의 노드 간 통신, 장애 감지와 Failover 등에 대해 깊게 다뤄보았습니다.
정말이지 이렇게까지 깊게 들어갈 생각은 없었는데(...), 어느새 Redis 코드까지 뒤지고 있는 저를 발견했습니다.
이왕 깊게 들어간 거, 이해하기 쉽게 글로 남겨보았습니다.
😁
김정현
Redis Cache세션 및 Clustering 테커톡을 준비하며 자료를 조사하다 보니, 생각보다 자세하게 설명된 자료가 많이 없었습니다.
Redis Cluster에서의 노드 간 통신, 장애 감지와 Failover 등에 대해 깊게 다뤄보았습니다.
정말이지 이렇게까지 깊게 들어갈 생각은 없었는데(...), 어느새 Redis 코드까지 뒤지고 있는 저를 발견했습니다.
이왕 깊게 들어간 거, 이해하기 쉽게 글로 남겨보았습니다.
😁
김정현
지금 여기 날씨, 지금 우리 스타일 - FashionCloud

프로젝트 주제를 선정할 때 고려한 점들이 있었다.
추천받은 몇 가지 키워드 중에서 마음에 드는 키워드를 골라 그에 알맞는 프로젝트 주제를 선정하고자 했다.
1. 첫째, 시시각각 변하는 유동적인 데이터 사용하기
2. 둘째, 공공데이터를 주기적으로 끌고 와서 사용하기
따라서 시시각각 변하는 공공데이터인 도로교통정보나 항공정보 등 여러 후보 중에서 고민하다가 날씨 정보를 이용하게 됐다.

”집에서 나갈 때마다 남들은 이런 날씨에 무슨 옷을 입었는지 참고할 수 있다면?”
이런 생각에서, 위와 같은 프로젝트 주제가 탄생했다.
날씨 데이터를 사용하는 것은 꽤나 어려운 과정이었다.
openAPI 문서는 친절하지 않았고, 열심히 해석해서 활용해야 했다.
초단기실황은 ‘가장 최근에 만들어진, 10분 간격으로 업데이트되는 실황 데이터 ’를 사용하는 것이고
초단기예보는 ‘10분 간격으로 업데이트되는 가장 가까운 예보 데이터 ’를 사용하는 것이므로
초단기실황 데이터가 초단기예보 데이터보다 더 정확할 것이라 판단했다.
이에 따라 최대한 많은 날씨 데이터를 초단기실황에서 뽑아 쓰고, 초단기실황에서 제공하지 않는 정보는 초단기예보에서 가져와 쓰기로 했다.
1. 초단기실황 — 기온, 1시간 강수량, 습도, 강수형태, 풍속 데이터
2. 초단기예보 — 하늘상태 데이터
3. 단기예보 — 최저/최고 기온 데이터
하늘상태 데이터와 최저/최고 기온 데이터는 초단기실황 예보로 제공되지 않으므로, 초단기예보와 단기예보까지 세 가지 예보 데이터를 적절히 사용하여 현재 날씨 데이터를 만들었다.
(정확히 말하자면, 하늘상태는 실황값이 아니고 가까운 예보값이므로 현재 날씨라고 보기는 어렵다.)
처음 구상했을 땐 기온과 하늘상태, 강수형태를 가지고 파악하려고 했다.
그러나 적절한 옷차림을 파악하는 데에 중요한 것은 실제 기온보다는 체감기온이라고 생각하여,
절대적인 기온 대신 체감온도로 비슷한 날씨를 파악하기로 했다.
1. 체감온도
사람마다 기온 차이를 인지하는 것은 차이가 있지만, 일반적으로 1도~3도부터 차이를 인지하기 시작한다고 한다.
따라서 기온이 +-1도 차이나는 경우를 날씨가 비슷한 경우라고 판단했다.
2. 하늘상태
맑음에 해당하는 경우는 하늘코드(0) 뿐이다.
흐린 경우는 구름많음(3), 흐림(4) 두 가지 모두 해당된다고 생각하여, 두 경우를 비슷한 날씨로 정했다.
3. 강수형태
강수형태는 딱 나누기에 애매한 부분이 있었다.
기상청에서 제공하는 날씨 정보가 비/눈이거나 빗방울눈날림인 경우는 비로 구분할지 눈으로 구분할지 애매했다.
그래서 이런 날씨는 눈과 비 모두에 해당되는 것으로 정했다.
❄️‘눈’에 해당하는 날씨 = 눈 + 비/눈 + 빗방울눈날림 + 눈날림
🌧️‘비’에 해당하는 날씨 = 비 + 비/눈 + 빗방울 + 빗방울눈날림
우리는 백엔드 서버를 거쳐 기상청으로부터 날씨 데이터를 받아오므로, 사실상 api호출은 두 번 일어나는 셈이다.
클라이언트에서 날씨 정보를 요청하면 그 때마다 외부 기상청 서버로 날씨 데이터를 또 요청해야 한다.

이에 따른 병목 문제를 해결하기 위해 날씨 정보를 캐시에 저장하기로 했다.
사용자의 위치를 Key로, 그 위치의 날씨 정보를 Value로 하여 key-value store인 Redis에 저장한다.
하지만 날씨 정보를 요청하는 위치마다 모두 위경도를 캐시에 저장하는 것은 불가능하다고 생각했다.
우리나라는 동경 124도와 132도 사이 / 북위 33도와 43도 사이에 위치하며
위경도는 소수점 아래 여섯 자리까지 표시하므로, 위치 데이터로 가능한 경우의 수가 약 33만개로 엄청나게 많아지기 때문이다.
이렇게 되면 캐시 데이터가 지나치게 많아지는 캐시 폭증 문제가 발생할 수 있고, 캐시 메모리를 낭비하게 된다.
또한 이렇게 세밀한 단위로 캐싱하게 되면 hit ratio가 낮아져 캐싱의 의미가 없을 것이라 생각했다.

이에 대한 해결책으로, 위경도가 아닌 격자점 단위로 key값을 저장하기로 했다.
기상청은 위경도를 XY 격자좌표로 변환하여 날씨 정보를 요청하도록 하고 있다.
어차피 같은 격자점 내에서는 같은 날씨를 응답하므로, 캐시 데이터를 줄이고 hit ratio를 증가시키기 위해 격자점 단위로 저장하는 것이다.
X축 격자점 수는 149개, Y축 격자점 수는 253개이므로 경우의 수가 약 3.8만가지다.
위경도로 계산할 때보다 key값이 될 수 있는 경우의 수가 90퍼센트가량 감소된다.

날씨 정보를 캐싱하는 것은 좋은 방법이라고 생각한다. 그러나 캐시에 저장된 정보가 실제 날씨 정보와 다르면 아무 의미가 없어진다.
날씨 정보는 계속해서 업데이트되므로 캐시에 저장된 날씨도 이에 맞게 업데이트해줘야 한다.
최저/최고기온은 당일 새벽 2시에 생성된 데이터를 사용하면 되지만,
나머지 모든 날씨 정보들은 10분 간격으로 업데이트된다.
캐시 불일치 문제를 막으려면 날씨 데이터 업데이트 시간마다 캐시가 초기화되거나, 그 시간마다 캐시 업데이트가 일어나야 한다.

이런 캐시 일관성 문제를 해결하기 위해 기상청의 날씨 정보 업데이트 시간마다 캐시의 날씨 정보를 업데이트하기로 했다.
key로 저장된 격자점 좌표를 가지고 기상청 서버로 날씨 데이터를 재요청하여 날씨 정보를 업데이트한다.
원래는 격자점의 개수를 잘못 계산하여, 캐시된 모든 날씨 정보를 업데이트하는 데에 무리가 있다고 생각했다.
따라서 API호출횟수가 많은 지역만 캐시 업데이트를 스케줄러로 자동화하고, 그렇지 않은 지역들은 매 10분 단위로 캐시 삭제하려고 했다.
(이 때 10분 단위라는 것은, 저장된 후 10분이 아니고 n시 10분, 20분, 30분,,과 같은 절대적인 단위다)

(잘못된 정보로 발표했던 자료다.😅😅)
그러나 생각보다 격자점 개수는 많지 않았다. 캐시된 모든 격자점의 날씨 정보를 업데이트하는 것에 무리가 있을지 현재로서는 잘 모르겠다.
이는 개발하면서 문제가 생기면 개선해나가는 방식으로 해결할 계획이다.

나의 데일리룩 사진에다가 현재 날씨에 알맞는 배경을 추가하고, 현재 날씨를 적어 인스타그램 스토리로 공유하는 기능을 개발할 계획이다.

사용자가 데일리룩을 업로드할 때, 옷 카테고리 태그와 함께 옷을 입었을 때의 후기를 업로드한다.

이에 따라 ’어떤 날씨에 어느 옷을 입었을 때 어땠는지’ 에 대한 데이터를 수집하고 통계를 내서 적합한 옷차림을 추천해주는 기능을 개발할 계획이다.
김정현
성남시 프로젝트가 나의 첫 번째 부트캠프였다. 나는 당시에 고학년이었지만 아무 것도 모르는 초보였고, end-to-end는 물론이고 제대로 완성된 프로젝트 경험이 전무했다. 그런 상태에서 시작했던 프로젝트는 도움이 많이 되었지만 그래도 아쉬움이 많이 남았었다. 그 때 남은 아쉬움을 이번 겨울 부트캠프에서 풀어보고자 하는 것이 나의 목적이었다. 그러기 위해 결심한 것이 아래의 두 가지였다.

프로젝트 리더의 경험은 생각보다 쉬운 일이 아니었다. 엇갈리는 의견을 조율해야 하고, 태스크 처리가 밀리는 팀원에게 부드럽게 압박을 넣어야 했으며, 낙오되는 팀원 없이 함께 나아가도록 균형을 잡아야 했다.
팀 내에서 가장 경험이 적은 내가 이런 역할을 수행하는 것은 만만한 일이 아니었다. 팀의 성과가 나지 않는 것은 곧 내 리더쉽 부족이었고, 그에 따른 압박도 있었다.
비록 압박과 부담이 있었지만 리더 경험은 팀원들의 역량을 얼마나 파악하고 어떻게 태스크를 분배하는지에 따라 성과가 크게 좌우된다는 사실을 깨닫는 좋은 경험이 되었다. 스스로가 완벽한 리더였다고는 할 수 없으나, 리더 경험을 통해서 리더십의 중요성을 새삼 뼈저리게 느꼈다.
개발환경을 세팅하는 것은 수많은 이슈와 맞닥뜨리고 밤새 해결하는 과정의 연속이었다. 그렇게 이슈를 고쳐나가며 며칠씩 회의하고 구글링하는 과정에서 프로젝트에 대하여 더욱 깊이 이해할 수 있었고, 이해가 깊어짐에 따라 의사소통 역시 점점 원활해졌다. 그리고 새벽까지 팀원과 자신이 이해한 것을 공유하며 함께 고민하는 경험은 생각보다 ‘삽질’이 즐거운 일이라고 깨닫는 계기가 되었다. 더이상 개발환경 세팅이 막막하게 느껴지지 않았다.
처음 주제를 정할때는 막막하게만 느껴졌던 프로젝트인데 어느새 돌아보니 꽤 먼 길을 걸어왔다. 5주간의 프로젝트였고 잠자는 시간 외 나의 모든 시간을 쏟았기에 끝이 멀게만 느껴졌는데, 이렇게 또 마무리를 하고 있으니 감회가 새롭다.
매일매일 눈앞에 주어진 태스크 해결에 집중하고, 해결하면 또 다른 일이 주어지는 과정을 반복하면서 나는 꽤 많이 성장했다고 느꼈다. 앞으로도 갈 길이 많이 남았지만 지금과 같이 한걸음씩 내딛다 보면 언젠가 내가 ‘저 사람 멋있다!’ 하고 느꼈던 수준과 어깨를 나란히 하는 날이 오지 않을까 기대한다.
노력은 미래의 나를 기대하게 만드는 강력한 도구다. 한달 그리고 일년, 10년 뒤의 내가 기대될 때의 감정이 얼마나 설레는지 느껴보지 않은 사람은 모른다. 내가 기대하는 미래의 나에 도달하기 위해 나아갈 원동력이 되며, 내가 이루어낼 수 있을 거라는 긍정적인 믿음을 가지게 된다.
나는 미래의 나를 믿고 싶다. 끝을 바라보며 한걸음씩 나아갔던 이번 부트캠프처럼, 내가 기대하는 나의 모습을 위해 앞으로도 나아가고자 한다.
아하
실시간 코드 공유 에디터를 제공하는 코딩 멘토링 플랫폼