스토리 홈

인터뷰

피드

뉴스

조회수 1988

Android Gradle Tips

안드로이드와 GradleAndroid 가 Gradle 을 이용하기 시작한 것도 3년이 다 되어 갑니다. 이제는 많은 유저가 당연히 Gradle 을 Android 기본 개발 환경으로 사용하고 있습니다.하지만 기본 설정으로만 Gradle 을 사용하는 사용자들이 많습니다. 게다가 구글에서 Android Gradle Build DSL 을 끊임없이 변경했기 때문에 많은 사용자들이 이를 이해하기도 전에 변경이 되는 경우가 매우 빈번했습니다.Gradle Dependency 분리하기안드로이드 자동화 툴위 두번의 포스팅을 통해서 TossLab 에서 사용하고 있는 Gradle 에 대해서 소개를 해드렸습니다.오늘은 Android 팀이 사용하는 Custom 설정들에 대해서 정리하도록 하겠습니다.1. 초기화 값 검증 및 설정하기개발자들이나 CI 에서 관리해야하는 속성 값에 대해서는 각각 다르게 설정할 필요가 있습니다.안드로이드 팀은 3개의 추가적인 속성값을 추가하여 사용하고 있습니다.# gradle.properties inhouse_version=2 # 배포/qa 버전의 hofix version 을 관리학 ㅣ위함 report_coverage=false # coverage 측정에 대한 on/off 기능 dev_min_sdk=21 # minSDK 의 개별적인 관리를 위함 위의 3개의 값은 존재 하지 않으면 빌드가 되지 않도록 하는 강제사항으로 만들었으나 새로운 개발자가 입사하게 되었을 때 또는 CI 서버에 실수로 기입하지 못하게 되었을 때 Project Import 나 빌드가 아예 되지 않는 현상이 발생하였기에 초기 값을 설정할 수 있도록 하였습니다.report_coverage 는 5. Android Gradle DSL 에서 buildTypes.debug.testCoverageEnabled 에서 사용되며 이 값은 설정에 따라서 디버그 과정에서 변수값들이 제대로 노출되지 않게 됩니다. report 가 필요한 CI 서버 용으로 만들어진 값입니다.// valid.gradle def checkValidProperties() { println "Properties Valid Checking.........." if (!project.hasProperty("inhouse_version")) { println "set up to gradle.propeties --> inhouse_version = 1 (default)" project.ext.inhouse_version = 1 } if (!project.hasProperty("report_coverage")) { println "set up to gradle.propeties --> report_coverage = false (default)" project.ext.report_coverage = false } if (!project.hasProperty("dev_min_sdk")) { println "set up to gradle.propeties --> dev_min_sdk = 19 (default)" project.ext.dev_min_sdk = 19 } println "Properties Valid Check OK" } checkValidProperties() // ------------------------------- // build.gradle apply from: 'valid.gradle' 위와 같이 설정한 뒤 gradle.properties 에 아무런 값을 설정하지 않고 빌드를 하게 되면 빌드 최초에 다음과 같은 log 를 보실 수 있습니다.================================================================================ Properties Valid Checking.......... set up to gradle.propeties --> inhouse_version = 1 (default) set up to gradle.propeties --> report_coverage = false (default) set up to gradle.propeties --> dev_min_sdk = 19 (default) Properties Valid Check OK ================================================================================ 2. APK Copy 하기QA 팀 전달 또는 스토어 배포시에 Android Studio 의 기본 기능을 이용하지 않고 Gradle Task 를 사용하여 빌드를 하게 되면 /app/build/outputs/apk 에 있는 패키지를 복사하는 것이 여간 귀찮은 작업이 아닐 수 없습니다.그래서 Gradle 에서 기본적으로 제공되는 Copy Task 를 이용하여 APK Copy Task 를 만들었습니다.// apk-copy.gradle android.applicationVariants.all { variant -> // 1. Copy Task 생성 def task = project.tasks.create("copy${variant.name}Apk", Copy) task.from(variant.outputs[0].outputFile) // 2. 바탕화면 Task 로 복사 task.into("${System.properties['user.home']}/Desktop/") // 3. 복사하는 과정에서 APK 이름 변경 def targetName = "jandi-${variant.baseName}-${variant.versionName}.apk" task.rename ".*", targetName task.doFirst { println "copy from ${source.singleFile.name} to $destinationDir" } task.doLast { value -> println "completed to copy : $targetName" } } // --------------- // build.gradle apply from: 'apk-copy.gradle' 위의 Task 는 총 3개의 단계로 구분할 수 있습니다.Copy Task 생성~/Desktop 으로 복사복사 할 때 APK 이름 변경Task 를 정의하는 과정에서 application 의 flavor, build-type, version 을 기반으로 복사하도록 한 것입니다.위와 같이 설정하면 다음과 같이 사용할 수 있습니다.# flavor : qa , build-type : Debug $> ./gradlew assembleQaDebug copyqaDebugApk # 또는 줄여서 아래와 같이 쓸 수 있습니다. $> ./gradlew aQD copyQDA Application Variant 에 대한 변수는 링크에서 확인하실 수 있습니다.3. CI TasksCI 용으로 CheckStyle 과 PMD 를 사용하기 때문에 관련 설정 또한 별도로 처리하였습니다.task pmd(type: Pmd) { source 'src/main' include '**/*.java' ruleSetFiles = files('../pmd.xml') ignoreFailures = true } task checkstyles(type: Checkstyle) { configFile file('../checkstyle.xml') source('src/main') include '**/*.java' classpath = files() showViolations = true ignoreFailures = true } // --------------- // build.gradle apply from: 'ci-tasks.gradle' CheckStyle 과 PMD 설정에 필요한 정보 또한 별도의 script 로 설정하였습니다.4. Gradle Properties빠른 빌드를 위해 추가적인 설정을 하고 있습니다.# gradle.properties # 백그라운드 빌드 org.gradle.daemon=true # 동시 빌드 org.gradle.parallel=true # jvm heap size org.gradle.jvmargs=-Xmx4346m # build jdk org.gradle.java.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home 위의 설정 중에서 제일 보셔야 할 것이 org.gradle.jvmargs 입니다. Android Gradle 설정 중에서 위의 값이 적으면 빌드속도가 현저히 느려집니다.빌드 할 때 console log 를 확인하시고 값을 적절하게 맞춰주실 것을 권장합니다.5. Android Gradle DSL 추가 정의하기 // build.gradle // ...중략 android { // 특정 Flavor에서 Release Build 막기 android.variantFilter { variant -> if (variant.buildType.name.equals('release') && (variant.getFlavors().get(0).name.equals('qa') || variant.getFlavors().get(0).name.equals('dev'))) { variant.setIgnore(true); } } buildTypes { debug { debuggable true testCoverageEnabled = project.hasProperty("report_coverage") && report_coverage.toBoolean() } // ..중략... } productFlavors { dev { // demo version applicationId 'com.tosslab.jandi.app.dev' versionName(defaultConfig.versionName + ".dev." + inhouse_version) minSdkVersion project.hasProperty("dev_min_sdk") ? dev_min_sdk : 19 } // ..중략.. } // 빌드 과정에서 CPU 와 Ram 최적화 하기 dexOptions { javaMaxHeapSize "2g" maxProcessCount Math.max(1, ((int) (Runtime.getRuntime().availableProcessors() / 2))) } } variant-filter 를 이용해서 qa 나 dev 용 빌드는 release 버전이 빌드되지 않도록 하였습니다.buildTypes 와 productFlavors 에서는 앞서 설정한 gradle-properties 에 대해서 설정에 따라 기본값이 지정되도록 하였습니다.dexOptions 설정은 개발하는 기기의 PC 환경에 따라 다를 수 있습니다.Android DSL 에 의하면 Dex 빌드 과정에서 최종적으로 사용하는 메모리는 heapsize * process-count 라고 합니다.heapsize 기본값 : 2048MBprocess-count 기본값 : 4참고문서6. Android Resource Image 의 EXIF 정보 삭제하기보통 디자이너가 Photoshop 과 같은 툴을 이용하여 이미지를 만들게 되면 자동으로 adobe 와 관련된 exif 정보가 붙게 됩니다. 그래서 빌드 할 때 libpng warning : iCCP ... 와 같은 warning 메세지를 보실 수 있습니다. 이는 Android Build 과정에서 aapt 가 이미지 최적화 하는 과정에서 불필요한 exif 정보로 인해서 오류를 내게 됩니다.따라서 exif 정보를 초기화 해주는 작업이 필요합니다.맥 사용자에 한해서 지원됩니다.HomeBrew 를 이용해서 exiftool 을 설치하셔야 합니다. exiftool 설명find . -path '*src/main/res/*' -name '*.png' -exec exiftool -overwrite_original -all= {} \; 저는 별도로 쉘 스크립트를 만들어서 실행합니다.아래를 복사해서 붙여넣기로 실행하시면 됩니다.echo "find . -path '*src/main/res/*' -name '*.png' -exec exiftool -overwrite_original -all= {} \;" > exif_clean.sh chmod 744 exif_clean.sh 관련 정보 : adt-dev google group 에서 제시된 해결책Wrap up안드로이드 팀은 Gradle 을 이용하여 반복적일 수 있는 작업을 자동화 하고 다양한 초기화 설정과 편의를 가지고자 하였습니다.초기화 값 검증 및 설정Apk 복사 자동화CI Task 정의Gradle Properties 지정Android Gradle DSL 정의Android Resource Image EXIF 삭제Gradle 을 얼마나 잘 활용하냐에 따라서 조직에 필요한 Task 를 금방 만드실 수 있습니다. 이번 포스팅이 도움이 되었기를 바라며 활용해보실 것을 권장합니다.#토스랩 #잔디 #JANDI #개발자 #개발팀 #앱개발 #안드로이드 #인사이트
조회수 1415

