프로그래밍/넥스터즈

[넥스터즈] 개발 일지 1주차 개발 내용 및 아이디어 선정

Jay Tech 2019. 1. 11. 15:44
반응형



넥스터즈 활동이 시작 되었다.  여러 기수 회원들이 참가한 이번 시즌에는 좋은 아이디어들이 많이 나왔다. 아이디어가 선정이 된 회원들은 (대략 10개정도) 발표를 하고 팀 모집을 시작했다. 모바일, 웹, 게임 등 다양한 프로젝트 아이디어들이 나왔다. 발표를 쭉 들어보고 원하는 팀에 가서 상담(?)을 받는 형식이었다. 


내가 중요하게 생각한 부분은 스택과 아이디어 였다. 아이디어들은 다들 너무 좋았기 때문에 하고 싶은것이 몇 개 있긴했지만 그 중 제일 재밌어보이고 현실성 있는 아이디어가 있는 팀으로 갔다. 게다가 내 스택과 맞는 팀이었다. 현재 내가 새로운 언어를 공부하면서 진행하기에는 무리가 있기 때문이다. 프로젝트 기간이 2달이기 때문에 1주차부터 바로 개발에 투입되어야 해서 처음부터 배우면서 한다는 것은 일단 말이 안된다. 어쨌든 들어가고 싶은 팀에 들어가서 너무 기뻤다. pm님을 비롯한 모든 팀원들도 다 좋았다. 


우리팀은 일단 서버 3, 프런트 2, 디자인 3 이렇게 꾸려졌다. (총 8명) 나는 서버에 속했다. 스택은 Spring Boot로 맞춰 졌고 리눅스 서버를 사용한다고 하였다. 아참 우리 팀의 아이디어는 Url 단축 서비스이다. 


Url이 단축되는 것은 여러 커뮤니티에서 공유할 때 굉장히 유용한 기능이라고 할 수 있다. 예를들어 트위터의 글자수 제한에 링크가 걸려 글을 다 쓰지 못하는 경우, 무조건 url을 단축 시켜야 한다. 하지만, 기존의 단축 서비스들이 존재한다. 물론 그쪽에 대적하지 못하겠지만 일단은 몇 가지 장점이 있다.


첫 번째로 동아리의 홍보이다. 줄여진 url의 메인 도메인이 동아리 도메인이기 때문에 동아리를 홍보할 수 있다. 마케팅의 이점이다.


두 번째로 해싱 알고리즘을 사용한 프로젝트를 해볼 수 있다는 점이다. 게다가 아주 기본적이면서 중요한 내용들을 다룰 수 있게 될 것 같다. 


세 번째로 뭐가 됐든 서비스를 운용할 좋은 경험이라는 것이다. 어쨌든 동아리를 홍보하고 링크도 줄여주는 좋은 프로젝트이기 때문에 완성된다면 존속 여부는 확실하다. 



초기에는 서버 1대로 구상하기로 했다. 실제 서비스가 구동되면 여러 대로 늘려야 한다. 일단은 한대로 한다면 동시성 문제는 생각하지 않아도 되지만 추후 고려해야할 대상 1순위다.


Url의 단축은 여러 알고리즘을 생각해 보았다. 보안 알고리즘 관련 글은 여기를 참고하자. http://pjh3749.tistory.com/222?category=761512


문제 해결 하는 과정 자체가 알고리즘이다. 접근을 할 때 문자열을 줄이려는 알고리즘을 써야해! 그럼 이걸 쓰자! 라고 접근하기 보다는 나는 문제 상황을 먼저 정의하고 그 문제를 해결하기 위한 방법을 고민하는게 우선으로 생각한다.


일단 당면한 문제는 이렇다. Url을 단축 시켜야 한다. 단축 시키면 길이가 줄어 들어야 한다. 


1) 마구잡이로 줄인다. -> 그냥 짜른다. 탈락. url 충돌 가능성이 매우 높다. 


2) 해시 함수를 쓴다. 해시 함수는 긴 입력값을 적절히 처리하여 짧게 만드는 함수이다. 그리고 단방향 암호화이기 때문에 원래 텍스트를 복원하지 못한다. 일단은 적절해 보인다. 관건은 충돌 가능성이다.


3) 암호화 (양방향). 굳이 양방향 암호화를 쓸 필요없다. 줄여준 url에서 원래의 url을 복호화 할 필요가 없다. 서로 매핑만 되면 되는 값이기 때문에 복잡하게 암호화 복호화가 필요없다. 게다가 무엇을 암호화했는지 중요하지 않다. 즉, 줄여주는 부분은 보안이 필요없다. 탈락.


이로써 두 번째 방법이 적합해 보인다. 그 다음 문제를 생각해보자. 이것이 바로 divide and conquer! 


MD5

