스토리 홈

인터뷰

피드

뉴스

조회수 2710

MOIN 안드로이드 개발자를 소개합니다

영화 같은 일들이 매일같이 벌어지는 요즘 모두들 안녕하신가요?해외송금 스타트업 모인에게 최근 새로운 변화가 생겼습니다.안드로이드 개발자가 합류했습니다.어떤 분인지 지금부터 소개 해드리겠습니다 ^^안드로이드 개발을 해주실 효찬님!- Professional Experience -2015.01~2016.10 kt R&D 연구개발센터 전임연구원2013.07~2015.12 kt R&D 연구개발센터 연구원2013.03~2013.06 kt R&D 연구개발센터 인턴- Education -2006.03~2013.08 고려대학교 컴퓨터통신공학부 학사2001.09~2005.05 Jakarta International School▶ 모인에서 어떤 일을 담당하고 계신가요?총체적인 안드로이드 개발과 웹 서버를 보조하는 일을 맡고 있습니다.▶ 개발자가 되겠다고 한 계기가 궁금합니다. 개발자로서 이력에 대해 간략히 설명해주시겠어요? 특정한 계기가 있어서 개발자가 되겠다고 한 건 아니었어요. 고등학교 시절, 컴퓨터 게임 하면서 막연히 나도 게임을 만들어 보고 싶다고 생각했고 그래서 관심은 가지고 있었죠. 친구들 이름 넣어서 RPG를 만들어보기도 했는데, 생각해보면 스토리 만들기가 재밌었던 거 같아요. 그러면서 자연스럽게 어떻게 하면 컴퓨터 개발할 수 있나 생각도 해보게 됐고, 책도 뒤적여보게 됐습니다. 이런 생활이 고2때까지 이어졌어요. 그런데 마땅히 공부할 수 있는 방법이 없어서 대학가서 해야겠다 생각했습니다. 대학 와서 본격적으로 컴퓨터공학을 공부하면서 재미를 느끼게 됐어요.▶ 그 중에서도 안드로이드 개발을 선택하게 된 이유는 뭐였을까요?예전에 KT에 있을 때, 안드로이드 개발 프로젝트를 맡으면서부터입니다. 원래 이 분야에 대해 전혀 몰랐는데 회사에서 3일간 안드로이드 개발 교육을 받고 해보라는 지시를 받게 된거죠. 막상 해보니 재밌었어요. 특히 이 시기가 2014년 초였는데, 당시에는 안드로이드가 워낙 인기 있는 분야여서 더욱 할만하겠다는 생각을 하게 됐습니다. 효찬님이 선보인 안드로이드 앱 (왼부터)가계부투게더, 메모캐스트, 돈테크 ▶ 본격적으로 모인에 들어오게 된 이야기를 들어보고 싶습니다. 어떻게 모인을 알게 되셨나요?이전 회사에서 늘 입버릇처럼 ‘스타트업을 하고 싶다’는 말을 하고 다녔습니다. 생각해보면 제가 굉장히 밉상이었을텐데 주변 회사분들이 응원을 많이 해주셨어요. 정말 좋으신 분들입니다. (하하) 지인 추천으로 원티드를 알게 됐어요. 저는 초기 단계에 있는 스타트업에 가고 싶었는데 쉽게 찾기는 힘들더라고요. 이후 설립한지 1년도 안 된 ‘모인’을 찾게 됐습니다. 회사에 대해 이것저것 찾아보고 한 번 만나서 이야기해보면 좋겠다는 생각이 들어 대표님을 만났어요. 대표님과 만나 이야기를 나누어 보니 같이 일하고 싶었습니다.  ▶ ‘스타트업을 하고 싶다’는 말을 입버릇처럼 하셨다고 했는데, 특별한 계기가 있었나요?대학 때, 그래픽 프로그래밍 관련 Term Project를 수행했던 적이 있었어요. 이 때 친구들과 밤을 새면서도 웃고떠들며 프로젝트를 해낸 게 제겐 정말 좋은 경험이었습니다. 친한 친구들과 같이 일을 하면 힘든 업무도 웃으면서 즐겁게 할 수 있다는 생각이 들었어요. 앞으로도 좋은 사람들과 같이 즐겁게 일할 수 있으면 좋겠다는 생각을 가지게 되었죠. 스타트업에서 근무하면 일과 동시에 좋은 조직문화를 만들어나갈 수 있을 거라고 생각했어요.  ▶ 개발자로서 자신 있는 영역이 무엇인가요?두루 다룰 줄 안다는 게 제 장점일 수 있겠네요. 그래서 스스로 찾아가면서 어떤 서비스든 개발할 수 있다는 자신이 있습니다. 하지만 역시 한 분야에 대한 전문성은 좀 부족하지 않나 생각해요. 안드로이드에 더더욱 집중해보려고 노력한 이유이기도 합니다. 앞으로도 저만의 차별점을 발굴하는데 계속 노력을 기울일 생각입니다. 효찬님이 가장 애착간다는 원피스 '상디'▶ 개발 외 관심 있는 영역이 무엇인가요?개발 외적으로는 조직 문화에 관심이 많습니다. 제가 개인적으로 일본 만화 ‘원피스’를 좋아해요. 루피 해적단을 보면 개개인이 발전하면서 동시에 팀이 강해지는 모습을 볼 수 있거든요. 어떠한 모험도 할 수 있을 정도로 강해지죠. 루피 해적단 같은 조직을 꿈꿉니다. 어떻게 보면 제가 꿈꾸는 조직 문화가 담겨있다고도 할 수 있죠.특히, 배트맨을 보면 악당이 배트맨 지인을 인질로 잡으면 배트맨은 지인을 구하러 가죠. 하지만 원피스에서는 악당이 루피 친구들을 인질로 잡으면 루피는 친구를 구하러 가지 않아요. 다만, 친구가 함정에서 알아서 잘 나올거라 믿습니다. 그리고 악당을 쓰려트려야 하는 자신의 역할을 수행하는 데 충실해요. 동료를 믿기 때문에 가능한 자세라고 생각해요. 제 나름대로 ‘믿음의 리더십’이라고 혼자 정의해봤어요. (웃음) 대신 내 능력은 스스로가 키워나가야 하죠. 이렇게 각자 자신의 일에 최선을 다하는 사람들과 함께 큰 꿈을 이루는 게 지금 제게 마지막으로 남아 있는 순수한 이상입니다.▶ 더 키워나가고 싶은 역량이 있나요?역량이라기 보다는 제가 만든 작품을 Developing 해나가고 싶어요. 발전가능성이 없는 서비스는 더 이상하고 싶지 않습니다. 내가 만든 앱을 상용화 시키고, 고객들이 반응하는 걸 직접 보고 싶어요. 더불어 서비스 개선에 필요한 역량은 지속적으로 키워나가려고 합니다.장효찬 개발자에게 '함께 일하고 싶은 사람'이란?#온정 #진솔 #파이팅 ▶ 출근한지 일주일도 안됐지만 (웃음) 모인에 대한 첫인상은 어땠어요?정말 아직 1주일도 안됐는데…. (웃음) 대기업에 있다 와서 그런지 소위 ‘젊음의 열정’이라고 하죠? 다들 파이팅 넘치는 모습이 좋았습니다. 그러면서 동시에 나 잘났다고 으스대지도 않고, 특히 대표님 같은 경우는 능력도 있으신데, 겸손하기까지 해서 반했어요. 무언가를 물어보면 설명도 친절하면서 꼼꼼하게 해주시구요. 팀워크가 좋을 거 같다는 긍정적인 예감이 들었어요. 사람 뽑는 데 신중하시다는 대표님을 믿으며, 앞으로도 잘 부탁드립니다.  ▶ 앞으로 어떤 개발자가 되고 싶으신가요? 모인에게도 한마디 해주세요.개발 PM(Project Manager)에 관심이 많습니다. 사실 앱 구현보다 뼈대를 구축하는 일이 더 중요하다고 생각해요. 저는 이 부분이 개발에서 30% 혹은 그 이상을 오롯이 혼자 차지하고 있다고 생각해요. 그러기 위해서는 리소스나 구현한 코드를 어떻게 관리할까, 어떤 부분을 어떻게 더 추가를 해서 연동시킬 수 있을까 등을 서비스 앱 전체를 보고 관리할 줄 알아야 하죠. 이 역할이 국내에서는 중요하게 다뤄지는 거 같지 않아 안타깝습니다. 대부분 보이는 것에만 관심을 가지고 제품이 어떤 제질로 만들어졌는지는 큰 관심을 가지지 않는 추세거든요. 저는 이러한 부분을 중요시 여기는 개발자가 되고 싶습니다. “저를 버리시면(?) 아니됩니다 (웃음)”- 장효찬이 꼽은 인생 명언 -“Do what you love. Everything else is secondary”by. Steve Jobs#모인 #MOIN #개발자 #개발팀 #안드로이드개발자 #안드로이드 #팀원 #팀원소개 #팀원인터뷰 #인터뷰 #기업문화 #사내문화 #조직문화
조회수 3309

Attention is all you need paper 뽀개기