대시보드 만들다 문득,

 고수의 프레젠테이션은 늘 심플하다. 읽기 좋은 보고서는 한 페이지로 요약된다. 가진 정보가 많다는 건 좋은 일이지만 때론 감당할 수 없는 양에 압도 당하고 교란 당한다. 정보는 권력이 된다. 그것의 불균형은 누군가에겐 돈을 벌어다 주고 누군가에겐 좋은 일자리를 준다. 정보가 있는 곳엔 그래서 늘 사람과 힘이 몰린다. 하여, 정보제공자에겐 막중한 책임역시 따라야 한다 생각한다. 제공할 정보가 사실에 기반해야 하는 건 물론이고 더 중요한 건 진정 필요한 콤팩트(compact)한 정보만을 제공해야 한다는 것이다. 현재진행형인 대시보드(dashboard) 프로젝트 과정에서 위와 같은 생각이 들었다. 그러면, 주관과 사욕을 완전히 배제하고, 내가 드러내고 보여주고 싶은 정보가 아니라 최대한 많은 이에게 가치롭게 활용되는 정보는 어떤 형태여야 할까? 스스로 답을 내렸다.  우선 사람별, 상황별로 다른 관점과 해석이 양립할 수 없는 요소로 구성돼야 하고, 전달과정에서 요구되는 추가적 배경지식은 불필요해야 하며 필요하다면 극히 적은 양이어야 한다. 무엇보다 관련된 이는 누구나 궁금해 해야 할 것이어야 하고 부차적인 것을 제외한 본질만을 담고 있어야 한다. 이 같은 정보를 핵심정보라고 정의하면 핵심정보는 각각의 업이 가진 '본질적 성장 방정식(fundmetal growth equation)'과 연관이 깊다. 본질적 성장 방정식이란 현 시점에서 비즈니스의 성장을 추진하는 모든 핵심요소, 즉 핵심적인 성장 지렛대를 표현한 간단한 공식을 뜻한다. 제아무리 시가총액 1조를 넘은 기업일지라도 그들의 성장공식을 대여섯 가지의 핵심요소로 도식화하는 것은 가능하며 그것은 제품, 서비스가 가진 성격별로 달라진다. 본질적 성장 방정식을 <진화된 마케팅 그로스 해킹>이란 책에서 나온 사례를 인용해 예시를 들면 아래와 같다.# 이베이의 방정식{아이템을 등록한 판매자의 수}x{등록된 아이템의 수}x{구매자의 수}x{성공적인 거래의 수}=총 매출 성장# 어느 온라인 뉴스사이트의 방정식{웹사이트 트래픽}x{이메일 전환율}x{활성 사용자 비율}x{유료구독으로의 전환율}+다시 찾은 구독자 =총 구독자 매출 성장 이베이의 방정식을 보면 트래픽 양보다는, 거래량을 일정수준 이상 유지하는 것이 성장에 있어 더 중요한 미션일 것이다. 그래서 신규 셀러와 동시에 판매 아이템에 대한 공급이 지속적으로 원활히 이뤄져야만 한다. 아울러 매일, 매주 등록되는 아이템 개수와 그것의 품질, 카테고리 같은 것도 광장히 중요한 관리요소 중 하나일 것이다. 한편, 어느 온라인 뉴스사이트의 경우 트래픽의 양은 광고매출과 직결되고 신규 독자 확보의 가능성을 높여주는 성과의 선행지표다. 뉴스레터 이메일은 수신자를 이후 결제 - 유료구독 -할 확률이 높은 활성 사용자로 전환시키는 데 주력할 것이다. 그래서 사이트를 드나드는 빈도가 높은 활성 사용자층을 얼마나 두껍게 유지하느냐는 온라인 뉴스 비즈니스에서 관건 중 하나일 것이다.  참고: https://www.youtube.com/watch?v=PvSW0ri7AEg기본적인 매출 성장 방정식을 소개하는 강의 동영상이 있어 첨부한다 이처럼 본질적 성장 방정식을 구성하는 요소를 해부해보면 어떤 정보가 현 시점에 우리의 비즈니스를 이끄는 핵심정보이고, 비교적 불필요한 정보인지, 잘 드러난다. 또한, 생각한 것보다 관리해야 할, 혹은 제공해야 할 정보가 적다는 것에 놀란다 - 개인적으론 충격이었다.  페이스북 광고 관리자 페이지에서 관찰할 수 있는 데이터 필드 수는 맞춤설정 활용 시 약 300개까지 지원된다. 그들 중 절반은 서비스와 관련성이 적거나 매일 추적한다 해도 당장의 마케팅 관련 의사결정에 도움을 주지 못하는 것이 대부분일 수 있다. 구글애널리틱스에서 제공하는 지표 또한 마찬가지다. 이탈률을 체크하는 것이 중요하다고들 하지만, 서비스의 태생적 특성 상, 신규 사용자 유치를 위해 지속적이고 공격적인 온라인 광고가 불가피하다면? 때론 업계 평균보다 높은 이탈률이 당연한 것이고 그것이 가진 시사점은 적을 수도 있다. 단지 '쿨'해 보이는 지표를 관찰할 게 아니라 각각의 비즈니스 '실정'에 맞는 성장 방정식을 꾸리고 그것을 지켜 보는 게 중요하단 말이다. 결론적으로 다시 대시보드 이야기로 돌아가면, 정보판으로써 구실하기 위한 최소요건으로 대시보드에는 성장 방정식을 이루는 구성요소만 들어있으면 된다. 그것들이 최소요건이자 거의 대부분이다. 그 외 정보는 실제로는 불필요하거나 수요가 낮은 정보일 가능성이 높다. 물론 그런 정보는 필요에 따라 '드릴 다운' 방식으로 제공하는 것도 좋겠다. 하지만 당장의 우선순위는 아니란 것이다. 대시보드의 첫인상은 고수의 피티처럼 심플하고, 잘 짜여진 보고서 앞 한 장 요약본처럼 말하는 바가 적확해야 한다.블랭크 코퍼레이션의 CI내밀한 이야기가 될 수 있는데, 대시보드 프로젝트를 진행하며 자사 비즈니스의 본질적 성장 방정식은 어떻게 생겼을까, 혼자 그려봤다. 디지털 마케팅  중심적 사고이기 때문에 주관적이며 생각차는 있을 수 있다. 그리고 미래의 가변적 환경을 반영하지 않았다. 어차피 대시보드에선 미래를 projection하지 않기 때문이다.# (현 시점 기준) blank의 방정식{상품기획력}x{콘텐츠 파워}x{SNS 광고비}x{광고유입후 0일-1일내 구매하는 이의 비율}x{재구매율}x{고객생애가치}= 성장의 크기 방정식 안에 bold체로 표시된 요소를 살펴보자. 내가 생각하는 - 공식적인 내용이 아니다 - 우리의 모델 안에서 {SNS 광고비}는 성장(매출)의 크기를 좌우하는 핵심인자다. 광고를 통해 설득 당한 잠재고객을 단번에 구매로 이끌 수 있는 흡인력 - 앞선 방정식에선 {광고유입후 0일-1일내에 구매하는 이의 비율}로 표시했다 - 을 지속하느냐 또한 DR(direct response ; 직접 반응) 마케팅에서 관찰하고 관리해야 할 주요요소다. 이후 구매자의 {재구매율}과 {생애가치}도 이해하고 관리할 수 있다면 완벽할 것이다. 하지만 해당 지표의 정의와 계산은 마냥 쉽지 않기에 정밀한 설정 안에서 관련 정보의 해상도를 높이는 일이 요구된다. 이 정도의 정보가 현 시점에서 마케팅 유닛에서 필수적으로 관찰하고, 유관부서에 공유해야 할 핵심지표가 될 수 있을 것이다. 대시보드 상에 CTR(클릭률), CPC(클릭당비용), CPM(1,000회 노출당비용)과 같은 매일의 광고지표를 넣었다간 보는 이로 하여금 복잡성만 가중시킬 뿐이다. 전자상거래 마케팅 과정에서 오직 알아야 할 정보는 "광고비를 얼마나 효율적으로 투자해 얼마를 벌었는가"라고 생각한다. 현재 페이스북이 제공하는 구매 최적화 광고의 알고리듬 상에선 구매 수와 CPA(액션당비용, 구매당비용) 외 다른 지표들은 그때그때 알고리듬 컨디션에 따라 결정되는 후행지표이자 수단일 뿐이다 - 이 부분은 나중에 기회가 있다면 더 설명해보고 싶고 다른 이와 토의하고 싶다. 불과 얼마 전까지 - 아니면 지금까지; - 난 아마도, 엑셀 시트에 피봇테이블을 덕지덕지 붙여넣고 형형색색으로 트렌드를 표시하면 좋은 정보가 되는 줄 착각했었다. 그리고 난 데이터분석가도 아니고 고급통계지식이 풍부한 편도 아니다. 프로그래밍을 할 줄 알아 데이터 처리기술이 남다른가? 고작 엑셀 단축키와 기본 함수를 사용해 평균보단 빠르게 잔머릴 굴리는 정도다. 하지만 최근에는 시각화, 데이터분석, 고급통계지식 모두 중요한 정보를 전달하는 수단일 뿐이란 생각이 든다. 자기위로적 감상일 수 있지만, 정말로, 정보를 다루는 데 있어 그러한 스킬보다 중요한 건 진정 필요한 정보를 옥석 가리듯 가려내는 정보 분별력이라고 생각한다. 수단에 현혹돼 정작 알맹이는 없고, 누구에게도 도움되지 않는 보고서를 만드는 일이 어떤 마케터, 사업PM에게도 없었으면 하는 바람이다.(끝)Jin Young Choi회사원
조회수 3637

[Tech Blog] Go 서버 개발하기

Go 서버 개발을 시작하며   특정 API만 다른 언어로 구현해서 최대의 성능을 내보자! 저희 서버는 대부분 Django framework 위에서 구현된 광고 할당 / 컨텐츠 할당 / 허니스크린 앱 서비스 이렇게 나눌 수 있는데 Python 이라는 언어 특성상 높은 성능을 기대하기가 어려웠습니다. 하지만 세가지 서비스에서 락스크린에서 어떤 컨텐츠나 광고를 보여줄지 결정하는 Allocation(할당) API 가 가장 많이 호출되고 있었는데 빈도로 보면 80% 정도로 높은 비중을 차지하고 있어서 이 Allocation API 들을 성능이 좋은 다른 언어로 구현하면 어떨까 하는 팀내 의견이 있었습니다. Why Go? 저는 예전부터 Java,  C# 등의 컴파일 언어에 익숙해서 기존 Java 와 C, 그리고 Go 라는 최근에 새로 나온 언어 중에서 아래 블로그글과 같이 여러 reference 들을 통해 성능이 좋다는 Go 로 이 API 들을 포팅하는 작업을 시작하게 되었습니다. Go 에 대한 첫 인상은 Java, C계열 언어보다 덜 verbose 보였고 python 보다는 strongly-typed, encapsulated 하다보니 자유도를 제한해서 코드를 보기 쉽게 하는 것을 선호하는 저의 성격과도 잘 맞는 언어였습니다.     출처: Carles Mateo, Performance of several languages서버 개발 환경   Server design How to import libraries  GVT (https://github.com/FiloSottile/gvt) – Go 는 vendering tool 을 통해 dependency 를 관리할 수 있습니다. GVT 의 경우 처음 도입했을 때 별로 유명하지 않았는데 사용법이 간단해서 도입하게 되었습니다. 아래와 같이 참조하고 있는 revision 을 관리해주며 update 통해서 최신 소스를 받아 올수 있습니다.   { "version": 0, "dependencies": [ { "importpath": "github.com/Buzzvil/go-env", "repository": "https://github.com/Buzzvil/go-env", "vcs": "git", "revision": "2d8489d40184a12c4d09d09ce1ff717e5dbb0745", "branch": "master", "notests": true }, ....  Design pattern  Go 언어에서는 package level cycling dependency 를 허용하지 않아서 좀더 명확한 구조를 만들기 좋았습니다. 예를들어 Service 에서는 Controller 를 참조할수 없고 Model 에서는 Controller / Service / DTO 등을 참조할수 없도록 강제했습니다. 모든 API 요청은 Route 를 통해 Controller 에게 전달되고 이 때 생성된 DTO (Data transfer object) 들을 Controller 가 직접 혹은 Service layer 에서 처리하도록 하였고 DB 에 접근할 때는 모델을 통해 혹은 직접 접근하도록 했지만 추후 구조가 복잡해지면 DB 쿼리 등을 담당하는 DAO (Data access object) 를 도입할 계획입니다   Libraries                  요소이름선택 이유NetworkGinWeb 서버이다 보니 네트워크 성능을 최우선으로 고려, 벤치마크 표를 보고 이 라이브러리를 선택Redis & cachego-redis역시 성능을 가장 중요한 지표로 보고 이 라이브러리 선택MysqlGormORM 없이는 개발하기 힘든 시대이죠. 여러 Database를 지원하고 ORM 중에서도 method chaining 을 사용하는 Gorm 을 선택Dynamoguregu dynamoAWS에서 제공하는 Dynamo 패키지를 그대로 사용하면 코드 양이 너무 많아지고 역시 method chaining 을 지원해서 선택Environment variablescaarlos0 envGo 에서는 tag 를 이용하면 좀더 코드를 간결하고 읽기 쉽게 사용할수 있는데 이 라이브러리가 환경변수를 읽어오기 쉽도록 해줌   Redis cache  func SetCache(key string, obj interface{}, expiration time.Duration) error { err := getCodec().Set(&cache.Item{ Key: key, Object: obj, Expiration: expiration, }) return err } func GetCache(key string, obj interface{}) error { return getCodec().Get(key, obj) }  Mysql  var config model.DeviceContentConfig env.GetDatabase().Where(&model.DeviceContentConfig{DeviceId: deviceId}).FirstOrInit(&config)  Dynamo if err := env.GetDynamoDb().Table(env.Config.DynamoTableProfile).Get(keyId, deviceId).All(&profiles); err == nil && len(profiles) > 0 { ... }  Environment variables  var ( Config = ServerConfigStruct{} onceConfig sync.Once ) type ( ServerConfigStruct struct { ServerEnv string `env:"SERVER_ENV"` LogLevel string .... } ) func LoadServerConfig(configDir string) { onceConfig.Do(func() {//최초 한번반 호출되도록 env.Parse(&Config) } }    Unit test   환경 구성 Test 환경에는 Redis / Mysql / Elastic search 등에 대한 independent / isolated 된 환경이 필요해서 이를 위해 docker 환경을 따로 구성하였습니다. Test case 작성은 아래와 같이 package 를 분리해서 작성했습니다.  package buzzscreen_test var ts *httptest.Server func TestMain(m *testing.M) { ts = tests.GetTestServer(m) // 환경 시작 tearDownElasticSearch := tests.SetupElasticSearch() tearDownDatabase := tests.SetupDatabase() code := m.Run() // 여기서 작성한 TestCase 들 실행 // 환경 종료 tearDownDatabase() tearDownElasticSearch() ts.Close() os.Exit(code) }  Mock server는 은 http.RoundTripper interface 를 구현해서 http.Client 의 Transport 멤버로 설정해서 구현했습니다. 아래는 Test case 작성 예제입니다.  httpClient := network.DefaultHttpClient mockServer := mock.NewTargetServer(network.GetHost(MockServerUrl)) .AddResponseHandler(&mock.ResponseHandler{ WriteToBody: func() []byte { return []byte(mockRes) }, Path: "/path", Method: http.MethodGet, }) clientPatcher := mock.PatchClient(httpClient, mockServer) defer clientPatcher.RemovePatch()  Unit test 관련해서는 내용이 방대해서 추후 다른 포스트를 통해 자세히 소개하도록 하겠습니다.  Infra API 요청 분할 AWS Application load balancer 여러 API 중에서 할당 API 를 제외한 요청은 기존의 Django 서버로 요청을 보내고 할당요청에 대해서만 Go서버로 요청을 보내도록 구현하기 위해 먼저 시도 했던 것은 AWS Application load balancer (이후 ALB) 였습니다. ALB 의 특징이 path 로 요청을 구별해서 처리할수 있었기 때문에 Allocation API 만 Go 서버 로 요청이 가도록 구현했습니다.  출처: Amazon Devops Blog, Introducing Application Load Balancer   하지만 이렇게 오랫동안 서비스 하지 못했는데 그 이유는 서버 구성이 하나 더 늘어나고 앞단에 ALB 까지 추가되다 보니 이를 관리하는데 추가 리소스가 들어가게 되어서 어떻게 하면 이러한 비용을 줄일수 있을까 고민하게 되었습니다.   Using docker & nginx  Go로 작성된 서버가 독립적인 Micro service 냐 아니면 Django 서버에서 특정 API 를 독립시켜 성능을 강화한 모듈이냐 의 정체성을 두고 생각해봤을때 후자가 조금더 적합하다보니 Go / Django 서버는 한 묶음으로 관리하는 것이 명확했습니다. Docker 를 도입하면서 nginx container 가 proxy 역할을 하고 path를 보고 Go container / Django container 로 요청을 보내는 구성을 가지게 되었습니다.  글을 마치며   시작은 미약하였으나 끝은 창대하리라 하나의 API를 이전했음에도 불구하고 Allocation API 에 대해서는 약 1/3, 서버 Instance 비용은 1/2.5 수준으로 감소했습니다.   설명: 기존 4개의 Django 인스턴스의 CPU 사용률이 모두 13% 정도 감소, Go 인스턴스의 CPU 사용율은 17% 정도   17 / (13 * 4)  ≒ 1 / 3  충분히 만족할만한 성과가 나와서 그 뒤로 몇가지 API도 Go 로 옮겼고 새로 작성하는 API 는 Go 환경 안에서 직접 구현하는 중입니다. 처음에는 호출이 많은 하나의 API 를 다른 언어로 포팅하기 위해 시작한 작업이었는데 Container 기술을 도입하는 등 서버 Infra 까지 변경하면서 상당히 큰 작업이 뒤따르게 되었습니다. 하지만 이 작업을 하면서 많은 동료들의 도움과 조언이 있었고 결국 완성할수 있었습니다. 이렇게 실험적인 도전을 성공 할수 있는 환경에 여러분을 초대하고 싶습니다! Go언어에 대한 문의나 좋은 의견도 환영합니다.
조회수 1672

