스토리 홈

인터뷰

피드

뉴스

조회수 950

AI 스쿨 필기 노트 ① 선형회귀분석(Linear Regression)

전세계가 AI first를 외치고 있습니다! 엘리스 인공지능 오프라인 교육과정인 AI 스쿨의 필기노트를 8주간 연재합니다. 인공지능 개론과 알고리즘에 대해 함께 공부해요.지난 5월 8일 구글의 연례 개발자 콘퍼런스 I/O에서 구글은 구글 듀플렉스라는 새로운 AI 기술을 선보였습니다. 구글 듀플렉스가 직접 미용실에 전화를 걸어서 예약에 성공하는 이 시연은 매우 인상적인 장면이었는데요. 국내의 여러 기업에서도 이미 인공지능 스피커를 출시하는 등 우리의 일상 생활 곳곳에도 인공지능 기술이 스며들고 있습니다.IDC, Tractica, Markets and Markets 등 글로벌 시장조사기관들은 2020년까지 세계 인공지능 시장이 연평균 50% 이상 가파르게 성장할 것이라고 예측하기도 합니다. 이미 세계 각국의 주요 IT 기업들은 AI 시장에서 영역을 넓히고 경쟁력을 확보하고자 전력을 투입하고 있는데요. 국내 기업들 역시 인수합병과 조직개편 등으로 인공지능 기술과 인재 확보를 위해 발 빠르게 움직이고 있습니다.엘리스에서는 IT 분야 및 연구 기관에 취업하고자 하는 분들을 위한 오프라인 교육과정을 운영하고 있습니다. 지난해에 이어 올해에는 양재 RNCD 혁신허브와 함께 인공지능 R&D 실무자 양성과정을 운영하게 되었는데요! 이론 수업(8주)과 팀 프로젝트(6주), 커리어 코칭 과정(2주)로 이루어진 이번 과정은 수료증 및 입사 추천서 발급, 테크니컬 인터뷰와 포트폴리오 준비, 국내 IT 기업과의 채용 연계 등으로 구성되어 있어 관련 분야에 취업을 희망하시는 분들의 많은 관심이 있었습니다.300명 가까운 분들이 지원해주셨고, 이 중 선발 과정을 거친 40여 명의 분들이 16주간 오프라인+온라인 교육을 받게 되었습니다. 이 중 기계학습과 알고리즘 개론에 대한 8주간의 교육 내용을 앞으로 8주간 여러분과 함께 공유하고자 합니다. 컴퓨터 공학과에 재학 중인 AI 스쿨 수강생이 직접 필기노트를 공유해 준다고 하니 함께 AI 개론에 대해서 공부해 봐요. :)안녕하세요! 저는 숭실대학교 컴퓨터학부 4학년에 재학 중인 대학생이에요. 저는 평소에 AI에 대해 관심이 많아서 제대로 된 교육을 받고 싶어서 이번 과정을 수강하게 되었어요. 앞으로 AI 스쿨에서 받는 수업이 제가 AI 엔지니어로 성장할 수 있는 밑거름이 될 것이라고 생각해요. 아직 배우는 단계이기 때문에 많이 부족하지만 앞으로 8주 동안 이 글을 통해서 함께 공부한다고 생각하며 그 주에 배운 내용을 요약해보려고 합니다!AI 스쿨 첫 수업에서는 ‘Linear Regression(선형 회귀)’에 대해 배웠어요. 대학교 2학년 때 전공 과목으로 ‘선형대수학’이 있었는데요, 배우면서 이런 학문은 도대체 어디에 쓰이는지 혹시 필요 없는 것을 배우느라 시간 낭비를 하는 것은 아닌지 힘들게 공부했던 기억이 나네요. 그런데 제가 읽은 한 기사에서 미국의 연구팀이 ‘장기적인 공기 정화 노력이 성장기 아이들의 폐기능을 개선시켰다’는 연구 결과를 증명한 후 캘리포니아 남부지역에서 ‘공기오염의 질 관리 정책’을 시행하여 오염 수준이 꾸준히 감소하고 있다는 내용이 있었는데요. 연구팀은 공기오염의 감소와 소아 호흡기 질환의 개선 사이에 개연성을 평가했고 이 연구에서 사용한 방법이 선형회귀분석(linear regression model)이라고 해요!첫 수업에서는 앤드류 응 교수님 강의 자료의 쉬운 예시를 바탕으로 Linear Regression(선형회귀)을 공부했어요.이 예시에서는 집 크기에 관한 정보 하나로 집의 가격을 예측하는 할 수 있는 데이터가 있다는 가정을 하고, 이 가정이 직선의 방정식 y = ax + b의 형태를 따른다고 가정했어요.인공지능은 예측을 기본으로 다루는데, 우리는 과거의 데이터를 학습함으로써 최적의 예측 모델을 만들게 돼요.이때 다루는 데이터를 Training set이라고 부르고, m은 학습 데이터의 숫자, x는 입력 변수 또는 feature, 그리고 y는 출력 변수 또는 타깃 변수라고 불러요.기존의 Training set으로 Learning 알고리즘을 학습시키면 그 학습된 부분이 h, 즉 가설이 돼요. h를 통해서 우리는 어떠한 집 크기에 대한 예측된 가격을 구할 수 있어요. 그런데 이때 보다 정확히 예측을 하려면 error를 최소로 하는 a, b의 최적의 값을 설정해야 해요.우리의 모델인 직선의 방정식을 통해 오차가 적은 예측값을 얻기 위해서는 a와 b에 어떠한 값을 넣어야 좋을까요? 위에서 언급했듯이 우리에게는 주어진 학습 데이터가 있죠. 이를 이용하여 최적의 값을 도출해야 해요. Cost function 이란 a, b가 주어진 학습 데이터인 Training set을 가장 적은 오차로 표현하고 있는지 알 수 있는 방법인데요. Loss function 또는 Objective function이라고도 해요. Linear Regression에서는 Cost function으로 Squared error function을 사용해요. Squared error function 이란 가설에 Training data의 입력값을 넣었을 때의 출력값과 해당 입력값에 대한 training data의 실제 출력값의 차를 제곱하여 이용하는 방법이에요.그렇다면 우리는 a, b를 어떻게 구할 수 있을까요? 이 방법을 산을 내려가는 예시를 통해서 쉽게 이해할 수 있었어요.만약 깜깜한 밤에 산꼭대기에서 길을 잃었다면 랜턴을 키고 주변을 살펴본 후 아래로 내려가는 길을 찾아 그 방향으로 내려가고, 도달한 지점에서 또다시 랜턴을 켜 주변을 살펴 아래로 향하는 길로 가야 산 아래까지 내려갈 수 있겠죠. 이것이 최적의 a, b를 구하는 Gradient descent의 기본 방식이에요.Gradient descent는 임의의 a, b를 지정한 후, 그 점으로부터 감소하는 기울기를 구간을 찾아 이동하는 것을 반복함으로써 해를 구하는 방법입니다!이번 주 수업의 과제로는 Loss Function과 Linear Regression을 구하는 과제가 주어졌어요. 첫 번째 과제인 만큼 난이도가 많이 높지는 않았지만 파이썬이 익숙하지 않다면 조금 헷갈릴 여지가 있는 문제였던 것 같아요. 강의를 해주신 주재걸 교수님께서는 첫 시간에 배운 개념들이 Linear regression에서 뿐만 아니라 인공지능, 머신 러닝, 딥러닝 분야에서 많이 쓰이기 때문에 첫 시간에 배운 것만 제대로 이해하고 가도 많은 것을 얻어 가는 것이라고 하셨어요. 위의 개념에 대해서 다른 자료들도 찾아보면서 공부하고, 다음 필기 노트로 만나요!#엘리스 #코딩교육 #교육기업 #기업문화 #조직문화 #서비스소개
조회수 936