이번 포스팅에서는 포자랩스에서 핵심적으로 쓰고 있는 모델인 transformer의 논문을 요약하면서 추가적인 기법들도 설명드리겠습니다.Why?Long-term dependency problemsequence data를 처리하기 위해 이전까지 많이 쓰이던 model은 recurrent model이었습니다. recurrent model은 t번째에 대한 output을 만들기 위해, t번째 input과 t-1번째 hidden state를 이용했습니다. 이렇게 한다면 자연스럽게 문장의 순차적인 특성이 유지됩니다. 문장을 쓸 때 뒤의 단어부터 쓰지 않고 처음부터 차례차례 쓰는 것과 마찬가지인것입니다.하지만 recurrent model의 경우 많은 개선점이 있었음에도 long-term dependency에 취약하다는 단점이 있었습니다. 예를 들어, “저는 언어학을 좋아하고, 인공지능중에서도 딥러닝을 배우고 있고 자연어 처리에 관심이 많습니다.”라는 문장을 만드는 게 model의 task라고 해봅시다. 이때 ‘자연어’라는 단어를 만드는데 ‘언어학’이라는 단어는 중요한 단서입니다.그러나, 두 단어 사이의 거리가 가깝지 않으므로 model은 앞의 ‘언어학’이라는 단어를 이용해 자연어’라는 단어를 만들지 못하고, 언어학 보다 가까운 단어인 ‘딥러닝’을 보고 ‘이미지’를 만들 수도 있는 거죠. 이처럼, 어떤 정보와 다른 정보 사이의 거리가 멀 때 해당 정보를 이용하지 못하는 것이 long-term dependency problem입니다.recurrent model은 순차적인 특성이 유지되는 뛰어난 장점이 있었음에도, long-term dependency problem이라는 단점을 가지고 있었습니다.이와 달리 transformer는 recurrence를 사용하지 않고 대신 attention mechanism만을 사용해 input과 output의 dependency를 포착해냈습니다.Parallelizationrecurrent model은 학습 시, t번째 hidden state를 얻기 위해서 t-1번째 hidden state가 필요했습니다. 즉, 순서대로 계산될 필요가 있었습니다. 그래서 병렬 처리를 할 수 없었고 계산 속도가 느렸습니다.하지만 transformer에서는 학습 시 encoder에서는 각각의 position에 대해, 즉 각각의 단어에 대해 attention을 해주기만 하고, decoder에서는 masking 기법을 이용해 병렬 처리가 가능하게 됩니다. (masking이 어떤 것인지는 이후에 설명해 드리겠습니다)Model ArchitectureEncoder and Decoder structureencoder는 input sequence (x1,...,xn)<math>(x1,...,xn)</math>에 대해 다른 representation인 z=(z1,...,zn)<math>z=(z1,...,zn)</math>으로 바꿔줍니다.decoder는 z를 받아, output sequence (y1,...,yn)<math>(y1,...,yn)</math>를 하나씩 만들어냅니다.각각의 step에서 다음 symbol을 만들 때 이전에 만들어진 output(symbol)을 이용합니다. 예를 들어, “저는 사람입니다.”라는 문장에서 ‘사람입니다’를 만들 때, ‘저는’이라는 symbol을 이용하는 거죠. 이런 특성을 auto-regressive 하다고 합니다.Encoder and Decoder stacksEncoderN개의 동일한 layer로 구성돼 있습니다. input $x$가 첫 번째 layer에 들어가게 되고, layer(x)<math>layer(x)</math>가 다시 layer에 들어가는 식입니다.그리고 각각의 layer는 두 개의 sub-layer, multi-head self-attention mechanism과 position-wise fully connected feed-forward network를 가지고 있습니다.이때 두 개의 sub-layer에 residual connection을 이용합니다. residual connection은 input을 output으로 그대로 전달하는 것을 말합니다. 이때 sub-layer의 output dimension을 embedding dimension과 맞춰줍니다. x+Sublayer(x)<math>x+Sublayer(x)</math>를 하기 위해서, 즉 residual connection을 하기 위해서는 두 값의 차원을 맞춰줄 필요가 있습니다. 그 후에 layer normalization을 적용합니다.Decoder역시 N개의 동일한 layer로 이루어져 있습니다.encoder와 달리 encoder의 결과에 multi-head attention을 수행할 sub-layer를 추가합니다.마찬가지로 sub-layer에 residual connection을 사용한 뒤, layer normalization을 해줍니다.decoder에서는 encoder와 달리 순차적으로 결과를 만들어내야 하기 때문에, self-attention을 변형합니다. 바로 masking을 해주는 것이죠. masking을 통해, position i<math>i</math> 보다 이후에 있는 position에 attention을 주지 못하게 합니다. 즉, position i<math>i</math>에 대한 예측은 미리 알고 있는 output들에만 의존을 하는 것입니다.위의 예시를 보면, a를 예측할 때는 a이후에 있는 b,c에는 attention이 주어지지 않는 것입니다. 그리고 b를 예측할 때는 b이전에 있는 a만 attention이 주어질 수 있고 이후에 있는 c는 attention이 주어지지 않는 것이죠.Embeddings and Softmaxembedding 값을 고정시키지 않고, 학습을 하면서 embedding값이 변경되는 learned embedding을 사용했습니다. 이때 input과 output은 같은 embedding layer를 사용합니다.또한 decoder output을 다음 token의 확률로 바꾸기 위해 learned linear transformation과 softmax function을 사용했습니다. learned linear transformation을 사용했다는 것은 decoder output에 weight matrix W<math>W</math>를 곱해주는데, 이때 W<math>W</math>가 학습된다는 것입니다.Attentionattention은 단어의 의미처럼 특정 정보에 좀 더 주의를 기울이는 것입니다.예를 들어 model이 수행해야 하는 task가 번역이라고 해봅시다. source는 영어이고 target은 한국어입니다. “Hi, my name is poza.”라는 문장과 대응되는 “안녕, 내 이름은 포자야.”라는 문장이 있습니다. model이 이름은이라는 token을 decode할 때, source에서 가장 중요한 것은 name입니다.그렇다면, source의 모든 token이 비슷한 중요도를 갖기 보다는 name이 더 큰 중요도를 가지면 되겠죠. 이때, 더 큰 중요도를 갖게 만드는 방법이 바로 attention입니다.Scaled Dot-Product Attention해당 논문의 attention을 Scaled Dot-Product Attention이라고 부릅니다. 수식을 살펴보면 이렇게 부르는 이유를 알 수 있습니다.Attention(Q,K,V)=softmax(QKT√dk)V<math>Attention(Q,K,V)=softmax(QKTdk)V</math>먼저 input은 dk<math>dk</math> dimension의 query와 key들, dv<math>dv</math> dimension의 value들로 이루어져 있습니다.이때 모든 query와 key에 대한 dot-product를 계산하고 각각을 √dk<math>dk</math>로 나누어줍니다. dot-product를 하고 √dk<math>dk</math>로 scaling을 해주기 때문에 Scaled Dot-Product Attention인 것입니다. 그리고 여기에 softmax를 적용해 value들에 대한 weights를 얻어냅니다.key와 value는 attention이 이루어지는 위치에 상관없이 같은 값을 갖게 됩니다. 이때 query와 key에 대한 dot-product를 계산하면 각각의 query와 key 사이의 유사도를 구할 수 있게 됩니다. 흔히 들어본 cosine similarity는 dot-product에서 vector의 magnitude로 나눈 것입니다. √dk<math>dk</math>로 scaling을 해주는 이유는 dot-products의 값이 커질수록 softmax 함수에서 기울기의 변화가 거의 없는 부분으로 가기 때문입니다.softmax를 거친 값을 value에 곱해준다면, query와 유사한 value일수록, 즉 중요한 value일수록 더 높은 값을 가지게 됩니다. 중요한 정보에 더 관심을 둔다는 attention의 원리에 알맞은 것입니다.Multi-Head Attention위의 그림을 수식으로 나타내면 다음과 같습니다.MultiHead(Q,K,V)=Concat(head1,...,headh)WO<math>MultiHead(Q,K,V)=Concat(head1,...,headh)WO</math>where headi=Attention(QWQi,KWKi,VWVi)dmodel<math>dmodel</math> dimension의 key, value, query들로 하나의 attention을 수행하는 대신 key, value, query들에 각각 다른 학습된 linear projection을 h번 수행하는 게 더 좋다고 합니다. 즉, 동일한 Q,K,V<math>Q,K,V</math>에 각각 다른 weight matrix W<math>W</math>를 곱해주는 것이죠. 이때 parameter matrix는 WQi∈Rdmodelxdk,WKi∈Rdmodelxdk,WVi∈Rdmodelxdv,WOi∈Rhdvxdmodel<math>WiQ∈Rdmodelxdk,WiK∈Rdmodelxdk,WiV∈Rdmodelxdv,WiO∈Rhdvxdmodel</math>입니다.순서대로 query, key, value, output에 대한 parameter matrix입니다. projection이라고 하는 이유는 각각의 값들이 parameter matrix와 곱해졌을 때 dk,dv,dmodel<math>dk,dv,dmodel</math>차원으로 project되기 때문입니다. 논문에서는 dk=dv=dmodel/h<math>dk=dv=dmodel/h</math>를 사용했는데 꼭 dk<math>dk</math>와 dv<math>dv</math>가 같을 필요는 없습니다.이렇게 project된 key, value, query들은 병렬적으로 attention function을 거쳐 dv<math>dv</math>dimension output 값으로 나오게 됩니다.그 다음 여러 개의 head<math>head</math>를 concatenate하고 다시 projection을 수행합니다. 그래서 최종적인 dmodel<math>dmodel</math> dimension output 값이 나오게 되는거죠.각각의 과정에서 dimension을 표현하면 아래와 같습니다.*dQ,dK,dV<math>dQ,dK,dV</math>는 각각 query, key, value 개수Self-Attentionencoder self-attention layerkey, value, query들은 모두 encoder의 이전 layer의 output에서 옵니다. 따라서 이전 layer의 모든 position에 attention을 줄 수 있습니다. 만약 첫번째 layer라면 positional encoding이 더해진 input embedding이 됩니다.decoder self-attention layerencoder와 비슷하게 decoder에서도 self-attention을 줄 수 있습니다. 하지만 i<math>i</math>번째 output을 다시 i+1<math>i+1</math>번째 input으로 사용하는 auto-regressive한 특성을 유지하기 위해 , masking out된 scaled dot-product attention을 적용했습니다.masking out이 됐다는 것은 i<math>i</math>번째 position에 대한 attention을 얻을 때, i<math>i</math>번째 이후에 있는 모든 position은 Attention(Q,K,V)=softmax(QKT√dk)V<math>Attention(Q,K,V)=softmax(QKTdk)V</math>에서 softmax의 input 값을 −∞<math>−∞</math>로 설정한 것입니다. 이렇게 한다면, i<math>i</math>번째 이후에 있는 position에 attention을 주는 경우가 없겠죠.Encoder-Decoder Attention Layerquery들은 이전 decoder layer에서 오고 key와 value들은 encoder의 output에서 오게 됩니다. 그래서 decoder의 모든 position에서 input sequence 즉, encoder output의 모든 position에 attention을 줄 수 있게 됩니다.query가 decoder layer의 output인 이유는 query라는 것이 조건에 해당하기 때문입니다. 좀 더 풀어서 설명하면, ‘지금 decoder에서 이런 값이 나왔는데 무엇이 output이 돼야 할까?’가 query인 것이죠.이때 query는 이미 이전 layer에서 masking out됐으므로, i번째 position까지만 attention을 얻게 됩니다.이 같은 과정은 sequence-to-sequence의 전형적인 encoder-decoder mechanisms를 따라한 것입니다.*모든 position에서 attention을 줄 수 있다는 게 이해가 안되면 링크를 참고하시기 바랍니다.Position-wise Feed-Forward Networksencoder와 decoder의 각각의 layer는 아래와 같은 fully connected feed-forward network를 포함하고 있습니다.position 마다, 즉 개별 단어마다 적용되기 때문에 position-wise입니다. network는 두 번의 linear transformation과 activation function ReLU로 이루어져 있습니다.FFN(x)=max(0,xW1+b1)W2+b2x<math>x</math>에 linear transformation을 적용한 뒤, ReLU(max(0,z))<math>ReLU(max(0,z))</math>를 거쳐 다시 한번 linear transformation을 적용합니다.이때 각각의 position마다 같은 parameter W,b<math>W,b</math>를 사용하지만, layer가 달라지면 다른 parameter를 사용합니다.kernel size가 1이고 channel이 layer인 convolution을 두 번 수행한 것으로도 위 과정을 이해할 수 있습니다.Positional Encodingtransfomer는 recurrence도 아니고 convolution도 아니기 때문에, 단어의sequence를 이용하기 위해서는 단어의 position에 대한 정보를 추가해줄 필요가 있었습니다.그래서 encoder와 decoder의 input embedding에 positional encoding을 더해줬습니다.positional encoding은 dmodel<math>dmodel</math>(embedding 차원)과 같은 차원을 갖기 때문에 positional encoding vector와 embedding vector는 더해질 수 있습니다.논문에서는 다른 *frequency를 가지는 sine과 cosine 함수를 이용했습니다.*주어진 구간내에서 완료되는 cycle의 개수PE(pos,2i)=sin(pos/100002i/dmodel)<math>PE(pos,2i)=sin(pos/100002i/dmodel)</math>PE(pos,2i+1)=cos(pos/100002i/dmodel)<math>PE(pos,2i+1)=cos(pos/100002i/dmodel)</math>pos<math>pos</math>는 position ,i<math>i</math>는 dimension 이고 주기가 100002i/dmodel⋅2π<math>100002i/dmodel⋅2π</math>인 삼각 함수입니다. 즉, pos<math>pos</math>는 sequence에서 단어의 위치이고 해당 단어는 i<math>i</math>에 0부터 dmodel2<math>dmodel2</math>까지를 대입해 dmodel<math>dmodel</math>차원의 positional encoding vector를 얻게 됩니다. k=2i+1<math>k=2i+1</math>일 때는 cosine 함수를, k=2i<math>k=2i</math>일 때는 sine 함수를 이용합니다. 이렇게 positional encoding vector를 pos<math>pos</math>마다 구한다면 비록 같은 column이라고 할지라도 pos<math>pos</math>가 다르다면 다른 값을 가지게 됩니다. 즉, pos<math>pos</math>마다 다른 pos<math>pos</math>와 구분되는 positional encoding 값을 얻게 되는 것입니다.PEpos=[cos(pos/1),sin(pos/100002/dmodel),cos(pos/10000)2/dmodel,...,sin(pos/10000)]<math>PEpos=[cos(pos/1),sin(pos/100002/dmodel),cos(pos/10000)2/dmodel,...,sin(pos/10000)]</math>이때 PEpos+k<math>PEpos+k</math>는 PEpos<math>PEpos</math>의 linear function으로 나타낼 수 있습니다. 표기를 간단히 하기 위해 c=100002idmodel<math>c=100002idmodel</math>라고 해봅시다. sin(a+b)=sin(a)cos(b)+cos(a)sin(b)<math>sin(a+b)=sin(a)cos(b)+cos(a)sin(b)</math>이고 cos(a+b)=cos(a)cos(b)−sin(a)sin(b)<math>cos(a+b)=cos(a)cos(b)−sin(a)sin(b)</math> 이므로 다음이 성립합니다.PE(pos,2i)=sin(posc)<math>PE(pos,2i)=sin(posc)</math>PE(pos,2i+1)=cos(posc)<math>PE(pos,2i+1)=cos(posc)</math>PE(pos+k,2i)=sin(pos+kc)=sin(posc)cos(kc)+cos(posc)sin(kc)=PE(pos,2i)cos(kc)+cos(posc)sin(kc)<math>PE(pos+k,2i)=sin(pos+kc)=sin(posc)cos(kc)+cos(posc)sin(kc)=PE(pos,2i)cos(kc)+cos(posc)sin(kc)</math>PE(pos+k,2i+1)=cos(pos+kc)=cos(posc)cos(kc)−sin(posc)sin(kc)=PE(pos,2i+1)cos(kc)−sin(posc)sin(kc)<math>PE(pos+k,2i+1)=cos(pos+kc)=cos(posc)cos(kc)−sin(posc)sin(kc)=PE(pos,2i+1)cos(kc)−sin(posc)sin(kc)</math>이런 성질 때문에 model이 relative position에 의해 attention하는 것을 더 쉽게 배울 수 있습니다.논문에서는 학습된 positional embedding 대신 sinusoidal version을 선택했습니다. 만약 학습된 positional embedding을 사용할 경우 training보다 더 긴 sequence가 inference시에 입력으로 들어온다면 문제가 되지만 sinusoidal의 경우 constant하기 때문에 문제가 되지 않습니다. 그냥 좀 더 많은 값을 계산하기만 하면 되는거죠.Trainingtraining에 사용된 기법들을 알아보겠습니다.Optimizer많이 쓰이는 Adam optimizer를 사용했습니다.특이한 점은 learning rate를 training동안 고정시키지 않고 다음 식에 따라 변화시켰다는 것입니다.lrate=d−0.5model⋅min(step_num−0.5,step_num⋅warmup_steps−1.5)warmup_step<math>warmup_step</math>까지는 linear하게 learning rate를 증가시키다가, warmup_step<math>warmup_step</math> 이후에는 step_num<math>step_num</math>의 inverse square root에 비례하도록 감소시킵니다.이렇게 하는 이유는 처음에는 학습이 잘 되지 않은 상태이므로 learning rate를 빠르게 증가시켜 변화를 크게 주다가, 학습이 꽤 됐을 시점에 learning rate를 천천히 감소시켜 변화를 작게 주기 위해서입니다.RegularizationResidual ConnectionIdentity Mappings in Deep Residual Networks라는 논문에서 제시된 방법이고, 아래의 수식이 residual connection을 나타낸 것입니다.yl=h(xl)+F(xl,Wl)<math>yl=h(xl)+F(xl,Wl)</math>xl+1=f(yl)<math>xl+1=f(yl)</math>이때 h(xl)=xl<math>h(xl)=xl</math>입니다. 논문 제목에서 나온 것처럼 identity mapping을 해주는 것이죠.특정한 위치에서의 xL<math>xL</math>을 다음과 같이 xl<math>xl</math>과 residual 함수의 합으로 표시할 수 있습니다.x2=x1+F(x1,W1)<math>x2=x1+F(x1,W1)</math>x3=x2+F(x2,W2)=x1+F(x1,W1)+F(x2,W2)<math>x3=x2+F(x2,W2)=x1+F(x1,W1)+F(x2,W2)</math>xL=xl+L−1∑i=1F(xi,Wi)<math>xL=xl+∑i=1L−1F(xi,Wi)</math>그리고 미분을 한다면 다음과 같이 됩니다.σϵσxl=σϵσxLσxLσxl=σϵσxL(1+σσxlL−1∑i=1F(xi,Wi))<math>σϵσxl=σϵσxLσxLσxl=σϵσxL(1+σσxl∑i=1L−1F(xi,Wi))</math>이때, σϵσxL<math>σϵσxL</math>은 상위 layer의 gradient 값이 변하지 않고 그대로 하위 layer에 전달되는 것을 보여줍니다. 즉, layer를 거칠수록 gradient가 사라지는 vanishing gradient 문제를 완화해주는 것입니다.또한 forward path나 backward path를 간단하게 표현할 수 있게 됩니다.Layer NormalizationLayer Normalization이라는 논문에서 제시된 방법입니다.μl=1HH∑i=1ali<math>μl=1H∑i=1Hail</math>σl= ⎷1HH∑i=1(ali−μl)2<math>σl=1H∑i=1H(ail−μl)2</math>같은 layer에 있는 모든 hidden unit은 동일한 μ<math>μ</math>와 σ<math>σ</math>를 공유합니다.그리고 현재 input xt<math>xt</math>, 이전의 hidden state ht−1<math>ht−1</math>, at=Whhht−1+Wxhxt<math>at=Whhht−1+Wxhxt</math>, parameter g,b<math>g,b</math>가 있을 때 다음과 같이 normalization을 해줍니다.ht=f[gσt⊙(at−μt)+b]<math>ht=f[gσt⊙(at−μt)+b]</math>이렇게 한다면, gradient가 exploding하거나 vanishing하는 문제를 완화시키고 gradient 값이 안정적인 값을 가짐로 더 빨리 학습을 시킬 수 있습니다.(논문에서 recurrent를 기준으로 설명했으므로 이에 따랐습니다.)DropoutDropout: a simple way to prevent neural networks from overfitting라는 논문에서 제시된 방법입니다.dropout이라는 용어는 neural network에서 unit들을 dropout하는 것을 가리킵니다. 즉, 해당 unit을 network에서 일시적으로 제거하는 것입니다. 그래서 다른 unit과의 모든 connection이 사라지게 됩니다. 어떤 unit을 dropout할지는 random하게 정합니다.dropout은 training data에 overfitting되는 문제를 어느정도 막아줍니다. dropout된 unit들은 training되지 않는 것이니 training data에 값이 조정되지 않기 때문입니다.Label SmoothingRethinking the inception architecture for computer vision라는 논문에서 제시된 방법입니다.training동안 실제 정답인 label의 logit은 다른 logit보다 훨씬 큰 값을 갖게 됩니다. 이렇게 해서 model이 주어진 input x<math>x</math>에 대한 label y<math>y</math>를 맞추는 것이죠.하지만 이렇게 된다면 문제가 발생합니다. overfitting될 수도 있고 가장 큰 logit을 가지는 것과 나머지 사이의 차이를 점점 크게 만들어버립니다. 결국 model이 다른 data에 적응하는 능력을 감소시킵니다.model이 덜 confident하게 만들기 위해, label distribution q(k∣x)=δk,y<math>q(k∣x)=δk,y</math>를 (k가 y일 경우 1, 나머지는 0) 다음과 같이 대체할 수 있습니다.q′(k|x)=(1−ϵ)δk,y+ϵu(k)<math>q′(k|x)=(1−ϵ)δk,y+ϵu(k)</math>각각 label에 대한 분포 u(k)<math>u(k)</math>, smooting parameter ϵ<math>ϵ</math>입니다. 위와 같다면, k=y인 경우에도 model은 p(y∣x)=1<math>p(y∣x)=1</math>이 아니라 p(y∣x)=(1−ϵ)<math>p(y∣x)=(1−ϵ)</math>이 되겠죠. 100%의 확신이 아닌 그보다 덜한 확신을 하게 되는 것입니다.Conclusiontransformer는 recurrence를 이용하지 않고도 빠르고 정확하게 sequential data를 처리할 수 있는 model로 제시되었습니다.여러가지 기법이 사용됐지만, 가장 핵심적인 것은 encoder와 decoder에서 attention을 통해 query와 가장 밀접한 연관성을 가지는 value를 강조할 수 있고 병렬화가 가능해진 것입니다.Referencehttp://www.whydsp.org/280http://mlexplained.com/2017/12/29/attention-is-all-you-need-explained/http://openresearch.ai/t/identity-mappings-in-deep-residual-networks/47https://m.blog.naver.com/PostView.nhn?blogId=laonple&logNo=220793640991&proxyReferer=https://www.google.co.kr/https://www.researchgate.net/figure/Sample-of-a-feed-forward-neural-network_fig1_234055177https://arxiv.org/abs/1603.05027https://arxiv.org/abs/1607.06450http://jmlr.org/papers/volume15/srivastava14a.old/srivastava14a.pdfhttps://arxiv.org/pdf/1512.00567.pdf
조회수 5074