한국에서 SaaS 서비스 하기

와탭랩스 는 국내에서 보기드문 B2B SaaS 서비스 기업입니다. 그러다 보니 많은 도움도 받을 수 있었고 좋은 기업들도 많이 만날 수 있었습니다. 하지만 모든 것이 처음이다 보니 많은 실수들과 함께 커온 것도 사실입니다. 아래는 SaaS 기업들에게 꼭 필요한 내용들만 추렸습니다. 건너뛰거나 아직 진행 안한 내용들은 지금이라도 꼭 해보세요.  좋은 고객을 골라내세요. 와탭랩스는 서버 모니터링 서비스를 먼저 시작했습니다. 우리는 스타트업이 자사의 제품을 안정적으로 서비스하기 위해 우리의 제품을 사용할 거라 생각했습니다. 하지만 와탭에게 스타트업들은 생각처럼 좋은 고객은 아니였습니다. 그래서 우리는 서버 모니터링의 주요 고객층을 SMB 중에서 100대정도의 서버를 가진 기업으로 변경해야 했습니다. 우리는 초기에 좋은 제품을 만드는 일에 집중하고 좋은 고객을 찾는 과정을 허술히 생각했습니다만 그것은 큰 오판이였습니다. 우리는 우리가 만든 서비스를 사랑하는 사람들을 찾아 내는 데 최선을 다해야 합니다. 우리가 만든 제품의 가치를 지속적으로 발견해내는 고객들이 누군지 찾아 내야 합니다. 그러기 위해 계속 고객을 정의해 나가야 합니다."고객이 우리의 제품을 사는 것은 고객이 우리가 하는 일을 알아서가 아니라 우리가 고객이 하는 일이 무엇인지 알기 때문입니다." 계속, 끊임없이 고객을 분류하세요. 와탭의 서버 모니터링은 서비스에 가입하고 자사의 서비스에 에이젼트를 설치 한 후에 간단한 무료 모니터링을 시작으로 유료 기능까지 넘어가게 되어 있습니다. 반대로 와탭의 어플리케이션 모니터링은 가입 후 트라이얼 사용 후 유료 사용자로 넘어가게 구조화 되어 있습니다. 단계별 활성화 사용자와 비 활성화 사용자를 구별할 수 있어야 합니다. 단계별로 고객을 분류 할 수 없다면 분류할 수 있는 장치들을 마련해야 합니다.고객을 팬으로 만드세요. TV를 보면 많은 걸그룹과 남성그룹들이 나옵니다. 그리고 열성적이 팬들이 있죠. 그리고 팬들은 자신들만의 공간을 만들어 갑니다. 와탭도 그런 과정을 만들기 위해 노력하고 있습니다. 좋은 컨텐츠를 만들고 세미나를 열고 다양한 IT 행사를 지원합니다. 아직은 많이 어설프지만 와탭의 고객분들이 저희의 팬이 될 수 있도록 노력하고 있습니다. 와탭 사용자 분들은 앞으로 더 기대하셔도 좋습니다.  현재 줄 수 있는 가치로 고객을 유치하세요.항상 세일즈에게 당부드리는 이야기 입니다. 미래에 나올 기능으로 고객을 대하지 마라. 미래에 나올 A라는 기능을 대상으로 고객과 이야기 하면 고객은 A가 나올 때까지 기다립니다. SI 기술 영업인 경우에는 SI를 통해 제공 될 미래의 기능을 파는 것이지만 서비스를 파는 와탭랩스는 현재의 제공되는 서비스로 영업을 해야 합니다. 그렇기 때문에 현재 우리가 가지고 있는 제품이 고객에게 어떤 도움이 되는지 정확하게 이해하고 설명할 수 있어야 합니다. 이것은 와탭이 온라인 상에서 제공하는 마케팅에도 그대로 적용됩니다. 허황된 약속은 Churn Rate만 높일 뿐입니다. 우리가 고객에게 줄수 있는 가치를 정확히 전달해야 합니다. 이메일을 다양하게 사용하세요.와탭은 서비스를 오픈하고 처음에는 메일 서버를 만들어서 가입 인증 메일만 보냈습니다. 사용자가 쌓인 후에는 메일챔프를 사용해서 뉴스레터를 보내기 시작했죠. 이메일을 통해 튜토리얼을 보내거나, 교육 컨텐츠를 보내는 것도 좋은 방법입니다.Transactional Email을 사용하세요. 와탭도 이제 Transactional email을 추가하려고 준비 중에 있습니다. Transactional email은 가입 축하 / 유료 권유 / 패스워드 변경 등 가입 또는 사용 기간 및 상황에 맞쳐 자동으로 보내는 이메일 입니다. 대표적인 서비스로는 맨드릴 이 있습니다. Transactional Email을 사용해서 가입 축하 메일, 에이젼트 설치 튜토리얼 메일, 탈퇴 후 다시 돌아와 달라는 메일 등 다양한 메일을 보낼 수 있습니다.소셜 미디어를 사용하세요.제가 지금 사용하고 있는 브런치도 좋은 소셜 미디어 입니다. 제가 이 글 하나에 얼마나 많은 와탭링크를 남겼을까요? :) 유튜브 채널을 활용하는 것도 좋습니다. 페이스북은 이제 거의 필수죠. 회사마다 블로그도 운영하고 있을 것입니다. 슬라이드쉐어에 회사 관련한 많은 내용들을 올리는 것도 좋으며 큐오라도 적절하게 사용한다면 좋을 것입니다. 생태계를 배척하지 마세요. 와탭랩스는 클라우드협회의 회원사입니다. 클라우드 협외의 많은 분들이 다양한 경험을 바탕으로 국내 클라우드 사업과 SaaS 사업의 발전을 위해 노력하고 있습니다. 혹시 해외 사례와 비교하다보니 지엽적인 한계가 명확히 보일지도 모릅니다. 그럼 같이 들어와서 바꿔가면 됩니다. 와탭랩스가 서비스하는 IT 모니터링은 MSP(Managed Service Provider)와 영업을 전문으로 하는 리셀러사들이 복잡하게 얼켜있는 생태계를 구성하고 있습니다. 와탭은 좋은 솔루션을 제공하는 기업으로써 해당 생태계의 좋은 구성원이 되는 노력을 수년간 진행하고 있습니다. 자신의 생태계를 만들어 가세요. 최근 저희는 제2회 와탭 세미나를 개최했습니다. 이제 막 시작했지만 100명이나 모인 세미나였습니다. 규모를 키우다 보면 컨텐츠도 쌓일 것입니다. 와탭은 백엔드 서비스 기업들을 모인 백엔드클럽도 만들었습니다. 열심히 회원사로 활동도 해야겠지요. (아, 최근 열심히 못했습니다. 죄송합니다. ) 와탭은 성능 분석 전문가들이 모일 수 있는 플랫폼도 만들 계획입니다. 이처럼 직첩 다양한 생태계를 만들어 가는 것도 중요합니다. SaaS 세계에서는 이 모든 것들이 마케팅입니다. 회원 탈퇴를 숨기지 마세요.미국 엘리베이터에 닫음 버튼은 동작하지 않습니다. 장애인의 불편을 해소하고자 닫음 버튼을 막았지만 여전히 닫음 버튼이 엘리베이터에 있는 이유는 심리적 안정감(내가 엘리베이터의 문을 닫을 수 있다는)을 제공하기 위해서 입니다. 그런데 많은 서비스들이 회원 탈퇴를 숨기고 있거나 또는 애써 외면하고 있습니다. 숨긴다는 것보다는 신경을 안씀으로써 자연스레 숨겨지는 결과를 만들어 내는 것에 가까운것 같습니다. 이 또한 가입자에게는 심리적 압박감으로 다가올 수 있습니다. 그리고 사용하지 않는 사용자들만 사이트에 쌓이게 만드는 효과를 내기도 합니다. 차라리 탈퇴를 공개하고 탈퇴 시 이유를 묻는 과정을 넣는 것이 유리합니다. 탈퇴를 하는 이유를 조사하세요.정말 중요한 질문입니다. 왜 탈퇴를 하시는 건가요? 해당 질문은 탈퇴의 마지막 구간에서 집행하는 것이 좋습니다. 와탭랩스는 아직 해당 프로세스를 타고 있지 못합니다. 하지만 결국은 우리도 만들 예정인 프로세스입니다. 아쉽게도 한국은 서베이를 참 안해주는 국가로 알고 있긴 합니다. :)고객과 관계를 맺으세요.와탭은 무료 서비스와 트라이얼 서비스를 제공합니다. 물론 유료화가 최종 목표입니다. 그렇기 때문에 매일 아침 무료 고객과 트라이얼 고객의 서비스 이슈를 분석합니다. 알럿이 너무 많이 나온 고객에게 전화해서 이슈를 확인하고 도움을 드린다거나 설치에 곤란을 겪는 고객에게 전화를 드리고 시연을 진행하는 일들이 있습니다. 물료 유료 고객에게도 마찬가지입니다. 유료 고객에게는 성능 리포트를 무료로 제공해 드리기도 합니다. 신용카드를 통한 자동이체 프로세스를 만드세요. 대부부의 가맹점들이 공식적으로 지원하지 않는 것이 신용카드를 통한 자동이체 프로세스입니다. 특히 한국에서는 어떤 빌링사에서도 공식적으로 지원하고 있지 않습니다. 하지만 SaaS 서비스 기업이라면 꼭 진행하셔야 합니다. 혹 당장 안해준다면 고객을 조금만 모은다음에 다시 연결해 보세요. #와탭랩스 #와탭 #SaaS #인사이트 #운영 #SaaS서비스 #SaaS기업
조회수 2778