Culturalization of Video Game Soundtracks: An Interview with Pierre Langer, Managing Director & Founder of Dynamedion

 Game culturalization, the process of cultural adaption, is the key to successfully launching video games in foreign markets. The main aspects are to make content suitable, understandable, and meaningful for the gamers of the targeted markets. To achieve these objectives, it is necessary to look into the five central pillars of culturalization: history, religion, ethnic and cultural tensions, geopolitical situations, and in-game elements.One in-game element that must be considered is music. To learn more, we interviewed the video game music expert and composer Pierre Langer, founder and managing director of Dynamedion based in Mainz, Germany. Pierre will tell us more about his internationally renowned company, the video game music business, and the culturalization process of video game soundtracks.  Pierre Langer  Dear Pierre, please let us know more about you and your company and the key services that you provide.  Pierre Langer: Dynamedion was founded by Tilman Sillescu and me in early 2000. We started with work-for-hire audio in the German games industry doing music composition, sound design and later also interactive audio integration and Live Orchestra production. We were the first to produce with live orchestra for a German game, and we eventually rolled this out as a service for other composers and game developers all over the world.Today we are one of the biggest game audio studios in the world with nearly 50 people doing music composition, music licensing, sound design, source sound recordings, audio integration, audio software development, live orchestra and live choir recording, and orchestration and arrangement for all sorts of media. We are still very much focused on video games, having worked on more than 1,800 games, but we also do a lot of movie trailers, TV series, and films.In 2009 we started a sub company of Dynamedion called BOOM library, which produces original sound effects collections as products that can be licensed by audio professionals throughout the world. BOOM Library is today recognized as one of the most popular and high-quality sound effects libraries in the world. Apart from that we also run two side labels with royalty-free stock music in a unique adaptive format (SmartSound) and a new product line of virtual software instruments (SONUSCORE). Our latest addition to our services is that we have become well known for high end vehicle recordings (cars, airplanes, helicopters, bikes, tanks, etc.) – that is a lot of fun, but also a huge challenge to source all sorts of rare or weird or super expensive vehicles.So, in short: we are specialists for everything that has to do with music & sound for games – everything except voice overs, and our music or sound effects or live productions have been used and heard in nearly every large game worldwide. As an example, we recently have been involved in these titles: Assassin’s Creed Series, Elder Scrolls Online, Monster Hunter Online, Battlefield V, League of Legends, Destiny 1 & 2, Lineage II, Horizon Zero Dawn, Fortnite, Mortal Kombat Series, World of Tanks, Hitman Series, Total War Series.Currently we are working on five super large unannounced titles, all international.  What part of the world do your requests mainly come from?  Pierre Langer: It is very international, really. Up until 2009 we had a very strong (overly strong I would say) position in Germany, working on nearly every German game title, quite some in France and some occasional overseas projects. Meanwhile this has completely changed: we are doing a good amount of German titles, but the major part comes from the US, UK, Scandinavia, Japan, Korea and China – China being one of the most important markets now.  Have you experienced a shift or a change over the years in game creation from Western countries to an international mix?  Pierre Langer: Absolutely! It seems that the five big “individual” markets (North America, Europe, China, Japan / Korea) are getting closer to each other. Even very self-sustaining markets, like the Japanese market, are opening up for more international projects coming in, but they are also looking into getting their own games distributed internationally, and of course into becoming as successful as possible worldwide. And then there is a huge amount of projects coming from all the emerging markets, so it seems that there is really no end to a lot of new great games. The biggest challenge with a new game certainly is to make yourself “heard” or do something special that your competition does not do, in order to stand out in a new market.  Orchestral Session - Dynamedion  What is culturalization in terms of video game soundtracks and sound effect production?  Pierre Langer: It is actually a very straightforward thing and kind of a no-brainer, since audio is a rather inexpensive asset for a game, while it has a huge emotional and atmospheric impact. Culturalization of a game means that you adapt the game to the specific requests of a new market. Western world audiences are used to different things than Chinese players, for example. So, if a Chinese game developer wants to push a game into the Western market, the game should be “westernized” so to say. This certainly already happens with gameplay mechanics and with graphics and – of course – with the localization. But simply changing the texts and voice over from Chinese to English doesn’t adapt a Chinese game to an EU or US audience. The look and feel of a game need to change as well, and this is where music and sound “culturalization” comes in: adapting the music and sounds (and the way of implementation and audio functionality in the game) to the specific audience that is being targeted. This does of course work in all directions – Japan to China, China to Europe, Europe to Korea, etc.  Can you give us some examples of audio culturalization in specific markets? (E.g. MENA, South America, China/Asia)  Pierre Langer: Let me go back a few years, to our very first larger game title we did music and sound culturalization for. It was “Runes of Magic” by Runewaker Entertainment, a developer based in Taiwan. The game was not extremely successful in Taiwan and Mainland China, but a German publisher by the time (Frogster) saw some great potential in that game. So, they licensed the title and got the rights to publish it in Europe and the US. In some respects, the game was a mess for a Western audience, partly due to the music and the sound + the implementation of all audio. The marketing people at Frogster understood this very quickly and started working on all these issues. The music and sound side was done in a matter of a few weeks: they asked us to replace the soundtrack by using music we had in our back catalogue (music for games that we had written, that either failed, or that had been unsuccessful – which we kept the rights to) and write a few new themes that would work as the iconic main themes of the game, so that the audience has something new and recognizable. We did that, with a full focus on writing and licensing music that would be ideal for the target audience. Then we did a similar thing with the sound effects: we simply threw out all the stuff that was in there and replaced it with sounds that where produced to fit a Western audience. To give you a very quick example: Asian players are used to high frequency sounds, very aggressive, very loud, the whole sound atmosphere being very crowded. European and US players are used to low frequency sounds – sub-bass, deep impacts, rumbling and more focused sound design (you hear one thing prominently, and everything else gets balanced down to make space for the one important sound going on). This is a very clear and super important difference – and it is also easy to fix with some new content and some new mixing.  What are typical issues that occur in sound culturalization?  Pierre Langer: Typical issues are that there needs to be some trust from the developer to the sound team. In most cases, the developer asks for culturalization from their home market to a foreign market. So, a US developer asking us to adapt the sound to fit a Chinese audience better needs to trust us that we know what we are doing, since the US developer doesn’t know themselves (otherwise they wouldn’t need us). Then there is always a big challenge with the correct audio integration. The most important bit is certainly to replace music and sound effects, to get a fitting new set of assets for the target market. However, even the best assets do not help if they are poorly integrated. Simply swapping them is not enough if the way they are being played back is not fitting. This then needs some more time and attention and focus, since we need to work with the developer directly to e.g. add some audio functionality, balance mix and master the audio, or introduce an interactive music system. It can be a very elaborate thing, but you can achieve a lot of additional quality with the most basic strategies that only cost a lower 5 digit budget.  Dear Pierre, thank you for your time and effort in providing us such enlightening insights into your work!About Pierre:Pierre was born near Frankfurt / Germany. After years of playing in bands as a guitar player in his teens, he decided to take his studies in classical music at the Johannes Gutenberg University in Mainz..A few months before his final exams he met Tilman Sillescu in early 2000, Dynamedion was founded a few weeks later. In the first years of Dynamedion Pierre worked on basically every single bit of the job you can do as an audio person in the games business: music composition, sound design, audio integration, audio management, design of audio tool chains, recording, mixing, mastering, project management, etc.As the thing grew and all the other guys joined in, Pierre focused more and more on the business side of things, leaving the creative work to the really focused experts.Nowadays Pierre enjoys keeping in touch with all the different clients of Dynamedion, thinking up new product lines and business ideas to further expand the reach and prominence of Dynamedion and all related sub-labels such as BOOM Library, Sonic Liberty, Sonuscore... and more to come.The Interview was conducted by Moritz Demmig. 