Bluetooth Low Energy(BLE) 파헤치기

1. What is BLE?스마트폰이 출시되어 대중화가 될 무렵, ‘스마트’한 개념의 밴드, 워치, 글래스 등이 출시되면서 웨어러블 디바이스 시장이 태동하기 시작했다. 그리고, 2015년 상반기, 애플워치의 등장으로 작은 생태계를 이루고 있던 웨어러블 디바이스들이 다시 한번 각광을 받게 되었다. 각기 생긴 모습은 다르지만 이들의 공통점은 스마트폰과 연동되어 작동한다는 것이었다. 과거부터 기기들간의 단거리 무선통신은 Bluetooth라는 기술이 이용되었다. Bluetooth가 공식적으로 등장한지 약 16년이라는 세월이 흘렀지만, 여전히 기기간의 무선통신에는 Bluetooth가 사용된다. 하지만, 지금 사용되는 Bluetooth는 기존과는 다른 방식이다. 바로 BLE라는 특징을 가진 Bluetooth인데, 바로 이것이 오늘날 다양한 종류의 웨어러블 디바이스들이 태어날 수 있었던 원동력이 되었다. 그렇다면 BLE라는 것이 도대체 무엇일까?그림1. BLE가 뭐지? 먹는건가?과거부터 기기들간의 무선 연결은 주로 Bluetooth라는 기술을 이용했는데, 이들은 기기간에 마스터, 슬레이브 관계를 형성하여 통신하는 Bluetooth Classic이라는 방식을 이용했다. 사람들이 이러한 기기들을 이용하면서 많이 염려했던 것은 ‘Bluetooth를 연결하면 베터리가 빨리 소모된다’, ‘사용하지 않을 때는 Bluetooth 꺼놓아야지’ 등과 같은 베터리 관련된 문제들이었다. 사실이었다. Bluetooth Classic은 다른 디바이스를 무선으로 연결을 하여 사용할 수 있는 편리함을 주었지만, 연결이 되는 동안에는 베터리를 빠르게 소모시켰기 때문에 사용하는 데에 많은 불편함이 있었다.2010년, 새로운 Bluetooth 표준으로 Bluetooth 4.0 이 채택이 된다. 기존의 Bluetooth Classic과의 가장 큰 차이는 훨씩 적은 전력을 사용하여 Classic과 비슷한 수준의 무선 통신을 할 수 있다는 점이었다. 이는 당시 Bluetooth의 최대 단점이었던 과도한 베터리를 소모 문제를 해결하는 기술이었기 때문에, Bluetooth 관련 업계에 큰 반향을 일으켰다. 이렇게 저전력을 이용하여 무선통신을 하는 특징을 Bluetooth Low Energy (이하 BLE) 라고 부르는데, Bluetooth 4.0 이후의 버전들은 이 용어로 대체되서 불리기도 한다. 최근 출시되고 있는 스마트 밴드, 워치, 글래스 등의 웨어러블 무선통신 기기들의 대부분은 이 BLE 방식을 이용하여 무선 통신을 한다.Bluetooth Smart Ready, Smart, ClassicBLE 기술이 등장하면서 Bluetooth 디바이스들은 아래와 같이 3가지로 분류 되었다.그림2. BLE 3가지 분류Bluetooth 4.0과 함께 새롭게 등장한 Bluetooth Smart Ready, Bluetooth Smart에 대해서 살펴보면,Bluetooth Smart Ready 디바이스는 Bluetooth Classic 및 저에너지 Bluetooth 무선통신 (BLE)을 지원하기 때문에 “듀얼 모드” 라디오라고 불린다. 따라서, 이들은 현재 시장에 나와 있는 수억 종의 Bluetooth 디바이스들에 대한 역방향 호환성을 가진다. 종류에는 스마트폰, 태블릿, PC, TV 그리고 셋탑박스 및 게임 콘솔 등이 있다. 이런 디바이스들은 클래식 Bluetooth 디바이스 및 Bluetooth Smart 디바이스들로부터 데이터를 받아, 이들을 유용한 정보로 변환시키는 Bluetooth 시스템의 허브라고 할 수 있다.Bluetooth Smart 디바이스 내에 있는 라디오는 “싱글모드” 라디오라 불리는데, BLE 연결만을 지원한다는 의미이다. 이들은 기존의 Bluetooth Classic 디바이스들과 호환이 되지 않고 듀얼모드 라디오를 가진 Bluetooth Smart Ready 디바이스 혹은 제조업체에 의해 호환성이 명시된 특정 Bluetooth 디바이스에만 연결이 가능하다. Bluetooth Smart 디바이스들은 ‘우리 집의 창문은 모두 잠겨 있는지’, ‘내 인슐린 농도는 얼마인지’, ‘오늘 내 몸무게는 몇 킬로그램인지’ 등과 같이 특정한 형태의 정보를 수집해, Bluetooth Smart Ready 디바이스로 보내기 위해 만들어진 디바이스이다. 종류에는 심박 모니터, 스마트 손목시계, 창문 및 현관 보안 센서, 자동차 키 체인, 그리고 혈압 팔찌 등이 있다.이 글에서는 BLE를 사용하는 디바이스들이 어떤 과정으로 서로 연결되어 통신을 하는지 그리고 이 과정들을 tracking 할 수 있는 장비인 Ubertooth 에 대해 내용을 정리해서 공유해보고자 한다.2. How they communicate?BLE를 지원하는 디바이스들은 기본적으로 Advertise(Broadcast) 과 Connection 이라는 방법으로 외부와 통신한다.Advertise Mode ( = Broadcast Mode)특정 디바이스를 지정하지 않고 주변의 모든 디바이스에게 Signal을 보낸다. 다시 말해, 주변에 디바이스가 있건 없건, 다른 디바이스가 Signal을 듣는 상태이건 아니건, 자신의 Signal을 일방적으로 보내는 것이라고 생각하면 된다. 이 때, Advertising type의 Signal을 일정 주기로 보내게 된다.Advertise 관점에서, 디바이스의 역할은 다음과 같이 구분된다.Advertiser ( = Broadcaster) : Non-Connectable Advertising Packet을 주기적으로 보내는 디바이스.Observer : Advertiser가 Advertise를 Non-Connectable Advertising Packet을 듣기 위해 주기적으로 Scanning하는 디바이스.그림3. Advertiser and ObserverAdvertise 방식은 한 번에 한 개 이상의 디바이스와 통신할 수 있는 유일한 방법이다. 주로 디바이스가 자신의 존재를 알리거나 적은 양(31Bytes 이하)의 User 데이터를 보낼 때도 사용된다. 한 번에 보내야 하는 데이터 크기가 작다면, 굳이 오버헤드가 큰 Connection 과정을 거쳐서 데이터롤 보내기 보다는, Advertise를 이용하는 것이 더 효율적이기 때문이다. 게다가 전송할 수 있는 데이터 크기 제한을 보완하기 위해 Scan Request, Scan Response을 이용해서 추가적인 데이터를 주고 받을 수 있다 (이에 대해서는 뒤에 자세히 설명한다). Advertise 방식은 말 그대로 Signal을 일방적으로 뿌리는 것이기 때문에, 보안에 취약하다.Connection Mode양방향으로 데이터를 주고받거나, Advertising Packet으로만 전달하기에는 많은 양의 데이터를 주고 받아야 하는 경우에는, Connection Mode로 통신을 한다. Advertise처럼 ‘일대다’ 방식이 아닌, ‘일대일’ 방식으로 디바이스 간에 데이터 교환이 일어난다. 디바이스간에 Channel hopping 규칙을 정해놓고 통신하기 때문에 Advertise보다 안전하다.Connection 관점에서 디바이스들의 역할은 다음과 같이 구분된다.Central (Master) : Central 디바이스는 다른 디바이스와 Connection을 맺기 위해, Connectable Advertising Signal을 주기적으로 스캔하다가, 적절한 디바이스에 연결을 요청한다. 연결이 되고 나면, Central 디바이스는 timing을 설정하고 주기적인 데이터 교환을 주도한다. 여기서 timing이란, 두 디바이스가 매번 같은 Channel에서 데이터를 주고 받기 위해 정하는 hopping 규칙이라고 생각하면 된다.Peripheral (Slave) : Peripheral 디바이스는 다른 디바이스와 Connection을 맺기 위해, Connectable Advertising Signal을 주기적으로 보낸다. 이를 수신한 Central 디바이스가 Connection Request를 보내면, 이를 수락하여 Connecion을 맺는다. Connection을 맺고 나면 Central 디바이스가 지정한 timing에 맞추어 Channel을 같이 hopping을 하면서 주기적으로 데이터를 교환한다.그림4. Central and Peripheral3. Protocol Stack디바이스들은 Bluetooth로 통신을 하기 위한 Protocol Stack을 가지고 있다. 일반적으로 네트워크 통신을 하기 위해서는, 통신을 위한 규약인 Protocol을 정의해야 되는데, 이렇게 정의된 Protocol들을 층층이 쌓아놓은 그룹이 Protocol Stack이다. Bluetooth Signal Packet을 수신하거나 송신할 때, 이 Protocol Stack을 거치면서 Packet들이 분석되거나 생성된다.그림5. Protocol Stack위 그림에서 볼 수 있듯이 Protocol Stack은 가장 아랫단부터 크게 Controller, Host, Application 로 나뉜다. 여기서는 Connection 과정에서 필요한 부분인 Physical Layer, Link Layer, Generic Access Profile(GAP), Generic Attribute Profile(GATT)에 대해서 알아볼 것이다.3.1 Physical LayerPhysical Layer에는 실제 Bluetooth Analog Signal과 통신할 수 있는 회로가 구성되어 있어서, Analog 신호를 Digital 신호로 바꾸어 주거나 Digital 신호를 Analog 신호로 바꾼다. 또한 Bluetooth에서는 2.4 GHz 밴드를 총 40개의 Channel로 나누어 통신을 한다. 40개 Channel 중 3개 Channel은 Advertising Channel 로써 각종 Advertising Packet을 비롯하여 Connection을 맺기 위해 주고 받는 Packet들의 교환에 이용된다. 나머지 37개의 Channel은 Data Channel 로써 Connection 이후의 Data Packet 교환에 이용된다.그림6. Channels3.2 Link LayerPhysical Layer의 바로 윗단에는 Link Layer이 있다. Link Layer은 하드웨어와 소프트웨어의 조합으로 구성되어 있다. 하드웨어 단에서는 높은 컴퓨팅 능력이 요구되는 작업들 (Preamble, Access Address, and Air Protocol framing, CRC generation and verification, Data whitening, Random number generation, AES encryption 등)이 처리되고, 소프트웨어 단에서는 디바이스의 연결 상태를 관리한다. 또한 통신하는데 있어서 디바이스의 Role을 정의하고 이에 따라 변경되는 State를 가지고 있다.RoleMaster : 연결을 시도하고, 연결 후에 전체 connection을 관리하는 역할.Slave : Master의 연결 요청을 받고, Master의 timing 규약을 따르는 역할.Advertiser : Advertising Packet을 보내는 역할.Scanner : Advertising Packet을 Scanning하는 역할. Scanner는 아래와 같은 2가지 Scanning 모드가 있다.Passive Scanning : Scanner는 Advertising Packet을 받고 이에 대해 따로 응답을 보내지 않는다. 따라서 해당 Packet을 보낸 Advertiser는 Scanner가 Packet을 수신했는지에 대해서 알지 못한다.Active Scanning : Advertising Packet을 받은 Scanner는 Advertiser에게 추가적인 데이터를 요구하기 위해 *Scan Request라는 것을 보낸다. 이를 받은 Advertiser는 *Scan Response로 응답한다.Scan Request, Scan Response : Advertising Packet type의 한 종류이다. 앞서, 31bytes 이하의 User data에 대해서는 Advertising Signal Packet에 넣어서 보낼 수 있다고 하였다. 하지만 31bytes보다는 크지만, Commection까지 맺어서 보내기는 오버헤드가 큰 데이터가 있을 때, Scan Request, Scan Response를 이용하면 두 번에 걸쳐서 데이터를 나눠 보낼 수 있게 된다. Advertising Packet을 받은 Scanner는 추가적인 User Data(예를 들어, Peripheral 디바이스의 이름)를 얻기 위해 Scan Request를 보내게 된다. Scan Request를 받은 Advertiser는 나머지 데이터를 Scan Response Signal에 담아서 보낸다.이들은 크게 Connection 전의 역할(Advertiser, Scanner), 후의 역할(Master, Slave)로 분류된다.StateLink Layer는 5가지 State를 가지고 있는데, 각 디바이스는 서로 연결이 되는 과정에서 이 State를 변화시킨다. 다음과 같은 5개의 State가 존재한다.Standby State : Signal Packet을 보내지도, 받지도 않는 상태.Advertising State : Advertising Packet을 보내고, 해당 Advertising Packet에 대한 상대 디바이스의 Response를 받을 수 있고 이에 응답할 수 있는 상태.Scanning State : Advertising Channel에서 Scaning하고 있는 상태.Initiating State : Advertiser의 Connectable Advertising Packet을 받고난 후 Connetion Request를 보내는 상태.Connection State : Connection 이후의 상태.아래 그림은 각각의 State를 Diagram으로 나타낸 것이다.그림7. Link Layer State3.3 Generic Access Profile (GAP)Generic Access Profile (GAP)는 서로 다른 제조사가 만든 BLE 디바이스들끼리 서로 호환되어 통신할 수 있도록 해주는 주춧돌 역할을 한다. 즉, 어떻게 디바이스간에 서로를 인지하고, Data를 Advertising하고, Connection을 맺을지에 대한 프레임워크를 제공한다. 그래서 GAP는 최상위 Control Layer라고도 불린다. Advertising Mode일 때, GAP에서 Advertising Data Payload와 Scan Response Payload를 포함할 수 있다.또한 GAP에서는 BLE 통신을 위해 Role, Mode, Procedure, Security, Additional GAP Data Format 등을 정의한다. 이들은 실제 API와 직접적으로 많은 연관이 있기 때문에 그 내용이 상당히 많지만, 여기서는 BLE Connection과 관련이 있는 Role에 대해서만 알아보겠다.RoleBroadcaster : Link Layer에서 Advertiser 역할에 상응한다. 주기적으로 Advertising Packet을 보낸다. 예를 들면, 온도센서는 온도데이터를 자신과 연결된 디바이스에게 일정주기로 보낸다.Observer : Link Layer에서 Scanner 역할에 상응한다. Broadcaster가 뿌리는 Advertising Packet에서 data를 얻는다. 온도센서로부터 온도데이터를 받아서 디스플레이에 나타내는 테블릿 컴퓨터의 역할이다.Central : Link Layer에서 Master 역할과 상응한다. Central 역할은 다른 디바이스의 Advertising Packet을 듣고 Connection을 시작할 때 시작된다. 좋은 성능의 CPU를 가지고 있는 스마트폰이나, 테블릿 컴퓨터들의 역할이다.Peripheral : Link Layer에서 Slave 역할과 상응한다. Advertising Packet을 보내서 Central 역할의 디바이스가 Connection을 시작할 수 있도록 하게끔 유도한다. 센서기능이 달린 디바이스들의 역할이다.3.4 Generic Attribute Profile (GATT)BLE Data 교환을 관리하는 GATT는 디바이스들이 Data를 발견하고, 읽고, 쓰는 것을 가능하게 하는 기초적인 Data Model과 Procedure를 정의한다. 그래서 GATT는 최상위 Data Layer라고도 불린다. 디바이스간에 low-level에서의 모든 인터렉션을 정의하는 GAP와는 달리, GATT는 오직 Data의 Format 및 전달에 대해서만 처리한다. Connection Mode일 때, GATT Service와 Characteristic을 이용하여 양방향 통신을 하게 된다. Service와 Characteristic에 대한 내용은 여기를 참고하길 바란다.GATT도 Data 처리와 관련해서 다음과 같은 역할을 정의한다.RoleClient : Server에 Data를 요청한다. 하지만 처음에는 Server에 대해서 아는 것이 없기 때문에, Service Discovery라는 것을 수행한다. 이 후, Server에서 전송된 Response, Indication, Notification을 수신할 수 있다.Server : Client에게 Request를 받으면 Response를 보낸다. 또한 Client가 사용할 수 있는 User Data를 생성하고 저장해놓는 역할을 한다.4. Packet TypeBLE 통신에서는 두 가지 종류의 패킷인 Advertising Packet, Data Packet만이 존재한다. Connection을 맺기 전에는 Advertising Packet type, 맺은 후에는 Data Packet type으로 Signal을 생성한다. Data Packet은 하나로 통일되지만, Advertising Packet은 특정 기준에 따라서 다음과 같은 성질들을 갖는다.ConnectabilityConnectable : Scanner가 Connectable Advertising Packet을 받으면, Scanner는 이를 Advertiser가 Connection을 맺고 싶어한다는 신호로 받아들인다. 그러면 Scanner는 Connection Request (이하 CONNECTREQ)를 보낼 수 있다. 해당 Connectable Signal을 보낸 Advertiser는 Scanner가 CONNECTREQ가 아닌 다른 타입의 Signal을 보내면 해당 Packet을 무시하고 다음 Channel로 이동하여 계속 Advertising을 진행한다.Non-Connectable : Non-Connectable Packet을 받은 Scanner는 CONNECT_REQ를 보낼 수 없다. 주로 Connection 목적이 아닌, Data 전달이 목적일 때 쓰인다.ScannabilityScannable : Scanner가 Scannable Advertising Packet을 받으면, Scan Request (이하 SCANREQ)를 보낼수 있다. Scannable Signal을 보낸 디바이스는 Scanner가 SCANREQ가 아닌 다른 타입의 Signal을 보내면 해당 Packet을 무시하고 버린다.Non-Scannable : Non-Scannable Signal을 받은 Scanner는 SCAN_REQ를 보낼 수 없다.DirectabilityDirected : Packet안에 해당 Signal을 보내는 디바이스의 MAC Address와 받는 디바이스의 MAC Address가 들어있다. MAC Address 이외의 데이터는 넣을 수 없다. 모든 Directed Advertising Packet은 Connectable 성질을 갖는다.Undirected : 해당 Signal을 받는 대상이 지정되어 있지 않다. Directed Advertising Packet과는 다르게, 사용자가 원하는 데이터를 넣을 수 있다.위의 내용을 종합하면, Advertising pakcet을 아래와 같이 4가지 type으로 나눌 수 있다.그림6. Advertising Packet Type5. How they really communicate?BLE 통신의 핵심은 ‘timing’이다.Before ConnectionConnection 전, 디바이스는 3개의 Advertising Channel을 이용해서 데이터를 주고 받는다고 했다. 이들은 이 3개의 Channel을 자신만의 time interval로 hopping한다. 서로의 hopping 규칙이 일치하지 않기 때문에 Channel이 서로 엇갈리는 경우가 많을 것이다. 예를 들어, Advertiser는 1번 Channel에 Advertising Packet을 보냈는데, 같은 시간에 Scanner는 3번 Channel에 대해서 Scanning을 하게 되면 데이터 전달이 되지 않는 것이다. 하지만 이러한 hopping이 빠르게 자주 일어나기 때문에, 두 디바이스가 같은 Channel에 대해 Advertising와 Scanning이 발생하는 경우도 많이 생긴다. 이 경우에 서로 데이터를 주고 받을 수 있다.After ConnectionConnection이 되면, Advertising은 종료되고 기기들은 Central, Peripheral 중 하나의 역할을 하게된다. Connection을 개시한 기기가 Central이며, Advertiser가 Peripheral이 된다. 그리고 두 디바이스는 엇갈렸던 hopping 규칙을 통일시킨다. 그렇게 함으로써, 매번 같은 채널로 동시에 hopping하면서 Signal을 주고 받을 수 있게 된다. 이는 둘 간의 Connection이 끊어질 때까지 지속된다.6. How they connect each other?디바이스간의 BLE 연결을 iPhone과 Zikto Walk와의 연결과정으로 설명하면 다음과 같다.1) Zikto Walk가 Advertising Channel을 hopping하면서 Advertising Packet을 보낸다.(Zikto Walk의 Advertising Packet 유형은 ADV_IND이다)2) iPhone Bluetooth를 켠 후, Zikto 앱에 Zikto Walk를 등록한다. iPhone은 Advertising Channel을 hopping하면서 Scan을 하다가 연결하려는 Zikto의 디바이스 이름 등의 추가적인 정보를 얻기위해 SCAN_REQ를 보낸다.3) SCANREQ를 받은 Zikto Walk는 SCANRSP를 보낸다.4) Pairing이 완료되고, Zikto Walk는 다시 Advertising Packet을 다시 일정 주기마다 보낸다.5) iPhone에서 Zikto Walk로부터 걸음 수 등의 Data를 받기 위해 Sync 버튼을 누른다. 이 버튼을 누르면 iPhone은 CONNECT_REQ를 보낸다.6) Zikto와 iPhone은 서로 Acknowledging을 시작하고, timing 정보 등을 동기화 한다.7) Connection이 완료된다.8) Connection이 완료된 후, Service Data, Characteristic Data 등에 대한 Data 교환이 일어난다.9) iPhone과 Zikto Walk간에 Data Sync가 완료되면, Connection이 해제되고, 다시 Advertising Packet을 보낸다. 이를 그림으로 표현하면 아래와 같다.그림6. Advertising Packet Type7. Ubertooth디바이스간 BLE를 이용한 통신 과정에 대해 알고나니, Bluetooth Signal Packet도 Capturing 할 수 있을 거라는 생각이 들었다. 검색을 해 본 결과, 오픈소스 Bluetooth Test tool인 Ubertooth라는 장치로 디바이스간의 BLE 통신을 tracking 할 수 있다는 사실을 알게 되었다. 가격은 100달러로 생각보다 저렴했지만 국내에서는 구매할 수가 없었다. 그렇다고 궁금한 것을 해보지도 않고 포기하는 것은 엔지니어의 마인드가 아니지 않겠는가. 직접 아마존 (www.amazon.com)에서 해외구매를 하였다. 이렇게 바다 건너 멀리서 날아온 Ubertooth를 사용했던 경험을 바탕으로, Ubertooth의 원리와 BLE 통신에 대해서 조금 더 자세히 설명을 해보고자 한다.Ubertooth는 10cm정도의 몸체와 그와 비슷한 길이의 안테나를 가지고 있는 매우 작고 귀여운 모양이다. 이것이 이름하여 Ubertooth!그림8. Ubertooth오픈소스이기 때문에 모든 소스가 공개되어 있고, 소스를 빌드하고 사용하는 방법도 Ubertooth Github 및 Ubertooth Blog에 잘 나와 있어서 사용하기가 수월했다.How it works?Ubertooth는 크게 Bluetooth Classic을 tracking하는 기능과 BLE를 tracking하는 기능으로 나뉘는데, 여기서는 BLE 통신을 tracking 하는 원리에 대해서 다루겠다.BLE는 앞에서 언급했다시피, Connection 전, 후로 통신하는 방법이 다르다. 그리고 위의 내용들을 꼼꼼히 읽은 독자라면 BLE 통신에서 가장 중요하다고 언급했던 timing 이라는 것을 기억할 것이다. timing 은 BLE 통신에서 굉장히 중요한 요소이기 때문에, 보다 더 자세하고 쉽게 설명을 해보겠다.종이컵 전화기를 사용하여 대화를 해야하는 두 사람이 있다. 종이컵 전화기는 총 40개가 놓여져 있다. 이 두 사람은 40개 전화기 중 하나를 사용해서 대화를 주고 받고, 일정시간 뒤에 다음번 전화기를 이용해야 한다. 이러한 커뮤니케이션 방식에서 소통을 하기 위해서는 한 전화기로 얼마만큼의 시간동안 통화를 할 것인지, 다음 전화기는 어떤 전화기를 사용할 것인지, 그리고 어떤 방식으로 자신들의 대화를 다른 사람들의 대화들로부터 구분할 것인지 등에 대해 알아야 할 것이다. 이것들이 위에서 말했던 timing 관련 정보이다.실제 BLE 통신에서 timing 과 관련된 정보들은 다음과 같다 : Access Adress, CRC Info, Hop Interval, Hop Increment (해당 내용들에 대한 자세한 설명은 여기를 참고하기 바란다). BLE 통신을 하는 디바이스들은 이 timing 관련 정보를 동기화하여, Connection이 맺어진 이후에 해당 규칙에 따라 Channel을 hopping하면서 데이터를 주고 받는다. Ubertooth는 바로 이 정보를 알아내어, Master, Slave와 같은 패턴으로 Channel을 hopping하면서 대화를 엿듣는다. 아까 말한 종이컵 전화기에 빗대어 말하면, 제 3자(Ubertooth)가 두 사람이 정한 대화 규칙을 알아내서, 매번 이들이 전화기를 바꿔가며 대화를 할 때 마다 해당 전화기의 대화 내용을 엿듣는 것이다. 굉장히 흥미로운 방법이 아닐 수 없다. 그렇다면 Ubertooth는 어떻게 이 정보를 알아낼까?Before Connection두 디바이스가 연결되기 전, Ubertooth가 timing 관련 정보를 알아내는 방법은 매우 간단하다. Scanner가 Advertiser에게 Connection을 맺기위해 보냈던 CONNECT_REQ을 기억하는가? 공교롭게도 해당 패킷에는 이 네 가지 정보가 전부 들어있다. Ubertooth는 그 정보를 추출해내어 저장해 두고, 그 규칙에 맞게 Channel을 hopping하면서 Signal Data를 전부 엿듣는다.그림9. Ubertooth로 Capture한 CONNECT_REQ packetAfter Connection이미 연결된 디바이스들은 CONNECT_REQ를 보낼 일이 없다. 그러면 Ubertooth는 Connection 이후의 상황에 대해서는 Signal Data를 엿듣지 못하는 것일까? 아니다. Connection 이후의 상황에 대해서 Ubertooth는 다음과 같은 방법을 이용한다.BLE Signal Packet은 Advertise Mode이든 Connection Mode이든간에 무조건 하나의 Signal Packet format만 존재하기 때문에, Packet마다 특정 정보가 존재하는 부분은 어느 Packet에서나 똑같다. 4가지 정보 중 Access Address라는 것은 모든 Signal Packet마다 존재한다. Access Address라는 것은 두 디바이스간의 Unique한 Connection을 나타내는 4bytes 크기의 Identifier로써, CONNECT_REQ를 보내는 디바이스에 의해 랜덤하게 생성된다. Ubertooth는 37개의 Data Channel을 hopping하면서 모든 Data Packet의 Access Address를 추출해내어 Look Up Table 형태로 저장해 놓는다. 그리고는 각각의 Access Address가 등장한 횟수를 세게 되는데, 가장 먼저 특정 횟수만큼 등장한 Access Address를 target으로 잡는다. 나머지 3가지 정보는 각각 추출해내는 방법 및 알고리즘이 따로 존재하는데 해당 내용도 위에 언급한 사이트에 잘 나와있다. 이렇게 해서 네 가지 정보를 알아낸 Ubertooth는 두 디바이스와 같은 패턴으로 Channel을 hopping하면서 Signal Data를 엿듣는다.그림10. Ubertooth로 Capture한 Aceess Address과 나머지 3가지 정보들이렇게 보면, Ubertooth로 모든 것을 할 수 있을 것처럼 보이지만, 몇 가지 한계점이 있기도 하다. Ubertooth가 timing 관련 정보를 얻어내는 과정에 대해 다시 한 번 생각해보길 바란다. 잘 모르겠다면, 직접 Ubertooth 구매하여 테스트를 해보는 것도 엔지니어로써 굉장히 좋은 경험이 될 것이다.8. ConclusionBLE 통신과 이를 tracking하는 Ubertooth에 대해서 알아보았다. 매우 장황한 내용처럼 보이지만 이것도 매우 압축해서 설명한 것이다. 하나하나 디테일하게 쓰기 보다는 BLE를 처음 접하는 사람이 최대한 이해하기 쉽도록 작성하는 것에 초점을 맞추었다. 위의 내용들을 바탕으로, 독자들이 BLE에 더 넒고 깊은 지식을 얻게 되었으면 하는 바램이다. 글을 읽으면서 Bluetooth Classic은 어떻게 통신하는지에 대해 궁금하신 분들도 있을거라 생각한다. 이에 대해서 간단히 언급하자면, Bluetooth Classic 통신 방식은 BLE보다 훨씬 더 복잡하다. BLE에 대해서 어느 정도 알게 되었다면, Bluetooth Classic에 도전해보는 것도 괜찮을 것이다. BLE내용과 관련해서 보충이 필요한 내용이나, 관련 경험 혹은 궁금한 점 등에 대해서 아낌없이 조이와 공유해주길 바란다.9. ReferenceAkiba, “Getting Started with Bluetooth Low Energy: Tools and Techniques for Low-Power Networking”, O’Reilly Media(2015)http://www.slideshare.net/steveyoon77/bluetooth-le-controllerhttp://www.hardcopyworld.com/ngine/aduino/index.php/archives/1132https://www.bluetooth.org/ko-kr/bluetooth-brand/smart-marks-faqshttp://trvoid.blogspot.kr/2013/05/ble.htmlhttp://blog.lacklustre.net/posts/BLEFunWithUbertooth:SniffingBluetoothSmartandCrackingItsCrypto/#조이코퍼레이션 #개발팀 #개발자 #개발환경 #업무환경 #인사이트 #경험공유
조회수 1331