Node 서버로 Slack 메신저 자동화하기

Overview백엔드 업무를 하면 데이터 요청과 CS문의를 자주 받습니다. 날짜만 다를 뿐 같은 유형의 문의가 대부분이죠. 결국 반복적인 업무를 효율적으로 처리할 수 있는 방법을 고민했고, 사내 메신저로 사용하는 Slack의 몇 가지 API를 사용하기로 했습니다.1. 알림봇 만들기비즈니스 로직을 만들다 보면 정해진 시간에 맞춰 작업을 해야 하는 경우가 발생합니다. Slack 메신저에 로그온한 상태에서 스케줄러를 이용해 지정한 시간에 Slack 메세지를 전송해보겠습니다.1)Slack API 유저토큰 받기Slack API에 사용할 해당 계정의 토큰을 받아야 합니다. Slack 가입 절차 및 채널 생성은 생략하겠습니다.https://api.slack.com/custom-integrations/legacy-tokens 접속합니다.Legacy tokens 메뉴에서 아래로 스크롤을 내려 토큰 생성버튼을 누릅니다.계정 패스워드를 입력하여 확인하면 토큰을 생성할 수 있습니다.생성된 토큰을 복사하여 저장합니다.2)Node.js를 이용한 알림봇 구현2-1.Node.js 설치Node.js 다운로드 해당 사이트에서 운영체제 환경에 맞는 파일을 다운받아 설치2-2.프로젝트 생성해당 프로젝트 폴더로 이동 후 명령어 실행$ npm init --yes // package.json 파일 생성2-3.Slack 연동2-3-1. slack-node 모듈 설치$ npm install slack-node --save2-3-2. 유저토큰을 이용하여 해당채널에 메세지 전송const Slack = require('slack-node'); // 슬랙 모듈 사용 apiToken = "발급받은 유저토큰"; const slack = new Slack(apiToken); const send = async(message) => { slack.api('chat.postMessage', { username: 'dev-test', // 슬랙에 표시될 봇이름 text:message, channel:'#general' // 전송될 채널 및 유저 }, function(err, response){ console.log(response); }); } send('메세지 내용'); 지정한 채널에 메시지가 발송됩니다. 하지만 이와 같은 방법은 유저 토큰이 공개 코드에 노출되기 때문에 보안이 취약할 수 있습니다. 유저 토큰이 필요 없어도 해당 채널에 URL을 생성하는 WebHooks API를 이용하여 메시지를 전송해보겠습니다.3) Incoming WebHooks APIWebHooks는 유저 토큰 대신 Webhook URL을 생성해 HTTP 통신으로 Slack 메세지를 전송할 수 있습니다. 다양한 메시지 형식을 지원하고 게시할 사용자 이름 및 아이콘 등을 통합적으로 관리할 수 있는 장점을 가지고 있습니다.3-2. Webhook URL 생성하기Slack 해당채널에서 Add an app 클릭검색필터에 WebHooks 검색Incoming WebHooks 추가채널 선택 후 Incoming WebHooks 생성생성된 Webhook URL 복사하여 저장해당채널에 생성되었는지 확인봇이름 및 아이콘등 기본 설정 변경하여 저장curl 사용 예제$ curl -s -d "payload={'text':'메세지 내용'}" "Webhook URL"Webhook URL 사용 중인 모든 메시지는 통합적으로 기본 설정이 변경된 걸 확인할 수 있습니다.다양한 형식의 메세지를 전송해보겠습니다.const Slack = require('slack-node'); // 슬랙 모듈 사용 const webhookUri = "Webhook URL"; // Webhook URL const slack = new Slack(); slack.setWebhook(webhookUri); const send = async(message) => { slack.webhook({ text:"인터넷 검색 포털 사이트", attachments:[ { fallback:"링크주소: ", pretext:"링크주소: ", color:"#00FFFF", fields:[ { title:"알림", value:"해당링크를 클릭하여 검색해 보세요.", short:false } ] } ] }, function(err, response){ console.log(response); }); } 다양한 형태의 메시지를 전송할 수 있습니다.4) Schedule 연동이제 스케줄러를 이용하여 지정한 시간에 메세지를 전송해보겠습니다.4-1. node-schedule 모듈 설치node-schedule는 Node.js 작업 스케줄러 라이브러리입니다.$ npm install node-schedule --savenode-schedule 코드 작성const schedule = require('node-schedule'); // 스케줄러 모듈 사용 // rule-style 사용 var rule = new schedule.RecurrenceRule(); rule.dayOfWeek = new schedule.Range(3,4); rule.hour = 19; rule.minute = 50; schedule.scheduleJob(rule, function(){ console.log('rule 방식'); }); // cron-style 사용 schedule.scheduleJob('50 19 * * *', function(){ console.log('cron-style 방식'); }); 취향에 맞는 스타일로 사용하면 됩니다.5) 지정 시간에 메세지를 전송하는 알림봇을 작성해보겠습니다.const Slack = require('slack-node'); // 슬랙 모듈 사용 const schedule = require('node-schedule'); // 스케줄러 모듈 사용 const webhookUri = "Webhook URL"; // Webhook URL const slack = new Slack(); slack.setWebhook(webhookUri); const send = async(message) => { slack.webhook({ text:message, attachments:[ { fallback:"구글드라이브: ", pretext:"구글드라이브: ", color:"#00FFFF", fields:[ { title:"[알림]", value:"해당링크로 접속하여 작성해 주세요.", short:false } ] } ] }, function(err, response){ console.log(response); }); } schedule.scheduleJob('5 19 * * *', function(){ send('업무보고 보내셨나요?'); }); 업무보고 시간을 미리 알려주는 알림봇2. 대화봇 만들기업무 문서는 주로 구글 독스와 같은 온라인 문서로 관리하고 있습니다. 하지만 매번 구글 드라이브에서 문서를 찾는 건 정말 귀찮은 일입니다. 번거로운 건 딱 질색입니다. Slack API를 이용해 관련된 키워드를 입력하면 링크 주소를 바로 받을 수 있는 대화봇을 만들어 보겠습니다.1) Slack API Bots 토큰 받기Slack API에 사용될 Bots 토큰을 받아야 합니다.https://{App Name}.slack.com/apps 에 접속합니다.Bots 추가Bots Api 토큰을 복사해 저장합니다.설정한 봇이름으로 Apps 영역에 자동으로 추가됩니다.2) 구글독스 대화봇 코드 작성2-1. botkit 모듈 설치$ npm install botkit --save2-2. 코드 작성const botkit = require('botkit'); // 봇 모듈 사용 const Slack = require('slack-node'); // 슬랙 모듈 사용 const controller = botkit.slackbot({ debug: false, log: true }); const botScope = [ 'direct_message', 'direct_mention', 'mention' ]; controller.hears(['업무보고'], botScope, (bot, message) => { bot.reply(message, '업무보고 링크주소'); }); controller.hears(['가이드', 'guide', '튜토리얼'], botScope, (bot, message) => { bot.reply(message, '가이드 링크주소'); }); controller.hears(['api', '명세서'], botScope, (bot, message) => { bot.reply(message, 'api명세서 링크주소'); }); controller.hears(['일정', '일정관리'], botScope, (bot, message) => { bot.reply(message, '일정관리 링크주소'); }); controller.hears(['비품', '비품정리'], botScope, (bot, message) => { bot.reply(message, '비품관리 링크주소'); }); controller.spawn({ token: '발급받은 봇 토큰' }).startRTM(); 지정한 키워드를 입력하면 해당 링크가 수신 됩니다.3) 데이터문의 대화봇 코드 작성데이터 요청 시 결과 데이터를 보내주는 대화봇을 만들어 보겠습니다. 일단 먼저 데이터문의 전용 Bots을 생성합니다.3-1. Python 연동 요청한 데이터는 Mysql 데이터를 조회해서 전송합니다. 그러면 Mysql 을 연동해야겠죠? Node.js에서도 직접 mysql 연결할 수 있지만, 기존 프로젝트가 Python으로 구현되어 있어 Python을 실행해 필요한 데이터를 추출해보겠습니다.3-2. python-shell 모듈 설치Node.js에서 Python 실행가능하도록 모듈을 설치$ npm install python-shell --save3-3. Mysql Sample Table3-4. 회원테이블에 저장된 가입일시 기준으로 몇일전에 가입한 회원을 추출하여 전송하는 코드 작성해 보겠습니다.const botkit = require('botkit'); // 봇 모듈 사용 const Slack = require('slack-node'); // 슬랙 모듈 사용 const ps = require('python-shell'); // 파이썬 쉘 모듈 사용 // 몇일 전 날짜 구하기 function getDaysAgo(dayNo = 0) { let nowDate = new Date(); let tempDate = nowDate.getTime() - (dayNo * 24 * 60 * 60 * 1000); nowDate.setTime(tempDate); let getYear = nowDate.getFullYear(); let getMonth = nowDate.getMonth() + 1; let getDay = nowDate.getDate(); if (getMonth < 10 xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed> 3-5. Python 코드 작성 # -*- coding: utf-8 -*- import sys import pymysql // mysql 접속 db = pymysql.connect('hostname', user='', passwd='', db='', charset='utf8') cursor_db = db.cursor() exe_query = "SELECT MEMBER_NAME FROM MEMBER_INFO WHERE MEMBER_REGIST_DETE >= '{}' ORDER BY MEMBER_NO ASC ".format(sys.argv[1]) cursor_db.execute(exe_query) all_rows = cursor_db.fetchall() for idx, row in enumerate(all_rows): print(row[0])     지정한 며칠 전에 가입한 회원 이름이 전송됩니다.   로그도 정상적으로 출력됩니다. 3. Node.js 프로세스 관리를 위한 pm2 모듈 설치 Node.js 는 비동기 I/O를 지원하며 단일 스레드로 동작하는 서버입니다. 비동기식 방식이지만 처리하는 Event Loop는 단일 스레드로 이루어져 있어 처리 작업이 오래 걸리면 전체 서버에 영향을 줍니다. 그래서 pm2를 이용해 프로세스별로 상태를 관리해야 합니다. 1) pm2 모듈 설치$ npm install pm2 -g2) 자주사용하는 pm2 명령어 pm2 list -> 실행중인 프로세스 확인pm2 start {node 파일} -> 시작pm2 stop {id or App name} -> 중지pm2 delete {id or App name} -> 삭제pm2 show {id or App name} -> 상세정보pm2 restart {id or App name} -> 재시작pm2 kill -> pm2 종료pm2 logs {id} -> id 앱의 로그 확인 3) pm2 실행화면$ pm2 start bot.js   프로세스별로 앱 이름, 버전, 상태, cpu 및 memory 사용량이 표시됩니다.$ pm2 show 0   해당 프로세스의 상세 정보를 확인할 수 있습니다. Conclusion 지금까지 Node.js 로 유용한 Slack 메신져 API를 알아봤습니다. 반복적인 업무를 하나씩 줄이다 보면 분명 일의 능률을 높아집니다. 하지만 무분별한 자동화는 서버의 부하를 증가시키기 때문에 꼭 필요한지 확인하고 선택하길 바랍니다. 오늘은 여기까지 글곽정섭 과장 | R&D 개발1팀kwakjs@brandi.co.kr브랜디, 오직 예쁜 옷만  
조회수 945

[인공지능 in IT] 인공지능과 저널리즘