일단은 MD5. 보안 측면에서는 쓰면 안되는 알고리즘이다. 하지만 해시 충돌을 찾는 방법이 오래전에 나왔기 때문이다. 일단은 돌렸을 때 128 bit가 나온다. 너무 길다. 이것을 다시 고유한 번호로 바꾸는 작업은 일을 두번 하는 것이다. 혹자는 MD5를 돌려서 상위 몇 비트만 이용하는 방법을 이야기 했는데 말도 안되는 소리다. 충돌 가능성이 더 높다. 낮추려면 길이를 길게 해야하는데 그것은 줄이려는 목적에 어긋난다. 

SHA

sha 계열도 마찬가지이다. MD5의 보완점으로 256계열이 나왔지만 이것은 더 길어진다. 

진법 인코딩

특정 진법으로 인코딩하는 방법이다. 예를들어 10진법은 0~9까지의 숫자로 표현하는것이 10진법이다. 즉 10개의 character로 모든것을 표현한다. 이점을 착안해 모든 알파벳과, 숫자를 동원해본다. 총 62개가 나온다. a부터 z, A부터 Z, 0부터9 총 62개이다. 64진법이 있는데 이것은 url에 들어가면 곤란한 문자들이 있는데 그것을 뺀 62개의 문자만 쓰는 것이 적절해 보인다. 명명은 base62 인코딩으로 한다. 

실제 구현한 코드의 일부이다. 자세한 개발 내용은 추후 게시글에 작성한다.


그럼 62진법 인코딩 방법이 가장 적절해 보이는데 이제는 몇 글자로 줄여줄지가 다음 단계이다. 

예를들어 5자리 까지 줄여 준다고 가정했을 때 나올 수 있는 가지수는 62 * 62 * 62 * 62 * 62  = 약 9억 개 이다. 9억개의 url이 우리 서비스에 충분한가? 여기서 엄청 많은 고민을 했다. 인코딩 함수를 일단은 int형을 쓰기로 했는데 이것은 21억 까지 이다. 그럼 int로 놀았을 때 9억개는 핸들 가능하다. 그 이상일 때는? 나는 long까지 고려해서 몇 백조개 까지 생각을 해보았다. 다다익선이지만 과연 이렇게 까지 필요할까? 다른 서비스들을 보았지만 조 단위까지는 올라가지 않았다. 그래서 그냥 일단은 9억개정도로 생각하고 개발 하자고 회의를 마쳤었다.


그 다음 마지막 단계이다. Generate할 숫자를 어디서 가져올까?

몇 가지 방법을 생각해 보았다.

Database 채번

데이버테이스의 id필드는 pk이므로 고유하다. 이 번호를 인코딩 한 문자를 줄여진 url로 쓰는 것이다. 아주 적절해 보인다. 

랜덤 번호 생성

서버 단에서 랜덤한 번호를 생성한다. 그 번호를 인코딩한다. 방법은 milli second를 이용 한 방법, 혹은 UUID를 이용한 방법 등이 있다. 혹은 mac주소 + 시간 + 여러 겹치지 않을 특별한 값들을 조합해서 유니크한 아이디를 만드는 방법도 있다. 이 방법은 숫자가 매우 길어진다. 5자리의 랜덤넘버를 generate하는 것을 생각해 보았다. 각 자릿수를 랜덤을 돌려서 매핑을 시켜준다. 초기엔 충돌이 나지 않겠지만 갈 수록 충돌 가능성이 높아지는 것은 수학적으로 자명하기 때문에 최후 고민에서 탈락시켰다. 

저 둘은 사실 장단점이 있다. 데이터베이스 채번은 겹치는 숫자가 나올 확률은 이론적으로 0이다. 매우 큰 장점이다. 하지만 서버가 여러대 생성됐을 경우 동시성 문제가 생겨 중복된 번호를 생성할 가능성이 있다. 이 문제의 해결책은 observer를 하나 두어야 한다. (Zookeeper) 추후에 고민할 것이다. 게다가 이 작업은 디비 단까지 내려오는 작업이기 때문에 부하가 생길 수 있다.

두 번째로 랜덤 번호 생성은 장점은 서버 단에서 로직이 전부 처리 된 다는 것이다. 데이터베이스까지 접근하지 않아도 숫자를 생성할 수 있다. 훨씬 비용이 적게 드는 작업이다. 단점은 충돌 가능성이다. 첫 번째 방법은 추후에 서비스를 하면서 개선해 나갈 수 있는 방법이 존재한다. 하지만 이 방법은 추후에 충돌이 잦아졌을 때 해결하려면 url의 길이를 늘려버리던가 하는 1차원적인 해결책밖에 존재하지 않는다. 확장이 매우 어렵기 때문에 탈락 시켰다. 


문제를 해결 하는 방법을 논의하는 것은 너무 재밌다. 100% 답이 있는 문제가 아니기 때문이다. 각자 서비스의 목적에 맞춰서 개발 방식과 환경을 다르게 구성하는 작업은 필수적이며 흥미롭다.


반응형