공포의 Swift3

라이비오를 시작하며 이전 사업과는 다르게 어쩔 수 없이 안고 출발했던 핸디캡이 있었다."너는 개발자가 아니잖아."사실이다.아무래도 위제너레이션이나 오드리씨를 할 때는 영업과 마케팅 위주의 조직이었다보니 급하면 급한대로 내가 직접 할 수 있는 것들이 많았다. 하지만 앱 개발은 완전 다른 차원의 이야기라 (디자인은 직접 맡고 있지만) 새롭게 배워야 할 부분이 정말 많았다.'그래도 이제와서 어떻게 개발을 배우겠어.' 싶어서 공부를 시작했다가 그만두기도 몇 번.개발의 ㄱ자라도 잡아보자 싶어 HTML이나 CSS, PHP 같은 언어들을 끄적끄적 공부해보곤 했었는데, 기본서 수준이거나 Codecademy 따라해 본 것이 전부이다보니 실제로 뭔가를 해 볼 수준에는 전혀 미치지 못했다.그래서 이번에는 돈을 좀 쓰더라도 독학 말고 수업을 들어보자고 생각했다.새해를 맞아 큰 맘 먹고 백만원 상당의 패스트캠퍼스 수업을 질러 Swift3 를 배우게 되었다. (iOS 개발언어)(나만의 앱을 만들고 싶은데 넘나 어려운 것..........)벌써 오늘이 11강째인데 전체가 16강인 것을 생각하면 어느새 진도를 많이 뺐다.그런데 문제는,초기 문법 배울 때는 괜찮았는데예제 따라하기로 들어가면서부터 수준이 높아져 따라갈 수가 없다는 것이다.특히 지난 주에는 수업을 들으면서 동시에 절망하는 수준에 이르렀는데다들 아무 말도 없고 키보드 마우스 소리만 들리기에, 나만 이해를 못하고 있다는 생각에 중반부터는 아예 수업 듣기를 포기하고 조용히 yes24를 켜서 Swift 기본서를 주문했다. (빠른 상황판단ㅋㅋㅋㅠㅠㅠ)그런데 수업을 마친 후 강사님이 "오늘 너무 빨랐나요?"하고 물으니,수강생들이 너도나도 손을 들며 너무 빨랐다고, 놓쳤다고 얘길 하는 게 아닌가!나만 놓친게 아니라는 (어리석은..) 잠깐의 위로를 받았다.하지만 설날이 지나고,이제 좀 더 쉬워졌게지 하는 생각으로 오늘 11강에 들어갔더니 웬걸.여전히 어렵고, 이해가 0되는 현상이 발생했다.역시 공부에는 지름길도 속임수도 없다.아무래도 Swift 책을 때며 따로 복습해야 따라갈 수 있을 것 같다.슬프게도 두께가 이만큼이다. (1473페이지 중에 226페이지까지 복습했다^^............)*강사님이 쓰신 책도 있지만 Objective C 라는 다른 언어와의 비교를 중심으로 설명하셔서 초심자에게는 오히려 어려운 부분이 있었다. 아예 초보에게는 '꼼꼼한 재은씨의 스위프트3 (기본편)' 책을 추천한다. 제목만큼 꼼꼼하게 쓴 책이다. (홍보는 아닙니다만 책이 너무 좋아서 구매링크)뭐 하나 쉬운 것이 없지만, 그래도 서른이 되기 전에 좀 더 제대로 코딩 공부를 해 보게 되어서 다행이다.언어 + 수학 + 논리의 결합인 코딩은 어렵지만 꽤 아름답다.난 문돌이라 못 한다고 한계만 짓지 않으면 충분히 할 수 있을 것 같다.대신 만만하게 생각하지는 말고 꾸준히...........올해 안에 꼭 내 이름으로 된 앱 출시를 해봐야겠다.#라이비오 #비전공개발자 #iOS #Swift #인사이트 #경험공유
조회수 1876