얼마 전, 재미있는 기사를 읽었다. 일본의 한 SF 공모전에 응모한 작품 1,400편 중 인공지능이 작성한 소설 두 편이 예선 심사를 통과했다는 내용이었다. 이 중 소설 한편의 제목은 '컴퓨터가 소설을 쓴 날'이다. 소설을 작성하는 인공지능 기술을 개발한 연구팀은 육하원칙 등의 제시어를 준 뒤, 연관어에 따라 소설을 쓰는 알고리즘을 활용했다.미디어 혹은 인공지능 분야에 생소한 독자들에게 다소 신기할 수 있겠지만, 사실 인공지능을 활용한 저널리즘은 수 년 전부터 진행 중이다. 국내에서는 2014년 서울대학교 언론정보학과의 'hci+d Lab' 이준환 교수팀이 개발한 알고리즘을 시초라고 할 수 있다. '프로야구 뉴스 로봇'이라고 불리는 소프트웨어는 KBL의 모든 경기를 자동으로 요약해 정리한다. 연구팀이 처음부터 이 같은 기능을 염두에 둔 것은 아니었고, 데이터를 시각화하는 과정에서 시각화 방식을 텍스트로 바꿔본 것이 연구의 시작이라고 한다. 위 사례는 사람이 아닌 기계가 직접 '글'을 작성했다는 점에 있어 의미가 크다. 미디어 업계에서도 디지털화는 불가항력 같은 존재가 되고 있다.얼마 전, 옥스퍼드-로이터 저널리즘 연구소에서 미디어 업계를 대상으로 조사를 시행했다. "2018년 실행해야 할 가장 중요한 과제는 어떤 것이라고 생각하는지"에 대한 물음에 "데이터 수용량을 증가시키는 것"을 가장 많이 답변했다. 모바일 알림, 웹사이트나 애플리케이션에 사용자를 등록시키는 일 등 여러 과제들이 있었지만, IT 솔루션 업계도 아닌 미디어 업계가 데이터 수용량 증가를 최우선 과제로 생각하고 있다는 사실은 개인적으로 매우 충격적이었다. 또한, "현재 귀사에서는 기사 보도에 있어 어떠한 용도로 적극적인 인공지능 기술을 도입할 예정입니까?"라는 질문에 '컨텐츠 추천', '업무 자동화', '기삿거리 탐색' 등 다양한 분야에서 인공지능 기술 도입을 계획하고 있었다. 그만큼 이미 언론에서도 인공지능 기술은 먼 세상 이야기가 아닌, 당장 피부로 느껴질 정도로 가까워졌다.세계 최대 통신사 중 하나인 'Associated Press(AP)'는 2017년 'The Future of Augmented Journalism: A guide for newsrooms in the age of smart machines'이라는 인공지능 활용 기술 가이드를 발간했다. 해당 가이드에 따르면, 인공지능은 언론에서 크게 다섯가지 영역으로 활용된다. 이에 대한 예시를 하나씩 살펴보도록 하자.첫번째로 'Machine Learning', 즉 기계학습이다. 기계학습을 이용하면, 방대한 데이터로부터 결론을 도출하는 과정을 쉽게 처리할 수 있다. 그리고 기계학습 알고리즘을 통해 기자들은 이미지를 포함한 막대한 양의 자료를 한 번에 처리할 수도 있다. 미국의 매체 'Quartz' 소속 'Sarah Slobin' 기자가 트럼프 미국 대통령의 취임 연설에 대한 기사에 기계학습을 이용한 분석 자료를 쓴 일례가 있다. 트럼프의 얼굴 표정과 연설에서 표현된 감정을 판단하는 데에 기계학습 알고리즘을 사용한 것.< 출처: Quartz, 제공: 스켈터랩스 >두번째 활용 영역은 'Language'다. 인공지능 분야에서 언어에 대한 연구는 꾸준히 이어지고 있는데, 언어 처리 분야 중에서도 저널리즘과 관련 있는 기술은 '자연어 생성'과 '자연어 처리'다. 당연하겠지만, 자동으로 문장을 생성하는 것은 언론에서 매우 유용하게 사용할 수 있는 기술 중 하나다. 'LA Times'는 'LA Quakebot'이라는 서비스를 개발했다. 'LA Quakebot'은 자연어 생성 기술을 활용해 지역에서 지진이 일어난 순간, 이미 작성된 프레임에 맞춰 기사를 작성하며, 완성된 기사는 트위터를 통해 송출한다.< 출처: LA QuakeBot 트위터, 제공: 스켈터랩스 >세번째는 'Speech'로, 저널리즘에서 대화형 인터페이스가 뉴스 소비 및 유통에 어떠한 영향을 미칠 지 관심을 가지고 있다. 이미 'AP', 'Wall Street Journal', 'BBC', 'Economist' 등 여러 미디어가 오디오 인터페이스 기술을 시도하는 것으로 알려졌다. Speech 역시 크게 두 가지로 나뉘는데, 'TTS'라고 불리는 'Text-To-Speech'를 활용하면 뉴스룸에서 제공하는 문자 기사를 음성으로 변환시키고, 합성된 음성을 콘텐츠로 송출할 수 있다. 반대로 'STT', 즉 'Speech-To-Text'를 활용하면 음성으로부터 의미를 잡아내고, 모든 의도와 목적에 맞춰 음성을 문자로 변환시키며, 이를 통해 기자들이 인터뷰 내용을 녹취하는데 소요하는 시간을 줄일 수 있다.< 출처: BBC NEWS LABS, 제공: 스켈터랩스 >네번째, 듣는 것과 녹취하는 것을 넘어 눈으로 본 것을 기록할 수 있는 'Vision' 기술이다. 컴퓨터 비전을 활용하면 빠르고 쉽게 이미지 및 영상을 분류하고 정리할 수 있다. 용이한 검색을 통해 궁극적으로 편집 속도까지 높일 수 있는 셈이다. 'AP'는 인공위성으로 수집한 영상 데이터를 공급하는 'Digital Globe'라는 기업을 통해 동남아 선박의 고해상도 위성사진을 확보했다. 이를 통해 노예선에 관한 탐사보도에 필요한 결정적인 증거를 찾으며, 2016년 공공서비스 부문 퓰리처상을 수상했다.< 출처: AP, 제공: 스켈터랩스 >마지막으로 'Robotics'를 꼽을 수 있다. 로봇 센서를 활용해 사건 사고에 대한 사람들의 반응을 실시간으로 측정할 수 있으며, 앞서 언급한 'Quakebot'의 예처럼 자연재해가 발생하는 것에 대해 다룰 수 있다. 'AP'는 2016년 하계올림픽 당시, 로봇과 원격 카메라를 이용해 기자들이 물리적으로 직접 접근할 수 없는 지역에 카메라를 설치하고, 원격 조종해 촬영했다. 또한, 드론을 이용해 이라크 모술 남동쪽 다이바가 근처에 추방된 이라크인들을 촬영해 중독 지역 난민 위기에 대해서도 보도한 바 있다.< 출처: AP, 제공: 스켈터랩스 >이렇듯 인공지능이 미디어 업계 전체에 긍정적인 영향을 주고 있으며, 이를 활용한 사례는 앞으로도 더욱 늘어날 것으로 전망한다. 다만, 지속적으로 발전하는 인공지능을 무조건 도입하는 것만이 능사는 아니다. 인공지능 기술의 확산으로 보도 속도, 보도 규모 및 범위 등에 도움될지라도, 데이터의 질에 따라 좋지 않은 기사가 나올 수 있기 때문이다. 'AP'의 스마트머신 시대 뉴스룸을 위한 가이드에도 언급된 포인트로 마무리를 해보자.1. 인공지능은 저널리즘의 도구이지, 저널리즘을 대체하지 않을 것이다.2. 인공지능은 인간과 마찬가지로 편향적이고, 실수를 할 수도 있다. 이는 데이터가 모든 것을 결정하기 때문이다.3. 인공지능이 만병통치약은 아니다. 최근 자율주행 자동차 사고 이슈처럼 기술이 극복하지 못하는 문제는 여전히 존재한다.4. 인공지능에 대해 더 많이 알아야 인공지능 활용 가능성의 문이 크게 열린다.5. 저널리즘의 도구가 변한다고 해서 저널리즘의 법칙이 변하지 않는다. 언제나 윤리와 기준은 매우 중요하다.이호진, 스켈터랩스 마케팅 매니저조원규 전 구글코리아 R&D총괄 사장을 주축으로 구글, 삼성, 카이스트 AI 랩 출신들로 구성된 인공지능 기술 기업 스켈터랩스에서 마케팅을 담당하고 있다 #스켈터랩스 #기업문화 #인사이트 #경험공유 #조직문화 #인공지능기업 #기술기업
조회수 1321

AWS X-Ray를 이용한 분산 애플리케이션 분석

OverviewMSA(Micro Service Architecture)를 구축하다 보면 분산 애플리케이션에 대한 분석, 디버깅, 모니터링이 어려울 때가 있습니다. 이 문제를 풀기 위해 AWS에서는 X-Ray라는 분산 추적 시스템을 제공하고 있는데요. X-Rray는 요청이 애플리케이션들을 통과하는 전체 과정을 추적합니다. 오늘은 Lambda에서 X-Rray를 사용하는 방법을 간단하게 살펴보겠습니다. lambda debuggingAWS Lambda 콘솔 > 함수선택 > Configuration > Debugging and error handling > Enable active tracing 을 선택합니다.AWS X-Ray 서비스맵Lambda에서 Enable active tracing만 선택해도 Lambda 서비스용 노드와 Lambda 함수용 노드를 확인할 수 있습니다.Lambda SDK를 추가해 하위 세그먼트를 구성하고, 주석 및 메타 데이터를 포함시키는 등의 작업을 할 수 있습니다. 이번 글에서는 Python SDK를 이용해 샘플을 만들어 보겠습니다. 우선, pip로 aws-xray-sdk를 설치합니다.SDK 패치X-Ray에서 지원하는 라이브러리를 패치해 SDK가 하위 세그먼트를 생성하고 레코딩할 수 있도록 합니다. 그 다음 patch_all 함수를 사용해 지원되는 모든 라이브러리를 패치합니다. (patch 함수로는 특정 라이브러리만 패치할 수 있습니다.)X-Ray 지원 라이브러리 (18.07.10 현재) botocore, boto3, pynamodb, aiobotocore, aioboto3, requests, aiohttp, httplib, http.client, sqlite3, mysql-connector-python subsegment 생성 및 metadata 작성subsegmentxray_recorder.begin_subsegment/end_subsegment 메서드를 사용해 하위 세그먼트를 구성할 수 있고, @xray_recorder.capture 데코레이터를 사용해 함수에 대한 하위 세그먼트를 생성할 수 있습니다.annotation, metadataput_annotation을 사용해 주석을 기록할 수 있고 put_metadata를 사용해 메타데이터를 기록할 수 있습니다. 1) Service mapTrace timelineSegment annotationSegment metadata서비스 맵을 통해 요청에 대한 노드 연결을 시각화해서 확인할 수 있습니다. 간단한 방법으로 서비스 오류, 병목, 지연 등 애플리케이션의 여러 문제를 식별할 수 있습니다. Service map errorTrace timeline errorSegment Exceptions서비스 맵과 타임라인을 이용하면 동기/비동기 요청, 서비스별 상태 및 오류 내용까지 확인할 수 있습니다. Service mapTrace timeline지금까지 분산 애플리케이션 환경에서 사용하는 AWS X-Ray의 기본 기능들을 실행했습니다. 기본적인 기능들만 살펴봤는데도 AWS 플랫폼의 분산 어플리케이션 환경에서 요청 추적 및 검토, 문제식별, 성능개선 등을 유용하게 활용할 수 있다는 걸 알 수 있었습니다. 추가적인 설명은 아래 참고의 링크들을 확인해주세요. 1) 어노테이션 데이터는 검색용으로 인덱싱되고 메타데이터는 검색에 사용할 수 없습니다. 참고AWS X-Ray – 분산 추적 시스템AWS X-Ray SDK for Python - AWS X-Ray글이상근 팀장 | R&D 개발1팀leesg@brandi.co.kr#브랜디 #개발자 #개발팀 #인사이트 #경험공유
조회수 895

flake8-import-order-spoqa