조회수 1024

Node.js 이해하기

Understanding node.js 글을 번역한 글입니다. 부족한 영어 실력이지만 공부를 위해 번역하여 틀린 내용이 있을 수 있습니다. 이런 부분이 있을 경우 댓글로 알려주시면 감사하겠습니다!! 글이 문답형으로 진행되니 감안하시고 읽어주세요!Node.js(이후 '노드'로 통칭)를 소개했을 때 사람들은 일반적으로 두 가지 반응을 보인다. 바로 알았다고 하는 반응 혹은 매우 혼란스러워 하는 반응이다.만약 너가 후자의 경우라면 노드를 설명하기 위한 내 시도가 있다.노드는 command line tool이다. 너는 파일을 다운로드하고 컴파일하고 소스를 설치한다.노드는 JavaScript(이후 '자바스크립트'로 통칭) 프로그램들을 터미널에 'node my_app.js'를 입력함으로써 실행하게 한다.자바스크립트는 V8 자바스크립트 엔진으로 실행된다. (구글 크롬을 빠르게 만드는 것이다.)노드는 네트워크와 파일 시스템에 접근하기 위한 자바스크립트 API를 제공한다.나는 내가 필요한 모든 것을 Ruby, Python, PHP, Java에서 구현할 수 있어!너의 말이 맞다! 미안하게도 노드는 너를 위해 오고 너의 일을 하는 별난 유니콘이 아니다. 이것은 단지 툴이고 적어도 지금은 너가 보통 사용하는 완벽한 툴들을 대체하지 않을 것이다.요점을 알려줘!ㅇㅋ. 기본적으로 노드는 같은 시간에 여러 가지의 일들을 해야할 때 매우 좋다. 코드를 작성하고 "나는 이것들이 동시에 작동했으면 좋겠어"라고 말해본 적 있니? 노드에서는 너의 코드를 제외한 모든 것들이 동시에 작동한다.엥??정말이다. 너의 코드를 제외한 모든 것들이 동시에 작동한다. 이것을 이해하기 위해 너의 코드는 왕이고 노드는 왕의 하인들이라고 상상해보자.한 하인이 왕을 깨워 왕이 필요한 것들이 있는지 물어보는 것으로 하루가 시작된다. 왕은 하인들에게 해야할 일 목록을 주고 다시 오랫동안 자러 간다. 하인은 이 할 일들을 동료들에게 나눠주고 그들은 일을 시작한다.하인이 일을 끝내면 그는 왕의 쿼터 밖으로 보고서를 나열한다. 왕은 한 하인씩 따로따로 들여보내고 그들의 보고서를 듣는다. 때때로 왕은 나가는 길에 하인에게 더 많은 일을 준다.인생은 좋다. 왕의 하인들이 동시에 왕의 모든 일들을 수행하는 동안 왕은 하나의 결과가 있는 보고서에만 따로따로 집중할 수 있다.짱이다! 하지만 그 어리석은 비유를 그만두고 컴퓨터적으로 말해줄 수 있니?ㅇㅋ. 간단한 노드 프로그램은 아래와 같을 것이다:너의 코드는 노드에게 파일을 읽고 쓰는 두가지 일을 주고 자러 간다. 노드가 일을 완료했을 때 이것을 위한 콜백이 실행된다. 하지만 그들은 동시에 실행되는 콜백이 될뿐이다. 콜백이 실행을 완료하는 동안까지 다른 모든 콜백들은 라인에서 멈춰있어야 한다. 게다가 그 콜백들이 실행될 것이라는 보장도 없다.그래서 나는 동시에 같은 데이터 구조에 접근하는 코드에 관해 걱정할 필요가 없지않아?맞다! 그것이 자바스크립트의 싱글 쓰레드와 이벤트 루프 디자인의 아름다움이다. 좋긴 하지만 내가 왜 노드를 써야해?한 가지 이유는 효율성이다. 웹 어플리케이션에서 너의 메인 응답 시간 비용은 대개 너의 모든 데이터베이스 쿼리들이 실행하는데 전력하는 시간들의 합이다. 노드에서는 제일 느린 쿼리를 실행하는 동안 응답시간을 줄이기 위해 너의 모든 쿼리를 즉시 실행한다.또 다른 이유는 자바스크립트다. 너는 노드를 브라우저와 백엔드 사이에서 코드를 공유하기 위해 사용할 수 잇다. 자바스크립트는 정말 다방면성의 언어다. 너가 과거에Python, Ruby, Java, PHP를 써왔다하더라도 아마도 어떤 자바스크립트를 선택해왔을 것이다.마지막 이유는 로우 스피드다. V8은 계속해서 행성에서 가장 빠른 동적 언어 인터프리터의 하나로 경계를 밀고 있다. 나는 자바스크립트만큼 적극적으로 속도를 위해 푸시되는 다른 언어를 생각할 수 없다. 게다가 노드의 I/O 설비는 정말 가볍고 너의 시스템의 가능한 많은 I/O 능력을 활용하게 다가가는 것이다.그러면 너는 내가 당장 내 모든 앱을 노드에서 구현하라고 말하는거야?그렇기도 하고 아니기도 하다. 너가 노드 망치를 휘두르기 시작하면 모든것들은 분명 손톱처럼 보이기 시작할 것이다. 하지만 만약 너가 데드라인이 있는 일을 한다면 너는 아래의 사항들을 기초하여 결정하고 싶을 수도 있다.- 적은 응답 시간과 높은 동시성이 중요한가? 노드는 이것에 정말 좋다.- 프로젝트가 얼마나 큰가? 작은 프로젝트는 괜찮다. 큰 프로젝트는 아마 신중하게 평가해야 한다. (이용가능한 라이브러리, 버그를 고치기 위한 리소스들, 투 업스트림 등)윈도우에서 노드가 실행되니?안된다. 만약 너가 윈도우라면 너는 리눅스와 함께 버츄얼 머신을 실행해야 한다. (VirtualBox를 추천한다.) 윈도우는 노드를 지원하는 계획이 있지만 그 포트와 함께 도와주기를 원하지 않는다면 앞으로 몇 달 동안 뜸들이지 마라.노드에서 DOM에 접근할 수 있니?좋은 질문이다! 접근할 수 없다. DOM는 물질적인 브라우저고 노드의 자바스크립트 엔진(V8)은 감사하게도 그 복잡한 모든것들과 분리했다. 그러나 사람들은 노드 모듈로써 DOM를 실행하여 일한다. 이것은 클라이언트 사이드 코드 유닛 테스트와 같은 매우 놀라온 가능성을 열어줄 것 같다. 이벤트 드리븐 프로그래밍은 어렵지 않니?그것은 너에게 달렸다. 만약 너가 juggle AJAX를 호출하는 방법과 브라우저에서 유저 이벤트들에 대해 이미 배웠다면 노드 사용 방법을 배우는게 큰 문제 아닐 것이다.그렇지 않다면 너가 유지 보수 디자인을 마련하는데 도움을 줄 수 있는 드리븐 개발을 테스트해라.노드는 누가 사용하고 있니?node wiki에 작고 불안정한 리스트가 있다. 야후는 YUI를 위해 노드를 경험중이고 Plurk는 거대한 comet을 위해 사용중고 Paul Bakaus(jQuery UI fame)은 노드 백엔드를 가지는 mind-blowing game engine을 빌드 중이다. Joyent는 노드 창시자인 Ryan Dahi를 고용하여 개발에 막대한 지원을 해주고 있다.아 그리고 Heroku는 실험적으로 hosting support for node.js를 발표했다.어디서 더 배울수 있니?Tim Caswell는 훌륭한 How To Node 블로그를 운영중이다. 트위터에서 #nodejs를 팔로우해라. 메일링 리스트를 구독해라. 그리고 IRC 채널 #node.js에서 시간을 보내라. 우리는 곧 200 lurker-mark에 도달해 간다. 또한 나는 계속 http://debuggable.com/에 글을 쓰고 있다. #트레바리 #개발자 #안드로이드 #앱개발 #Node.js #백엔드 #인사이트 #경험공유
조회수 1776