GDG DevFest Seoul 2018, 크래커나인 부스 참가 후기

2018년 11월 10일 토요일, 세종대학교 광개토관 컨벤션홀에서 GDG DevFest Seoul 2018이 열렸습니다. 세종대학교 광개토관 컨벤션홀 세션장과 세션 소개지GDG 행사 중 가장 큰 개발자의 축제에 크래커나인이 빠질 수 없겠지요?GDG DevFest는 GDG 커뮤니티에 의해 매년 개최되는 개발자 행사 중 하나로, 올해는 'Digital Wellbeing' 이라는 키워드 아래 진행되었습니다.이번 행사는 구글 기술과 관련된 세션, 해커톤, 코드랩 등의 형태로 구성이 되어 짜임새 있고 더 유익했습니다.⬆️ 위의 시간표 출처: 티켓구입처(https://festa.io/events/88)여기서 코드 랩은 무엇인지 궁금 하시지요?* Codelab은 미리 작성된 가이드를 따라 빠르게 해당 기술의 튜토리얼을 해볼 수 있는 프로그램이였어요. Codelab 튜터가 상주하고자유롭게 출입해 시작할 수 있다는 큰 매력으로 많은 개발자님들이 참여해주셨습니다.이미지 출처: https://devfest-seoul18.gdg.kr/timetableTrack E에 후반에 진행하는 마인드폴니스는 이번 'Digital Wellbeing' 키워드에 가장 걸맞았어요.* Mindfulness는 경직된 자세로 오랜 시간 작업을 하기 쉬운 개발자들을 위해 명상을 하는 시간을 가지는 프로그램입니다.저희 크래커나인 팀원들도 마인드폴니스에 참여하여 힐링하였다고 하네요 :)이미지 출처: https://devfest-seoul18.gdg.kr/timetable그 밖의 세션들은 Android, Firebase, Google Cloud Platform, Machine Learning, Web Technologies, Chrome 등의 Google 개발자  기술  콘텐츠 뿐만  아니라  더  나아가  트렌드에  부합하는  많은  주제를  폭  넓게  다루는  다양한  시간이었습니다.이미지 출처: https://devfest-seoul18.gdg.kr/timetable단 5분만에 디자인을 코드로 만들어주는 크래커나인은 행사의 꽃, 부스 참가하였습니다.구글 코리아, 레이니스트, 카카오페이, 알지피코리아 등과 나란히 부스 참가하여 많은 개발자님들을 만날 수 있었습니다.이미지 출처: https://devfest-seoul18.gdg.kr크래커나인은 10월 1일 부터 GDG DevFest Seoul 2018을 준비하기 시작했습니다.더 많은 개발자님들에게 편리하고 효율적인 크래커나인을 소개하여 작업 속도와 능률을 올리고자 했습니다.대략 40일간 준비하면서 진짜 디자이너와 개발자가 원하는 바가 무엇인지도 생각해보는 뜻깊은 시간들 이었습니다.먼저, 개발자님들의 애정한다는 스티커를 팀 명함과 함께 제작하였습니다.또한 많은 분들에게 크래커나인 무료 베타 서비스와 더불어 선물을 선사해드리고 싶어 경품 이벤트도 진행했답니다 :)  국내에서 다수가 사용하는 GUI 가이드 프로그램 제플린의 아성에 도전하는 크래커나인!실제 크래커나인을 사용하면 GUI 정보는 물론, 안드로이드 코드까지 생성해주어 매우 효율적입니다. 실제 블로터에 메인 게재될 만큼 혁신적이고 획기적인 크래커나인을 많은 분들께 소개하려니 너무 설레였습니다 :)“디자인만 하면 코드 자동 생성”…‘크래커나인’ 베타 출시코드를 '클릭'으로 해결해준다.www.bloter.net이 날, 제플린 vs 크래커나인 속도 테스트 영상을 공개하여 큰 이슈를 받았는데요~ 많은 개발자님들의 환호와 관심에 더욱 더 좋은 기능과 서비스로 보답해야 겠다는 마음이 커졌습니다.   제플린과 크래커나인 속도 테스트 영상 궁금하시지요?Cracker9 VS Zeplin (19sec)똑같은 앱 화면 디자인을 크래커나인과 제플린을 사용하여 GUI정보를 받아 안드로이드 스튜디오를 이용하여 화면을 구성하기 까지의 작업 속도를 비교한 영상입니다. 안드로이드 코드까지 생성해주는 크래커나인은 5분대에 화면 완성! GUI가이드문서를 만들지 않아도 빠르고 간편하게 GUI가이...youtu.be코드 생성 프로그램은 기존에도 존재한 적 있지만, GUI 정보와 안드로이드 레이아웃 코드까지 클릭만으로 뽑아주는 크래커나인은 그야말로 +_+ 최고!실제 사용해보고 시연할 수 있는 곳을 만들어 많은 개발자님들의 검증도 받았답니다.  믿음이 가는 코드에 만족하셨나요?스피드하게 짜는 손코딩 장인 "시니어 개발자"도~알아가는 단계지만 꼼꼼하게 체크하며 한땀한땀 작성해가는 "주니어 개발자"에게도~시연, 체험했던 크래커나인!개발자님들에게 편의성 뿐만 아니라 신뢰성 마저 안겨주었던 좋은 기회였습니다. :)그 밖에도 카카오인형 경품으로 많은 인원을 모은 카카오페이는 "요즘개발자, 카카오페이" 라는 카피와 QR 코드로 부스를 장식했습니다. 명함 이벤트를 진행한 요기요 배달통 부스는 경품 당첨때만 인산인해를 이루었답니다. 갑자기 많은 개발자님들이 당첨 여부 확인하러 오셨다가 저희 부스에 와주셔서 또 다른 기회로 크래커나인을 소개할 수 있었답니다 :) 세션에 참가하여 각자의 생각과 견해를 적어주신 개발자님들께도 감사의 인사를 드립니다.세션의 상세내용은 아래의 포스트에서 좀 더 자세히 보실 수 있습니다.※ 디테일한 강연내용과 후기를 남겨주신: http://eclipse-owl.tistory.com/18?category=1022165※ 자신의 견해와 행사의 세션 정리를 잘 해주신: https://brunch.co.kr/@oemilk/196#에이치나인 #디자이너 #개발자 #협업툴 #크래커나인 #솔루션기업 #이벤트참여 #이벤트후기
조회수 2283

평균 응답시간의 의미

어플리케이션 성능 분야에서 평균 응답 시간은 어플리케이션 서버가 사용자에게 요청 결과를 반환하는 데 걸리는 시간을 말합니다. 어플리케이션 서버의 응답시간은 일반적으로 밀리세컨드에 가깝지만 부하량에 따라 많은 시간이 걸리기도 합니다. 고객이 기다리는 시간 3초인터넷 초창기인 1999년 전자 상거래 사이트의 최적로드 시간은 8초 였습니다. 2006년도에 들어서는 4초까지 줄어들었습니다. 그리고 지금은 3초를 고객을 떠나게 만드는 시간으로 이야기 합니다. 구글 이 운영하는 더블클릭(https://www.doubleclickbygoogle.com/articles/mobile-speed-matters/)은 모바일 페이지가 로드되는데 3초가 지나면 사용자의 절반 이상이 서비스를 포기한다고 조사결과를 발표했습니다. 3초라는 시간 속에는 웹페이지의 렌더링 시간과 네트웍이 사용하는 시간등이 포함되어 있기 때문에 웹 어플리케이션이 소모해야 하는 시간은 실제로 밀리세컨드에 가깝습니다. 하지만 실제 서비스의 장애가 발생하면서 웹 어플리케이션의 평균 응답시간은 점점 길어지게 됩니다. 성능분석에서 평균 응답시간부하가 늘어나면서 임계치가 넘어가면 초당 처리량은 더이상 증가하지 않게 됩니다. 논리적으로 생각 해보면 초당 처리량이 더이상 증가하지 않은 상태에서 사용자만 늘어나면 TPS와 인지시간이 상수처럼 동작하므로 응답시간이 사용자에 비례하여 늘어나게 됩니다. [응답시간(Respons Time) = [동시사용자수 / 초당 요청수(TPS)] - 인지시간(Think Time)하지만 일반적인 상황에서 응답시간은 밀리세컨드 단위의 값이데 비해 인지시간은 3초에서 10초 이상의 값을 가지고 됩니다. 그럼 이번에는 성능을 분석하는 스토리를 만들어 보겠습니다. 우리가 영어 문장을 한글로 번역하는 웹 서비스를 만든다고 해 보겠습니다. 우리는 동시 사용자 100명을 예상하고 서비스를 만들고 있습니다. 여기서 서비스 특성상 사용자가 한번 번역을 요청하고 다음번 요청을 보내는데 평균 30초의 시간이 걸립니다. 마지막으로 최대 응답시간은 0.5초를 넘지 않도록 설계하려고 합니다. 이런 경우 우리가 목표로 하는 초당 요청수는 서비스를 동시에 사용하는 사람들의 요청을 시간으로 나누므로 계산식은 동시사용자수(100명)/(응답시간(0.5초) + 인지시간(30초)) 이고 결과값은 약 3.27이 됩니다.     초당 요청수(TPS) = 동시사용자수 / [응답시간(Respons Time) + 인지시간(Think Time)]이렇게 성능을 계산하는 과정에서 서비스의 처리시간 즉 응답시간은 인지시간에 비해 매우 적기 때문에 인지시간이 커지면 커질수록 TPS에 관여하는 비율이 0에 수렴하게 됩니다. 결론적으로 성능을 설계하는 시점에서 응답시간은 별로 중요한 이슈가 아니게 됩니다. 대신 인지시간이 중요해 집니다.인지시간(Think Time)이란?웹 서비스를 사용하는 사용자는 자신의 요청을 확인하는 시간이 필요합니다. 이렇게 이전 요청과 다음 요청 사이의 시간을 인지 시간이라고 합니다. 인지 시간은 사용자나 서비스 유형에 따라 다릅니다. 예를 들어 시스템 간 상호 작용은 사람이 관여하는 웹 서비스 상호작용에 비해 매우 낮은 인지 시간을 포함합니다. 또는 블로그 서비스에 비해 사전검색 서비스의 인지시간은 매우 짧을 것입니다. 서비스의 도메인을 분석하여 인지 시간을 결정하는 것은 매우 중요합니다. 인지시간을 사용하여 분당 완료해야 하는 요청 수는 물론 시스템에서 지원할 수 있는 동시 사용자 수를 계산할 수 있습니다. 튜닝 지표로서의 평균 응답시간현실에서 웹 서비스의 응답시간은 수식과 다르게 나타나게 됩니다. 그래서 많은 성능 분석 도구가 평균 응답시간을 보여주고 있습니다. 실제 성능 분석 도구들이 알려 주는 평균 응답시간은 수집 주기 동안에 수집된 트랜잭션의 응답 시간을 합산하여 평균한 값입니다.와탭의 서비스는 5초 간격으로 트랜잭션의 평균 응답시간을 계산합니다. 응답시간이 성능 지표보다 튜닝지표로서의 의미를 가집니다. 예를 들어 사용자가 적은 밤 시간에 배치잡과 같은 일부 응답시간이 길어짐으로써 사용자가 많은 낮보다 평균 응답시간이 더 길수도 있습니다. 하지만 실제 성능을 올리기 지표로써 응답시간은 매우 직접적입니다. TPS와 상관없이 평균 응답시간이 길어지는 요소가 있다면 주변 요소와 함께 평균 응답시간을 살펴봐야 합니다. #와탭랩스 #개발자 #개발팀 #인사이트 #경험공유 #일지
조회수 908

할아버지/할머니도 코딩을 해야 하는 이유

대부분의 교육은 초, 중, 고등학생이나 대학생 등 주로 젊은 층을 위주로 진행되고 있습니다. 프로그래밍 교육도 마찬가지로, 현재 10대에서 30대인 주로 젊은 층의 학생과 직장인들을 대상으로 교육이 서서히 일어나고 있습니다. 하지만 높아진 평균 수명으로 노인층이 급격히 늘어나고, 빠르게 변화하는 산업 아래 노인층의 재교육을 통한 지속적인 사회 활동이 요구 되는 시대가 되었습니다.2016년 한국의 인구분포도. 42–57세의 중장년층이 15–24의 청년층보다, 청년층이 0–9세의 유아층보다 월등히 많습니다. Wikipedia위 그래프에서 보이는 것처럼 이렇게 사회의 전체적인 평균 연령의 급격한 상승이 예고되어있음에도 불구하고, 고등학교나 대학까지의 일회성 교육이 아닌 전 연령층을 대상으로 한 지속적인 교육 제공은 아직 보편화 되어 있지 않습니다. 노인층 대상으로 진행되는 교육은 미미하며, 특히나 젊은층도 배우기 어려운 코딩 교육은 노인층에게는 교육이 불가능하거나 전혀 필요하지 않다고 여겨지고 있습니다.UC San Diego 대학의 Phillip Guo 교수Phillip Guo 교수는 HCI (사람-컴퓨터 인터랙션) 및 온라인/컴퓨터 교육 분야에서 명성이 높은 연구자입니다. Guo 교수는 처음으로 노인층에 대한 코딩 교육 연구를 진행하여 온라인에서 프로그래밍을 배운 52개국 60~80대 504명으로부터 다양한 설문조사와 심층조사를 진행한 결과를 CHI 국제 학술회에 출간했습니다. 본 연구 설명과 함께 엘리스에서 생각하는 로드맵을 소개합니다.연구본 연구는 http://www.pythontutor.com 웹사이트에서 실시된 온라인 코딩 교육 설문조사에 응한 504명의 60~85세 학생에 대한 심층 분석과 인터뷰로 이루어져있습니다. 이들이 코딩을 배우는 목적은 세가지 주요 요점으로 종합됩니다.첫째는 코딩을 배움으로서 노화되는 뇌를 자극하기 위함이고, 둘째로 젊은 시절 놓쳤던 새로운 기회를 잡기 위함, 그리고 마지막으로 어린 가족 구성원들과 소통하기 위함이었습니다.혼자 공부하는 방식의 교육은 온라인에서 특히 더 높은 이탈율을 보입니다.이들이 프로그래밍을 배우는 원동력은 교육을 통한 취업과 같은 정확히 정해진 목표보다는, 스스로의 동기부여 및 젊은층과의 소통을 위한 이유가 더 컸습니다. 코딩을 배우는 과정 중에 가장 힘든 세가지는 감퇴하는 인지력, 질문에 대답해 줄 수 있는 강사나 조교 혹은 학생이 없었고, 매번 변화하는 SW를 따라가기 어려움이 있었습니다. 첫번째를 제외한 나머지 어려움은 다른 연령층에서도 겪은 어려움이었습니다.마치며Philip Guo 교수의 논문에서 알 수 있는 것은 노인층이 노화하면서 겪을 수밖에 없는 배움의 어려움과 더불어, 현재 교육 시스템이 노인층을 전혀 고려하지 않고 있다는 것입니다. 이것은 노인층 대상의 교육을 더욱 어렵게 합니다.논문에서는 노인층에게 적합한 교육 시스템이 만들어지거나 제공된다면, 이들이 산업에 바로 투여될 수 있는 능력을 갖추기는 어려울 수도 있으나 프로그래밍 교육을 할 수 있는 선생님으로 활동할 수 있다고 서술하고 있습니다. 이를 활용하면 현재 현저히 부족한 SW 교육자 수로 어려움을 겪고 있는 공교육에 도움이 될 수 있습니다.엘리스에서는 라이브 교육 방송 진행, 헬프 센터 조교 도우미 등 학생들에게 좋은 교육을 제공하기 위해 부단히 노력하는 다양한 연령층의 온라인 조교님들이 계십니다. 언젠가는 60~80대 조교님이 활동하실 수 있다고 믿고 있습니다. 이러한 믿음을 주신 중2 아들을 둔 한 어머니의 피드백을 참조합니다. (엘리스 기초 자바 과정에서 최상위 점수를 받으셨습니다.)저는 전공도 인문학쪽이고 수학 싫어서 문과갔던 문과생인지라, 코딩처럼 논리력 요구하는 수업 따라가기나 할까 큰 기대없이 시작했었습니다.수업 초반에는 마냥 어리둥절했고, 시키는대로 따라하면 다 되었기 때문에 ‘어라 쉽잖아?’ 라고 느꼈습니다. 하지만 중반부 넘어가면서…클래스, 메소드라는 개념이 낯설기도 했고, 각종 연산자의 적용이나 변수들을 식에 적용시키는 다양한 패턴들이 적응이 잘 안되었어요. 반복문의 순서나 마침표,세미콜론, 콜론을 기억하지 못해서 다시 되돌아와서 확인한 것만도 수 십번이었습니다.다른 분들은 마치 초급 과정을 어디서 마스터 하고 온 것처럼 잘 따라가시는데, 저는 매 시간마다 헤매고 오류나고…하지만 똑똑한 것 보다 꾸준한 것이 더 낫다고… ‘머리가 안따라가면 더 오래 공부하면 되겠지’ 하고 다시 보고, 다시 풀고, 계속 질문하고그러나보니 어느 순간 이해가 가는 개념들, 저절로 외워지는 패턴들이 조금씩 늘어났어요.특히 실시간 강의라서 피드백을 받을 수 있고, 조교님이나 강사님들께 질문을 편하게 할 수 있는 시스템이 정말 좋았습니다. 비주얼 좋은 두 분이 수업을 진행해 주신 것도 좋았구요. 반응 좋은 우리 반 수강생들도 참 좋았습니다.저녁 설거지 해 두고 (때로는 저녁상을 치우기 바쁘게) 컴퓨터 앞에 앉아서 8주간 공부한 시간들이 저한테는 정말 소중한 시간이었습니다. 이렇게 집안 일 하고, 애들 챙기면서도 공부할 수 있고, 배울 수 있다는 것이 너무 좋습니다. 좋은 강의 열어주셔서 고맙습니다. ^^*p.s.수업 중에 어떤 분이 자바 알고리즘 강의 열어달라고 하시던데, 알고리즘이 뭔지 물어보고 싶었는데 못 물어봤네요 ㅋ#엘리스 #코딩교육 #교육기업 #기업문화 #조직문화 #서비스소개
조회수 1859

잔디의 새싹 같은 안드로이드 개발자 Gary를 만나다.

맛있는 인터뷰 : 안드로이드 개발자(Android Developer) Gary 편집자 주잔디와 함께 하는 멤버는 총 35명. 국적, 학력, 경험이 모두 다른 이들이 어떤 스토리를 갖고 잔디에 합류했는지, 무슨 일을 하고 있는지 궁금해하는 분들이 많습니다. 잔디 블로그에서는 이 궁금증을 해결해 드리고자 ‘맛있는 인터뷰’를 통해 ‘잔디’ 멤버들의 이야기를 다루고 있습니다.인터뷰에서 가장 기초적인 질문. 예상하신 자기소개 부탁한다.G : 잔디 개발자 중 제일 어린! 핵심 키워드다. 강조 부탁한다. 가장 어린! 안드로이드 플랫폼 개발을 맡은 Gary다(이하:G). 잔디 입사한 지는 9개월 되었다. 특별한 일 없이 정말 열~! 심히 개발만 했다. 일주일 전부터 식당 선택을 강요(?)했다. 이 식당을 선택한 이유는 무엇인가?G : 음식이 푸짐하게 나오기도 하지만 조명이 좋다. 인터뷰 중 사진을 찍는다고 들었는데 그 사진이 예쁘게 나올 것 같아서 선정했다. 게다가 음식이 정갈하다. 안에 룸도 있어서 회식하기도 좋다. 내 입이 복잡하질 않아서 뭘 먹어도 다 맛있다. 어차피 다 맛있는 거 사진이라도 잘 나와야 한다 싶어서 선택하게 되었다. 잔디에 들어오게 된 계기는?G : 모집 공지가 뜨길래.. 농담이다^^; 전 직장과의 시스템이 다른, 자체 서비스를 하는 회사에 가보고 싶었다. 전 직장에서는 기획, 서버, 디자인, 개발을 각각 다른 회사에서 진행했다. 내가 속한 회사는 개발만 진행했다. 처음부터 끝까지 한 곳에서 서비스하는 회사를 가보고 싶었다. 또한, 기술 스택이 너무 좋았다. 이를 통해 앞으로 나의 실력이 일취월장할 수 있겠다는 생각이 들었다. 9개월 동안 많이 발전한 것 같은가?G : 상당히 많이 발전했다. 어떤 부분에서 발전한 것 같은가?G : 이전 회사에서는 일정에 쫓기다 보니 개발 자체에서 설계라는 게 없었다. 손 가는 데로, 일단 만들고 보자라는 식으로 신기술이고 뭐고 공장처럼 찍어내는 것이 일이었다. 하지만 잔디는 다르다. 2주 단위로 생각을 통해 설계도 해보고 ‘객체지향 설계 5대 원칙’ 등 다양한 사항을 고려해보며 많은 고민 끝에 개발하는 것이 너무 좋다. 이를 통해 개발자로서 더욱 성장한 것이 느껴진다. 이전 회사보다는 일찍 퇴근하는 편인가?G : 이전 회사는 철야, 야근 거의 매일 했다. 입사한 지 9개월 정도 되었는데 이제야 사람답게 사는 것 같다. 그동안은 짐승인 줄 알았다. 일어나면 출근하고 퇴근하면 자고. 9개월 동안 사람답게 살면서 잠도 푹 잤다. 몸이 편해지면 사람 얼굴이 확 산다고 하던데 생긴 건 나아지지 않더라. 옛말도 틀린 말이 있나 보다. (하하) 주말엔 뭐하시는가?G : 집돌이 성향이라 집에 있는 경우가 많다. 밖에 나가면 이웃 주민들과 소통하기도 한다. 지금 사는 곳은 취업한 지 얼마 안 된 사회초년생들에게 국가에서 주는 ‘행복주택’이라는 곳이다. 그곳엔 대부분 사회초년생이라 연령대가 20대 후반에서 30대 초반 정도 된다. 그분들과 소통을 하며 지내고 있다. 나이가 비슷하니 공감대 형성도 되고 행복주택에서 행사 같은 걸 많이 해서 문화생활 영위하는 듯하다. 말 그대로 사람 사는 듯한 느낌이다. 서울 집값이 너무 비싸다. 행복주택은 저렴한 편인가?G : 다른 원룸에 비교하면 저렴한 편이다. 보증금이 들어가지만, 월세는 10만 원 전후다. 서울에서 월세 10만 원 전후라면 저렴한 편 아닌가? 사회 초년생분들께 추천한다. 이웃들도 좋고 문화생활도 하고. 엄청나지 않은가? 신청 후 당첨이 되어야 하지만 당첨되기 쉬운 편이다. 꼭 한번 도전해봐라. 처음 들어왔을 때 잔디는 어땠는가?G : 사실 처음 들어왔을 때 사무실이 시끌벅적하며 소통이 아주 활발할 줄 알았다. 그런데 딱 들어오니 어?! 음? 오?!… 조용하다. 진짜 활발한 곳은 따로 있었다. 목소리가 아닌 손가락으로 얘기하는 곳. 잔디 앱이었다. 사무실 자체는 너무 조용한데 잔디 앱 안에서 매우 활발하다. 아이러니하지만 의사소통은 아주 활발했다. 잔디의 생활 중 가장 마음에 드는 문화는?G : 영어 이름을 사용하며 상호 간에 존중하는 문화다. 30년 동안 한글 이름으로만 살았는데. 회사만 오면 Gary라고 부른다. 첨엔 이게 날 부르는 건지도 잘 몰랐지만 익숙해지니 너무 좋다. 수평적인 관계의 시작이 무엇인지 알게 되었다. 이전 회사와는 다르게 잔디에서는 수평적인 관계여서 의견 개진이 편했다. 의견을 나눌 수 있다는 것이 너무 좋았다. 물론 손끝으로 얘기하지만:D 감정표현도 이모티콘으로 한다. 표정은 무표정이지만 손가락은 웃고 있달까? 내 얼굴은 무표정인데 프랑키 (파랑몬스터 캐릭터)가 웃어준다. 이젠 오프라인으로도 소통이 되었으면 한다. 사무실 밖에선 말이 많으신 분들인데. 사무실만 들어오면 조용하시다. 손으로 말하고 계시니까. (웃음) 회식은 자주 하는가?G : 팀마다 다른 것 같다. 팀 내에서 석 달 치 회식비를 모아서 한 번에 하던가 쪼개서 자주자주 하던가. 어차피 쓰는 돈은 같으니까. 이루고 싶은 꿈이 있다면?G : 백수가 되고 싶다. (비장) 충분한 불로소득이 있는. 소득과 상관없이 내 맘대로 살 수 있는 그런 백수가 되고 싶다. 회사를 가고 싶으면 회사를 가고 사업을 하고 싶으면 사업을 하는 그런 백수(하하). 사실 프로그래머로서 직업을 정했을 때는 최고의 프로그램을 만들어보는 게 꿈이었다. 또한, 안드로이드로 시작했으니 구글에서 종지부를 찍자! 이런 꿈을 꾸었다. 그런데 이전 직장이 너무 힘들었나 보다. 꿈이 변했다. 백수로. 하루는 7개월 정도 만에 칼퇴근하고 집에 갔더니 어머니께서. “너 잘렸냐?”라고 물어보시더라. 그땐 내 회사 생활에 문제가 있구나 싶었다. 백수는 아니지만 일과 삶의 밸런스가 맞는 삶을 살고 싶다. 다음 인터뷰어에게 하고 싶은 질문이 있나?G : 회사 내에 다른 팀원들과 지금 먹고 있는 음식을 같이 먹을 수 있다면 누구랑 같이 먹고 싶은가?#토스랩 #잔디 #JANDI #팀원소개 #인터뷰 #기업문화 #조직문화 #사내문화 #팀원자랑
조회수 2001

나는 이쁜 데일리룩을 보고 싶은걸? \w pose estimation

안녕하세요. 스타일쉐어 백엔드 개발자 김동현입니다.2018년의 스타일쉐어에서는 뷰티, 중고 그리고 데일리룩이라는 피드가 추가로 등장했는데요, 그중 제가 작업했던 데일리룩 피드를 만들게 된 배경과 개발 방향에 대해 공유드리고자 합니다.스타일쉐어 데일리룩#데일리룩 #ootd / 타자 치는 것은 귀찮아데일리룩에 관련된 스타일들만 뽑아내는 방법 중에 가장 간단한 방법은 텍스트로 분리해내는 방법이었을 것입니다.하지만 #데일리룩 #ootd는 사진이나 내용이 관계가 없더라도 들어가 있는 경우가 많았습니다.또한 위의 피드처럼 정성스러운 글을 써주는 유저도 많긴 했지만 자신의 데일리 로그를 남기면서 글을 작성하지 않는 경우도 더러 있었습니다.즉, 단순히 텍스트로만 구별해내기에는 이미지에 대한 질을 확신할 수 없었고, 텍스트가 주된 서비스가 아니다 보니 설명 없는 좋은 이미지들이 많았는데요.우리는 이 이미지들을 놓치고 싶지 않았습니다.그래서 결과적으로 텍스트 대신 이미지를 사용하는 방향을 선택하게 되었습니다.이미지로 어떻게 구별해낼까?다행히도 R-CNN의 높은 인식률과 Pre-Trained 된 모델의 label 중 person이 이미 학습되어있던 터라 별도의 Transfer Learning 없이 이미지 내에서 body parts가 있는지 없는지 찾아내는 것은 아주 어렵지 않았습니다.다만 문제가 있다면 body parts에 들어가는 모든 부분을 person이라고 예측하던 부분이었죠.예를 들자면 아래와 같습니다.다음과 같이 제가 사용한 모델에서는 body parts를 person이라는 라벨로 처리하고 있었습니다.단순히 R-CNN의 person 라벨만을 믿기에는 의도했던 데일리룩 외에도 너무나도 많은 것들이 데일리룩이라는 이름으로 필터링될 것 같았습니다.그래서 또 다른 필터가 하나 더 필요하다는 생각이 들었습니다.Pose EstimationBody Parts 중 우리가 원하는 부분이 사진에 있으면 좋겠다!라는 생각을 곰곰이 하다 보니 우연히 머릿속에 스쳐 지나가는 하나의 장면이 있었습니다.Source: http://graphics.berkeley.edu/papers/Kirk-SPE-2005-06/바로 3D 모델링 중에서 Motion Tracker 에 관련된 장면이었는데요. 이것을 Tracker가 아니라 이미지에서 stick figure를 뽑아낼 수 있으면 되지 않을까?라는 생각이 들었습니다.놀라운 딥러닝의 세계에는 이미 여러 명의 Stick Figure를 뽑아낼 수 있는 경지에 도달해 있었습니다.Source: https://github.com/ZheC/Realtime_Multi-Person_Pose_EstimationPose Estimation 딥러닝 모델을 사용하여 아래와 같은 결과물을 얻어낼 수 있었는데요.이미지 내의 Body Parts의 존재 여부를 알게 되었으니 우리가 원하는 Body Parts가 이미지 내에 있는지 검사할 수 있게 되었습니다.하지만 해당 모델이 마냥 가볍지는 않았기에 사용자의 업로드가 많은 순간에는 예측 Task가 밀리기 시작했습니다.그래서 아주 단순하지만, 효과적인 아이디어들을 적용하였는데요.pose estimation을 하기 전에 R-CNN을 돌린 후 person으로 예측된 bounding box가 있다면 pose estimation 모델을 돌리도록 했습니다.하지만 위의 필터를 통했음에도 원하는 결과물이 안 나오는 경우가 종종 있었는데요.바로 다음과 같은 경우입니다.생각보다 작은 사람의 stick figure도 잘 추출 내어서 해수욕장으로 떠나 찍은 사진 속의 저 멀리 있는 휴양객을 데일리룩으로 잡는 일이 종종 발생했거든요.그래서 위의 조건에 더불어서 person이라고 예측된 bounding box size가 전체 이미지 크기 대비 n % 이상의 크기 일 경우 Pose Estimation을 진행하자는 것이었죠.적당한 크기 이상의 데일리룩들을 뽑아내고 싶었고 사람이 너무 작아서 안 보이는 경우도 피할 수 있었습니다.빠른 분류 속도는 덤이었고요.덕분에 유저들이 올린 콘텐츠 중 데일리룩이라는 범주에 속하는 콘텐츠를 잘 뽑아낼 수 있었습니다.아래는 위의 과정을 거쳐서 Pose Estimation까지 처리되어 데일리룩 사진이라고 판별된 이미지입니다.이다음으론 무엇을 더 해볼 수 있을까요?사진 속의 자세를 알 수 있게 되었으니 좀 더 재밌는 것을 할 수 있을 것 같은데요.예를 들면 K-Means를 적용하면 비슷한 모습의 데일리룩들만 모아볼 수도 있고 스타일쉐어 유저들이 자주 찍는 자세 라던가 유저 별 자세 선호도 등등 재밌는 것들을 할 수 있을 것 같습니다.날 따라 해 봐요 같은 것도 해볼 수 있겠네요 :)같이 해보지 않을래요?아직도 재밌는 것들이 많이 남은 스타일쉐어 에서는 더 많은 것을 하기 위해 개발자분들을 모시고 있습니다 :)백엔드 개발자라고 해서 백엔드 개발에만 국한되지 않고 하고 싶은 것들을 해도 된다, 할 수 있다고 이야기해 주는 회사라고 생각합니다.스타일쉐어를 좀 더 알고 싶으시다면 여기를 눌러 주세요 :)#스타일쉐어 #개발팀 #개발자 #백엔드개발 #개발인사이트 #경험공유 #후기
조회수 1209

OLTP에 대하여

Overview우리는 대부분의 활동을 스마트폰 하나로 해결할 수 있습니다. 은행에 가지 않아도 앱만 있으면 은행 업무를 할 수 있고, 몇 번의 터치만으로 다양한 물건을 구매할 수 있습니다. 모든 것을 온라인에서 해결합니다. 이 말을 바꿔 말하면, ‘온라인에 연결되지 않았다는 건 대부분의 경제활동에서 벗어났다’는 의미이기도 합니다. 우리가 온라인에서 무언가를 클릭(또는 터치)한다는 건 서버에 호출하는 행위이기도 합니다. 서버가 실시간으로 원하는 결과를 우리에게 다시 보내주는 것이죠. 이렇듯 많은 사람들에게 실시간으로 서버가 자료를 처리하는 과정을 OLPT(Online transaction processing)라고 합니다. Table의 구조OLTP 처리를 하려면 DB를 어떻게 설계해야 할까요. 예를 들어봅시다. 모든 웹사이트는 서비스를 이용하려면 우선 회원가입을 해야 합니다. 가입을 할 때는 ID 와 비밀번호를 꼭 만들어야 하고요. 이것을 DB Table로 가정하면 회원 Table은 ID와 암호 컬럼으로 구성될 겁니다. 회원ID암호위의 Table은 가입자 수가 많아지면 운영을 하고 건수가 많아지면 두 가지 문제가 발생합니다. 첫 번째는 ID가 중복된다는 것, 그리고 두 번째는 자료가 많아질수록 가입된 회원의 ID를 가져오는 게 느려진다는 것이죠. 전자의 문제는 Application 단에서 어느 정도 확인할 수는 있지만 다중 사용자 구조에서 중복되지 않는다는 보장을 할 수 없습니다. 후자의 문제는 Table만으로는 해결되지 않습니다. 이를 해결하려면 Index(Primary Key)를 생성해 해결할 수 있습니다. Index 생성으로 문제를 해결할 수 있다는 게 생소할지도 모릅니다. 우선 Index의 기본적인 구조를 알아야 합니다. 보통 Table에 자료를 Insert하면 입력한 순서대로 자료가 쌓입니다. 회원입력순서ID암호1홍길동12342강감찬56783이순신abcd4김좌진efgh하지만 Oracle Cluster Table과 MySQL InnoDB Table은 Table에는 입력한 순서대로 쌓이지 않고, 특정 KEY에 따라 쌓입니다. 그러므로 모든 테이블이 꼭 위의 예시처럼 순서대로 쌓이진 않습니다. Oracle Cluster Table과 MySQL InnoDB Table은 아래 예시처럼 보여집니다.회원입력순서ID암호2강감찬56784김좌진efgh3이순신abcd1홍길동1234이번에는 Index에서 가장 많이 사용하는 BTree Index를 살펴보겠습니다. Index는 보통 테이블의 자료를 빠르게 검색하기 위해 생성합니다. 1개의 Table 위에 N개의 Index를 생성할 수 있습니다.1) 회원 테이블의 ID를 KEY로 하는 Index를 생성한다고 가정하면 아래와 같은 Index 구조를 가집니다.회원_ID_IndexID(KEY)Table 위치 값강감찬XXX김좌진XXX이순신XXX홍길동XXXIndex는 KEY의 순서(오름차순 or 내림자순)로 정렬되어 있습니다. 그러므로 N개의 KEY를 지정해 Inedx를 생성하면 N개의 KEY 순서대로 정렬됩니다. 그렇다면 BTree Index는 왜 정렬되어 있을까요? 자료를 찾는 속도가 빠른 것과는 어떤 관계가 있을까요?자료 구조를 조금이라도 공부했다면 이미 BTree라는 이름에서 눈치채셨을 겁니다. Btree Index는 이진검색(Binary Search)에 기반을 두고 있습니다. Binary Search는 자료가 정렬되어 있는 상태에서 자료의 절반 위치를 찾아가는 구조입니다. (처음 전체의 절반, 절반의 절반 , 그 절반의 절반) 전체를 읽을 때보다 빠르게 원하는 값을 찾을 수 있고, 자료를 읽어내는 속도도 빨라집니다. 이렇게 해서 Index가 생성되어 있다면 Index에서 값을 빠르게 찾을 수 있고, 이 값이 위치한 Table의 레코드를 바로 접근해 원하는 값을 가져올 수 있게 됩니다. Index에서 원하는 값을 빠르게 찾을 수 있기 때문에 Index를 생성할 때 속성(UNIQUE or NON UNIQUE)을 설정해 중복 허용 여부를 지정할 수 있습니다. Index와 Table관계를 표시하면 아래와 같습니다.회원_ID_IndexID(KEY)Table 위치 값강감찬2김좌진4이순신3홍길동1▼회원입력순서ID암호1홍길동12342강감찬56783이순신abcd4김좌진efghPrimary Key만약 ID의 컬럼 속성을 NOT NULL로 설정하면 중복이 되지 않고 값을 항상 입력합니다. ID의 무결정을 보장하고, 자료도 빠르게 찾을 수 있게 되는데요. 방법은 크게 두 가지로 설정할 수 있습니다. 하나는 Unique Index 와 NOT NULL을 사용하는 것이고, 다른 하나는 Primary Key를 지정하는 것입니다.2) 그렇다면 우리는 어떤 것을 지정하는 것이 좋을까요? 사실 DB 특성과 Table특성, 용도에 따라 달라지기 때문에 정답은 없지만 일반적으로 Primary Key를 지정합니다. Primary Key를 지정하는 건 몇 가지 이유가 있습니다. 첫째, 논리적으로 Primary Key를 지정해 Table의 기준을 알 수 있습니다. 둘째, 거의 모든 DB가 같은 조건(Index가 여러 개 있을 경우)이라면 Primary Key를 우선적으로 사용합니다. 마지막으로, 특정 DB는 Table(MySQL InnoDB Table)이 Primary Key로 정렬되고, 이것이 위치 값으로 사용되면 다른 Index를 쓰는 것보다 속도가 빠릅니다. 그러므로 가능한 Primary Key를 사용하는 것이 좋고, 그 외의 경우엔 Index를 사용하면 됩니다. Conclusion지금까지 OLTP 처리를 할 때의 기본적인 회원 Table 구조와 문제점 및 해결 방안 , 간단한 Index 및 Primary Key를 알아봤습니다. 다음 글에서는 조금 더 확장된 개념인 단일 Table을 Select하는 법을 다뤄보겠습니다. 뭐든 기초가 중요하니까요. 하하.. 참고 1) Oracle Bitmap Index의 경우 2개 테이블을 연결하여 1개의 Index를 생성할 수도 있습니다. 2) Primary Key는 NOT NULL컬럼만 지정 가능합니다. 글한석종 부장 | R&D 데이터팀[email protected]브랜디, 오직 예쁜 옷만#브랜디 #개발문화 #개발팀 #업무환경 #인사이트 #경험공유
조회수 1363