안녕하세요. 스포카 프로그래머 홍민희입니다.스포카 사내에서는 파이썬 코드의 스타일을 맞추기 위해 flake8을 사용해왔습니다. PEP 8 스타일을 준수하게 해주고, 안 쓰는 임포트를 꼭 지우게 하는 등의 좀더 구체적인 규칙도 지키게 해주는 린트 도구입니다. 사실상의 표준이기 때문에 파이썬을 이미 쓰고 있는 분들이라면 많이들 알고 계실 것입니다.그렇지만 import문의 사용에 대해서는 우리가 원하는 것만큼의 규칙을 제공하지 않아서, 예전부터 동료 강효준 님이 import-order를 별도로 만들어서 써왔습니다. 만들었을 당시에는 import문의 쓰임에 대한 린트 도구가 없었기 때문에 유용하게 써왔고, 다른 파이썬 오픈 소스 프로젝트에서도 유용할 것 같다고 생각하여 쓰인지 1년쯤 지난 뒤에 오픈 소스로 공개했습니다.하지만 flake8과는 다르게 외부 커뮤니티에서 널리 쓰이지는 못했고, 사실상의 표준이 되었다면 편집기 연동 등이 이뤄졌겠지만, 그에 미치지는 못했습니다. pre-commit hook이나 CI에서나 검사가 이뤄지기 때문에, 코딩을 마쳤다고 생각한 이후에 뒷북으로 실수를 바로잡는 일이 많아 불편했습니다.그 뒤로 시간이 지나자 커뮤니티에서는 flake8-import-order라는 도구가 나와서 사실상의 표준이 됐습니다. 이미 많은 편집기에서 연동이 되는 flake8의 확장으로 구현됐기 때문에 편집기에서 즉시 확인이 가능했고, 더 많은 옵션도 제공했습니다. 그렇지만 cryptography 프로젝트 사람들이 만든 도구다보니, cryptography 스타일 및 Google 스타일 등 몇 가지만 제공했고, 이 도구를 활용하려면 스포카에서 3년 넘게 쓰이던 import 스타일을 포기하고 사내의 모든 코드를 전부 수정하는 난리를 피우거나, flake8-import-order에 스포카 사내 스타일을 옵션으로 추가하거나, 프로젝트를 포크해서 별도로 유지보수하며 써야 했습니다.사내 모든 코드를 전부 수정하는 것은 쉽지도 않을 뿐더러, 스포카에서 쓰이던 스타일에도 나름의 논거는 있기 때문에 쉽게 포기하기는 힘든 결정이었습니다. 일부 프로젝트부터 옮겨가는 시도도 있었으나, 같은 회사에서 코드마다 스타일의 일관성이 달라지는 혼란이 있었습니다.저는 flake8-import-order에 스타일을 추가하는 것을 주저했습니다. Google 스타일처럼 문서화가 이미 아주 자세히 되어 있지도 않고 유명하지도 않은, 일개 회사의 사내 스타일을 사실상의 표준 린트 도구의 7번째 공식 지원 스타일로 추가하는 것이 이뤄질 개연성이 낮다고 봤습니다.그래서 프로젝트를 포크하기로 마음먹은 것이 보름 전쯤입니다. 그런데 코드를 열어보니 좀더 나은 아이디어가 떠올랐습니다. flake8-import-order의 코드를 고치지 않고 런타임에 스타일을 확장 가능한 플러그인 구조를 추가하면, 스포카에서 쓰는 import 스타일을 별도 패키지로 구현할 수도 있다는 생각이 든 것입니다. 당시 flake8-import-order의 스타일 구현은 Style의 기반 클래스를 상속받는 식으로 이뤄져 있었고, 다만 스타일의 목록이 하드코딩되어 있는 것이 문제였습니다. 막상 코드를 읽어보니 플러그인 구조를 도입하는 것이 어렵지 않을 것이라는 생각이 든 것입니다.파이썬 생태계에서는 서로 다른 패키지 사이에서 런타임에 확장 가능한 의존성 주입을 위해 setuptools 시스템이 엔트리 포인트라는 개념을 제공합니다. 예를 들어 국제화 라이브러리인 Babel은 파이썬 이외의 프로그래밍 언어에서도 gettext 문자열을 extract할 수 있게 하기 위해, 확장 가능한 babel.extractors 엔트리 포인트를 노출합니다. 그리고 별도의 템플릿 언어인 Jinja는 해당 템플릿 엔진을 쓸 때 국제화도 대응할 수 있도록, babel.extractors 엔트리 포인트에 Jinja 언어를 해석하는 jinja2.ext.babel_extract를 주입합니다.저는 같은 개념을 활용하여, flake8-import-order가 flake8_import_order.styles라는 엔트리 포인트를 노출하게 하는 패치를 제출했고, 다행히도 업스트림에 받아들여졌습니다.flake8-import-order를 런타임에 확장할 수 있는 구조가 됐으니, flake8-import-order 위에서 스포카의 import 사용 가이드를 구현하는 것은 어렵지 않은 작업이었습니다. 어차피 스포카의 파이썬 코딩 스타일은 대부분 PEP 8을 그대로 따르고 있었고, 따라서 flake8-import-order에 이미 존재하는 스타일 구현에서 몇 부분만 덮어씌우는 것으로 충분했기 때문입니다.위와 같은 장광설 끝에, 그래서 이번에 소개하려고 한 스포카의 파이썬 import 린트 도구는 flake8-import-order-spoqa입니다. 만든지 보름이 지난 뒤에 소개하는 것은, flake8-import-order에 제출한 패치가 포함된 0.12가 PyPI에 릴리스될 때까지 기다려야 했기 때문입니다.사용법은 어렵지 않습니다. pip로 flake8-import-order-spoqa를 설치한 뒤에, flake8 설정에 다음 옵션을 추가하면 됩니다.[flake8]import-order-style = spoqa#스포카 #개발 #개발자 #개발팀 #개발팁 #꿀팁 #인사이트
조회수 1403

박문수 이야기

출근 첫날 이효진 대표님으로부터 입사 지원 메일을 하나 전달받았다. 이력서를 살펴보니 컴퓨터를 전공하지도 않았고, 현재 개발을 하고 있지도 않았지만 개발자로 일하고 싶다고 적혀 있었다. 개발을 할 수만 있다면 인턴부터 시작해도 좋다고 말했다. 남들이 부러워하는 삼성에 다니고 있는데 어떤 이유로 개발자가 되고 싶어 할까? 궁금한 마음에 한 번 만나보기로 했다. (뽑을 생각은 없었다)첫인상은 그냥 수수한 시골 청년이었다. 나도 입사한 지 얼마 안 되어 회사 주위 식당을 몰라 그냥 눈에 띄는 식당으로 들어갔다. (생각해 보니 그 식당을 그 이후로는 한 번도 가지 않았다) 지난 회사에서 어떤 일들을 했고, 왜 개발에 대한 목마름을 느꼈는지를 들었다. 개발자가 되기 위해 어떤 것들을 포기할 수 있는가에 대한 각오도 들었다.나는 앞으로 일 년 동안 인턴 월급을 받아야 할지 모른다고 이야기했다. 정말 열심히 하지 않으면 그저 그런 개발자가 되어 인생이 꼬일지도 모른다고 경고했다. 그런데도 흔쾌히 도전해보고 싶다고 말했고, 나는 배움의 기회를 제공하겠다는 약속을 했다. 좋은 대학을 나와 어렵게 얻은 직장을 포기하고 다시 새로운 길을 선택하려는 용기를 높이 샀다. 입사일은 3주 뒤로 정했다. 파이썬 책과 웹 프로그래밍 기본 책을 던져주고 모두 읽어 오라고 했다.입사 후 정신없이 3주가 지나고 문수님이 입사를 했다. 첫날 개발 환경을 셋업 하는 것을 도와주었다. 나에게는 너무나도 자연스러운 많은 것들이 그에게는 생소한 것이고 설명을 해야 했다. 문수님이 이해할 수 있는 간단한 것만 설명하고 나머지는 더 크면 알게 된다고 설명을 미루었다.(첫날 전체를 대상으로 자기소개를 하는 문수님. 우리 회사에는 입사자가 전체를 대상으로 자기소개를 하는 문화가 있다. 이 문화의 유래에 대해서는 다시 한 번 이야기해 보겠다.)내가 모든 것을 알려 줄 수는 없으니 코세라 수업을 같이 들어 보자고 이야기했다. 내 기준으로는 너무 쉬운 강의였지만 나는 회사 내에서 공부하는 분위기를 만들어 가고 싶었고 문수님께는 회사에서 필요한 기술 스택을 맛보는 기회가 될 수 있으리라 생각했다. (현재 시점으로 3달째 코세라 강의를 이어서 듣고 있다.)첫 강의인 HTML5를 들으면서 간단한 버그 수정부터 문수님께 요청을 하기 시작했다. 오자를 고치거나 박스의 위치를 조정하는 일부터 시작했다. 입사하고 3일이 지나서 첫 번째 배포를 했다. 처음이 어려웠을 뿐 간단한 수정을 하는 것에는 일주일이면 충분했다. 그때부터는 git과 git flow를 알려주기 시작했다. 착한 신입은 마음이 열려 있어서 불만 없이 모든 것을 따라 했다. 어느 정도 이해를 했는지는 알 수가 없다. 하지만 프로그래밍을 배우는 길에는 머리보다 손이 먼저 익히는 것들도 많다.3주가 지난 시점에는 첫 번째 데모를 전체 앞에서 보였다. (우리는 스크럼을 하고 있어서 매번 스크럼이 끝나는 날에 개발자가 스스로 자신이 개발한 것을 전 직원 앞에서 데모를 보인다.) 지금은 잠깐 문을 닫은 채권 거래소에서 채권 판매자가 손쉽게 채권을 팔 수 있는 기능이었다. 그것을 만들기 위해 일주일 넘게 꽁꽁 머리를 싸매고 있었고, 결국은 결과물을 내놓았다.(첫 번째 데모를 보이는 문수님. 긴장한 모습이 느껴진다. 데모를 마치고 다들 뜨거운 박수를 보내주었다)내가 만들면 2시간이면 끝났을 기능이라 일주일간 고생하는 것을 옆에서 지켜보는 것은 상당한 인내를 필요로 했다. 하지만 최대한 혼자만의 힘으로 첫 번째 과제를 해내기를 원했기에 최소한의 도움만을 주었다.이제 문수님이 입사한 지 만 3개월이 되었다. 그동안 많은 변화가 있었다. 회사에서 조그마한(점점 커지고 있다) 수정/기능들은 대부분 맡아 주고 있기에 다른 개발자들은 좀 더 어려운 문제를 풀 수 있게 되었다. 처음에는 코드 리뷰를 온라인으로 할 수가 없었다. 옆에 앉아서 어떤 부분을 어떻게 고쳐야 하는지를 구체적으로 알려 주어야 했고, 이해하지 못하면 관련된 지식을 얻을 방법을 알려 주어야 했기 때문이다. 하지만 이제 github의 PR을 보고 코멘트를 다는 것 만으로 코드를 적절히 수정할 수 있게 되었다. 얼마 전에는 하루에 1억이 넘는 이체를 하는 내부 시스템을 80% 이상 만들기도 했다. (내가 뼈대는 잡아 주기는 했다.)개발자라 부를 수 있는 기준이 따로 있겠냐만은 나는 이제 그를 개발자라 부를 수 있을 것 같다. 아마도 오늘의 문수님에게는 “개발자 박문수 님”이 가장 듣고 싶은 호칭이 아닐까 생각한다.  마지막으로 전공하지도 않았고, 첫 직장과도 관련 없는 새로운 도전을 하는 문수님의 용기에 박수를 보낸다. 내게 말하지는 않았지만 수많은 주위의 걱정과 우려를 이겨내기 위해 최선을 다하고 있으리라 생각한다. 나는 앞으로 그에게 “문수님은 지금 어디로 가고 있나요?"를 종종 물어봄으로 내 역할을 해야겠다.8퍼센트는 멋진 저희 팀과 함께 할 분들을 찾고 있습니다. 특히 저보다 개발을 잘 하시는 시니어 개발자, 그리고 3년 뒤에는 저 보다 잘하게 되실 주니어 개발자는 제가 모시러 갑니다. hr@8percent.kr로 연락 주세요.박문수 님이 이체 시스템 개발을 할 때 Toss의 이체 대행 API를 사용했습니다. 정말 간편합니다. 관련 개발을 하시는 분들은 사용해 보세요.#8퍼센트 #에잇퍼센트 #채용 #채용후기 #개발자 #개발자채용 #인턴 #인턴채용 #스타트업CTO
조회수 1460

확률론적 프로그래밍 언어는 왜 필요 할까요?