Infrastructure dashboard

와탭랩스는 IT 서비스를 운영하는 개발팀과 운영팀에 도움이 되는 솔루션과 서비스를 만드는 스타트업입니다. IT 서비스를 잘 운영하게 위해서는 Infrastructure의 전반적인 상황을 항시 체크할 수 있어야 하는데요. 이런 기능을 하는 대표적인 화면이 대시보드 입니다. 최근 와탭랩스는 Infrastructure 모니터링 서비스에 대시보드를 넣는 작업을 진행하고 있는데요. 와탭랩스는 대시보드를 통해 Infrastructure를 운영하는 개발팀과 운영팀에 어떻게 도움을 줄 수 있도록 할 것인지 소개하겠습니다. 1. IT 서비스 운영에 사용된 인프라 자산 현황을 알아보자지금 회사에서 사용하는 서버의 대수를 알고 계신가요? 현재 동작하는 서버는 몇대인지 혹시 죽어있는 서버가 있는지 등에 대한 정보는 운영팀에서 항상 체크하는 정보입니다. 하지만 개발팀에서는 잘 모르는 정보이기도 하죠. 이런 기본적인 정보가 대시보드에 나온다면 평소 서비스를 운영하는 감을 잡는데 도움이 됩니다. 이런 정보들은 간략한 수치로도 표현할 수 있는데요. 우리는 아래와 같은 데이터를 수집할 수 있습니다. 서버 기본 정보 (inactive servers / all servers)우리가 사용하는 총 서버의 수자와 비활성화된 서버의 숫자는 우리가 항상 알고 있어야 하는 정보입니다.운영체계별 서버 정보 (Linux / Windows / Unix)운영체계를 섞어 사용하는 경우에는 운영체계에 따라프로젝트가 나눠지기도 합니다. 그렇기 때문에 운영체계별로 서버의 총량과 비활성화된 서버 정보를 알면 도움이 됩니다. 프로세스 수프로젝트의 프로세스 수는 일정한 경우가 많습니다. 전체 프로세스의 숫자가 변경된다면 서비스의 운영 상황에 대해 의문을 가져야 합니다. 이벤트 개수24시간동안 발생한 전체 이벤트의 개수와 아직 해결하지 못한 이벤트의 개수를 보여줍니다. 하루동안 얼마나 많은 이벤트가 발생하는지 그리고 아직 해결하지 못한 이벤트가 있는지 알수 있습니다. 디스크 사용량/전체 용량디스크 사용량은 일반적으로 큰 변화를 가지지 않습니다. 디스크 사용량이 평소와 다르다면 서비스의 장애가 발생했거나 발생할 가능성이 높습니다. 메모리 사용량 / 전체 용량메모리 사용량은 일반적으로 큰 변화를 가지지 않습니다. 메모리 사용량이 평소와 다르다면 서비스의 장애가 발생했거나 발생할 가능성이 높습니다. 수치 데이터의 예 2. 서비스를 구성하는 인프라의 CPU 흐름 전체를 알아보자 CPU 사용량은 변화량이 많은 지표입니다. 변화량을 비교하는 챠트로는 라인 차트가 가장 많이 쓰이지만 라인 차트는 개수가 많아지면 전체 상황이 보이지 않는 문제점을 가지고 있습니다. 또한 실시간으로 추가되거나 삭제되는 인프라가 생기는 클라우드 인프라 상황에서 라인챠트는 표현의 한계를 가지고 있기도 합니다. 이런 문제를 해결하기 위한 방법으로 아래와 같은 온도 차트를 사용할 수 있습니다. 온도 차트는 단위 영역에 밀도에 따라 색상으로 깊이를 표현하는 방식입니다. 최근 많은 양의 데이터를 표현하는 방식으로 많이 사용되고 있습니다. 온도 차트의 예3. 경고가 발생했는지 또는 해결 되었는지 알고 싶다.  CPU 사용량이 설정치 이상으로 높아지거나 디스크 사용량이 높아지거나 프로세스가 사라지는 등 다양한 상황에 대한 이벤트가 발생할 수 있습니다 이런 상황을 쉽게 확인할 수 있다면 서비스 운영 상황에 도움이 됩니다. 이벤트 관리의 예이런 스토리를 기반으로 와탭랩스에서 대시보드를 기획하고 있습니다. 개발자와 디자이너가 함께 토론하고 논의하면서 화면과 스토리를 더 다듬게 되면 첫번째 화면이 나올 예정입니다. 아래는 기획과정에서 나온 화면 리소스 입니다. 아직 기획 단계이기는 하나 첫번째 대시보드가 완성되면 이 페이지가 메인으로 올라갈 예정입니다. 대시보드는 데이타의 종류와 위치등을 수정할 수 있으면 좋지만 우선은 고정형으로 개발하여 제공할 예정입니다. 이번 대시보드는 서비스 첫번째 의미가 강한 메인 화면의 성격에 더 초점을 맞추고 있습니다. 아직 몇몇 논의되는 사항이 많은 화면이지만 빠르게 개발하여 가능한 이른 시일에 소개드리도록 하겠습니다. #와탭랩스 #개발자 #개발팀 #인사이트 #경험공유 #일지
조회수 8300