docker the cloud

당신의 기획안을 통과시키는 마법의 단어, 클라우드안녕, 여러분! 다들 다망하신 와중에 이렇게 지면으로 찾아뵙게 되어 굉장히 반갑습니다. 저는 spoqa의 노예 xym입니다. 어느덧 벌써 연말이네요. 온갖 골든 위크로 시작했던 4/4분기, 이제 한창 주말 외에는 법정공휴일이 없는 데스마치를 진행중이시리라 생각되는데요, 안 그래도 다들 크리스마스만 바라보고 미친듯이 달리고 계시죠?네, 그래서 제가 이렇게 잠시 여러분 머리를 식혀드리기 위해 한 번 재밌는 이야기를 하고자 찾아뵙게 되었습니다. 개발자가 아닌 분들에게도 별로 어렵지 않게 쓰고자 노력했으니 한번쯤 “오 이런 신기한 게 있구나”하고 읽어보시고 머리 좀 식히고 가세요.업계 분들이나, 이쪽 업계에 소식이 빠삭한 분들은 아시겠지만 몇년 전부터 이 바닥은 새롭게 몰아치는 파도를 맞고 있습니다. 2, 3년 전부터 올해 중순까지 업계 뜨거운 감자였던 키워드들에 대해서 기억하고 계신가요? 네, 그 소위 HTML5니 클라우드, 빅데이터, 소셜 게임 따위의, 기획안에 쓰면 사장님 입이 귀에 걸리게 만드는 마법의 단어들이요.이 글도 사실 그 마법의 단어들에 관련된 이야기입니다. 정확히는 클라우드 기술에 관련된 이야기예요.뜬구름 잡는 클라우드대관절 클라우드란 무엇이길래 여러분의 기획안을 통과시키게 하는가 궁금하지 않으셨나요? 알고 계신 분들도 많을 테니 간략하게 설명하고 넘어가겠습니다. 클라우드는 클라우드 컴퓨팅 기술의 약자입니다. 위키피디아에 있는 정의는 다음과 같습니다:인터넷 따위의 네트워크를 통해 실시간으로 많은 컴퓨터들을 관리하는 여러 컴퓨팅 기술과 관련된 개념들을 총칭얼핏 들으면 굉장히 뜬구름 잡는 소리입니다. 아니, 그럼 그 전까지는 그런 걸 안 했다는 건가? 물론 아닙니다. 클라우드 컴퓨팅이란 단어가 버즈워드로써 시장을 강타하기 전에도 소위 클라우드 컴퓨팅을 위한 기술들은 존재했습니다.엄밀히 말하면 클라우드 컴퓨팅은 ‘기술 융합’의 일종이라고 볼 수 있습니다. 기존에 존재하던 개념들과 기술들을 융합하여 새로운 접근법을 탄생시킨 것이죠. 간단히 소개하자면 그 클라우드 컴퓨팅을 이루는 기반에는 다음과 같은 두 개의 거대한 축이 있습니다.가상화(Virtualization) : 하나의 컴퓨팅 자원을 여러 개로 나누어 마치 여러 개의 독립된 컴퓨터처럼 사용하는 기술 혹은 개념그리드 컴퓨팅(Grid computing) : 하나의 작업을 동시에 여러 개의 컴퓨터가 분할하여 처리하는 기술 혹은 개념거기에 중요한 개념 하나만 더 얹고 넘어가겠습니다. 이것도 한 때는 버즈워드로 사람들을 흥분시켰었죠.Application Programming Interface(API) : 복잡한 내부 동작에 대해서는 잘 몰라도 정해진 규약(인터페이스)만 알고 있으면 해당 기능을 사용할 수 있도록 한다는 개념그러니까 어떤 작업을 하기 위해 하나의 컴퓨터를 여러 개로 분리하고(자르고), 또다시 그 분리된 컴퓨터들을 합쳐서(합치는), 어쨌든 정해진 규약대로 사용할 수 있게 만드는 것(편한 거).아, 너무 기네요. 줄여서 “난 잘 모르겠지만 뭔가 좀 편한 거군.” 정도로 해두죠. 그게 클라우드의 궁극적인 목표이자 본질이라고 볼 수 있겠습니다. 그래서 이름도 뜬구름 잡는 소리 같다고 클라우드잖아요?그래도 마냥 뜬구름 잡는 소리만 할 수는 없으니 한번 클라우드 서비스의 종류를 알아봅시다.IaaS(Infrastructure as a Service) - 인프라스트럭쳐, 한마디로 서버를 조립하고 설치하는 방법을 몰라도 쓸 수 있도록 편하게 제공한다고 보면 됩니다. Amazon Web Service 같은 애들이죠.PaaS(Platform as a Service) - 이번엔 IaaS를 잘 몰라도 서비스를 돌릴 수 있게 만들어진 플랫폼을 제공합니다. Heroku가 대표적입니다.SaaS(Software as a Service) - 그렇게 만들어진 플랫폼 위에 돌아가는 서비스들을 제공합니다. icloud.com의 keynote 따위가 있겠군요.생각보다 어렵지 않죠?docker 란 무엇인가사설이 길었네요. 이제부터가 본론입니다. 제가 오늘 소개할 녀석은 클라우드 컴퓨팅에 있어 “자르는” 축을 담당하는 가상화의 떠오르는 아이돌, LXC를 사용한 docker 입니다. LXC가 무엇인지는 여기서 중요하지 않습니다#2. 그냥 업계의 떠오르는 아이돌 정도로 해 둡시다. 그러니까 아이유 같은 존재죠.docker가 등장한 배경을 설명하자면 이렇습니다. Heroku와 함께 PaaS계에서 끗발을 날렸던 dotCloud는 어느 날 갑자기 충격적인 발표를 합니다. 자기네들이 쓰는 가상화 및 애플리케이션 플랫폼을 공개해 ‘오픈 소스로’ 제공하겠다는 것이죠. 아니, 이럴 수가! 이러시면… 이러시면 정말 감사합니다#3!docker의 가장 큰 특징은 다음과 같이 요약할 수 있습니다.image 관리의 간편화와 container 관리 간편화어떤 서비스를 돌리기 위해서는 필요한 서버들이 있습니다. 데이터베이스 서버, 웹 서버, 캐시 서버, 워커 서버 따위의 것들이죠. 이 모든 걸 한 군데로 퉁쳐서 모을 수도 있겠지만 그렇게 되면 데이터베이스, 웹, 캐시, 비동기 업무를 위한 설정과 프로그램들을 한 군데로 모아 관리해야 합니다. 그렇게 되면 설정이 복잡해지거나 애플리케이션이 거대해지거나 필요할 때 횡적인 확장을 하기가 어려워집니다.예를 들어 웹서버에서는 A라는 라이브러리의 1버전을 필요로 하는데 데이터베이스 서버에서는 2버전을 필요로 한다던지, 이벤트 하느라 접속자가 너무 증가했는데 다른 웹서버가 한시간 정도만 필요한 일을 그럴 수 없어서 서버를 통째로 하나 사야 한다던지 하는 일들이죠. docker는 그런 상황에 유연하게 대응하기 위해 서버 설정과 필요한 프로그램들을 따로 관리할 수 있는 환경을 제공합니다.docker는 이렇게 분리된 환경을 image라고 부르며, 이 image를 기반으로 여러 개의 container를 생성할 수 있습니다. 음… 이렇게 이해하시면 편할 것 같습니다. image는 유전자 설계도고, container는 그 유전자 지도에서 만들어진 생물체라고나 할까?즉, 이 설계도를 관리하면 필요할 때 목적에 적합하게 만들어진 생물체를 얼마든지 만들어낼 수 있게 되죠. 필요할 때는 설계도의 설계를 바꿔서 새로운 생물체를 만들어낼 수도 있습니다. 단순하지만 docker의 가장 커다란 컨셉이고 강력하기까지 합니다. 이렇게 단순하고 간편한 환경은 여러 가지 시도를 가능하게 합니다.오토스케일링(웹서버가 필요할 때 웹서버를 막 찍어낸다던가!)유연한 배포 정책(서버를 최신 버전으로 업데이트했는데 버그가 있어서 재빨리 옛날 버전으로 돌아가야 한다던가!)자원의 효율적인 활용(이 쪽 서버가 놀고 있으니까 여긴 웹서버 두개 정도 더 띄운다던지)거기다 수고를 좀 더 들이면, docker의 API를 활용해 Heroku 부럽지 않은 웹 GUI PaaS 서비스를 만들 수 있을지도 모릅니다(만들어 주시면 감사히 쓰겠습니다).한번 docker를 살펴봅시다이야기는 실컷 했으니 한번 설치해보고 실행시켜봅시다. 지면 관계상 모든 플랫폼을 다룰 수는 없기에 우분투 13.10을 기준으로 살펴보도록 하겠습니다. 필요하신 분들은 공식 홈페이지 설치 메뉴얼을 참고하여 진행해주세요.주의 : 이후 내용은 비 개발자 분들에게는 다소 지루한 내용일 수도 있습니다.docker 설치curl http://get.docker.io | sudo sh 참 쉽죠?자 이제 시작이야이제 여러분의 플랫폼에는 docker가 설치됐습니다. 한번 서버에서 기본 이미지를 다운받아 설치해 봅시다.sudo docker pull base 인터넷 환경에 따라 좀 기다리셔야 하실지도 모릅니다. 이미지가 설치되면 아래 명령으로 확인할 수 있습니다.sudo docker images 아래와 비슷한 화면이 나타났다면 성공한 겁니다.REPOSITORY TAG IMAGE ID CREATED SIZE base latest b750fe79269d 8 months ago 24.65 kB (virtual 180.1 MB) base ubuntu-12.10 b750fe79269d 8 months ago 24.65 kB (virtual 180.1 MB) …(생략) 이렇게 내려받은 image에는 다음과 같은 명령어로 접근할 수 있습니다.sudo docker run -i -t base /bin/bash 자세한 명령어 사양은 docker help run을 실행해 알아볼 수 있습니다. 여러분은 이제 base라는 image에 접속했습니다. 지금부터 하는 행동은 image에 영향을 미치게 되며, 이는 전부 로그로 남아 저장됩니다. 한번 이것저것 설치해봅시다.sudo apt-get install python ruby … 이후에 Ctrl+D를 눌러 이미지를 빠져나옵니다. 그리고 아래 명령을 입력하면 방금 전에 수정한 container 목록이 출력됩니다.sudo docker ps -a 아래와 같은 식으로 출력됩니다.CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES eda0060b7af9 base:latest /bin/bash 6 minutes ago Exit 0 lavender_deer 66c849867834 busybox:latest echo Docker has been 8 minutes ago Exit 0 blue_cat 이제 image의 수정사항을 기반으로 새로운 이미지를 만들어 봅시다. 이미지를 만드려면 변경사항을 commit 해야 합니다. VCS나 DVCS를 쓰시는 분이라면 무슨 말인지 감이 오실 겁니다. 네, 바로 버전 관리 시스템의 그것입니다. 기존 base를 기반으로 변경사항을 만들고 commit하여 새로운 이미지를 생성할 수 있습니다. 매우 쉽군요. 한번 생성해봅시다.docker commit [ID] [image name] commit 명령의 구조는 단순합니다. container ID와 그리고 만들 이미지 이름입니다. 이미지 이름은 보통은 만든이/목적 같은 컨벤션으로 만들곤 합니다. 저는 아래와 같이 만들어보겠습니다.sudo docker commit eda0060b7af9 xymz/grocery 확인은 당연히 아래와 같이 할 수 있습니다.sudo docker images repository 에서 여러분이 만든 이미지 이름을 확인할 수 있다면 성공한 겁니다. 여러분의 첫 docker image 생성을 축하합니다!물론 이렇게 약간 거칠어보이는 방법과는 다르게 Dockerfile 이라고, 딱 봐도 버전관리 시스템에 넣을 수 있을 거 같고 정리가 잘 되는 방법도 존재합니다. 아마도 실제로 사용하실 땐 Dockerfile을 사용하게 되실 거고, 그 방법이 훨씬 낫습니다. 다만 본 포스트의 목적은 개발자나 비개발자 분들에게 docker를 한번 소개해보자는 취지라서 Dockerfile의 operation 을 일일히 설명하기엔 얘기가 너무 복잡해질 것 같아 직접 try-out 하기에 쉬운 commandline 쪽을 선택하게 되었습니다.당연히 이게 끝은 아닙니다여기까지 나온 내용으로 서비스를 구성하기에는 무리가 있습니다. 우리는 이제 막 docker image를 생성하고 저장하는 방법을 알았을 뿐이지 그 외에는 아무것도 모릅니다. docker를 제대로 사용하기 위해서는 아래와 같은 방법들을 추가적으로 알아야 합니다.생성된 이미지 관리 : 새로 만든 이미지를 어딘가에 업로드하여 다른 docker 시스템(host)에 배포하기 위한 방법에 대해 알아야 합니다.실제 서비스를 container 에 올리고 관리하는 방법 : 아까 언급한 것처럼 예시를 들자면, 현재 서버에서 웹서버를 를 몇개나 띄울 건지 등을 결정하고 관리하는 방법에 대해 알아야 힙니다.docker host와 guest간의 통신 관리 : docker가 설치된 실제 서버와 그 위에서 돌아가는 container들 간에 오가는 통신에 대한 이해가 필요합니다. 포트 바인딩, 포트포워딩이라고도 하죠.docker API : 이 모든 스택을 관리하기 위한 docker의 API를 알고 있다면 무한한 활용이 가능해집니다.하지만 이 방법들에 대해 여기서 다 열거하고 넘어가기에는 무리가 있으니 좋은 링크를 몇 개 소개토록 하겠습니다.파이썬 웹앱 올려보기docker를 개발환경으로 사용해보기Dockerfile 로 image 관리하기포트 리다이렉션적어놓고 보니 대부분 docker 공식 홈페이지 자료들이네요. 사실 docker는 documentation이 훌륭한 편이라, 그 쪽만 참고해도 많은 도움이 되실 겁니다.Deis?그리고 이 모든걸 쉽게 해주겠다는 Deis라는 녀석이 있습니다. Docker, Chef, Heroku Buildpacks를 이용해 하나의 PaaS스택을 만들고 그 위에 여러분의 서비스를 돌릴 수 있도록 해주겠다는 녀석인데요. 어쩌면 진정한 Open source PaaS 종결자일지도 모르겠습니다. 기회가 된다면 다음에 또 소개할 수 있었으면 좋겠네요.마치기 전에즐거우셨나요? 중간 이후 내용은 다소 비개발자분들에게 지루한 내용이었을지도 모르겠습니다만, 전반적으로 최대한 쉽게 설명하고자 노력했습니다. 다음 번에는 더욱 재밌는 글로 찾아볼 수 있도록 하겠습니다. 그럼 뿅!참고한 링크들docker.ioUsing Docker as a Development EnvironmentDocker: Error starting container: Unable to load the AUFS module주석사실 API는 거창한 기술적 개념이라기보단, 소소한 개발 방법론에 가까운 이야기입니다. 온갖 프로그래밍 언어와 다양한 기술들이 난립하는 와중에 그 모든 걸 알고 전부 뭉쳐서 하나의 덩어리를 만들면 관리/사용하는 비용이 너무 커지니 각 영역을 딱딱 잘라 구분하여 ‘정해진 규약’만 알면 서로 통할 수 있게 만들자. 라는 개념입니다.(약간의 지식이 있는 분들을 위해) LXC(LinuX Containers)는 기존 전가상화full virtualization나 반가상화paravirtualization와는 다르게 OS 위에 가상머신이 따로 돌아가는 게 아니라 OS영역에서 공유 라이브러리를 가지고 유저가 생성하는 프로세스 단위로 성능 분리를 합니다. 덕분에 이름에서 보이듯 특정 플랫폼밖에 지원을 하지 않는다는 단점이 있네요. 그래도 가상화에 따른 자원 손실이 최소화된다는 점에서 많이들 선호하고 있습니다. Heroku에서도 LXC를 통해 가상화를 하고 있죠.보통 이렇게 자신들의 플랫폼을 오픈소스로 공개하는 이유는 단순히 사회에 기여하기 위해서도 있지만, 사내에서 사용되는 기술의 수준을 오픈 소스 커뮤니티의 참여를 통해 향상시키고, 또 좋은 개발자들을 리크루팅 할 수 있게 되는 기회를 만드는 등 선순환을 유도하기 위해서입니다. 그러니까 여러분도 사내에서 사용하는 기술을 공개해 주시면 누이 좋고 매부 좋은 일이라 할 수 있죠.이 글은 __저의 개인 텀블러__에서도 찾아볼 수 있습니다.#스포카 #개발 #개발자 #개발팀 #인사이트 #Docker #클라우드 #꿀팁

기업문화 엿볼 때, 더팀스

로그인

/