AI•머신러닝은 모든 분야에서 거론되며 이를 적용해볼 수 있는 다양한 AI•머신러닝 툴들이 쏟아져 나오고 있습니다. 기본적인 머신러닝 기법들을 담고 있는 scikit-learn을 시작으로 deep learning이 화두가 되며 구글에서 내놓은 tensorflow까지 다양한 회사, 연구원이 오픈소스 트렌드에 맞춰 수많은 머신러닝 라이브러리를 공개하고 있습니다. 이러한 라이브러리들은 기존의 프로그래밍 언어를 이용하여 효율적으로 계산될 수 있도록 개발, 패키징 되어 보다 손쉽게 머신러닝을 체험해볼 수 있습니다. 최근에는 기존 프로그래밍 언어로 개발된 머신러닝 라이브러리를 넘어서 머신러닝 기법에 특화된 확률론적 프로그래밍 언어(Probabilistic Programming)들이 개발되고 있습니다. 이는 기존 하드웨어에서 머신러닝 계산에 적합한 GPU 하드웨어의 폭발적인 인기를 넘어서 인공지능에 최적화된 하드웨어(Google Tensor Processing Unit) 개발 시도가 소프트웨어에서도 일어나고 있다고 생각합니다. 백문이 불여일견이니만큼 엘리스에서 간략한 소개 튜토리얼을 해보실 수 있습니다.구글 Tensor Processing Unit (TPU)확률론적 프로그래밍 언어란?확률론적 프로그래밍 언어는 머신러닝 분야, 확률과 통계 분야, 그리고 프로그래밍 언어 분야, 총 세 분야를 아울러 만들어진 새로운 프로그래밍 언어입니다. 기존의 전산학(Computer Science)은 주어진 변수/파라미터가 있고, 이를 프로그램 및 계산하여 결과 값을 얻습니다. 머신러닝 내에서 주로 쓰이는 방법은 추론인데 이는 관측되는 결과 값 들이 있고, 이를 다양한 수학적 방식으로 추론하여 변수/파라미터값들을 구합니다. 따라서 확률 통계의 수학적 계산법을 직관적으로 프로그래밍 할 수 있기 위해선 기존의 전산학 방식이 아닌 새로운 방식의 프로그래밍 언어가 필요하고, 확률론적 프로그래밍 언어는 이러한 패러다임에 맞춘 시도라고 볼 수 있습니다. 이렇게 개발된 언어는 복잡한 머신러닝 기법도 간략한 코드로 개발할 수 있게 하는 목표를 가지고 있습니다.확률론적 프로그래밍 언어란? (NIPS Tutorial 2015)확률론적 프로그래밍 언어 리스트 (Wikipedia)우리에게 아직은 생소해 보이는 확률론적 프로그래밍 언어는 현재 활발히 연구되고 있으며, 그 종류도 30가지가 넘습니다. 각 확률론적 언어는 기존의 다양한 프로그래밍 언어에서 파생 되었는데요, 엘리스에서 사용하는 주 언어 중 하나인 Python을 기반으로 한 PyMC3을 기반으로 튜토리얼을 만들었습니다.그 외 실제 실험에서 적용된 Picture라는 확률론적 프로그래밍 언어는 2D 얼굴 사진을 토대로 3D 얼굴을 모델하는 프로그램을 단 코드 50줄로 만들어 2015년에 공개되었습니다. 이를 보통 프로그래밍 언어로 개발했다면, 몇 천줄로 개발되어야 했다고 합니다.마치며이번 글에서는 간략하게 확률적인 프로그래밍 언어를 소개했습니다. 아직은 생소할 수 있지만, 점점 다양한 분야에서 머신러닝이 사용 될 수록 이에 적합한 확률론적 프로그래밍 언어의 연구, 개발은 활발해 질 것으로 예상됩니다. 지금 엘리스에 로그인 하셔서 확률론적 프로그래밍 언어 실습 예제를 실행해보세요!엘리스에 올려진 실습문제를 실행하면 책에서만 보던 이런 그래프들이 무슨 의미인지 이해하고 실제로 그려볼 수 있습니다!글쓴이김재원: The Lead, Elice김수인: KAIST 전산학부 박사과정박정국: KAIST 전산학부 박사과정#엘리스 #코딩교육 #교육기업 #기업문화 #조직문화 #서비스소개
조회수 4233

개발자 직군 파헤치기 4 | 빅 데이터 엔지니어

빅 데이터 엔지니어는 무엇을 하나요?빅 데이터가 부상하면서 그와 관련된 직업군도 함께 주목받기 시작했습니다. 빅 데이터 엔지니어, 빅 데이터 애널리스트, 빅 데이터 사이언티스트 등 다양한 직업군이 생겼습니다. 오늘은 개발자 직군 중 데이터와 관련된 빅 데이터 엔지니어에 관해 이야기해 볼 것입니다. 빅 데이터 엔지니어는 무엇을 할까요? 빅 데이터 엔지니어가 무엇을 하는지 알기 위해서는 먼저 빅 데이터가 뭔지 알필요가 있겠습니다.빅 데이터는 기존 데이터베이스 관리도구의 능력을 넘어서는 대량의 정형 또는 심지어 데이터베이스 형태가 아닌 비정형의 데이터 집합조차 포함한 데이터로부터 가치를 추출하고 결과를 분석하는 기술입니다(위키 참조).빅 데이터의 특징은 방대한 데이터와 더불어 비정형 데이터까지 포함한다는 것입니다. 많은 양의 데이터와 정형화 되지 않은 데이터를 수집하는 일은 보통 일이 아닙니다. 빅 데이터를 통한 새로운 알고리즘를 만들거나 인사이트를 발견하기 위해서는 빅 데이터가 존재해야 합니다. 빅 데이터 엔지니어는 이러한 빅 데이터를 수집하고 관리하는 프로그래머입니다. 일반적인 데이터 수집과 달리 수십테라 정도의 정보를 수집 하게 됩니다. 또 그런 데이터를 어떻게 효율적으로 관리할지 고민해야합니다.데이터는 미래의 석유라고 합니다. 빅 데이터 엔지니어는 빅 데이터 분석가나 과학자들에게 이러한 석유를 가져다 주는 송유관을 설치하고 관리하는 역할을 한다고 볼 수 있습니다. 빅 데이터 활용을 위해서라면 빅 데이터 엔지니어의 역량이 반드시 필요합니다.데이터 과학자와 데이터 엔지니어는 다르다.위에서 빅 데이터 엔지니어는 데이터를 수집하고 관리하는 업무를 한다고 했습니다. 하지만 구체적으로 빅 데이터 과학자(Big Data Scientist)와 빅 데이터 엔지니어(Big Data Engineer)는 무엇이 다를까요?어떤 직업의 업무라는 것이 무 자르듯 쉽게 나눌 수 있는 것은 아니지만 확실히 그 직업만의 특징은 존재합니다. 각 직업 별로의 특징을 통해 빅 데이터 엔지니어가 빅 데이터 과학자와 어떻게 다른지 알아보도록 하겠습니다.1. 빅 데이터 엔지니어(Big Data Engineer)빅 데이터 엔지니어는 위에서도 언급 했지만, 데이터를 수집하고 관리하는 일을 합니다. 빅 데이터 엔지니어를 통해 '빅 데이터'가 만들어진다고 해도 무방하죠. 숫자나 규칙이 있는 정형 데이터는 물론이고 글자나 불규칙적인 비정형 데이터까지 수집하고 관리합니다. "그냥 데이터를 수집하고 관리하는 일인데 별거 있나?"라고 생각하실 수도 있습니다. 빅 데이터라는 개념 이전에도 데이터는 수집되었고 분석을 통해 비즈니스 문제를 해결해 왔으니까요. 그렇지만, 빅 데이터라는 개념이 부상하고 실현 가능할 수 있었던 이유는 방대한 데이터를 수집할 수 있는 퍼널(funnel) 설계과 그 데이터를 관리하고 알맞게 사용할 수 있는 시스템을 구축할 수 있었기 때문입니다.그렇기 때문에 빅 데이터 엔지니어는 프로그래밍에 아주 능숙해야합니다. 빅 데이터를 수집하고 관리할 수 있는 방법을 짜야하니까요. 또한, 개별적인 정보가 아닌 큰 틀에서의 정보를 다루고 통합하고 나누어 볼 수 있는 설계 능력이 따라주어야 합니다.정교하게 짜여진 빅 데이터가 아니라면 빅 데이터 과학자가 그것을 분석하고 사용하는데 상당한 자원이 들거나 최악의 경우 아예 이용하지 못하게 될 것입니다.2. 빅 데이터 과학자(Big Data Scientist)빅 데이터 엔지니어가 빅 데이터를 수집하고 관리한다면 빅 데이터 과학자는 그것을 요리하는 역할을 합니다. 데이터보고 직면한 비즈니스 문제를 해결할 새로운 인사이트를 도출해 내는 것입니다. 혹은 현재 가지고 있는 프로세스를 개선할 알고리즘을 만들어 낼 수도 있습니다.빅 데이터 과학자는 데이터를 분석할 수 있는 통계학적 지식뿐만 아니라 그 데이터를 다룰 수 있는 프로그래밍적 지식도 요구됩니다. 일반적인 데이터가 아닌 '빅' 데이터다 보니 그것을 쉽게 운용하고 자유자재로 이용하게 해줄 툴을 익혀야합니다. 또한, 빅 데이터 과학자에게 요구되는 핵심 역량 중 하나는 바로 머신러닝에 대한 지식입니다. 이 또한 프로그래밍 지식과 알고리즘 지식이 필요합니다. 빅 데이터 엔지니어가 되기 위한 Key Skills그렇다면 빅 데이터 엔지니어가 되기 위해서는 어떤 기술 스택들을 익혀야할까요? 빅 데이터 엔지니어는 데이터와 관련된 직군인만큼 데이터베이스와 관련된 기술스택들이 중요합니다.1. SQL데이터 관리를 하시는 분들이면 다들 알고 계시는 SQL입니다.  SQL은 관계형 데이터베이스 관리 시스템의 데이터를 관리하기 위해 설계된 특수 목적의 프로그래밍 언어입니다(위키참조).2. MapReduce(맵리듀스)맵리듀스는 구글에서 대용량 데이터 처리를 분산 병렬 컴퓨팅에서 처리하기 위한 목적으로 제작하여 2004년에 발표한 프레임워크입니다.(위키참조).3. Apache Hadoop(아파치 하둡)Apache Hadoop은 대규모 데이터 세트를 효율적으로 처리하는 데 사용할 수 있는 오픈 소스 소프트웨어 프로젝트입니다. 하나의 대형 컴퓨터를 사용하여 데이터를 처리 및 저장하는 대신, 하둡을 사용하면 상용 하드웨어를 함께 클러스터링하여 대량의 데이터 세트를 병렬로 분석할 수 있습니다.4. Apache Cassandra(아파치 카산드라)Apache Cassandra 자유-오픈 소스 분산형 NoSQL 데이터베이스 관리 시스템의 하나로, 단일 장애점 없이 고성능을 제공하면서 수많은 서버 간의 대용량의 데이터를 관리하기 위해 설계되었습니다. 카산드라는 여러 데이터센터에 걸쳐 클러스터를 지원하며 마스터리스(masterless) 비동기 레플리케이션을 통해 모든 클라이언트에 대한 낮은 레이턴시 운영을 허용합니다(위키참조).5. Java(자바)빅 데이터 엔지니어는 기본적으로 프로그래머이기 때문에 프로그래밍 지식있어야 합니다. 빅 데이터 엔지니어를 목표로 처음 프로그래밍을 시작한다면 자바를 추천합니다. 물론, 다른 언어를 통해 프로그래밍 실력을 쌓아도 됩니다. 그렇지만, 아파치 하둡과 아파치 카산드라가 자바를 베이스로 만들어졌기 때문에 자바를 배운다면 이 기술스택들을 습득하는데 훨씬 효율적일 것입니다.다른 포스팅에서도 항상 말씀드려왔지만 기술스택만 익힌다고 해서 그 직업을 가질 수 있는 것은 아닙니다. 기술스택은 기본이고 개발자로써의 역량이 뒷받침 되어야 시장에서 환영받는 빅 데이터 엔지니어가 될 수 있습니다.Photo by Ehud Neuhaus on Unsplash빅 데이터 엔지니어가 되기 위한 학습 콘텐츠시중에서는 완성된 단계로써 빅 데이터 엔지니어를 양성하는 프로그램은 많지 않습니다. 따라서 개인이 빅 데이터 엔지니어에게 필요한 기술 스택들을 하나씩 익혀 나가야 합니다.무료 온라인 콘텐츠도 많겠지만, 비싸지 않으면서도 잘 정제된 콘텐츠를 소개하려고 합니다. 유튜브 강좌보다는 보기 편하고 학습 환경이 잘 갖춰져 있어서 공부하기에 좋은 콘텐츠를 추천합니다.1. SQL - SQL 프로그래밍 : SQL을 무료로 학습할 수 있는 사이트(한글)2. Hadoop - 유데미 The Ultimate Hands-On Hadoop - Tame your Big Data! (영어)3. Cassandra - 유데미 From 0 to 1: The Cassandra Distributed Database (영어)데이터 엔지니어는 예전부터 있었다.오늘은 빅 데이터 엔지니어에 대해 알아보았습니다. 사실, 빅 데이터 엔지니어는 어느 날 갑자기 생겨난 직업이 아닙니다. 데이터베이스를 관리하는 프로그래머가 더 나은 기술 스택을 익히고 더 좋은 방법으로 데이터를 수집하고 관리하면서 생겨난 것입니다.세상은 빠르게 변한다고 하지만 그 안을 들여보면 서서히 발전한 것들이 다르게 네이밍(Naming) 되면서 새롭게 다가오는 것이라 생각합니다. 그렇다고 해서 그것이 변하지 않는 것이 아닙니다. 새롭게 변하는 기술들을 익히고 자신의 역량을 갈고 닦아야만 새롭게 다가오는 변화에 휩쓸리지 않고 주도할 수 있는 것 같습니다.
조회수 661