Node.js로 Amazon DynamoDB 사용하기

DynamoDB 로컬 설정 (다운로드 버전)실제 DynamoDB 웹 서비스에 액세스하지 않고 로컬에서 애플리케이션 작성 및 테스트를 할 수 있음1. 다운로드 링크에서 DynamoDB 무료 다운로드2. 압축 해제 후 해당 디렉터리에서 아래의 명령어로 실행java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb* Ctrl+C로 중지할 수 있고 중지하기 전까지 수신 요청을 처리함* 기본적으로 8000번 포트를 사용Node.js 용 AWS SDK 설치1. 설치npm install aws-sdk2. 실행// app.jsvar AWS = require("aws-sdk");var s3 = new AWS.S3();// 버킷 이름은 모든 S3 사용자에게 고유한 것이어야 합니다.var myBucket = "dynamodb.sample.wonny";var myKey = "myBucketKey";s3.createBucket({ Bucket: myBucket }, function(err, data) {  if (err) {    console.log(err);  } else {    params = { Bucket: myBucket, Key: myKey, Body: "Hello!" };    s3.putObject(params, function(err, data) {      if (err) {        console.log(err);      } else {        console.log("Successfully uploaded data to myBucket/myKey");      }    });  }});node app.js테이블 생성// CreateTable.jsvar AWS = require("aws-sdk");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var dynamodb = new AWS.DynamoDB();var params = {  TableName: "Movies",  KeySchema: [    { AttributeName: "year", KeyType: "HASH" }, // Partition key    { AttributeName: "title", KeyType: "RANGE" } // Sort key  ],  AttributeDefinitions: [    { AttributeName: "year", AttributeType: "N" },    { AttributeName: "title", AttributeType: "S" }  ],  // 다운로드 버전인 경우 아래 코드 무시  ProvisionedThroughput: {    ReadCapacityUnits: 10,    WriteCapacityUnits: 10  }};dynamodb.createTable(params, function(err, data) {  if (err) {    console.log(      "Unable to create table. Error JSON: ",      JSON.stringify(err, null, 2)    );  } else {    console.log(      "Created table. Table description JSON: ",      JSON.stringify(data, null, 2)    );  }});node CreateTable.js샘플 데이터 로드1. 이곳에서 샘플 데이터 파일 다운로드데이터 형태는 아래와 같음[    {        "year": 2013,        "title": "Rush",        "info": {            "directors": ["Ron Howard"],            "release_date": "2013-09-02T00:00:00Z",            "rating": 8.3,            "genres": [                "Action",                "Biography",                "Drama",                "Sport"            ],            "image_url": "http://ia.media-imdb.com/images/M/MV5BMTQyMDE0MTY0OV5BMl5BanBnXkFtZTcwMjI2OTI0OQ@@._V1_SX400_.jpg",            "plot": "A re-creation of the merciless 1970s rivalry between Formula One rivals James Hunt and Niki Lauda.",            "rank": 2,            "running_time_secs": 7380,            "actors": [                "Daniel Bruhl",                "Chris Hemsworth",                "Olivia Wilde"            ]        }    },    ...]- year 및 title을 Movies 테이블을 위한 기본 키 속성 값으로 사용- info의 나머지 값들은 info라는 단일 속성에 저장- JSON을 DynamoDB 속성에 저장2. 샘플 데이터 Movies 테이블에 로드// LoadData.jsvar AWS = require("aws-sdk");var fs = require("fs");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();console.log("Importing movies info DynamoDB. Please wait.");var allMovies = JSON.parse(fs.readFileSync("moviedata.json", "utf8"));allMovies.forEach(function(movie) {  var params = {    TableName: "Moves",    Item: {      year: movie.year,      title: movie.title,      info: movie.info    }  };  docClient.put(params, function(err, data) {    if (err) {      console.error(        "Unable to add movie",        movie.title,        ". Error JSON:",        JSON.stringify(err, null, 2)      );    } else {      console.log("PutItem succeeded:", movie.title);    }  });});node LoadData.js테이블에 항목 추가// PutItem.jsvar AWS = require("aws-sdk");var fs = require("fs");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var table = "Movies";var year = 2017;var title = "The Big Wonny";var params = {  TableName: table,  Item: {    year: year,    title: title,    info: {      plot: "Nothing happens at all.",      rating: 0    }  }};console.log("Adding a new item...");docClient.put(params, function(err, data) {  if (err) {    console.error(      "Unable to add item. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    console.log("Added item:", JSON.stringify(data, null, 2));  }});node PutItem.js- 기본 키가 필요하므로 기본 키 (year, title) 및 info 속성 추가항목 읽기// GetItem.jsvar AWS = require("aws-sdk");var fs = require("fs");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var table = "Movies";var year = 2017;var title = "The Big Wonny";var params = {  TableName: table,  Key: {    year: year,    title: title  }};docClient.get(params, function(err, data) {  if (err) {    console.error(      "Unable to read item. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    console.log("GetItem succeeded:", JSON.stringify(data, null, 2));  }});node GetItem.js항목 업데이트// UpdateItem.jsvar AWS = require("aws-sdk");var fs = require("fs");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var table = "Movies";var year = 2017;var title = "The Big Wonny";var params = {  TableName: table,  Key: {    year: year,    title: title  },  UpdateExpression: "set info.rating = :r, info.plot=:p, info.actors=:a",  ExpressionAttributeValues: {    ":r": 5.5,    ":p": "Everything happens all at once.",    ":a": ["Larry", "Moe", "Curly"]  },  ReturnValues: "UPDATED_NEW"};console.log("Updating the item...");docClient.update(params, function(err, data) {  if (err) {    console.error(      "Unable to update item. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    console.log("UpdateItem succeeded:", JSON.stringify(data, null, 2));  }});node UpdateItem.js- 지정된 항목에 대해 수행하고자 하는 모든 업데이트를 설명하기 위해 UpdateExpression을 사용- ReturnValues 파라미터는 DynamoDB에게 업데이트된 속성("UPDATED_NEW")만 반환하도록 지시원자성 카운터 증가시키기update 메서드를 사용하여 다른 쓰기 요청을 방해하지 않으면서 기존 속성의 값을 증가시키거나 감소시킬 수 있음 (모든 쓰기 요청은 수신된 순서대로 적용)실행 시 rating 속성이 1씩 증가하는 프로그램// Increment.jsvar AWS = require("aws-sdk");var fs = require("fs");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var table = "Movies";var year = 2017;var title = "The Big Wonny";// Increment an atomic countervar params = {  TableName: table,  Key: {    year: year,    title: title  },  UpdateExpression: "set info.rating = info.rating + :val",  ExpressionAttributeValues: {    ":val": 1  },  ReturnValues: "UPDATED_NEW"};console.log("Updating the item...");docClient.update(params, function(err, data) {  if (err) {    console.error(      "Unable to update item. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    console.log("UpdateItem succeeded:", JSON.stringify(data, null, 2));  }});node Increment.js항목 업데이트(조건부)UpdateItem을 조건과 함께 사용하는 방법조건이 true로 평가되면 업데이트가 성공하지만 그렇지 않으면 수행되지 않음// ConditionalUpdateItem.jsvar AWS = require("aws-sdk");var fs = require("fs");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var table = "Movies";var year = 2017;var title = "The Big Wonny";// Increment an atomic countervar params = {  TableName: table,  Key: {    year: year,    title: title  },   UpdateExpression: "remove info.actors[0]",  ConditionExpression: "size(info.actors) > :num",  ExpressionAttributeValues: {    ":num": 3  },  ReturnValues: "UPDATED_NEW"};console.log("Attempting a conditional update...");docClient.update(params, function(err, data) {  if (err) {    console.error(      "Unable to update item. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    console.log("UpdateItem succeeded:", JSON.stringify(data, null, 2));  }});node ConditionalUpdateItem.js다음과 같이 작성하면 아래와 같은 에러 메시지가 표시 됨The conditional request failed"영화에는 3명의 배우가 있는데 배우가 3명보다 많은지를 확인하고 있어 에러가 발생다음과 같이 수정하면 정상적으로 항목이 업데이트 됨ConditionExpression: "size(info.actors) >= :num",항목 삭제// DeleteItem.jsvar AWS = require("aws-sdk");var fs = require("fs");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var table = "Movies";var year = 2017;var title = "The Big Wonny";var params = {  TableName: table,  Key: {    year: year,    title: title  },  ConditionExpression: "info.rating <= :val",  ExpressionAttributeValues: {    ":val": 5.0  }};console.log("Attempting a conditional delete...");docClient.delete(params, function(err, data) {  if (err) {    console.error(      "Unable to update item. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));  }});node DeleteItem.js다음과 같이 작성하면 아래와 같은 에러 메시지가 표시 됨The conditional request failed특정 영화에 대한 평점이 5보다 크기 때문에 에러가 발생다음과 같이 수정하면 정상적으로 항목이 삭제 됨var params = {  TableName: table,  Key: {    year: year,    title: title  }};데이터 쿼리- 파티션 키 값을 지정해야 하며, 정렬 키는 선택 사항- 1년 동안 개봉한 모든 영화를 찾으려면 year만 지정, title을 입력하면 2014년 개봉된 "A"로 시작하는 영화를 검색하는 것과 같이 정렬 키에 대한 어떤 조건을 바탕으로 일부 영화를 검색할 수도 있음한 해 동안 개봉한 모든 영화// QueryYear.jsvar AWS = require("aws-sdk");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var params = {  TableName: "Movies",  KeyConditionExpression: "#yr = :yyyy",  ExpressionAttributeNames: {    "#yr": "year"  },  ExpressionAttributeValues: {    ":yyyy": 1985  }};docClient.query(params, function(err, data) {  if (err) {    console.error("Unable to query. Error JSON:", JSON.stringify(err, null, 2));  } else {    console.log("Query succeeded.");    data.Items.forEach(function(item) {      console.log(" -", item.year + ": " + item.title);    });  }});node QueryYear.jsExpressionAttributeNames는 이름을 교체함. 이를 사용하는 이유는 year가 DynamoDB에서 예약어이기 때문. KeyConditionExpression을 포함해 어떤 표현식에서도 사용할 수 없으므로 표현식 속성 이름인 #yr을 사용하여 이를 지칭ExpressionAttributeValues는 값을 교체함. 이를 사용하는 이유는 KeyConditionExpresssion을 포함해 어떤 표현식에서도 리터럴을 사용할 수 없기 때문. 표현식 속성 값인 :yyyy를 사용해 지칭* 위의 프로그램은 기본 키 속성으로 테이블을 쿼리하는 방법. DynamoDB에서 1개 이상의 보조 인덱스를 테이블에 생성하여 그 인덱스로 테이블을 쿼리하는 것과 동일한 방식으로 쿼리 작업 가능. 보조 인덱스는 키가 아닌 속성에 대한 쿼리를 허용하여 애플리케이션에 더 많은 유연성을 부여함한 해 동안 개봉한 모든ㄴ 영화 중에 특정 제목을 지닌 영화year 1992에 개봉한 영화 중에 title이 "A"부터 "L"까지의 알파벳으로 시작하는 영화를 모두 조회합니다.// QueryTitle.jsvar AWS = require("aws-sdk");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();console.log(  "Querying for movies from 1992 - titles A-L, with genres and lead actor");var params = {  TableName: "Movies",  ProjectionExpression: "#yr, title, info.genres, info.actors[0]",  KeyConditionExpression: "#yr = :yyyy and title between :letter1 and :letter2",  ExpressionAttributeNames: {    "#yr": "year"  },  ExpressionAttributeValues: {    ":yyyy": 1992,    ":letter1": "A",    ":letter2": "L"  }};docClient.query(params, function(err, data) {  if (err) {    console.error("Unable to query. Error JSON:", JSON.stringify(err, null, 2));  } else {    console.log("Query succeeded.");    data.Items.forEach(function(item) {      console.log(        " -",        item.year + ": " + item.title + " ... " + item.info.genres + " ... ",        item.info.actors[0]      );    });  }});node QueryTtiel.js스캔테이블의 모든 항목을 읽고 테이블의 모든 데이터를 반환선택 사항인 filter_expression을 제공할 수 있으며 그 결과 기준이 일치하는 항목만 반환하지만 필터는 테이블 전체를 스캔한 후에만 적용됨// Scan.jsvar AWS = require("aws-sdk");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var params = {  TableName: "Movies",  ProjectionExpression: "#yr, title, info.rating",  FilterExpression: "#yr between :start_yr and :end_yr",  ExpressionAttributeNames: {    "#yr": "year"  },  ExpressionAttributeValues: {    ":start_yr": 1950,    ":end_yr": 1959  }};console.log("Scanning Movies table.");docClient.scan(params, onScan);function onScan(err, data) {  if (err) {    console.error(      "Unable to scan the table. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    // print all the movies    console.log("Scan succeeded.");    data.Items.forEach(function(movie) {      console.log(        movie.year + ": ",        movie.title,        "- rating:",        movie.info.rating      );    });    // continue scanning if we have more movies, because    // scan can retrieve a maximum of 1MB of data    if (typeof data.LastEvaluatedKey != "undefined") {      console.log("Scanning for more...");      params.ExclusiveStartKey = data.LastEvaluatedKey;      docClient.scan(params, onScan);    }  }}node Scan.jsProjectionExpression은 스캔 결과에서 원하는 속성만 지정FilterExpression은 조건을 만족하는 항목만 반환하도록 조건을 지정. 다른 항목들은 모두 무시됨테이블 삭제// DeleteTable.jsvar AWS = require("aws-sdk");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var dynamodb = new AWS.DynamoDB();var params = {  TableName: "Movies"};dynamodb.deleteTable(params, function(err, data) {  if (err) {    console.error(      "Unable to delete table. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    console.log(      "Deleted table. Table description JSON:",      JSON.stringify(data, null, 2)    );  }});node DeleteTable.js#트레바리 #개발자 #안드로이드 #앱개발 #Node.js #백엔드 #인사이트 #경험공유 #데이터베이스 #DB #개발 #AWS #아마존 #NoSQL 

기업문화 엿볼 때, 더팀스

로그인

/