비트윈이 사용자를 분석하는 방법 - VCNC Engineering Blog

 빅데이터분석이 최근 이슈가 되면서 관심이 많으실 것 같습니다. 비트윈팀도 데이터 분석 참 좋아하는데요, 저희도 한번 해보았습니다. 이번 포스팅에서는 비트윈팀의 데이터 분석 노하우를 아낌없이 공유해드립니다.왜 사용자의 데이터를 분석해야하는가요?비트윈같은 서비스는 초기 단계에는 앱을 기획하고 만들어낸 팀에 아이디어에 의해 계속해서 발전하고, 유지됩니다. 하지만 기능이 점점 다양해지고 사용자가 점점 많아지면서 사용자들의 앱 사용패턴을 점점 예측하기 어려워집니다. 게다가 비트윈은 해외 진출을 구상 중이었는데, 개인 혹은 팀의 아이디어만으로 해외에서의 사용패턴을 정확히 알기는 어려웠습니다.이런 시점에 필요한 것이 사용자 분석입니다.사용자들의 사용패턴을 분석해 보는 방법은 여러 가지가 있습니다. 초기에 해볼 수 있는 가장 직관적이고 쉬운 것은 비트윈을 사용하는 자기 자신의 사용 패턴을 돌아보고 분석해보는 것입니다. 또 친구들이나 익명 사용자들의 사용패턴을 물어보거나, 관찰하는 방법들이 있습니다. 이런 방법은 매우 효과적이고 많은 아이디어를 주지만 여러 가지 한계점이 있습니다. 지역적, 시간적인 한계 등이 그것입니다.그래서 택할 수 있는 방법이 실제로 사용자들의 행동을 컴퓨터로 수집해서 분석하는 것입니다. 말 그대로 '데이터 분석'을 하게 되는 것입니다.무엇을 분석할지 알아야 합니다데이터로 분석할 수 있는 것은 무궁무진합니다만, 먼저 데이터가 있어야합니다. 비트윈과 같이 서버와 통신하는 앱은 사용자들이 서버에 요청을 할 때마다 엑세스 로그를 남기게 됩니다. 이 엑세스 로그는 사용자들의 사용패턴을 고스란히 담고 있어, 소중한 데이터가 됩니다.엑세스 로그 분석은 전혀 어렵지 않습니다. 엑세스 로그에서 특정 행동에 해당하는 내용을 세는 것만으로도 여러 가지 유의미한 값을 얻어낼 수 있습니다. 하루 동안의 로그를 한줄씩 읽어서 메시지에 관련된 로그를 카운트하면 그날의 메시지 전송 건수를 얻을 수 있는 것입니다. (참 쉽죠?)엑세스로그에서 가입, 메시지, 사진, 메모 등 기본적인 내용에 해당하는 것들을 카운트하는 것만으로도 꽤 자세하게 앱 전체 사용자들의 전반적인 사용통계를 얻어낼 수 있습니다. 이제 해당 데이터를 엑셀에 넣어서 차트를 그려보면, 사용 통계에 대한 그럴싸한 차트가 그려집니다.엑세스 로그 분석에 성공했다면 좀 더 다양한 분석을 해볼 수 있을 텐데요, 사용자별 행동패턴 분석이나, 나라별, 혹은 아이폰, 안드로이드 디바이스별 분석 등 다양한 분석을 시도해볼 수 있습니다. 분석을 하기 전에 중요한 것은 무엇이 궁금한지, 어떻게 궁금한 데이터를 모을지 아이디어를 먼저 내는 것입니다. 여러 예제들을 찾아보며 공부해보면, 금방 좋은 아이디어를 얻으실 수 있을 겁니다.물론 여기서 중요한것은 개인정보나 사생활의 보호입니다. 로그가 유출되었을때의 보안 문제 뿐 아니라, 데이터 분석팀에게조차 개인정보가 노출된다면 곤란합니다. 이 문제에 저희가 어떻게 대처하고 있는지는 글 뒷부분에 자세히 알려드리겠습니다.특정 기술에 구애받지 말고 다양하게 구현해봅시다처음에는 로그 파일을 돌며 간단한 string을 검사하는 스크립트와 엑셀로도 충분했지만, 점점 복잡한 분석을 할수록 다양한 기술이 필요해집니다. 비트윈 사용자 분석도 점점 다양해지고 복잡해지면서 여러 가지 기술들을 사용하고 있습니다.비트윈 사용자 분석은 처음에는 6줄짜리 간단한 shell script에서 시작되었습니다.cat 2011-10-31.log | grep /messages | grep POST | wc -l cat 2011-10-31.log | grep /photos | grep POST | wc -l cat 2011-10-31.log | grep /memos | grep POST | wc -l cat 2011-10-31.log | grep /like | grep POST | wc -l cat 2011-10-31.log | grep SIGN | wc -l cat 2011-10-31.log | grep REL | grep POST | wc -l 이런 스크립트를 만들어서 결과를 이메일로 공유하거나, 엑셀로 만들어 놓곤 했습니다.여기에 비트윈 분석은 조금 더 발전하여, 로그파일을 쿼리하여 Map Reduce 작업이 가능한 Hive를 사용하고, PHP로 통계 웹사이트를 만들어 차트를 그리기 시작했습니다. 이 방식은 처음에는 매우 편리했지만 차츰 쿼리만으로 원하는 결과를 얻기가 힘든 다소 복잡한 분석이 필요해지기 시작했습니다.현재는 모든 로그를 분산 데이터베이스인 HBase에 Date Key와 User Key로 넣고, 코드 생산성이 좋은 Scala로 직접 Map Reduce코드를 작성해서 데이터들을 분석하고 있습니다. 그래서 충분히 scalable하면서도 꽤 편리하게 이용할 수 있는 데이터베이스를 활용하고, Scala의 좋은 expression을 활용하여 짧고 유지보수나 확장이 쉬운 코드로 분석을 수행하면서도 Java와 호환되는 Scala의 특성을 이용하여 Map Reduce 코드 작성을 효과적으로 하고 있습니다. 이렇게 분석한 데이터는 MySQL에 넣어서 2차로 가공하고, Scala Web Framework인 Play Framework을 이용하여 분석 사이트를 구축하고 D3 Chart를 이용해서 Visualize하고 있습니다. 이렇게 함으로써 편리한 MySQL 쿼리 사용의 장점을 취하고 멋진 차트를 효과적으로 그려낼 수 있습니다.좋은 Visualization은 멋질 뿐만 아니라 손쉽게 아이디어를 공유할 수 있게 해줍니다.앞으로는 더 빠른 성능을 위해 Hive를 더 잘 사용해보거나, Elastic Search같은 index engine들을 사용해 볼 계획도 가지고 있습니다. 또한 End point들에서 직접 성능을 측정하여 중앙으로 모아서 분석해보려는 생각도 가지고 있습니다.기술을 선택함에 있어서 정답은 없는 거 같습니다. 널리쓰이는 MySQL같이 scalability가 좀 떨어지지만, 다양한 쿼리로 높은 생산성을 낼 수 있는 데이터베이스도 있고, HBase같이 scalability가 좋지만, 데이터를 저장하는 형태에 제한이 있어 생산성이 조금 떨어지는 데이터베이스도 있습니다. 저희는 앞서 소개드렸듯이 이 두 가지를 모두 혼용하여 사용하고 있습니다. 각자가 마주한 상황에 맞게, 또 각자가 익숙한 기술에 맞게 설계하고, 사용해보면 됩니다.개인정보 보호는 철저하게빅데이터 분석이 개인정보를 침해하는 빅 브라더가 될 수 있다는 우려들이 나오고 있습니다. 300만이 넘는 커플들의 비밀스러운 일기를 담고 있는 비트윈 서비스는 당연하게도 모든 업무를 진행하는 데 있어 보안과 개인정보를 최우선으로 하고 있습니다. 데이터 분석에서도 분석할 수 있는 내용을 상당히 제한받더라도, 예외 없이 그 원칙을 지키고 있습니다.비트윈의 API서버는 AWS클라우드에서 운영되고 있는데, 사용료가 상당히 비싸기 때문에 큰 컴퓨팅 파워를 사용해야 하는 데이터분석까지 AWS에서 하기엔 좀 부담이 되었습니다. 그래서 PC급 컴퓨터 여러 대를 구입하여 사무실 구석에 쌓아놓고 사용하고 있습니다.하지만 문제는 보안이었습니다. AWS의 비트윈 API서버는 다중으로 보안이 유지되고 있지만, 사무실에 있는 서버에 사용자들의 개인정보를 담아둘 수는 없는 일이었습니다. SECO*이 사무실을 지켜주고 있긴 하지만 보안회사에 고객들의 소중한 개인정보를 맡기고 안심할 수는 없으니까요. 그리고 설사 보안 문제가 잘 해결된다고 해도, 분석을 수행하는 비트윈 데이터분석팀원에 개인정보 혹은 사생활이 노출된다면 그 또한 문제라고 생각하였습니다.그래서 저희가 생각해낸 방법은 '익명화'입니다. Access Log들을 저장할 때 사용자의 아이디를 전부 단방향 salted-hash하여 누구인지 알 수 없게 만들었습니다. (물론 salt key는 데이터 분석팀은 알 수 없습니다.) 그리고 애초에 Access Log에는 '어떤 사람'이 '50글자짜리 메시지를 보냈다' 라던가, '사진을 올렸다' 정도만 기록이 되기 때문에, 이를 통계적으로 분석하는 것은 유의미하지만, 사적인 정보를 담고 있지는 않습니다.익명화되어 처리되고 있는 로그는 개인정보는 거의 담고 있지 않으면서도, 유익한 분석 결과를 만들어줍니다.이런식으로 운영을 한다면 데이터 분석팀에서도 사적인 정보(예: 메시지 내용)에 대해서는 접근할 수 없기 때문에, 회원들의 소중한 개인정보와 사생활을 지킬 수 있습니다. 어떤 분석을 수행할 때 언제나 비트윈팀은 언제나 보안과 사생활 보호의 원칙을 지킬 수 있는 범위에서만 진행하고 있습니다.아이디어의 공유, 그리고 액션아이템이 무엇보다도 중요합니다데이터 분석의 목표가 무엇인지, 왜 해야 하는지 생각해보면, 무엇을 해야 하는지 알 수 있습니다. 바로 분석으로부터 얻은 아이디어를 공유하고 액션아이템을 정하고 실천하는 것입니다.데이터를 visualization하는것이 중요한 이유가 여기에 있습니다. 보기 좋은 떡이 먹기도 좋다는 말이 있듯이, 데이터도 먹기 좋아야 합니다. 여러 사람이 쉽게 이해할 수 있어야 아이디어를 공유하고 의사결정을 내리기가 수월하기 때문입니다.민트&베리 사용량 분석. 연인들이 쓰는 앱이라 사랑표현이 인기가 많군요. 디자인팀이 이런 자료를 참고하여 이후 디자인 아이디어를 내는 데 도움이 되면 좋겠죠?비트윈팀은 매번 데이터 분석 미팅을 진행하고 나면 액션아이템을 정하고 실천합니다. 저희가 어떤 식으로 의사결정을 내리고 행동하는지에 대해서는 비트윈 팀블로그의 VCNC는 데이터분석에 기반해 어떤 결정을 내렸나 포스팅을 보시면 도움이 되실 것 같네요.맺으며이번 포스팅에서는 비트윈팀이 어떻게 무엇을 분석하는지 간단하게 다뤄봤습니다. 의견이나 참견 모두 환영이니 댓글 많이 남겨주세요! 다음번 포스팅엔 기술적인 부분에 대해 좀 더 자세하게 다뤄보도록 하겠습니다.

기업문화 엿볼 때, 더팀스

로그인

/