2018년 12월 25일 화요일

Elastic Stack 6.5 업데이트.

사용할 계획은 없지만 관심은 항상 있는 Elastic Stack의 6.5 업데이트 소식.
마이너 버전 업이지만 마이너한 것은 없는 릴리즈라는 개발사의 얘기처럼 방대한 양의 기능 업데이트가 있었다.

https://www.elastic.co/kr/blog/elastic-stack-6-5-0-released


Cross-Cluster Replication (Beta | Platinum)

한 클러스터의 인덱스를 다른 클러스터로 이중화(replicate) 해준다. 기존의 다른 클러스터 이중화 기법들보다 오버헤드가 적고, 추가적인 자원(임시 저장장치 등)이 필요하지 않으며 시스템 복잡성도 낮다. Follower가 Leader를 실시간 룩업, 인덱스 변화를 관찰하여 변경점을 복제한다.

이 기능을 활용함으로서 장애 복구(Disaster Recovery), 글로벌 서비스의 경우 지역별로 복제본을 두어 시스템 응답성을 높일 수 있다. (Data Locality) 그리고 여러개로 나누어져 운용되는 클러스터의 데이터를 한군데로 모아 통합 쿼리를 수행하거나 리포트를 만들 수도 있다. (Central Reporting Center)


_source Only Snapshot (데이터 복원 기능)

전체 풀 스냅샷 대비 50%정도의 저장 공간을 차지한다. 소스만 저장하고 복원하는 방식이기 때문에 복원(restore)하는데 재색인을 필요로 한다. 긴 복원 시간과 적은 저장 공간의 trade off.


Canvas !! (Beta | Basic)

Kibana의 신규 기능으로 Canvas는 기존 대비 향상된, 마치 파워포인트를 이용해 페이지를 만드는 것과 유사한 경험을 가져다 준다. 데이터의 라이브 쇼케이스 기능으로 나만의 방식으로 데이터에 대한 스토리텔링을 할 수 있다. Elasticsearch SQL을 지원하고 보고서 파일 생성이 가능.


Rollups in Kibana (Beta | Basic)

자동으로 데이터를 집계가 필요한 부분만 roll up 해서 관리한다. 통계성 데이터만 저장하므로 데이터의 저장 공간이 절약되고 적은 양의 데이터를 대상으로 하기 때문에 집계 쿼리가 빨라진다.

기타 6.5엔 Beats를 중앙에서 관리하는 도구인 Beats Central Management, 서버리스 아키텍쳐의 function 레벨로 사용가능한 새로운 타입의 Beat은 Functionbeat. Metric Beat와 연동하여 수많은 인프라 기반의 동작 데이터를 한 눈에 볼 수 있는 큐레이션 도구인 Infrastructure UI 등의 신규 기능이 도입되었다. Basic 라이센스로 제공되는 Machine Learning의 Data Visualizer는 사용자가 업로드하는 데이터 파일의 구조를 시각화해준다. 대략적인 데이터의 속성과 분포를 알려주는 것 뿐만 아니라 잘 아는 형식에 대해선 Grok pattern도 제공해주고 있다.

Java 11 버전을 지원하며 G1 가비지 컬렉터를 사용할 수 있게 되었으며 이번 업데이트를 통해선 6.3에서 지원하던 JDBC 드라이버 뿐만 아니라 ODBC 드라이버도 지원한다. Elastic Stack은 데이터를 다루는 솔루션이 제공해야할 기능의 모범사례를 누구보다 빠르고 적확하게 제공하기 때문에 데이터 관련된 일을 하는 사람이라면 Elastic Stack을 사용하지 않더라도 변경점에 대해서 관심을 가져야 할 것이란 생각이 든다.


2018년 12월 19일 수요일

시리얼 통신 (RS-232)

시리얼 통신

1. 직렬 통신은 하나 또는 두 개의 전송 라인을 사용하여 한 번에 한 비트씩 데이터를 지속적으로 송수신하는 통신 방법이다.

2. 직렬 통신에서 데이터는 하나의 신호선을 사용해 한번에 한비트씩 전송되므로, 수신측에서 데이터를 정확하게 수신하려면 송신측에서 비트를 어떤 속도로 전송하는지 알고 있어야 한다.

3. 전송 표준으로 RS-232C, RS-422A, RS-485가 있다.

4. 커넥터는 주로 D-sub 25핀, D-sub 9핀이 사용된다.
 DTR: Data Terminal Ready, 데이터 터미널 준비
 TXD: Transmit Data, 전송 데이터
 RXD: Receive Data, 수신 데이터
 RI: Ring Indicator, 착신 표시
 CTS: Clear to to Send, 송신 허가
 RTS: Request to Send, 송신 요구
 DSR: Data Set Ready, 데이터 세트 준비
 ,..... 기타

5. 설정 값.
 5.1 전송 속도: 초당 보낼 비트 수를 지정한다. (Baudrate)
 5.2 정지 비트 길이: 데이터의 끝을 나타내는 비트의 길이. 일반적으로 1, 1.5, 2비트.
 5.3 데이터 비트 길이: 일반적으로 영숫자 및 기호에는 7비트, 1바이트 이진 데이터에는 8비트.
 5.4 패리티 체크 설정: 데이터에서 오류를 찾는 기능. 짝수 패리티, 홀수 패리티, 패리티 없음 중 하나.

시리얼 통신은 Com Port를 통해 Read Write하는 단순한 구조기 때문에 Open, Close, Read, Write의 4가지 명령을 통해 작업을 제어하게 된다.

.Net Framework 환경에서의 프로그래밍

SerialPort 클래스가 정의되어 있고, 데이터 수신, 에러 수신, 핀 체인지에 대한 이벤트 설정을 할 수 있게 되어 있다. {System.IO.Ports (Assemblies: System.dll, System.IO.Ports.dll)}

설명 및 예시:
https://docs.microsoft.com/ko-kr/dotnet/api/system.io.ports.serialport?view=netframework-4.7.2


Win32 API 환경에서의 프로그래밍

파일 다루듯 다루어진다.

 1. 포트 열기: CreateFile
 2. 포트 구성: SetCommState, SetCommTimeouts
 3. 데이터 전송: WriteFile
 4. 데이터 수신: ReadFile
 5. 장치 모니터링: SetCommMask

써야되는지 알고 식겁했다.

2018년 12월 10일 월요일

[Spring] Configuration, Bean 어노테이션

org.springframework.context.annotation의 Configuration 어노테이션과 Bean 어노테이션을 이용하면 Spring Container에 새로운 Bean 객체를 제공할 수 있다.

@Configuration
public class AppConfig {
  @Bean
  public MyBean myBean() {
    // instantiate, configure and return bean ...
  }
}

초기화 과정에서 특정 값을 지정할 경우엔 다음과 같이 할 수 있을 것이다. (@Value, @Autowired, ..)

@Configuration
@PropertySource("classpath:/com/acme/app.properties")
public class AppConfig {
  @Inject Environment env;

  @Value("${bean.name}") String beanName;

  @Bean
  public MyBean myBean() {
    // return new MyBean(env.getProperty("bean.name"));
    // or
    // return new MyBean(beanName);
  }
}

여러 개의 @Configuration 간 의존 관계는 @Autowired나 클래스 상단에 @Import 구문을 이용해 지정할 수 있다.

@Configuration을 <XML>로 표현하면 다음과 같다.
<beans>
  <context:annotation-config/> <!-- enable ConfigurationClassPostProcessor -->
  <bean class="com.acme.AppConfig"/>
</beans>

참고로 @Configuration 어노테이션을 사용한 클래스에서 @Bean 어노테이션을 사용한 함수가 리턴하는 객체는 Singleton으로 관리된다.

적용된 내용은 AnnotationConfigApplicationContext로 가져올 수 있다.

ApplicationContext context = new AnnotationConfigApplicationContext();
context.register(AppConfig.class);
context.refresh();

MyBean myBean = ctx.getBean(MyBean.class);
// use myBean...

@Bean 어노테이션과 함께 initMethod, destroyMethod를 지정할 수 있는데 이는 각각 초기화/종료 메서드에 대한 것이다.
@Configuration과 @Bean은 @Profile 어노테이션과 결합하여 'production', 'development' 등 환경에 따라 다르게 동작하게끔 할 수 있다.

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html

JPA 기본 골격.

// Entity
@Entity
@Data
@NoArgsConstructor
public class Member {
 @Id // javax.persistence.Id
 @GeneratedValue(strategy=GenerationType.AUTO)
 private long id;

 @Column(nullable = false, length = 30)
 private String name;

 private int age;

 public Member(String name, int age) {
  this.name = name;
  this.age = age;
 }

 @Override
 public String toString() {
  return String.format("Member[id=%d, name='%s', age=%d]", id, name, age);
 }
}

// Repository
public interface MemberRepository extends CrudRepository<Member, Long> {
 List<Member> findbyNameAndAgeLessThan(String name, int age);
 List<Member> findbyNameAndAgeLessThanOrderByAgeDesc(String name, int age);

 @Query("select t from Member t where name=:name and age < :age")
 List<Member> findByNameAndAgeLessThan(@Param("name") String name, @Param("age") int age);
}

// Booter
@EntityScan(basePackages="package.name")
@EnableJpaRepositories(basePackages="another.package.name")
@SpringBootApplication
public class TestJpaApplication {
 public static void main(String[] args) {
  SpringApplication.run(TestJpaApplication.class, args);
 }
}

참고로 JPA가 제공하는 Repository의 상속 계층은 다음과 같다.
CrudRepository만 써도 일반적인 CRUD 작업은 할 수 있다.

1. public interface Repository<T, ID extends Serializable>
2. public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID>
3. public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID>
4. public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>

https://www.concretepage.com/spring-boot/spring-boot-crudrepository-example

2018년 12월 6일 목요일

[BlockChain] 이더리움 2.0

이더리움의 최종 목적지는 Serenity, 이더리움 2.0이라고 불리기도 한다. (* Serenity는 고요함, 맑음의 뜻을 가지고 있다.)



현재는 Metropolis 단계로 Metropolis는 비잔티움과 콘스탄티노플로 세분화되어 있다. 그 다음이 Serenity다. (* 콘스탄티노플은 1월로 연기된 바 있다.)

현 단계에서 이더리움은 UX에 대해서도 고민이 많다고 한다.
예를 들면 '당신의 할머니가 비트코인을 사용할 수 있는가?'에 대한 솔루션을 찾아가는 것이다.

Serenity의 핵심은 Sharding, Casper(PoS, Proof of Stake)로 요약된다.

특정 블록 체인은 Decentralization, Scalability, Safety 3가지를 모두 만족시킬 수 없다 (Blockchain Trielemma). 이더리움은 상대적으로 Scailability에 약점이 있어서 TPS가 낮은 편이다. 이더리움은 Serenity에 Sharding 기법을 적용해서 이를 일부 극복하고자 한다. 그런데 Sharding은 PoW 방식에서 동작하지 않으므로 PoS를 같이 도입할 계획을 가지고 있다.

이더리움이 완전한 PoS로 전환하는 것은 아니고, 현재 동작하는 PoW 네트워크 하위에 PoS 레이어를 둬서 PoW와 PoS를 조합해서 사용하는 방식을 구상중이다. 이를 Casper라고 한다. 4개의 Layered Architecture로 구성되어 있다.

  1. Main Chain (PoW) - 기존의 이더리움 네트워크
  2. Beacon Chain (2019) - 코디네이션 수행. PoS 노드를 샤드에 할당하는 등의 관리 레이어.
  3. Shard Chain (2020) - Data Layer, 여기에 PoS 노드가 위치. 특징으로 30 ETH만 있어도 PoS에 참여 가능. 대쉬의 경우 PoS 노드에 참여하려면 1억 가량이 필요하다고 한다.)
  4. Execution VM (2021) - 잘 모르겠다..


** PoW (Proof Of Work)
PoW는 컴퓨팅 파워를 이용, 새로 생기는 블록의 nonce 값을 찾아내 거래의 유효성을 증명하는 방식. Nonce 값을 찾아낸 사람은 거래의 유효성을 증명해 준 것에 대한 대가로 코인을 받게 된다.

(Difficulty에 따라 선택된 target 데이터 규격을 만족시키는) nonce 값을 풀기 위한 공식은 따로 없으므로 채굴자는 숫자를 하나씩 넣어보는 수 밖에 없다. 블록의 nonce 값을 찾기 위해서는 평균 수천조 번 이상의 시도가 필요하여, 이를 한명이 시도하기는 불가능하다. 이 때문에 특정 단체에 자신의 컴퓨팅 파워를 할당해주고 해당 단체에서 채굴에 성공한 경우 컴퓨터 파워를 할당한 양만큼 코인을 나눠받는 방식이 많이 이용된다. 이 단체를 '마이닝 풀'이라고 부른다. Difficulty는 조절 알고리즘에 의해 변화되며 10분당 1~2개의 블록이 생성되는 것을 보장한다.

** PoS (Proof Of Stake)
PoS는 지분을 이용한 거래 유효성 증명방식이다. 지분을 많이 가진 노드는 데이터를 업데이트할 권한을 더 많이 갖게 된다. 각 노드가 옳다고 생각하는 블록에 동의를 하면서 자신이 가진 지분을 해당 블록에 보여주고 증명하는 것이고, 과반수의 자산이 동의한 블록이 더 빠르고 더 길게 블록을 형성하게 된다.

거래 수수료는 블록을 생성한 노드가 가져간다. 다른 참여자에게는 이자와 유사한 방식으로 코인이 지급되며 일정한 양 이상의 코인을 보관하고 있는 지갑을 블록체인 네트워크와 연결시킬 경우 보상을 받을 수 있다.


Price 상 나쁜 상황이지만 이더리움은 로드맵을 충실히 따라가고 있을 뿐이다.

의식의 흐름을 따라가면서 정리한 Auth.

Authentication : A client must provide some evidence of who they are. This might involve signed certificates or it might involve credentials like a username and password. It might involve multiple factors, such as an sms message to a phone that the user should have access to. The web server must validate this authentication.
→ 특정 서비스의 서버는 사용자가 누구인지 식별할 수 있어야 한다.

Authorization : A server must define areas of authority and allocate these to groups of users. Furthermore, individual users must be defined as members of the authorization groups.
→ 클라이언트가 서비스에서 이용 가능한 기능의 범위. 권한에 대한 영역을 설정하고 각각의 사용자를 특정 권한 그룹에 포함시키는 것이 일반적.

인증 정보를 제공하는 다양한 방법이 있다.
  1. 인증서: 암호화된 인증서로 디지털 서명 뿐만 아니라 인증 기관에 대한 참조를 포함한다. 이러한 인증서는 SSL(Secure Socket Layer)를 통해 교환된다. 일반적으론 서버 측에서 단방향으로 제공되는 정보이지만 특정 환경에서는 클라이언트와 서버가 모두 상호 인증에 사용되는 인증서를 갖고 있어야 하는 경우도 있다.
  2. API 키 / 토큰: 웹 서비스는 특정 리소스에 접근 가능한 키를 제공할 수 있다. 키에 라이프-타임을 지정할 수도 있을 것이다.
  3. 사용자 이름 / 비밀번호: 웹 서버는 사용자 이름과 비밀번호를 통해 사용자를 식별할 수 있다. e-mail, SMS 인증 단계가 추가될 수 있다.
  4. 타사(Third-party) 인증: OpenID와 같은 서비스. 모든 사이트에 방문할 때마다 새로운 계정을 만들고 관리할 필요가 없다. 특정 사이트(Relying Party)는 OpenID Provider에게 인증을 위임하게 된다.


HTTP 인증

  1. HTTP "Basic" 인증: 사용자 계정과 패스워드를 전송하는 방식. Base64 인코딩을 이용한다. 클라이언트 서버 간의 안전한 데이터 교환(암호화)을 위해 SSL(Secure Socket Layer)을 사용하며 각 요청에 Authorization 헤더가 포함된다.
https://developer.mozilla.org/ko/docs/Web/HTTP/Authentication
  2. HTTP "Digest" 인증: 클라이언트가 서버에 특정 페이지를 요청하면 서버는 Digest 인증이 필요하다고 통보하면서 nonce(자주 바뀌는 증표) 값 등의 서버 정보를 함께 전달한다. 클라이언트는 전달받은 nonce와 클라이언트 정보를 결합해 MD5(권장 알고리즘) 암호화하여 전송하고 서버는 이를 검증한다.


OpenSSL

OpenSSL은 Self-signed certificate를 만들 수 있는 툴이다. 프로덕션 레벨 전 단계에서 테스트 목적의 인증서를 발급하기 위해 주로 쓰인다. 프로덕션 레벨에서 쓰이는 공인 SSL 인증서의 경우엔 비용이 발생한다.
(* SSL, 인증서: SSL은 웹 서버와 클라이언트(브라우저) 사이의 보안을 위한 프로토콜이다. SSL은 대칭키를 이용한 암호화 방식을 채택하고 있는데 이러한 암호화 통신(https)을 하기 위해선 SSL 인증서가 필요하다. 인증서에는 인증서 소유자의 정보, 용도, 유효기간, 공개 키 등의 정보가 포함되어 있다. 인증서가 유효한지는 CA가 보증해준다. 그리고 공인된 CA 목록은 이미 브라우저가 알고 있다.)
  1. private key file을 만든다. 파일명은 ssl.key
→ openssl genrsa 1024 > ssl.key
  2. [1]에서 생성한 key file을 가지고 certificate를 만든다. 파일명은 ssl.cert
→ openssl req -new -x509 -nodes -sha1 -days 365 -key ssl.key > ssl.cert


OAuth

OAuth는 인증을 위한 오픈 스탠더드 프로토콜. 버전 1.0, 1.0 A, 그리고 2.0 버전이 있는데 1.0 버전과 2.0 버전은 호환되지 않는다.

OAuth에서 Auth는 Authentication 과정도 포함하지만 주 목적은 특정 기능에 접근하려는 사용자에게 해당 권한(Authorization)이 있는지를 확인하는 것이다. 그렇기 때문에 OAuth 인증을 진행할 때 해당 서비스 제공자는 '제3자가 어떤 정보나 서비스에 사용자의 권한으로 접근하려 하는데 허용하겠느냐'라는 안내 메시지를 보여주고 있다.

OAuth는 방문증을 수령하는 과정에 비유할 수 있다. 방문증은 사원증과 다르다. 예를 들면, 방문증을 가진 사람이 출입할 수 있는 곳은 제한적일 수 있다.

OAuth 1.0에 대한 개념 용어.
  1. User: Service Provider에 계정을 가지고 있으면서, Consumer를 이용하려는 사용자.
  2. Service Provider: OAuth를 사용하는 Open API를 제공하는 서비스 (Service Provider는 Open API를 제공함으로써 자연스러운 서비스 홍보 효과를 기대할 수 있다.)
  3. Consumer: OAuth 인증을 사용해 Service Provider의 기능을 사용하려는 애플리케이션이나 웹 서비스
  4. Request Token: Consumer가 Service Provider에게 접근 권한을 인증받기 위해 사용하는 값. 인증이 완료된 후에는 Access Token으로 교환한다.
  5. Access Token: 인증 후 Consumer가 Service Provider의 자원에 접근하기 위한 키를 포함한 값. (* 방문증 예시를 떠올리면 방문증이 Access Token 이다.)

OAuth 1.0 vs OAuth 2.0
  1. OAuth 1.0은 웹 애플리케이션에 특화되어 있다면 OAuth 2.0은 다양한 형태의 애플리케이션에 대한 지원을 강화했다.
  2. OAuth 2.0은 HTTPS를 사용하고 암호화 과정이 필요하지 않다.
  3. OAuth 2.0은 보안 강화를 위해 Access Token의 Life-time을 지정할 수 있도록 했다.

이어지는 내용은 게으름으로. 링크만.

OAuth 2.0 정리글.
http://blog.weirdx.io/post/39955

토큰 기반 인증에 대한 정리글.
https://velopert.com/2350
https://velopert.com/2389



직장생활, 돈에 대한 뼈때리는 글.

하루종일 일만하는 사람은 돈 벌 시간이 없다.
- 존 D 록펠러

원문 링크.
https://m.blog.naver.com/huridam/221413264325

돈과 직업에 대한 가치관을 먼저 정립하자.
직장인, 회사원의 삶 만이 전형적인 삶의 모습이 아니다.

연봉 7천과 1억은 월소득으로 50만원 이하로 차이가 난다.
월급 150과 200은 큰 차이인데, 300만원이나 350만원은 별 체감상 차이가 없다.

세상에 돈을 버는 길은 직장인 만이 아니라는 사실을, 성적과 학벌은 돈을 버는 것과 상관관계는 있을지언정, 인과관계가 있는 것은 아니라는 것을 받아들이자.

나는 과연 무엇을 해서 얼마나 돈을 벌고 싶은가에 대해 생각해볼 지점이다.
인생의 테크트리는 결국 치킨집이라는 얘기가 있다. 저런거 보고 쓴웃음 짓고 그냥 넘어가면 안된다. 냉정하게 생각해보자. 내 20년 후가 저렇다는 것을 받아들일거면 지금 이 시점에 회사를 다녀야 할 이유는 무엇일까.

무엇을 해서 돈을 벌고, 어떤 직업을 가질 것인지, 거기에 지금 내가 다니는 대학이, 하는 공부가 도움이 되는 것인지 고민해봐야 한다. 내 의지대로 내 시간을 쓰면서 살기 위해서 준비가 필요하다. 돈버는 것에 대한 공부. 치킨집을 하더라도 떠밀려서 차리는 경우와 공부하고 준비해서 차리는 경우는 결과가 다르다.

어쨌든 최소한, 남들에게 등떠밀려서, 무리에 섞여서 직장인이 되지는 말고 직장인의 삶이 무엇인지 알고, 다른 돈벌이가 있다는 것도 알고 내 손으로 자발적으로 그 길을 선택하자.

2018년 12월 5일 수요일

윤종신 - 계절은 너에게 배웠어.

좋아하는 가수가 있고, 따라부를 수 있는 노래가 있다는 건 큰 힘이 된다. 윤종신 굿즈 '계절은 너에게 배웠어'를 출퇴근 하면서 읽었다. 가사가 절반이라 금새 읽을 수 있다. 읽기 전엔 윤종신의 생각과 개인사에 대해 들여다볼 수 있겠구나 하는 기대가 있었다. 하지만 개인사보단 '사랑, 이별'에 관한 노랫말 비중이 컸고, 가사를 적었을 때의 느낌과 생각을 위주로 서술하고 있었기 때문에 기대완 결이 조금 달랐던 책이다.

69p

저는 좋은 가사란 구체적이면서도 구체적이지 않은 가사라고 생각합니다. ... 노래를 듣는 이가 머릿속에 그림을 그려나갈 수 있도록 충분히 구체적이되, 사람마다 각기 다른 그림을 상상할 수 있도록 적당히 여백이 있어야 한다는 말입니다.


82p

사랑 이야기는 응당 어떠해야 한다는 서사적 경계에 갇히지 말았으면 좋겠어요. 그리고 사랑 이야기라고 해서 감정을 직접 서술해야 한다는 고정관념에서 벗어났으면 좋겠어요.


157p

...

그저 노래가 좋아 부르다
남들보다 늦게 떠나기에
조금은 이르게 뒤돌아보는 소중한
나의 이십대


164p

삼십대는 불안한 시기입니다. 아예 모르면 괜찮을 텐데 뭔가를 좀 알게 됐기 때문에 더욱더 불안해지는 시기죠. 지금 여기서 잘못되면 끝이라는 압박 때문에 필사적이고, 지금 이 기회를 무조건 움켜쥐어야 한다는 강박 때문에 고통스럽습니다. 삼십대를 치열하게 보내야 남은 인생에서 고생하지 않는다는 암묵적인 분위기 때문에 마음고생도 심하고, 이제 더는 어리지 않다는, 누구도 봐주지 않는다는, 진짜 어른이 되어야 한다는 자각 때문에 어깨도 무겁습니다. ... 각자 나이를 먹어가면서 단단해진 가치관이 부딪히는 건 피할 수가 없습니다.


180p

...
이렇게 노래의 힘을 빌어
한번 말해본다
기어코
행복하게 해준다.


182p

저는 아이들 때문에 희생하는 부모는 되고 싶지 않습니다. 제 아이들 역시 부모에게 종속되지 않기를 바라고요. ... 각각의 소중한 개인으로 성장하기를 바랍니다. ... 자기 자신을 위해 살아가는 개인이 되는 것. 제가 아이들에게 바라는 건 그것뿐입니다.


206p

이제 지난 삶을 조금은 관조할 수 있는 나이가 되었기 때문일까요, 저는 제가 그런 사람이라는 게 못내 아쉽습니다. 특히 젊은 시절을 떠올리면 안타까운 마음이 커지는데, 뭐랄까 저는 좀 퍼져 있었거든요. 약간의 패배주의와 막연한 기대감에 젖어서 공상만 많이 했어요. ... 그때 내가 겁없이 돌아다니고 원 없이 배웠다면 어땠을까, 좀더 진취적이고 활동적이고 오픈 마인드인 사람이면 어땠을까, 하는 생각을 지금도 가끔 해요. 떠나지 못했다는 아쉬움이 늘 가슴 한쪽에 남아 있는 거죠.


258p

제 장례식에서는 술을 마음껏 마실 수 있었으면 좋겠어요. 소주나 맥주뿐만 아니라 막걸리도 있었으면 좋겠고, 와인이나 양주도 마실 수 있으면 좋겠습니다. 파티처럼 다들 자기가 마시고 싶은 술을 직접 들고 오면 좋을 것 같아요. 그리고 저를 기억하면서 마음껏 건배해줬으면 좋겠습니다. 저에 대해 섭섭했던 것들, 아쉬웠던 것들, 인상적이었던 것들, 좋았던 것들을 떠올리면서 웃고 떠들었으면 좋겠어요.


263p

제 말이 활자화되는 것도 부담스러운 게 사실입니다. 한번 활자화되면 오랜 시간이 지나도 남기 때문에 그게 제 의지와는 상관없이 또다른 저를 만드는 것 같거든요. ... 아마도 저는 이 책 안에서 그 모든 실수를 했을 겁니다. 어떤 부분에서는 실제의 저보다 훨씬 더 근사해 보였을 거고, 또 어떤 부분에서는 실제의 저보다 훨씬 못나 보였을 거에요.

2018년 12월 2일 일요일

[MS-SQL] 날짜 변환 함수, CONVERT

MS-SQL의 CONVERT 함수는 CAST 함수와 비슷하지만
DATE 형식을 변환할 때 세부 변환 스타일을 지정해줄 수 있어서 날짜 변환 연산이 필요한 경우엔 CONVERT 함수를 사용하는 것이 낫다.

CONVERT와 CAST의 형식은 아래와 같다.
CONVERT ( data_type [ ( length ) ] , expression [ , style ] )
CAST ( expression AS data_type [ ( length ) ] )

현재 시간을 문자열 형식으로 바꾸는데, 마지막 'style' 파라미터를 이용해 변환 형식을 지정할 수 있다.
우리나라 사람은 '년-월-일' 표현이나 '시:분:초' 표현에 익숙하기 때문에 자주쓰게 되는 형식은 다음과 같다.
참고로 형식 2가 'yy' 버전이라면 형식에 100을 더한 102가 'yyyy' 버전이 된다.

SELECT CONVERT(VARCHAR, GETDATE(), 2) -- 18.02.03 (yy.mm.dd, ANSI 표준)
SELECT CONVERT(VARCHAR, GETDATE(), 102) -- 2018.02.03 (yyyy.mm.dd, ANSI 표준)
SELECT CONVERT(VARCHAR, GETDATE(), 11) -- 18/12/03 (yy/mm/dd, 일본 표준)
SELECT CONVERT(VARCHAR, GETDATE(), 111) -- 2018/12/03 (yy/mm/dd, 일본 표준)
SELECT CONVERT(VARCHAR, GETDATE(), 12) -- 181203 (yymmdd, ISO 표준)
SELECT CONVERT(VARCHAR, GETDATE(), 112) -- 20181203 (yyyymmdd, ISO 표준)
SELECT CONVERT(VARCHAR, GETDATE(), 20 or 120) -- 2018-12-03 10:54:34 (yyyy-mm-dd hh:mi:ss(24h), ODBC canonical 표준)

[MSDN: https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-2017]

2018년 11월 26일 월요일

마이바티스 - mybatis, mybatis-spring

마이바티스만 쓸거면 mybatis를 보고,
스프링에 마이바티스를 연동해 쓸거면 mybatis-spring를 보고,
스프링-부트에 마이바티스를 연동해 쓸거면 mybatis-spring-boot-starter를 보자.

하이버네이트 같은 ORM 방식이 나은지 마이바티스 같은 데이터 매퍼 방식이 나은지는 그때 그때 다르겠다.
꼰대 DBA가 없으면서 심플한 데이터 관계를 갖는 New 프로젝트에선 ORM 방식이 나은 것 같고,
DBA를 설득하기 빡세고, 레가시 도메인이 복잡하면 그냥 마이바티스 쓰는게 최선인 것 같다.


마이바티스 주요 클래스 인스턴스의 스코프와 생명주기

마이바티스의 주요 클래스로 SqlSessionFactoryBuilder, SqlSessionFactory, SqlSession이 있다.
다행인것은 DI 프레임워크가 생명주기에 대해 기억하지 않아도 쓰레드로 부터 안전하게 동작하도록 관리해준다는 것이다.

1) SqlSessionFactoryBuilder (SqlSessionFactoryBean); SqlSessionFactory를 생성한 후 유지될 필요가 없으므로 메소드 스코프.
2) SqlSessionFactory; 한번 생성한뒤 SqlSessionFactory는 애플리케이션이 실행되는 동안 계속 존재하는 것이 좋다. 따라서 애플리케이션 스코프. 가장 간단한 방법은 싱글턴 패턴이나 static 싱글턴 패턴을 사용하는 것인데, 스프링과 같은 DI 컨테이너를 사용하는 것이 일반적이다.
3) SqlSession (SqlSessionTemplate); 각자의 쓰레드는 자체적으로 SqlSession 인스턴스를 가져야 한다. SqlSession 인스턴스는 공유되지 않고 쓰레드에 안전하지도 않기 때문이다. 따라서 요청 단위 또는 메소드 스코프.


mybatis

1) 마이바티스 애플리케이션은 SqlSessionFactoryBuilder로 SqlSessionFactory 인스턴스를 만들어 사용한다.
2) SqlSessionFactory는 SqlSession을 만드는 역할을 한다.
3) SqlSession은 데이터베이스에 대해 SQL 명령어를 실행하기 위해 필요한 모든 메서드를 가지고 있다.


mybatis-spring

1) SqlSessionFactoryBuilder 대신 SqlSessionFactoryBean이 SqlSessionFactory를 만들어 준다. SqlSessionFactory는 DataSource를 필요로 하고, 다른 스프링의 데이터베이스 연결과 동일한 형식으로 DataSource가 설정되어야 한다. 매퍼의 위치는 SqlSessionFactoryBean에 mapperLocations 프로퍼티를 이용해 지정한다.

<!-- sample.config.mappers 패키지 아래와 그 하위 패키지를 모두 검색해서 마이바티스 매퍼 XML 파일을 모두 로드한다. -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="mapperLocations" value="classpath*:sample/config/mappers/**/*.xml"/>
</bean>

2) mybatis-spring에선 SqlSessionFactory를 직접 사용할 필요가 없다. SqlSessionTemplate은 SqlSession을 구현하고 코드에서 SqlSession을 대체하는 역할을 한다. SqlSessionTemplate은 쓰레드에 안전하고 여러개의 DAO나 매퍼에서 공유될 수 있다. 아래의 빈은 DAO에 직접 주입될 수 있다. SqlSessionTemplate은 인자로 ExecutorType을 갖는 생성자를 가지고 있는데 실행 방식을 아래와 같이 배치 형태로 바꿀 수도 있다.

<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg index="0" ref="sqlSessionFactory"/>
    <constructor-arg index="1" value="BATCH"/>
</bean>

3) SqlSession을 제공하는 추상클래스인 SqlSessionDaoSupport가 있고, MapperFactoryBean 방식으로 DAO를 다룰 수도 있다. 이들은 추가적으로 작성되는 코드를 줄이거나 없애는 역할을 한다.

출처: http://www.mybatis.org/spring/ko/index.html

2018년 11월 15일 목요일

WPF - 빈 버튼 만들기, DataGrid Column 좌측 정렬하기.

1. 빈 버튼 만들기
아래처럼 버튼의 Template을 Rectangle이나 TextBlock 같은 것으로 덮어버리면 지정된 효과를 제거할 수 있다.

<Button>
    <Button.Template>
        <ControlTemplate TargetType="Button">
            <Rectangle Fill="Red"
                       Width="{TemplateBinding Width}"
                       Height="{TemplateBinding Width}"/>
            <!-- TextBlock Text="{TemplateBinding Content}"/> -->
        </ControlTemplate>
    </Button.Template>
</Button>

최소한의 효과를 갖게하려면 스타일로 ToolBar.ButtonStyleKey를 지정하면 된다.

<Button Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" Background="Blue"/>

2. DataGrid Column 좌측 정렬.
DataGridTemplateColumn으로 처리하면 되는데 정석은 아닌 것 같지만 동작한다. :(
CellTemplate에 왜 Top Padding이 필요한지는 잘 모르겠다.
디자이너가 없어서 일하기 힘들다..

<DataGridTemplateColumn IsReadOnly="True" CanUserSort="False">
    <DataGridTemplateColumn.HeaderTemplate>
        <DataTemplate>
            <TextBlock Text="Header" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </DataTemplate>
    </DataGridTemplateColumn.HeaderTemplate>
    <DataGridTemplateColumn.CellStyle>
        <Style TargetType="DataGridCell">
            <Style.Setters>
                <Setter Property="TextBox.BorderBrush" Value="Transparent"/>
                <Setter Property="TextBox.Background" Value="{x:Null}"/>
            </Style.Setters>
        </Style>
    </DataGridTemplateColumn.CellStyle>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Padding="10, 5, 0, 0" Text="{Binding CellData}" HorizontalAlignment="Left"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

2018년 11월 12일 월요일

Java의 NIO (New I/O)

IO : NIO = Stream : Channel

Java의 기존 I/O는 느렸다. 다행히 어렵진 않았다. Buffered 계열의 클래스를 이용해 쉽게 I/O 작업을 할 수 있었다.
 - FileReader / FileWriter
 - PrintReader / PrintWriter

NIO 이전의 I/O는 Stream 기반으로 input/output 스트림을 구분하는 방식이다. 읽기를 수행할 땐 InputStream을 사용해야 하고, 쓰기를 수행할 땐 OutputStream로 구분해서 사용해야 한다. 그리고 읽기/쓰기가 끝나야 return 되는 blocking 방식이다.

기존의 I/O 방식이 느렸던 까닭은 커널 버퍼에 직접 접근하는 Direct Buffer를 핸들링할 수 없었기 때문이다. 이로 인해 커널에서 JVM 내부로 Buffer를 복사할 때의 CPU 소모, 복사한 Buffer에 대한 GC 등의 오버헤드가 발생하였다.

JDK 1.4부터 NIO가 생겼다. NIO는 New I/O의 줄임말이다. (Non-blocking I/O를 뜻하는 것이 아니다.) 기존의 I/O는 Blocking방식으로, 해당 블럭이 끝나기 전에는 아무 것도 수행할 수 없었다. 왜 1.4 이전엔 이런게 없었을까? 멀티 플랫폼을 지향하는 자바 특성상 각 OS의 System Call이나 커널에 맞춰 Non-blocking I/O를 지원하기 어려웠을 것이다.

NIO가 되면서 커널의 Direct Buffer에 접근할 수 있는 클래스가 생겼다. Buffer는 시스템 메모리를 직접 사용할 수 있는 클래스로 기본 데이터 타입을 저장할 수 있다. 형태는 배열과 유사하고 제한된 크기에 순서대로 데이터를 저장한다. Buffer에는 read/write 위치에 대한 position, read/write 최대 값인 limit, 그리고 크기에 해당하는 capacity 등의 속성이 있다. 메서드로는 rewind(), flip(), compact(), slice()등이 있다.

Buffer 자체는 추상 클래스이며 이에 대한 Concrete 클래스로
 - ByteBuffer
 - MappedByteBuffer
 - CharBuffer
 - DoubleBuffer
 - FloatBuffer
 - IntBuffer
 - LongBuffer
 - ShortBuffer
가 있다. 이 중 ByteBuffer는 시스템 메모리를 직접 사용하는 Direct Buffer를 만들 수 있는 유일한 Buffer이다.

NIO에서는 기존 I/O 방식과 다르게 Channel이라는 것을 통해 양방향 읽기/쓰기를 동시에 할 수 있게 지원한다. Channel도 Stream과 마찬가지로 데이터가 흘러다니는 통로지만 Stream과 달리 input/output을 구분할 필요가 없다.

Channel은 Buffer를 통해서만 데이터를 읽거나 쓸 수 있다. 또 하나의 특징으로 Channel은 Non-blocking operation도 지원한다. NIO의 일부가 Non-blocking을 지원한다는 것이지 NIO의 모든 동작이 Non-blocking 방식으로 동작하는 것은 아니다. Blocking 모드로 동작하더라도 성능상 유리한 System Call을 활용하기 때문에 기존의 Stream I/O에서 병목을 유발했던 몇가지 레이어를 건너뛸 수 있다. 그리고 NIO에서는 Selector라는 것을 통해 모든 연결을 중앙집중식으로 관리하게 된다. 이벤트를 Selector가 감지하고, 이벤트가 발생한 I/O와 관련된 Channel을 불러와 작업을 수행하는 방식이다.

2018년 11월 7일 수요일

엘라스틱서치 로그스태쉬(Logstash)

데이터 흐름을 위한 오픈 소스 중앙 처리 엔진.
데이터 Flow 파이프라인을 구축. 이벤트 데이터의 변환 및 스트림을 설정.

# 일반 구성.
beats - lightweight / edge shippers
logstash - central / dataflow engine
ealsticsearch

# 주 기능.
1. 데이터 스트림의 실시간 변형, 제거 및 정규화
2. 조건을 이용한 데이터 흐름 분할 및 라우팅
3. 파이프라인 성능 및 활성 상태 모니터링.

# 일반적인 흐름.
input > filter > output

1. input - files, syslog, sql queries, http requests, elasticsearch, beats, metric systems, and more..
2. filter (데이터에 변형을 가함)
 - log parsing
 - 데이터 확장
 - 태그 추가. and more..
3. output - elasticsearch, data 보관소 (amazon), alert & monitoring system, and more.. # 코덱 지정 가능함. (ex. rubydebug)

# filter example.
grok {
  match => { "message" => "Hello %{WORD:name}" }
...
date {
  match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]
  remove_field => "timestamp"
...
geoip {
  source => "clientip"
  field => ["city_name", "country_name", "location", "region_name"]
..

엘라스틱서치 샤드.

메모했던 내용을 옮겨 적어본다. 엘라스틱서치는 홀로 외로이 실무에 도입해보려 했다가 접었..


1. 엘라스틱서치에서 인덱스는 한 개 혹은 여러 개의 샤드로 구성된다.

2. 샤드는 루씬 인덱스, 엘라스틱서치가 데이터를 클러스터 내에 분산 저장하기 위한 단위다.

3. 샤드는 결국 클러스터 내에 인덱싱을 하거나 데이터 일부를 조회하기 위한 독립적인 검색 엔진의 역할을 갖는다.

4. 샤드는 한개 혹은 여러 개의 세그먼트로 구성되고, 세그먼트 개수가 많아지면 주기적으로 더 큰 세그먼트로 병합된다. 병합 작업은 리소스에 민감하며 디스크 I/O에 큰 영향을 받는다.

5. 매우 큰 샤드를 만드는 것은 피하자. 실 사용 관점에서 50GB를 넘기지 말자.

6. 데이터 보관 주기를 관리하기 위하여 가능한한 시간 기반 인덱스를 사용하자. 보관 주기에 따라 데이터를 그룹핑하여 인덱스를 저장하자. 시간 기반 인덱스는 프라이머리 샤드와 리플리카의 개수 조정을 쉽게 해주며, 후속 인덱스 생성시 이를 쉽게 변경할 수도 있다. 또한 데이터의 볼륨과 요구사항을 쉽게 반영할 수도 있게 한다.

7. 작은 샤드는 작은 세그먼트를 만들며 부하를 증가시킨다. 평균 샤드 크기를 수 GB와 수십 GB 사이를 유지하는 것이 권장된다. 시간 기반 데이터를 사용한 사례를 보면 20GB ~ 40GB 정도의 사이즈가 적당했다.

8. 각 샤드의 부하는 세그먼트 개수와 크기에 따라 결정된다. 피크 시간을 피해 인덱스에 더 이상 데이터가 입력되지 않으면 forcemerge 기능을 사용해 큰 세그먼트로 병합시키는 것이 권장된다.

9. 하나의 노드에 설정된 힙은 1GB당 20~25개 샤드가 적당했다.

10. 쿼리에서, 샤드당 단일 쓰레드가 쿼리를 실행한다. 많은 개수의 작은 샤드를 조회하면 각 샤드마다 처리 속도는 빨라지지만 더 많은 작업을 큐에 넣고 순서대로 처리해야 하므로, 적은 개수의 큰 샤드를 검색하는 것보다 반드시 빠르다고 보장할 수 없다. 결론적으로 1개 샤드의 권장하는 크기를 넘지 않는 선이라면, 작은 크기의 여러 샤드보다는 큰 크기의 적은 샤드가 더 효율적이다.

10. 시간 기반 인덱스에서, 데이터 볼륨에 맞게 일 단위, 주 단위, 월 단위 인덱스를 고려하자. 이는 시간이 지남에 따라 클러스터에 저장하는 인덱스와 샤드의 개수를 적게 유지하는데 도움이 된다.

11. 데이터 인덱싱량이 빈번하게 변하는 경우라면 rollover, shrink api를 활용해서 유연하게 대응할 수 있도록 하자. rollover 인덱스 api는 클러스터가 저장해야 하는 도큐먼트와 인덱스의 개수를 지정하거나, 저장해야할 도큐먼트의 최대 기간을 지정할 수 있다.

12. shrink api는 기존 인덱스를 더 적은 개수의 프라이머리 샤드를 가진 신규 인덱스로 shrink하게 해준다.

윈도우 10 (Windows 10) 프로그램 경로

프로그램 경로는
%ProgramData%\Microsoft\Windows\Start Menu\Programs
%AppData%\Microsoft\Windows\Start Menu\Programs

시작 프로그램 경로는
%ProgramData%\Microsoft\Windows\Start Menu\Programs\StartUp
%AppData%\Microsoft\Windows\Start Menu\Programs\Startup

2018년 10월 25일 목요일

한글 환경에서 자주 접하는 인코딩 정리. (UTF-8, EUC-KR, CP949)

대부분의 출처는 나무 위키. 나무 위키는 볼수록 놀랍다.
https://namu.wiki/w/%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C

ASCII: American Standard Code for Information Interchange. 미국 정보 교환 표준 부호. 미국 산업 표준화 단체인 ANSI에서 표준화한 7비트 부호체계. 한글자당 1바이트를 할당하는데 영문 키보드로 입력할 수 있는 모든 기호들이 할당되어 있다. 2바이트 이상의 코드를 표현할 수 없기 때문에 국제표준의 위상은 유니코드로 넘어갔다. 참고로 초기엔 1바이트 중 7비트만 사용했는데 맨 앞 비트는 통신 에러 검출을 위한 Parity Bit로 쓰였다고 한다. 8비트 버전의 확장형 ASCII 코드도 있다. ASCII는 UTF-8과 호환되지만 UTF-16과는 호환되지 않는다.

Unicode: 전 세계의 모든 문자를 다루도록 설계된 표준 문자 전산 처리 방식. Unicode는 문자를 숫자로 매핑하는 것(예를 들어 A는 숫자 65)에 대한 개념이고 Unicode 인코딩으로 UTF-8, UTF-16, UTF-32가 있다. 일반적인 상황에선 Unicode를 UTF-8로 이해해도 무리가 없다. UTF-32의 경우 낭비가 심해 잘 쓰지 않지만 가변 길이를 고려하지 않아도 된다는 장점 또한 존재해 프로그램 내부적으로 사용하는 경우도 있다고 한다.

UTF-8: 가장 많이 쓰이는 가변 길이 유니코드 인코딩 방식. CP65001. 하나의 글자는 1~4 바이트 중 하나로 인코딩 되고, 1바이트 영역은 ASCII 코드와 하위 호환성을 갖는다. 재미있는게 한글의 경우 주로 3바이트 구간에 존재해서 한글로 작성된 문서의 경우 EUC-KR이나 UTF-16으로 저장한 것 보다 UTF-8로 저장했을 때 파일의 크기가 더 커진다.
MS 계열 프레임워크에서 C/C++등을 이용해 비 유니코드의 멀티바이트 캐릭터를 UTF-8 형식으로 변환하기 위해서는 와이드바이트 형식의 완전 2바이트 유니코드로 변환한 다음 다시 UTF-8 플래그를 주어 멀티바이트 형식으로 다시 변환하는 과정이 필요하다.

ANSI: 일반적으로 MS-DOS의 기본 인코딩인 OEM-US 내지 영문 Windows의 기본 인코딩인 Windows-1252를 지칭. 메모장에서 인코딩을 지정하지 않고 저장한 경우 'ANSI'라고 표시되는데 이는 잘못된 표기임. 실제 인코딩은 System Locale을 따라가므로 한글 Windows에선 CP949가 된다.

EUC-KR: 완성형 한글 인코딩 방식 중 하나. 현재 산업 표준이다. 시작은 '가', 끝은 '힝'. 지원하는 한글 글자 수는 2,350자로 현대에 사용되는 한글 11,172자에 비해 부족하다. 나름 빈도를 조사해 2,350자를 선정했다고 하지만 역부족.

CP949: 통합 완성형 (확장 완성형). 한국어판 Windows의 기본 코드 페이지로 EUC-KR의 확장이다. EUC-KR이 지원하지 않던 8000여자를 지원한다. 마이크로소프트가 개발했기 때문에 MS949, Windows-949 등으로 불리기도 한다.

* GCC 같은 비 MS 진영 컴파일러를 이용해 C/C++ 등의 네이티브 프로그래밍 언어를 갖고 UTF-8로 한글 출력을 하면 한글이 깨지는 현상이 있다. 이럴 땐 소스 코드 자체는 UTF-8로 하되, wchar_t 같은 와이드바이트 자료형을 사용해야 한다.

* Nodepad++의 경우 EUC-KR, CP949를 구분하는데 CP949로 작성된 문서를 Notepad++로 열면 시스템 기본 인코딩(ANSI)로 읽히는 경우가 흔해, 한글 버전이 아닌 다른 언어 윈도우에서는 글자가 깨진다고 함.

* BOM : Byte Order Mark. 문서의 처음에 눈에 보이지 않는 특정 바이트를 넣어 문서가 어떤 Endian, 인코딩 방식을 사용하고 있는지 알려주기 위한 장치다. 상황에 따라 이게 오히려 문제를 일으키기도 한다. 유닉스/리눅스 계열에서는 쓰지 않는 것이 관례. 웹 프로그래밍에서도 사용하지 않는 것이 좋다.
 . UTF-8 >> EE BB BF (UTF-8 Signature, 단지 UTF-8로 인코딩되었다는 사실을 알리는 사인.)
 . UTF-16 Big Endian >> FE FF
 . UTF-16 Little Endian >> FF FE
 . UTF-32 Big Endian >> 00 00 FE FF
 . UTF-32 Little ENdian >> FF FE 00 00

[파이썬과 인코딩]
https://datascienceschool.net/view-notebook/250c1869eab54157827adf54c5e9f064/

Kafka 간단 개념 정리.

참고로 Kafka 안써봄.. ㅠㅠ

카프카는 1)영속적, 2)분산, 3)분할, 4)복제되는 대량의 데이터를 수집하기 위한 메시징 시스템이다. 카프카는 데이터 소스와 데이터 처리기 사이에서 버퍼 역할을 해주는데 이는 스트림 처리에서 꼭 필요한 요소다. 참고로 링크드인에서 데이터 흐름을 한곳으로 모으기 위해 만들었다고 한다. 분산 시스템이기 때문에 한 두개 장비가 망가져도 잘 동작하며 Queue를 기본으로 하는 메시징 시스템이기 때문에 데이터의 순서를 보장해준다. 카프카는 프로듀서, 컨슈머, 브로커로 구성된다. 프로듀서는 데이터를 만들어 넣는 역할, 컨슈머는 데이터를 꺼내 쓰는 역할, 그리고 브로커는 프로듀서와 컨슈머의 메시지를 관리하는 클러스터 서버의 역할을 수행한다. (DDS와 유사한 형태의 Publish/Subscribe 모델.) 분산 코디네이터로는 주키퍼를 쓴다.

카프카는 높은 성능, 다양한 언어를 지원하기 위해 클라이언트와 서버 간 통신으로 TCP 프로토콜을 이용하며 카프카 브로커는 FIFO 형태의 토픽이라는 카테고리를 가지고 있다. 토픽은 Queue의 구조와 같다.. 각 메시지는 자신의 고유한 식별자인 인덱스를 가지고 있는데, 카프카에서는 이를 오프셋이라 한다. 각각의 컨슈머는 어디까지 읽었냐에 대한 오프셋을 관리하게 된다. 오프셋 관리만 잘하면 장애로 인해 예상치 못하게 중단되거나 운영 상의 이유로 언제든지 중단하여도, 안심하고 장애 처리나 업그레이드 같은 작업을 하고 재시작할 수 있다. 단, 중단된 시간이 길어지면, Kafka에서 버퍼링하며 저장할 수 있는 데이터 크기를 넘어설 수 있으므로 주의해야 한다. (근데 오프셋 관리가 어렵다고 함.)

기본적으로 토픽은 1개 이상의 파티션(물리적으로 분할된 Queue)을 가지고, 하나의 브로커나 다수의 브로커에 분산 배치될 수 있다. 토픽을 다수의 파티션에 나누어 여러 브로커에 분산 배치함으로 메시지 전송에 따른 부하를 분산시키는 구조다. 카프카는 영속성을 제공하기 위해 파일 시스템에 메시지를 저장한다. 데이터를 파일에 쓰면서도 메모리 대비 성능을 잃지 않는 것이 특징이다. OS 페이지 캐싱을 통해 read()에 의한 블락 없이 직접 매핑된 주 메모리를 참조하여 파일에 데이터를 기록하면서도 빠른 성능을 보장한다. 또한 Zero Copy 기법을 채택한 Java nio의 FileChannel.transferTo()를 통해 메모리의 데이터를 커널 레벨에서 소켓으로 바로 넘겨 버리는 방식으로 성능을 높이고 있다.

* OS 페이지 캐싱
주 메모리에 가능한 많은 파일을 미리 캐싱해서 실제 요청이 왔을 때 파일 Read 시간을 최소화 하는 기법.

결과적으로 메모리 사용을 최소화하는 구조이므로 GC에 의한 성능 감소를 예방한다. (자바 오브젝트의 메모리 오버헤드는 매우 높고, 종종 저장된 데이터의 크기보다 더 크게 부풀려진다. 자바 GC는 힙 안의 데이터가 증가할수록 점점 더 다루기 어렵고 느려지는 특성이 있다.)

각 파티션은 설정한 서버의 숫자만큼 복제되고, 각 파티션은 카프카 클러스터에 분산되 저장된다. 파티션은 Leader 역할을 하는 하나의 서버와, 0개 이상의 Follower 서버를 갖는데 Follower가 Leader를 복제하는 동안, Leader는 파티션을 위한 모든 읽기와 쓰기 요청을 처리한다. 복제는 파티션 단위로 처리되는데 복제 계수가 3이면 1개의 Leader, 2개의 Follower 구성을 뜻한다. 복제 계수는 브로커 개수 이상으로 설정할 수 없다. (한 서버에 동일한 파일을 저장할 필요가 없기 때문.) 사용자의 모든 요청은 리더 파티션이 담당하며, 카프카의 복제는 가용성(Availability)을 높일 뿐, 성능 향상에 영향을 주진 않는다. 카프카는 프로듀서가 특정 토픽 파티션에 전송한 데이터의 순서를 보장한다. 그리고 컨슈머는 저장된 순서대로 메시지를 처리하게 된다. 카프카는 메시지의 순서와 메시지가 단한번 소비되는 것을 보장하지만 처리 순서는 하나의 파티션에 대해서만 보장한다. 여러 개의 파티션으로 분산된 데이터의 순서는 보장하지 않는다는 뜻이다. 게다가 비동기 방식이라 클러스터 구성이 복잡해지면 골때리는 경우가 제법 생기는 듯 하다.

* 주키퍼
주키퍼 = 분산 코디네이터. 분산 코디네이터라고 하면 뭔가 어렵게 다가온다. 클러스터 구성원 간의 데이터 공유를 위한 데이터 저장 기법(기술)이라 생각하면 조금 편해지려나.. 데이터를 디렉터리 구조로 저장한다. 데이터를 저장할 때 해당 세션이 유효한 동안 데이터가 저장되는 Ephemeral Node라는 것이 존재하고, 데이터를 저장하는 순서에 따라 자동으로 일련번호가 붙는 Sequence Node라는 것이 존재한다. 이러한 기능이 주키퍼의 전부. 이러한 기능을 가지고 입맛에 맞게 확장해서 사용하면 된다.
(입맛? 서버 투입/제거 시에 대한 이벤트 처리, 분산 환경에서 서버들 간의 정보 공유, 서버 모니터링, 분산 락 처리, 장애 상황 판단, 분산 시스템에서 리더 선출, 클러스터 멤버십 관리를 통한 데이터 변경 통지..)

주키퍼는 일반적으로 3대 이상을 사용하며 홀수로 구성한다. 서버 간의 데이터 불일치가 발생하면 보정이 필요한데 이떄 과반수의 룰을 적용하기 때문이다. 주키퍼 서버는 Leader와 Follower로 구성되어 있다. 서버들끼리 자동으로 Leader를 선정하며 모든 데이터 저장을 주도한다. 클라이언트가 Follower 서버로 데이터 저장을 시도한다면
Client > Server(Follower) > Server(Leader) > 나머지 Server(Follower) 순으로 데이터를 전달한다. 저장을 마치면 클라이언트에게 성공/실패를 동기 방식으로 알려준다. 즉 모든 주키퍼 서버는 동일한 데이터를 가지고 있고, 클라이언트가 어떤 서버에 연결되어 데이터를 가져가더라도 동일한 데이터를 가져가게 된다. 주키퍼에 잦은 변경이 일어나는 애플리케이션 성격의 데이터를 저장하는 것을 옳지 않으며 Read:Write 비율이 10:1 이상이 권장된다.

Apache ZooKeeper is an effort to develop and maintain an open-source server which enables highly reliable distributed coordination. // Zookeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services. 

읽어볼만한 국문 링크.
1] http://www.chidoo.me/index.php/2016/11/06/building-a-messaging-system-with-kafka/
2] http://readme.skplanet.com/?p=12465

2018년 10월 13일 토요일

hilite.me - 코드 시각화.

구글 블로거에 code 태그는 따로 처리 안하고 있었는데 가독성이 너무 안좋은것 같아서 몇군데 찾아보다가 hilite.me라는 사이트를 발견했다. 시간 오래 안걸리고 사이트 이름 잊어먹을 일 없으니 종종 이용하기로.
(결과물은 div랑 pre로 뽑히는게 함정.)



스타일은 vs에 css 값은 요정도가 깔끔한듯.
background-color: #f8f9fa;
border: 1px solid #eaecf0;
padding: 10px;
white-space: pre-wrap;

print 'hello world!'
print 'hello world!'

근데 별로네 ㅋㅋㅋ

가벼운 Django 사용 후기.

정말 단기간에 가볍게 사용해본거라 잘 모르지만 정리는 해두는게 나으므로.

#
2년전이던가. 사내에서 간단하게 쓸 웹 서비스를 만들기 위해 여러가지 프레임워크를 살펴보다가 Admin 기능 하나에 끌려 파이썬의 Django를 사용해보게 되었다.

최근 흐름은 모르겠지만 그래도 아직까진 Django와 Flask가 파이썬에서 가장 인기있는 웹프레임워크인 것으로 알고 있다. Django가 풀스택 프레임워크에 가깝다면 Flask는 개발자가 상황에 맞게 필요한 라이브러리를 조합해 사용하는 경량 프레임워크란 차이가 있다.

Django와 Flask 둘 중에 꼭 뭐가 배우기 쉽고 뭐가 좋다고 말하긴 어려운 것 같다. 특정 프레임워크의 선택은 만드는 목적과 달성하려는 수준, 그리고 개인과 팀의 취향에 따라 갈리는 부분이기 때문이다.

어쨌든 난 Django의 Admin 기능 하나를 보고 Django를 선택했었다. 물론 엄청 괜찮은 수준의 문서 지원도 한 몫 했지만 지금 다시 살펴봐도 Django의 Admin 기능은 쿨하다. models.py와 admin.py만 만져주면 뚝딱 생기는 Admin 페이지는 많은 수고를 줄여준다. 빌트-인 미들웨어 지원도 좋았고, 데이터베이스나 웹서버에 대한 지식 없이도 쉽게 서비스를 띄울 수 있는 점도 큰 장점이다.

Django는 웹프레임워크가 제공했으면 하는 거의 모든 기능을 기본적으로 지원해준다. 요청, 응답에 대한 다양한 변환, 참조, 그리고 렌더링 함수를 제공하고 있고, 다양한 빌트-인 미들웨어 제공은 딱히 창의적일 필요없는 지루한 작업을 줄여준다. (물론 상용으로 확장되면 꽤나 어렵고 까다로운 문제점들이 있다곤 하나 그건 다른 프레임워크에서도 마찬가지지 않나 싶다.)

# 설치
pip install django=={version}

# 버전 확인
console;
python -m django --version
code; 
import django
print(django.VERSION)
print(django.get_version())

# 프로젝트 생성
django-admin startproject {project_name}
L manage.py - Django 프로젝트와 상호작용 하는 커맨드라인 유틸리티. (python manage.py shell 과 같은..)
L {project_name}/settings.py - Django 프로젝트의 환경 구성을 지정.
L {project_name}/urls.py - 라우팅을 위한 프로젝트의 URL 선언. path()에 대해 알아야 한다. 정규 표현식이나 파라미터를 받아 처리할 수 있고, 처리 함수(view 함수), 사전형 인수(kwargs), 그리고 프로젝트에서 참조가능한 이름(name)을 지정할 수 있다.
L {project_name}/wsgi.py - WSGI 호환 웹 서버의 진입점.

* WSGI?
Web Server Gateway Interface. WSGI는 정적인 컨텐츠를 처리하는 웹서버와 파이썬 웹애플리케이션 사이의 인터페이스를 위한 파이썬 프레임워크다. 이에 대한 구현체인 WSGI 미들웨어로는 mod_wsgi, uwsgi, gunicorn, twisted.web, tornado 등이 있다. 웹서버의 관점에선 애플리케이션이고, 웹애플리케이션의 관점에서는 서버로 동작하게 되는 셈인데 애플리케이션 컨테이너의 역할을 수행한다고 보면 된다. WSGI 서버는 독립적인 웹서버로서의 기능이 약하고 DDOS 공격에 취약하므로 Nginx나 Apache 같은 독립적인 웹 서버와 함꼐 사용하는 것이 권장된다.

# 앱 생성
python manage.py startapp {app_name}
L {app_name}/admin.py
L {app_name}/apps.py
L {app_name}/migrations/
L {app_name}/models.py
L {app_name}/tests.py
L {app_name}/views.py - MVC의 V, View가 아님에 유의하자. Django는 MTV (Model - Template - View) 패턴을 따르는데 views.py는 MVC C, Controller와 유사한 역할을 한다.

# 모델 변경과 적용
1. models.py에서 모델을 추가하거나 변경.
2. python manage.py makemigrations 명령을 통해 변경사항을 migration 파일로 기록하낟.
3. python manage.py migrate 명령을 통해 변경사항을 데이터베이스에 적용한다.
4. Admin에 노출시킬 필요가 있는 모델은 admin.py에 admin.site.regiter()로 등록해준다.

* makemigrations 명령어 : 모델에 대해 변경된 내역을 migration이라는 개념의 파일로 저장해준다. migration은 Django가 모델의 변경사항을 저장하는 방법으로 디스크상의 파일로 존재하게 된다.
* migrate 명령어 : settings.py 내 INSTALLED_APPS의 설정을 탐색하여 필요한 데이터베이스 테이블을 생성한다. 클래스 1개는 Table 1개로 생성되며 id (Primary Key)는 자동으로 생성되므로 신경쓰지 않아도 된다. (ORM에 대한 기본적인 개념을 알고 접근하면 좋다. 결국 Django-ORM이 지저분한 뒷작업을 다 해주는거다.)
https://docs.djangoproject.com/ko/2.1/intro/tutorial01/

# 관리자 생성
python manage.py createsuperuser # 관리자 사이트 접근 가능한 user 생성.
생성후 Admin 페이지에서 기본으로 보여지는 Groups, Users 내용은 INSTALLED_APPS에 선언된 django.contrib.auth 모듈이 제공하는 인증 기능이다.
관리자 페이지 편집에 대한 내용은 다음 링크를 참고해보자.
https://docs.djangoproject.com/ko/2.1/intro/tutorial07/

# settings.py
DEBUG; 디버그 모드 설정
INSTALLED_APPS; 설치된 앱 또는 본인이 만든 app 추가
MIDDLEWARE_CLASSES; request와 response 사이에서 동작하는 기능 레이어 지정
TEMPLATES; Django template 관련 설정과 실제 view 위치.
DATABASES; 데이터베이스 엔진의 연결 설정
STATIC_URL; 정적 파일의 URL(css, js, image, etc.)

# 기타
1. XSS, CSRF 등의 보안 이슈에 Django가 어떻게 대응하고 있는지 살펴볼 필요가 있다. (autoescape, safe // {% csrf_token %}
2. 템플릿 생성, 처리 관련 내용은 튜토리얼 문서를 천천히 읽어보는 것이 낫다.
https://docs.djangoproject.com/ko/2.1/intro/tutorial03/
3. 배포 관련해서는 다음 링크를,
http://pythonstudy.xyz/python/article/316-Site-Deployment-Nginx
4. 한국어로 학습할 수 있는 방법은, 공식 문서나 장고-걸스에서 제공하는 문서의 질이 좋고, 위키독스 자습 페이지도 괜찮아 보인다.
https://wikidocs.net/6609
5. 책중에 Two Scoops of Django가 괜찮다 하여 구매해두었는데 잘 안읽히는 걸 보면 입문서는 아닌듯 하다.



2018년 10월 10일 수요일

WPF - telerik 차트 다루기

WPF GUI 툴킷으로 Telerik 제품을 사용하고 있다. (텔레릭으로 읽어야 하는지 떼레릭읽어야 하는지 아직도 궁금함.) 다양한 기능이 있는듯 하지만 아무래도 자주 쓰게되는 건 차트 컨트롤이다. Telerik의 차트는 제품 내부적으로 X,Y축을 두고 그리는 일반적인 형태의 RadCartesianChart와 방사형의 RadPolarChart로 큰 구분을 두고 있다. 방사형의 RadPolarChart는 아직 써보지 못했으나 RadCartesianChart를 표현하는 방식과 크게 다른 점은 없을거라 생각한다.

이 글은 RadCartesianChart에 대한 정리글인데 최근 차트 관련 컨트롤을 사용하게 될때마다 기억이 잘 안나서 자료 써칭하다가 허비하는 시간을 줄이기 위함이다. RadCartesianChart의 골격은 Axis를 정의하고, Series에 데이터 컬렉션을 지정해 그리는 방식으로 다른 라이브러리에서 제공하는 형태와 매우 유사하다.

Chart
 - Axes (Horizontal, Vertical)
 - Series
* 기타 Annotation, Grid 등이 있다.

Axis

Axis는 세로 축을 담당하는 VerticalAxis와 가로 축을 담당하는 HorizontalAxis가 있는데 세세한 표현을 위해 각 축이 갖는 속성을 잘 알아둘 필요가 있다. 속성을 잘못 지정하게될 경우 축의 특정 Label이 다른 Label을 덮어버리거나 축의 Step 값이 너무 크거나 세밀해서 데이터를 한 눈에 파악하기 어려운 경우가 생긴다. Axis엔 수치 값을 표시하는데 적합한 LinearAxis와 Category를 구분하는데 적합한 CategoricalAxis, 그리고 DateTimeAxis가 있다.

Axis의 주요 속성.
1. PlotMode (for CategoricalAxis, DateTimeAxis) : 데이터를 표시할 때 데이터의 Tick와 Label 표시 방식에 대한 것으로 기본값은 BetweenTicks이다. 그리고 OnTicks와 OnTicksPadded가 있다. (https://docs.telerik.com/devtools/wpf/controls/radchartview/axes/plotmode#plot-mode)
2. LabelInterval : Label이 표시되는 간격을 지정할 수 있다.
3. Minimum, Maximum, MajorStep (for LinearAxis) : 최소값, 최대값, 주-표시선 간격에 대한 설정. 값을 지정해주지 않아도 자동으로 계산되지만 지저분한 결과물이 나오기 마련이라 이 값들은 직접 지정해주는 것이 좋다.
4. LabelFitMode : Label이 서로 겹치지 않도록 Label 표시 방법을 지정할 수 있다. Label을 여러 행으로 표시하는 MultiLine과 Label을 회전해서 표시하는 Rotate가 있는데 MultiLine의 경우 차트를 지저분하게 만드므로 LabelInterval과 Rotate를 적절히 사용하는 방식이 나은 것 같다. (내부 알고리즘 방식으로 동작하는 SmartLabelsMode 속성도 확인해볼 필요가 있다. https://docs.telerik.com/devtools/wpf/controls/radchartview/axes/axis-smart-labels)


Series

실제 표현하려는 데이터 컬렉션이 담길 개체.
자주 쓰게되는 것은 아무래도 Line, Scatter Point, Scatter Line 시리즈. 주식 차트를 그리는데 쓰이는 CandleStick도 제공한다.
https://docs.telerik.com/devtools/wpf/controls/radchartview/series-and-axes


GridLine Annotation

차트 데이터 내부의 특이구간을 표시하거나 Limit 값을 표시하는 용도로 GridLine Annotation을 사용할 수 있다. Axis 방향과 값, 그리고 Stroke를 지정하는 방식이다. Annotation에 대한 Label도 붙일 수 있고, Annotation Label의 Definition 정의를 통해 Label 표시 위치 또한 설정할 수 있다.
<telerikChart:RadCartesianChart.Annotations>
<telerikChart:CartesianGridLineAnnotation Axis={Binding ElementName=#ChartYAxis}" Value="..." Label="..." DashArray="..."/>
http://docs.telerik.com/help/windows-8-xaml/chart-annotations-gridline-types.html
http://docs.telerik.com/help/windows-8-xaml/chart-annotations-labels.html


Grid

차트 Background의 X, Y 보조 표시선을 긋는 용도로 쓰인다.
<telerikChart:RadCartesianChart.Grid>
<telerikChart:CatesianChartGrid MajorLinesVisibility="XY"/>
</telerikChart:RadCartesianChart.Grid>
와 같이 해주면 무난하다.


No data to plot

차트에 정의한 Series에 담긴 데이터가 하나도 없으면 기본 값으로 No data to plot이 출력된다. 실제 쓰다보면 데이터가 나중에 바인딩 되는 경우가 잦은데 그럴 때마다 보이는 No data to plot 문구는 꽤나 거슬리는 부분이다. 다행히 이 문구는 새롭게 정의할 수 있다. 차트 속성 중 EmptyContent라는게 있는데 단순히 EmptyContent=""와 같이 빈 값으로 지정해주면 표시를 막을 수 있다. 빈 데이터 셋에 대해 출력되는 문구를 이미지로 대체한다던가 하는 작업이 필요한 경우엔 차트 하위 속성은 EmptyContentTemplate를 다시 정의하는 방법을 사용할 수도 있다.
https://docs.telerik.com/devtools/wpf/controls/radchartview/features/empty-content

2018년 10월 4일 목요일

[링크] 자바는 어디로 가고 있을까?

요즘엔 새로운 기술에 대한 내용보다 이런 글이 더 자극이 되는 것 같다.

https://medium.com/@jongdae.lim/%EC%9E%90%EB%B0%94-java-%EB%8A%94-%EC%96%B4%EB%94%94%EB%A1%9C-%EA%B0%80%EA%B3%A0-%EC%9E%88%EC%9D%84%EA%B9%8C-37dc915f00f1

[C#] Delegate, Func, Action

Delegate

Delegate는 C/C++의 함수 포인터와 유사하다.
* Caller -> Delegate (-> Callee)

이론적(?)으론 원하는 메서드를 안전하게 감싸는(캡슐화) 것이지만
주 활용 목적은 1) 콜백, 2) 메서드-체인 구성(멀티캐스트~이벤트), 3) '동작을 지정하는 틀'을 만드는 것에 있는 것 같다.

예}
string을 인수로 사용하고 void 반환 타입 메서드를 캡슐화 하고자 한다면 동일하게 string을 인수로 사용하고 void 반환 타입을 갖는 delegate를 선언해 주면 된다.

public static void DelegateMethod(string message) { ... }
public delegate string Del(int id);

Generic Delegate로도 선언할 수 있다.
public delegate void Del<T>(T message);

대리자의 형식은 대리자의 이름으로 정의된다.
위 예시에서 Delegate의 이름이 'Del'이므로 형식은 'Del'이 된다.
Del handler = DelegateMethod;
handler("hello world");

익명 메서드나 람다도 물론 허용한다.
{익명 메서드} Del handler = delegate(string message) { Console.WriteLine(message); };
 -> 익명 메서드는 이름이 없는 메서드기 때문에 이를 호출하기 위해서 delegate 키워드가 필요한 것이다.
{람다} Del handler = (string message) => Console.WriteLine(message);

Delegate는 객체이기 때문에 매개 변수로 전달하거나 속성에 할당할 수 있다.
메서드의 매개 변수가 될 수 있는 점은 꽤나 유용하다. (ex. 비동기 콜백)

Delegate의 또 하나의 큰 특징으로 둘 이상의 메서드를 호출할 수 있다.
이러한 호출을 멀티캐스트라고 한다.
Del d1 = Func1;
Del d2 = Func2;
Del d3 = Func3;
Del allMethodsDelegate = d1 + d2;
allMethodDelegate += d3;

allMethodDelegate("hello world"); // Func1 > Func2 > Func3 으로 호출된다.

멀티캐스트 대리자는 이벤트 처리에서 광범위하게 사용된다.


C#에서의 Delegate vs Event

Delegate는 자신이 속한 클래스 외부에서도 호출이 가능하지만,
Event는 자신이 속한 클래스 내부에서만 호출하도록 강제된다.

! 참고로 event는 단지 delegate 앞에 'event' 키워드만 붙이는 것으로 선언이 된다.
Del myDelegate; -> event Del myEvent;


Func, Action

Func와 ActionFunc와 Action은 미리 선언된 Delegate 변수로
Func는 반환값이 있고, Action은 반환값이 없는 차이가 있다.

Func 선언은 매개변수를 앞에 지정하고, 반환 값은 가장 뒤에 지정한다.
Func<int, float> func = (a) => a * 0.1f; // int형 매개변수를 1개 갖고, 반환값은 float 형.

2018년 6월 25일 월요일

veamcamp HTML+CSS 재미있게 입문하기 5주차

과제까지 마치고 정리를 하려 했는데 계속 미뤄지는 것 같아 우선 수업 내용부터 정리해볼까 한다. 16일을 끝으로 수업은 마무리되었다. 너무 얕지도 깊지도 않아서 재미있게 따라갈 수 있었던 것 같다.

마지막 수업에서도 결과물을 보고 그대로 만들어보는 작업을 했다. 페이지를 만드는 과정은 항상 같다. 큰 단위에서 작은 단위로, 덩어리에 백그라운드 컬러를 줘서 어떤 공간을 차지하고 있는지 확인하는 과정. 그리고 스타일을 담백하게 만들고 시작하는 CSS Reset 과정.

오늘 배운것은 position.

Position

다른 요소에 영향을 주지 않고 선택된 요소의 위치를 지정하고 싶을 때 position을 사용한다. 자주 쓰는 값은 relative와 absolute. relative는 부모 요소로부터 상대적인 position을 지정해주기 위해 쓴다.

position: relative;
left: 30px;
top: 50px;

주위 환경에 영향을 주지 않고 이동하는 것을 확인할 수 있다. 자유도가 꽤나 높아진다. position엔 가급적 left, top을 이용해서 하는 것이 바람직. right, bottom 대신에 left, top에 음수 값을 주는 것이 이해상 낫다. right, bottom을 사용하는 경우는 right: 0, bottom: 0인 경우 정도가 될 듯.

position: absolute;
right: 0;
bottom: 0;

absolute 값은 부모와의 관계를 끊고 독립하는 것으로, 브라우저 기준점에서 어디로든 이동할 수 있다. 위와 같이 하면 브라우저의 우하단에 float되는 효과를 얻을 수 있다. 그런데 브라우저 기준점이 아니라 부모로부터의 절대값을 표현하고 싶을 때가 생길 수 있다. 이런 때엔 부모에 relative를 주고, 자식에게 absolute를 주면 부모위치를 기준점으로 절대 위치를 표현할 수 있다. (강사님은 상대적인 절대값이란 표현을 쓰셨음.)


위와 같은 예제가 있다고 할 때, 각 아이콘의 delete 버튼은 부모 아이콘으로부터 '상대적인 절대 위치'로 표현된 것을 확인할 수 있다.

<ul class="container">
    <li>
        <img class="icon" src="...">
        <img class="del" src="...">
        <h2>iphone</h2>
    </li>
....

.container {
    margin: 100px auto;
    background-image: url(images/bg.png);
    background-attachment: fixed;
    background-position: center;
    width: 1000px;
    border-radius: 10px;
    padding: 20px;
    overflow: hidden;
}

.container li {
    position: relative;
    float: left;
    width: 200px;
    margin: 25px;
}

.container li .del {
    position: absolute;
    right: -20px;
    top: -20px;
}

float와 position을 같이 사용한 예제로 CSS와 결과물을 확인해보면 매우 직관적으로 결과물이 표현된 것을 확인할 수 있다. 마지막으로 position: absolute 에서의 가운데 정렬. 요소의 가로, 세로 값이 150px라 할 때 아래와 같이 해주면 요소를 정가운데로 위치시킬 수 있다.

position: absolute;
left: 50%;
top: 50%;
margin-left: -75px;
margin-top: -75px;

position은 앞선 예시에서 보았듯이 직관적이고 매우 편리하지만 position 기능만 가지고 모든 페이지를 구성하기에는 유지보수 측면에서 어려우므로 margin, padding, width, height, border 등으로 커버가 되지 않는 경우에만 제한적으로 쓰는 것이 좋다.


기타 내용

+ 개인적으로 수업 시간에 진행했던 애니메이션이 재미있었는데 IE 하위 버전에선 동작하지 않는다고 한다.

.header .frog img {
    margin: 25px;
    position: relative;
    top: -100px;
    transition: all 1s;
}

.header .frog:hover img {
    top: 0;
    transform: rotate(-360deg) scale(0);
}

+ background color 값에 rgba 모델을 사용할 수 있다. rgba(255, 255, 255, 0.45); 마지막은 알파 값. opacity 값이다.

+ z-index 속성을 이용해 요소간 겹침이 발생할 때 어떤 요소를 우선적으로 표시할지 지정해줄 수 있다.

+ width: 100% 값을 주면 부모 너비를 따라 자식의 너비가 결정되는데, position을 이용해서 동일한 표현을 할 수 있다.

position: absolute;
left: 0;
right: 0;

+ div에 background-image를 주었는데 표시가 되지 않는 이유? 블록 엘리먼트는 명시적인 높이를 갖지 않으므로 Height를 지정해주어야 확인할 수 있다. Width는 기본적으로 부모의 100%를 가져간다.

끝.

2018년 6월 20일 수요일

[디자인 패턴] Adapter, Decorator, Facade, Proxy

특정 클래스를 Wrapping해서 사용하는 디자인 패턴으로 Adapter, Decorator, Facade, Proxy 등이 있다. 각각의 역할과 쓰임에 대해 알아보기로 하자.

Adapter Pattern

Incompatible → Compatible. Convert!!


Adapter 패턴은 클라이언트가 원하는 인터페이스(Target)와 호환되지 않는 클래스(Adaptee)를 소스 코드 변경 없이 클라이언트가 원하는 인터페이스로 동작할 수 있게 해준다. Adapter 클래스가 서로 호환되지 않는 인터페이스를 변환하여 동작할 수 있게 하는 것이다. 이를 이용하면 클라이언트는 Adaptee를 몰라도 되고, Adaptee의 수정 없이 원하는 목적을 달성할 수 있는 이점이 생긴다.

public class AdapteeToClientAdapter implements Adapter {
    private final Adaptee instance;

    public AdapteeToClientAdapter(final Adaptee instance) {
         this.instance = instance;
    }

    @Override
    public void clientMethod() {
       // call Adaptee's method(s) to implement Client's clientMethod
    }
}



Decorator Pattern

대상 Object의 기능을 확장


원래의 코드를 Wrapping하여 동적으로 책임을 인터페이스에 추가하기 위해 사용한다. 전형적인 예로 자바의 I/O가 있다.
BufferedReader br = new BufferedReader(new FileReader(new File("test.txt")));

public interface Coffee {
    public double getCost(); // Returns the cost of the coffee
    public String getIngredients(); // Returns the ingredients of the coffee
}

public abstract class CoffeeDecorator implements Coffee {
    protected final Coffee decoratedCoffee;

    public CoffeeDecorator(Coffee c) {
        this.decoratedCoffee = c;
    }
...
    public String getIngredients() {
        return decoratedCoffee.getIngredients();
    }
}

class WithMilk extends CoffeeDecorator {
    public WithMilk(Coffee c) {
        super(c);
    }
...
    public String getIngredients() {
        return super.getIngredients() + ", Milk";
    }
}

class WithSprinkles extends CoffeeDecorator {
    public WithSprinkles(Coffee c) {
        super(c);
    }
...
    public String getIngredients() {
        return super.getIngredients() + ", Sprinkles";
    }
}



Facade Pattern

복잡한 것을 간단하게, 개별 컴포넌트로의 접근을 하나로.


클래스 라이브러리 같은 어떤 소프트웨어의 다른 커다란 코드 부분에 대한 간략화된 인터페이스를 제공하는 객체이다. (위키피디아)
Wrapper가 특정 인터페이스를 준수해야 하며, 폴리모픽 기능을 지원해야 할 경우에는 Adapter 패턴을 쓰고 단지 쓰기쉬운 인터페이스를 이용하고 싶을 경우에는 Facade를 쓴다.

class CPU {
    public void freeze() { ... }
    public void jump(long position) { ... }
    public void execute() { ... }
}

class HardDrive {
    public byte[] read(long lba, int size) { ... }
}

class Memory {
    public void load(long position, byte[] data) { ... }
}

class ComputerFacade {
    private CPU processor;
    private Memory ram;
    private HardDrive hd;

    public ComputerFacade() {
        this.processor = new CPU();
        this.ram = new Memory();
        this.hd = new HardDrive();
    }

    public void start() {
        processor.freeze();
        ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE));
        processor.jump(BOOT_ADDRESS);
        processor.execute();
    }
}



Proxy Pattern

Subject에 대한 은닉과 제어


특정 객체에 대한 접근을 제어하고, 객체에 대한 접근에 대해 추가 기능을 제공할 필요가 있을 때 사용한다. 보안, 성능, 네트워킹 등의 이유로 Subject (실제 object)를 숨겨야 하는 경우 쓰인다.
구현 예로 원격 object와 통신하는 Remote proxy, 비용이 드는 object에 접근을 통제하는 Virtual proxy,  Role 기반 object의 접근을 제공하는 Protection proxy, 캐시 object를 반환하는 Caching proxy 등이 있다.

interface ICar
{
    void DriveCar();
}

// Real Object
public class Car : ICar
{
    public void DriveCar()
    {
        Console.WriteLine("Car has been driven!");
    }
}

// Proxy Object
public class ProxyCar : ICar
{
    private Driver driver;
    private ICar realCar;

    public ProxyCar(Driver driver)
    {
        this.driver = driver;
        this.realCar = new Car();
    }

    public void DriveCar()
    {
        if (driver.Age < 16)
            Console.WriteLine("Sorry, the driver is too young to drive.");
        else
            this.realCar.DriveCar();
     }
}

public class Driver
{
    public int Age { get; set; }

    public Driver(int age)
    {
        this.Age = age;
    }
}

2018년 6월 16일 토요일

veamcamp HTML+CSS 재미있게 입문하기 4주차

이제 좀 눈에 들어오는 것 같다.

4주차의 주요 내용은 float와 overflow.
inline-block의 대안(?) float는 inline-block에서 생기는 의도치 않은 spacing을 컨트롤할 수 있게 해준다. 그리고 overflow는 float의 부작용을 컨트롤 해준다. 물론 float와 overflow가 요소의 가로 배치를 위해 만들어진 기능은 아니다.

컨텐츠의 가로 배치를 고려할 때 선택사항 세가지.
1. inline-block : inline tag 특성상 생기는 띄어쓰기 공백 문제
2. float + overflow
3. grid : 브라우저 하위 호환성 문제
→ float + overflow !

몇 가지 속성에 대해..

> line-height : p 태그 내 컨텐츠에서 한 행이 갖는 높이를 설정한다. '1'이라 하면 1em과 같은 효과로 지정된 font size만큼의 행 높이가 설정된다. 기본적으로 웹사이트 내 font size는 16px라 한다. ! 태그가 차지하는 높이가 200px라 하고, line-height가 200px면 세로축 가운데 정렬과 같은 효과를 만들어낼 수 있다. 다만 영어의 경우 y, g와 같이 꼬랑지가 붙는 경우가 있기 때문에 완전히 가운데 정렬처럼 보이진 않는다.
> letter-spacing : 글자 사이의 간격
> vertical-align : 인라인 태그에 대한 수직 정렬을 제공한다. 기본 값은 baseline. 주의할점은 middle값이 line-height의 정가운데를 의미하진 않는다는 것이다. 실제론 서체의 영어 소문자 기준 가운데를 가리킨다. ! inline-block으로 나열된 상황에서 요소의 수직축 정렬이 상하로 뒤틀어지는 현상이 생길 수 있다. 이런 경우엔 vertical-align을 top으로 조정해주면 다시 원하는대로 정렬이 가능하다. vertical-align 기본값이 baseline이라 발생하는 현상으로 자세한 내용은 생략..
> text-indent: 들여쓰기 속성으로 -9999px와 같이 매우 작거나 매우 큰 값을 지정하면 text를 사라지게 하는 표현을 할 수 있다. SEO를 위해 이미지 a태그에 text를 넣어주고 text를 날리는 식으로 실무에서 쓰이는 듯 함.

em?

부모 태그에 font size가 50px라 되어있고, 자식 태그에서 font size를 0.5em라 되어있다면 자식 태그의 font size는 50px * 0.5 = 25px가 된다.
em은 font size에만 적용되는 개념이 아니고 일반적인 단위의 개념이다. 따라서 margin과 같은 속성에 em값을 지정 해줄 수 있음.

float

float는 컨텐츠를 화면에 띄우는 역할로, height를 갖지 않는 특징이 있다. 원래는 이미지와 텍스트 컨텐츠를 어우러지게 하는 목적으로 고안된 기능이지만 이를 응용해 요소들을 가로배치 하는데에도 응용된다. inline-block을 활용해 가로배치할 때 생겼던 띄어쓰기 여백을 없앨 수 있다.
float 사용에서 주의할점은 float 사용이 끝나면 해제(clear) 해주어야 한다. 그렇지 않으면 float가 선언된 이후의 모든 요소에 float 속성이 전달된다. float: left는 clear: left, float: right는 clear: right로 해제하는데, 그냥 clear: both로 하는게 일반적.



overflow

원래 목적은 문서 내 새로운 영역을 생성(격리)하는 것이지만 overflow가 갖는 성질을 이용한 각종 trick이 여러 곳에 쓰인다. 대표적으로 float와 같이 쓰거나 마진 겹침 현상을 해소해주기 위해 쓰인다.
overflow는 격리될 때 overflow가 품는 자식 요소의 모든 시각적인 표시 범위를 떠안고 격리되어진다. 앞서 적혀있듯이 float된 요소엔 따로 height 값이 없기 때문에 float의 부모도 마찬가지로 height가 적절히 지정되지 않게 된다. 이러한 부분에서 오는 여러 문제가 생길 수 있는데 float의 부모에 overflow: hidden; 속성을 줌으로 이러한 문제를 해결할 수 있다. overflow: hidden;은 부모 요소에 대해 자식 요소가 흘러 넘치면 그 내용을 숨기라는 의미지만 부모 요소에 height가 없기 때문에 부모는 어쩔 수 없이 자식 요소를 감싸야 하는 책임이 주어져 float된 만큼의 height 값을 갖게 되는 것이다. (직접 해보면 이해가 빠름.)
overflow: hidden; → float가 적용된 부모에게 overflow: hidden을 지정하면 문제 해결! 글로 적긴 힘듦..
overflow: scroll; → 부모 요소에 대해 자식 요소가 흘러 넘치면 스크롤을 붙여라. (height가 지정될 때만 동작)


이미지-스프라이팅

브라우저 렌더링 속도를 끌어올리기 위한 trick. 페이지에 담기는 이미지를 하나의 통-이미지로 만들어 각각의 요소에 통-이미지의 특정 영역을 지정해 주는 방식. 위 그림의 이미지 링크가 스프라이팅 기법으로 되어있다.
.icon a.view { background-position: left top; }
.icon a.like { background-position: center top; }
.icon a.share { background-position: right top; }

애니메이션

transition 속성으로 단순한 애니메이션 기능을 넣을 수 있다. 아래는 예시. li의 a태그 기본 상태에서 hover될 때 바뀌는 변화를 0.5초 이내에 브라우저가 부드럽게 표현해준다. 익스플로러 하위 버전에선 동작하지 않는다고 함.

.sidebar .menu li a {
    display: block;
    padding: 10px;
    background-color: #222;
    border-left: 5px solid #333;
    transition: all 0.5s;
}

.sidebar .menu li a:hover {
    border-color: dodgerblue;
    color: dodgerblue;
    background-color: #111;
    padding-left: 20px;
}


2018년 6월 6일 수요일

veamcamp HTML+CSS 재미있게 입문하기 3주차

2주차엔 과제가 있었다. 배운 내용을 가지고 해보는 자유과제 였는데 그냥 하기엔 좀 심심할 것 같아서 자바 스크립트를 사용해서 간단한 대화 기능을 만들었다. 의식적으로 제이쿼리나 다른 프론트엔드 프레임워크를 쓰지 않고 하려니 생각보다 시간이 걸렸다. 아래는 결과물.


업무 시간 외에 뭔가 만들어본건 오랜만이라 완성도를 떠나서 꽤나 신선한 경험이었다. 3주차엔 선택자에 대한 심화(?) 내용과 display 속성에 대해 배웠다.

마진 병합, CSS의 우선순위

마진과 마진이 만나면 자동으로 병합이 된다는 내용. 예를 들어 연속된 두개의 요소에 각각 margin이 20px를 지정하면 두 요소 사이의 간격이 40px가 아니라 20px가 된다는 내용이다.

CSS의 우선순위. 나중에 선언될수록, 구체적일수록 높은 우선순위가 높다. 선택 구문마다 일종의 score가 메겨진다고 보면 되는데, 당연히 score가 높을수록 우선순위는 높다.

<h1 class="wow wow2"/>를 가장 구체적으로 선택해보자.
 → h1.wow.wow2
.wow.wow2는 어색한 표현이지만 아무튼 저렇다고 한다. h1:hover에서 'hover'도 클래스의 범주에 들어가므로 h1:hover는 좀 더 구체적인 h1.wow.wow2에 의해 무시된다는 점을 이해할 수 있어야 한다.

.section.skill:hover h2 { ... }
 → section이면서 skill 클래스를 갖는 태그에 hover가 되면 그 하위의 h2 스타일이 변경된다.

.section.skill :hover { ... }
 → section이면서 skill 클래스를 갖는 태그 내 모든 자식에 hover가 되면 스타일이 변경된다.

다시 정리하는 페이지 만들기 순서

1. 덩어리를 구성한다.
2. CSS를 담백하게 만들고 시작하자. (CSS RESET)
 → 브라우저마다 지정되는 기본 스타일이 조금씩 다르므로 동일한 기준에서 동작하도록 한다.
3. 각 덩어리의 백그라운드를 지정한다.
 → 요소가 차지하는 영역을 확인하기 위함이다.

서체 지정

구글 웹폰트 (https://fonts.google.com/)
전문가가 미리 만들어놓은 웹 폰트를 따다 쓰는 쪽으로 많이 한다고 한다. 구글 웹폰트 기준으로, script를 로드하고 css만 해당 서체를 지정해주면 폰트를 쉽게 적용할 수 있다.

Span

인라인 태그를 감싸는 용도로 span이 권장된다. 인라인 태그는 완전한 박스모델을 따르지 않으므로 사용법이 다름에 주의할 필요가 있다. 예를 들면 span에 width는 적용되지 않는다. (span에는 width 대신 길이의 개념이 적용된다.) 그리고 span엔 margin, padding을 지정할 순 있지만 top, bottom 값이 동작하지 않는다.

Display

각 요소에 대해 display css 속성을 이용해 다른 성격을 줄 수 있다. 예를 들어, 인라인 태그에 display: block 값을 주면 해당 요소는 블록 엘리먼트 처럼 동작하게 된다. a 태그 같은거에 inline-block이나 block 같은 속성을 지정해주면 a 링크가 갖는 크기를 키울 수 있는 것이 주 활용 예다.
display: inline-block은 블록 엘리먼트의 가로 배치를 하는데 자주 쓰인다. inline 속성까지 같이 부여되기 때문에 inline 특성상 원치않는 여백이 포함되는데 이러한 부분에 대해선 floatgrid 같은 대안이 있는 듯 하다.

3주차까지 마치면 다음과 같은 웹 페이지를 만들 수 있다. 뽀록 없이 기계적으로 만들어 낼 수 있다는데서 의미가 있다. 여타 UI Framework에서 자주 쓰곤하는 margin에 음수 값을 주는 trick은 html/css에서도 유효하다.


>> 취미와 업무의 접점에서 스트레스가 찾아온다. 취미 생활에서 스트레스를 받는다면 곤란하겠지만 경험상 취미와 업무가 애매하게 걸치는 경우엔 목표를 약간 높게 설정하는 것이 좋았던 것 같다. 다음주부턴 꽤 어려워질거라 하는데 이번 기회에 잘 배워서 React나 Vue까지 연계해 볼 생각이다.

2018년 6월 1일 금요일

AWSomeday online conference 요약.

180531 AWSomeday online conference 요약

세션1. AWS 소개 및 AWS의 역사
세션2. AWS 인프라스트럭처 소개 - 컴퓨팅, 스토리지 및 네트워킹
세션3. AWS 보안 및 AWS IAM
세션4. 데이터베이스
세션5. AWS 배포 및 관리 서비스

by 정도현, 안준필 강사님.

좀더 실용적인 내용은 아래 링크를 참고하자.
http://www.pyrasis.com/private/2014/09/30/publish-the-art-of-amazon-web-services-book

세션1. AWS 소개 및 AWS의 역사

:: Amazon Web Services의 커버리지
  스토리지 / 개발 및 관리 도구 / 분석 / 콘텐츠 전송 / 메시징 / 앱 서비스 / 컴퓨팅 / 데이터베이스 / 결제 / 모바일 / 네트워킹 / 온디맨드인력 / VPC

:: 클라우드?
  클라우드 플랫폼에서 다양한 IT 리소스를 인터넷으로 제공하고 사용한 양만큼 비용을 지불하는 모델. 원하는 때 원하는 만큼 자원을 사용. 전기회사가 전기를 공급하는 것과 유사하다. AWS는 개발자와 서비스 사업자를 위한 Building 블럭을 제공. AWS를 이용하여 확장 가능하고 정교한 애플리케이션을 구축할 수 있다.

:: 왜 AWS를 사용해야 하는가?
1. 확장, 그리고 축소에 대한 민첩성
2. 비용절감 (자본비용 > 가변비용)
 - 규모의 경제로 얻게되는 이점
 - 데이터 센터 운영 및 유지 관리에 비용 투자 불필요
3. 탄력성  (시설 과잉 설치 > 실제 필요한 만큼만 리소스를 갖춤)
 - 용량 추정 불필요
4. 기능성의 폭 (타 클라우드 플랫폼과 차별성.)
5. 글로벌 서비스 (세계 곳곳에 배치된 리젼과 가용역역. 몇 분 안에 전 세계 배포 가능)
*** 기존(온프레미스) 환경 대비 최악의 상황을 고려한 프로비저닝을 하지 않아도 된다. 관리 장비와 이를 관리하는 인력에 대한 비용을 줄일 수 있다.

:: AWS 기반 시스템 구축을 위한 일곱가지 모범 사례
1. 장애를 감안한 디자인
2. 소결합 적용
3. 탄력성 구현
4. 모든 계층에서 보안 설정.
5. 여러가지 제약에서 벗어나기.
6. 모든 것을 병렬적으로 생각하기
7. 다양한 스토리지 옵션을 적용.

:: AWS가 제공하는 서비스의 구분
  서비스의 성격에 따라 색상으로 특징하였음. 예를 들면 컴퓨팅, 네트워크는 주황색, 스토리지 서비스는 빨간색으로 구성되는 식임. 'Amazon'으로 시작하는 서비스는 주 재료에 해당하고, 'AWS'로 시작하는 서비스는 보조재료, 마지막으로 아무것도 안붙는 서비스는 Amazon EC2 하부 서비스로 보면 된다고 함.

:: AWS 리전과 가용영역
 . 리전 - 지리적 위치. 2개 이상의 가용 영역(AZ)로 구성됨.
 . 가용영역 - 데이터 센터의 클러스터, 다른 가용 영역의 장애로부터 격리된다. 다중 AZ를 통해 장애에 대한 고 가용성을 보장함.
* 클러스터링된 가용영역의 집합이 리전.
* 모든 서비스를 모든 리전에서 사용할 수 있는 것은 아니라고 함.
* 엣지 로케이션 - Amazon Route 53, Amazon CloudFront 서비스를 주로 지원하는 로컬 지점.

:: AWS 사용하는 세가지 방법
 . AWS Management Console - GUI 기반. ID/PW 인증.
 . CLI - Access Key 기반 인증
 . SDK - 프로그래밍 레벨의 언어 라이브러리로 접근


세션2. AWS 인프라스트럭처 소개 - 컴퓨팅, 스토리지 및 네트워킹

:: Amazon EC2
 . 요구 사항에 따라 컴퓨팅 파워를 조정 가능한 가상화 서버 인스턴스
 . 사용한 만큼만 지불한다.
 . 새로운 서버 인스턴스 확보 및 부팅 시간을 수 분으로 단축.
 . 안정성을 위해 여러 리전과 가용 영역에 걸쳐 배포됨 또는 배포되는 것을 권장.
*** AWS Lambda라는 FaaS도 있다. 이건 아예 서버리스한 구성으로 노출시킨 Function에 대한 호출 비용만 지불하면 된다.
*** Amazon Lightsail이라는 서비스도 있는 것 같다. 간편한 웹 및 애플리케이션 서버 관리에 쓰인다고 하는데 살펴봐야 함. 저렴한게 강점인듯. Amazon ECS는 관리형 컨테이너 서비스로 뛰어난 확장성과 성능을 제공한다.

:: Amazon EC2 시작
1. 리전을 정함
2. 사전 구성된 AMI에서 Amazon EC2 인스턴스 시작
3. CPU, 메모리, 스토리지, 네트워크 요구사항에 따라 인스턴스 유형 선택
4. 네트워크, IP주소, 보안그룹, 스토리지볼륨, 태그, 키페어를 구성.

:: AMI (Amazon Machine Image)
일종의 템플릿. 리전, 운영체제, 아키텍처(32bit or 64bit), 시작 권한, 루트 디바이스용 스토리지를 기준으로 AMI를 선택하면 됨. AMI는 OS, 애플리케이션 및 구성에 해당. 실제 실행되고 중지되는건 EC2 instance.

:: EC2 인스턴스 종류
 컴퓨팅 파워 우선, 메모리 우선, 스토리지 우선, 그리고 범용 컴퓨팅 등 목적에 맞게 인스턴스가 세분화되어 지원됨. 컴퓨팅은 C, 범용 컴퓨팅은 M이 붙는 식.
 . 컴퓨팅 (C4, C3) - 고성능 프론트 엔드, 비디오 인코딩
 . 메모리 (R3) - 고성능 데이터베이스, 분산 메모리 캐싱
 . 스토리지 (I2, D2) - 데이터 웨어하우징, 로그 또는 데이터 처리 애플리케이션
 . GPU (G2) - 3D 애플리케이션 스트리밍, 기계학습
 . 범용 (T2, M3, M4) - 트래픽이 적은 웹 애플리케이션, 소형 및 중형 데이터베이스
* 인스턴스 메타데이터를 가져와 실행 중인 인스턴스를 구성 또는 관리하는데 사용할 수 있다.

:: EC2 구입 옵션 *** 확실치 않음
 . 온디맨드 인스턴스 - 시간당 비용 지불. (초당 과금 기본)
 . 예약 인스턴스 - 사용 시간을 지정하고 사용. 선 결제.
 . 예정된 인스턴스 - 일정 기간에만 사용할 경우. (트래픽이 몰리는 걸 예상 가능할 때 쓰는 모델인듯)
 . 스팟 인스턴스 - 일종의 입찰 형식으로 사용하는 모델인듯
 . 전용 호스트 - 물리적 호스트가 전적으로 인스턴스 실행에 사용되는 모델.

:: Amazon S3
 . 인터넷을 위한 스토리지, 데이터 객체에 대한 HTTP/S 엔드포인트를 제공함. (표준 REST / SOAP 인터페이스 제공)
 . 웹에서 언제 어디서든 원하는 양의 데이터를 저장하고 검색할 수 있다.
 . 데이터는 버킷 내 객체로 저장된다. 버킷 크기와 버킷 내 객체는 무제한.
 . 객체는 최대 5TB.
 . AWS SDK 통한 암호화 지원.
 . S3는 CAP에서 가용성과 파티션 내성에 중점적. 데이터 Upload / Delete 즉시에는 수정 전 데이터를 참조할 수도 있음.
* 일반 사용 시나리오: 스토리지 백업, 정적 호스팅, 미디어 호스팅, 소프트웨어 전송, AMI 및 스냅샷 저장 등 // 여러 서버에서 공용으로 쓰는 파일을 S3에 올려서 SDK와 URL로 엑세스하는데 주로 쓰임.
* 스토리지 요금, 요청 요금, 데이터 전송 요금을 기준으로 과금됨.

:: 버킷과 버킷에 저장되는 데이터 객체
  객체는 파일과 파일을 설명하는 메타데이터로 구성. 계정당 100개의 버킷 보유 가능하고 버킷 및 버킷 내 객체에 대한 access 제어가 가능함. 각 객체는 버킷 내 고유 식별값인 객체 키를 갖는다. 버킷의 버전 관리를 활성화 하면 객체에 대한 버전 관리가 가능하여 특정 버전으로 손쉽게 롤백할 수 있음.

:: S3 객체 수명 주기
  객체의 특성에 따라 나뉘게 되는 수명 주기에 대한 객체 관리 방법을 지원함. 최근에 생성된, 자주 참조되는 데이터는 '핫' 데이터. 핫 데이터에 대한 참조가 적어지거나 시간이 경과하면 콜드 데이터로 분류. 특정 데이터를 특정 기간 이상 지나면 삭제하거나 다른 영역으로 이동.

:: Amazon Glacier
 . 아카이빙 목적의 저렴한 장기 보관 서비스
 . 자주 엑세스하지 않는 데이터에 최적.
 . 3~5시간의 검색시간. (객체 복원 시간이 포함되어 느림)
 . 월별 GB당 0.01달러 수준.

:: Amazon EBS (Elastic Block Store)
 . 일관적이고 짧은 지연 시간의 성능을 제공하는 영구적 블록 레벨 저장장치
 . 가용 영역 내에서 자동으로 복제된다.
 . 스냅샷을 Amazon S3에 안정적으로 저장함.
 . EBS 지원 EC2 인스턴스만 중지 > 가동이 가능. (잘 이해는 안감.)
* EBS를 사용하면 EC2인스턴스의 수명주기와 데이터 스토리지의 수명주
기를 분리할 수 있음. (EC2 인스턴스 스토어는 휘발성이라 함. 인스턴스 스토어에 저장된 데이터는 인스턴스가 활성화되어 있는 동안만 유지. EBS는 영구적. EC2를 삭제해도 EBS는 다른 EC2에 붙일 수 있다고 하는데 확실한 건 아님.)
* 일관적 짧은 지연 시간의 성능을 제공하는 영구적 블록 레벨 저장장치. 가용 영역 내에서 자동 복제된다.

:: EBS vs S3
  EBS는 일반적으로 디스크 드라이브 용도. S3는 온라인 스토리지. EBS는 프로비저닝한 만큼 과금. S3는 사용한 만큼 과금됨. S3는 한번 쓰고 여러 곳에서 여러 번 읽는 용도.

:: Amazon VPC
 . 가상 네트워크를 프로비저닝 함. 가상 네트워크 환경을 제어할 수 있음.
 . 선택한 IP 주소 범위(서브넷)에서 AWS 리소스를 시작할 수 있고,
인터넷으로 액세스 할 수 없는 리소스에 대한 프라이빗 서브넷. (일종의 내부망. Public NAT 게이트웨이 통해 외부 데이터를 가져올 수 있긴 함.)
인터넷으로 액세스할 수 있는 리소스에 대한 퍼블릭 서브넷으로 구분. (퍼블릭에 ELB, 프라이빗에 WAS 배치.)
* 각 서브넷은 하나의 AZ 내에 모두 상주해야 하며 다른 영역으로 확장 불가함.

:: ACL (네트워크 엑세스 제어 목록)
인바운드 아웃바운드 필터링. Amazon EC2의 방화벽 역할을 한다.


세션3. AWS 보안 및 AWS IAM

:: SSL 엔드포인트
 . SSL / TLS을 이용해 보안 통신 세션(HTTPS) 구축

:: 보안 그룹
 . 보안 그룹을 사용하여 인스턴스에 대한 방화벽 규칙 구성

:: VPC
 . VPC에서 리소스 액세스에 대한 low level의 네트워킹 제약 조건을 생성.
 . 퍼블릭, 프라이빗 서브넷에 따른 리소스 접근 설정

:: 멀티 티어 보안 그룹
  웹 티어, 애플리케이션 티어, 데이터베이스 티어를 나누고, 계층 단계로 티어끼리의 연결 설정 가능.

:: IAM (Identity and Access Management)
 . AWS IAM 사용자 및 액세스 관리
 . AWS IAM 역할 및 권한 관리
 . 자격 증명 연동 사용자 및 권한 관리
 . IAM은 모든 AWS 리소스에 접근하기 위해 최초로 접근되는 포털 게이트웨이 영역
 . AWS 계정과 달리 IAM은 인스턴스 레이어의 접근을 위한 계정.
* 그룹과 사용자에 따라 권한 부여. JSON 형식으로 정책이 기술되어 있다. 별도로 IAM 역할이라는 개념이 있는데, expire time이 있는 휘발성 개념의 롤임. 특정 시기와 특정 시점에만 영역 밖의 권한이 필요할 때 임시로 사용되는 형태라 한다. IAM 역할에는 연결된 자격 증명이 없음. IAM 사용자, 애플리케이션 및 서비스는 IAM 역할을 맡을 수 있다고 하는데 듣기만한거라 그런지  잘 이해는 안감.
* 자격 증명을 공유하기보다는 역할을 사용하여 위임.
* 불필요한 사용자와 자격 증명을 제거하는 방향으로.


세션4. 데이터베이스

:: Amazon RDS
 . 비용 효율적이고 크기 조정 가능한 용량 (간편하고 빠른 배포, 확장)
 . 시간 소모적인 데이터베이스 관리 작업을 AWS가 해준다. (관리 부담을 최소화)
 . 다양한 관계형 DB 엔진을 제공함.
 . SSL 연결, 암호화 등의 보안 기능을 제공함.
* 비즈니스 프로세스 중심의 앱
* 복잡한 쿼리, 조인 및 업데이트
* 클러스터링, 파티션, 샤딩으로 극복

:: DB 인스턴스
 . DB 인스턴스는 Amazon RDS의 기본 빌딩 블록.
 . DB 인스턴스는 클라우드에 있는 격리된 데이터베이스 환경으로 사용자가 생성한 여러 데이터베이스가 포함될 수 있다.
 . 자동 백업이 기본 활성화 되어 있으며 최대 35일까지 보존기간 선택 가능.
 . 수동 스냅샷 기능 또한 제공. Amazon S3에 저장된다.

:: Amazon RDS 모범 사례
1. 메모리, CPU, 스토리지 사용량을 모니터링 한다.
2. 다중 AZ 배포를 사용해 다른 가용 영역에 동기식 대기 인스턴스를 자동으로 프로비저닝하고 유지한다.
3. 자동 백업을 활성화 한다.
4. 일일 쓰기 IOPS가 낮을 때 백업 기간이 되도록 설정한다. (*IOPS: Input/Output Operations Per Second, 저장 장치 벤치마크 성능 측정 단위)
5. I/O 용량이 높은 DB 인스턴스 클래스로 마이그레이션 하며 표준 스토리지에서 프로지버닝된 IOPS 스토리지로 변환한다.
6. 처리량 용량을 추가로 프로비저닝한다.
7. 클라이언트 애플리케이션이 DB 인스턴스의 DNS 데이터를 캐시하는 경우 TTL을 30초 미만으로 설정한다.
8. DB 인스턴스에 대한 장애 조치를 테스트 한다.

:: Amazon DynamoDB
 . 완전 관리형 No SQL 데이터베이스 서비스.
 . 어떤 양의 데이터든 제한없이 저장 가능. SSD를 사용해 빠르고 예측 가능한 성능.
 . DynamoDB에 저장되는 객체는 파티션 키과 정렬 키를 기본 키로 갖는다.
* 적은 용량의 읽기 및 쓰기를 다수 수행하는 경우 적합.
* 범위 쿼리, 단순 데이터 모델, 트랜잭션

// 물론 관리형 서비스 말고 사용자가 자체적으로 원하는 AMI에 데이터베이스를 직접 설치해 운영할 수도 있다.


세션5. AWS 배포 및 관리 서비스

:: Auto Scailing
 . Amazon EC2 용량을 조정. (도커 컨테이너, AWS DB 등도 포함.) 사용량 변화가 많은 애플리케이션에 적합하며 추가 요금없이 사용할 수 있다.가용성을 향상시키고 비용 관리 측면에서 이점이 있다. Auto Scailing 그룹으로 최소 크기, 최대 크기에 대한 EC2 인스턴스 모음을 구성한다.
 . Elastic Load Balancing과 CloudWatch와 함께 동작함.

:: ELB (Elastic Load Balancing)
  트래픽을 가용 영역에서 여러 인스턴스에 분산시켜줌. 특정 인스턴스 헬스체크에 실패하면 해당 인스턴스를 Auto Scailing 그룹에서 제외시키고 재가동 시킨다.
* Classic load balancer: TCP와 HTTP Layer 4에서의 트래픽 분석
* Application load balancer: Layer 7에 기반한 애플리케이션 레이어의 트래픽 분석 (컨테이너 기반에 유리하다함)

:: Cloud Watch
 . Auto Scailing 정책 실행 주체로 Auto Scailing 그룹의 확장과 축소 시점을 판단한다.
 . AWS에서 실행하는 AWS 클라우드 리소스와 애플리케이션에 대한 모니터링 서비스. 운영 성능 등에 대한 가시성 제공, 이벤트 기반의 룰 설정 기능 제공.
 . CPU 사용량 등의 Limit을 걸어놓고 경보를 발생시킬 수 있다. 이를 기준으로 SMS / 메일 등의 메시징 발신이나 Auto Scailing을 진행함.

- 이상 AWS 한번도 안써본 유저의 AWSomeday 후기. 잘못된 내용 있으면 알려주세요.

2018년 5월 27일 일요일

veamcamp HTML+CSS 재미있게 입문하기 2주차

오늘 배운 내용은 선택자(selector)에 대한 내용. 그리고 하나의 페이지를 구성하는데 있어서의 접근법. 다른 UI framework를 다루더라도 유사하게 적용되는 개념이다.

디자인은 단순히 예쁜 화면을 의미하는 것이 아니라 의사 결정, 사고 방식을 포함하는 개념임을 잊지 말자.

레이아웃을 만드는데 앞서 우선 html을 구성하는 각 태그가 block element인지 inline element인지 알아야 한다. div, ul, li, h1~h6과 같은 태그는 block element에 속한다. 그리고 a, span, img 등의 태그는 inline element에 속한다. Block element는 box-model을 따르며 inline element는 그렇지 않으므로 둘을 올바르게 구분할 수 있어야 원하는 결과물을 얻을 수 있다.

img 가운데 정렬 (* inline element 가운데 정렬)

img 태그로 작성된 내용이 text-align: center;에 의해 가운데 정렬이 된다는 점에선 다소 불만스러운 부분이 있지만 어쨌든 inline element에 대한 가운데 정렬엔 text-align 스타일 속성이 쓰인다고 한다. 모든 태그 요소에 대해 하나의 방법으로 horizontal align과 vertical align 속성을 지정할 수 있다면 누구에게나 좋은 상황일텐데 표준화란게 참 어렵긴 어려운가 보다.

css 별도 파일로 구분하기

역할이 다른 내용은 서로 다른 파일로 관리하는 것이 바람직하다. 특히 인라인 스타일은 지양해야 한다. css 파일은 별도 파일로 분리하는 것이 관리 측면에서 좋다.
<link rel="stylesheet" href="style.css">

레이아웃

화면을 구성할 때엔 레이아웃을 먼저 생각해야 한다. 당연한 얘기지만 큰 단위에서 작은 단위로, 작은 단위에서 더 작은 단위로 구체화 시켜 나가야 한다. 개별 요소에 대한 style은 가장 나중의 일이다.

화면 요소의 단위를 나누는 데에도 일종의 룰, 컨벤션이 있다. header - contents - footer의 3분할 구성이 일반적으로, 가장 외곽의 div는 wrapper라든가 container라든가 하는 이름을 붙인다
<div class="wrapper">
  <div class="header"></div>
  <div class="contents"></div>
  <div class="footer"></div>
</div>

Reset css

h1, li 등의 태그엔 bold체로 지정된다든가 bullet이 붙는다든가 하는 등의 기본적으로 할당되는 스타일이 있다. 거슬린다면 스타일을 제거하고 원하는 형식으로 새롭게 지정해줄 수 있다. 크롬의 검사 기능이 유용하게 쓰이는데 크롬의 검사 기능을 이용하면 각 요소가 잡히는 사이즈를 확인할 수 있을 뿐만 아니라 기본으로 지정된 스타일이 무엇인지에 대해 알 수 있다. 

기본 스타일을 무효화 해보자.
h2, ul {
  margin: 0;
  padding: 0;
}

li {
  list-style-type: none;
}

선택자

자세한 내용은 w3schools.com reference를 참고하자. (https://www.w3schools.com/cssref/css_selectors.asp)

선택자, selector는 특정 요소에 스타일을 지정하거나 동작을 부여할 때 활용되는 개념이다. 상위-하위의 관계를 표현해 특정 요소를 한정할 수 있으며 별도로 부여한 class나 id 값을 기준으로 특정 요소를 지정할 수 있다. (class는 '.'으로, id는 '#'으로 참조한다.) 그리고 :hover 등의 가상 선택자를 통해 특정 액션에 대한 스타일을 지정해줄 수도 있다.
.section li:hover {
  border-left: 5px solid dodgerblue;
  color: dodgerblue;
}

.info {
  background-image: url(images/icon-info.png);
  background-repeat: no-repeat;
  background-position: right center;
}

끝.




2018년 5월 23일 수요일

Blocking, Non-Blocking, Synchronous, Asynchronous.

면접에서 non-blocking과 asynchronous의 차이점을 질문받았었는데 제대로 답변하지 못했다. Blocking와 non-blocking 차이점을 말씀드린 후, synchronous와 asynchronous의 차이점을 말씀드리는 편이 나았을 것 같다. 아니면 blocking과 non-blocking의 차이점을 설명해보라는 질문이었다면 좀 더 나은 상황(?)이었을 것이다.

다 알고있다고 생각했던 개념이었지만 막상 설명하려고 하면 말문이 막히는 개념.. 정리해보고자 한다. 아래 링크의 자료가 가장 큰 도움이 되었다.
https://www.slideshare.net/namhyeonuk90/tcp-ip-io-model


Blocking vs Non-Blocking

Blocking, non-blocking은 호출한 입장에서 구분지을 수 있다. 함수(system call)를 호출했을 때 처리 결과와 무관하게 바로 리턴 받아 제어권을 갖을 수 있으면 non-blocking. 일반적인 함수 호출에서처럼 작업이 끝날 때까지 대기해야 하면(작업이 끝날 때가지 리턴이 없음) blocking.


Synchronous vs Asynchronous

Synchronous, asynchronous는 함수의 처리방식에서 구분지을 수 있다. 작업 완료 여부를 누가 신경쓰냐에 대한 것으로 함수의 작업 완료 후 리턴을 기다리거나 바로 리턴을 받더라도 작업 완료 여부를 스스로 확인하면 synchronous. 작업을 요청해놓고 다른 일을 하다가 해당 작업이 완료되면 완료되었음을 통지 받고 그에 따른 처리를 하는 모델은 asynchronous. (통지 방식; 델리게이트, 퓨처, 프로미스, 콜백)

→ 결과 형태의 구분으로 non-blocking과 asynchronous를 구분하기도 하고, 의견은 다양하다.

! 추가로 I/O 모델과 I/O 이벤트 통지 모델에 대한 정리. 마찬가지로 위 슬라이드 쉐어 링크에 자세히 정리되어 있다.

I/O

I/O에서 대화의 주체는 커널과 프로세스다. I/O 작업은 사용자 레벨에서 할 수 없기 때문에 프로세스는 커널에게 I/O를 요청해야 한다. 그리고 커널은 프로세스에게 I/O 상황을 응답(통지) 한다.


Blocking I/O

Blocking 모델로 클라이언트 별로 스레드를 생성해서 처리하는 방식이 일반적이다. 클라이언트 수가 많아질 수록 많은 스레드의 생성을 요구하기 때문에 스레드 생성 비용, 스레드 간 스위칭 비용 등 성능상 비효율적이다.


Non-Blocking I/O

I/O 작업을 진행하는 동안 유저 프로세스의 작업을 중단하지 않는다. selector나 poll에 여러 소켓을 바인딩 시킨 후 하나의 채널(스레드)에서 관리한다.


I/O 이벤트 통지 모델

Non-Blocking I/O의 개선 버전. 마찬가지로 하나 또는 적은 스레드로 다수의 클라이언트를 제어할 수 있다. I/O 처리를 할 수 있는 소켓(또는 fd)를 가려내서 커널이 통지해주는 방식이다.

I/O 이벤트 통지 모델 in Linux

select
이벤트 별로 감시할 소켓을 등록하고, 등록한 소켓에 이벤트가 발생하면 그것을 확인하는 방식으로 동작한다. (fd는 1024개 제한)
→ 자체 event loop를 통해 상태 변경을 확인하기 때문에 Synchronous 방식이며 timeout이 nullptr이면 Blocking, timeout이 지정되어 있으면 Non-Blocking이라 할 수 있다.

epoll
select가 매번 모든 fd를 검사한다면 epoll은 검사할 fd만 등록해 놓으면 커널이 fd를 관리하면서 이벤트 발생 여부를 알려주므로 효율이 좋다. fd 개수 제한은 없다.
→ select와 마찬가지로 Synchronous 방식이며 timeout 인자에 따라 Blocking, Non-Blocking으로 구분된다.

I/O 이벤트 통지 모델 in Windows

WSAAsyncSelect
특정 소켓에 대해 통지 받을 이벤트와 통지 받을 때 사용할 메시지를 지정해주면 이벤트가 생길 때 메시지 큐를 이용해 윈도우 메시지 형태로 통지해주는 방식이다. 소켓 이벤트를 다른 메시지 처리하듯 일관성 있게 처리할 수 있는 장점.
→ 운영체제가 I/O 완료 통지를 해주므로 Asynchronous. WSAAsyncSelect에 지정된 소켓은 Non-Blocking으로 동작이 바뀐다. 따라서 Non-Blocking.

WSAEventSelect
윈도우 메시지 모델이 아니고, 네트워크 이벤트가 발생했을 때 이와 연동시킬 이벤트 오브젝트를 등록하는 방식으로 처리된다.
→ select와 비슷하게 폴링하는 방식이므로 Synchronous. 마찬가지로 WSAEventSelect에 지정된 소켓은 Non-Blocking으로 동작이 바뀐다.

2018년 5월 22일 화요일

veamcamp HTML+CSS 재미있게 입문하기 1주차

빔캠프(veamcamp.com)란 곳에서 HTML+CSS 무료강의를 하길래 신청해서 듣기 시작했다. 집에서 가까운 곳이기도 했고, HTML과 CSS에 대해 기초를 쌓고 싶어서 고민없이 신청했다. 빔캠프는 웹디자인 코딩 강의를 하는 곳으로 상수역 근처에 위치해 있다.

신청한 강의는 토요일 오후 5시부터 8시까지 3시간씩 5주 과정으로 HTML과 CSS에 대해 초심자가 꼭 알아야 하는 내용에 대한 강의로 구성되어 있다. 5주간 배울 수 있는 것은 다음과 같다.
a. 박스모델
b. 선택자
c. 블록과 인라인 태그 구분
d. float와 position과 관련된 레이아웃

정규 강좌는 아니고 일종의 맛보기 강좌이기 때문에 깊이 있는 주제를 다루진 않는 듯 하다. 그래서 어찌보면 검색 엔진에서 쉽게 찾을 수 있고 충분히 혼자서 익힐 수 있는 내용이긴 하다. 하지만 이 강의가 괜찮게 느껴지는건 잘 짜여진 틀 안에서 직접 실습해보며 익힐 수 있기 때문에 쉽게 안잊어버릴 것 같단 생각이 든다. 그리고 강사 분 강의 실력이 참 괜찮다. 유머도 있으시고, 완전 초보까지 다 끌고가면서도 정해진 시간안에 나가야 하는 진도를 다 끝마치시는 걸 보면 말이다.

정리 차원에서 간단하게나마 기록은 해두자.

1주차 후기.


개발 환경을 구성했다.

brackets를 설치했고, 자동 들여쓰기와 tab 자동완성 기능을 제공하는 emmetindent guide라는 확장 기능을 설치하였다. atom과의 비교는 잘 모르겠고, sublime text와 비교했을 땐 brackets가 web 개발 환경만큼은 live view를 제공하기 때문에 좀 더 편한듯 하다. 현재 줄을 복사 붙여넣기 하는 단축키(Ctrl + D)와 색상 선택 단축키(Ctrl + E)는 기억해두자.

HTML 문서의 기본 골격과 컨텐츠를 표현하는 태그에 대해 실습하였다.

* 박스 모델: width + height + padding + border + margin.
* HTML은 구조, CSS는 인테리어. 구조를 잡는다는 것은 태그를 이용해 컨텐츠에 성격을 부여하는 것. 각 컨텐츠 요소는 부모-자식의 관계를 갖으면서 확장해 나간다.

. CSS에선 UI Framework에서 흔히 제공되는 center align 속성이 없다. width를 지정해 주고, margin-left: auto; margin-right: auto;와 같이 지정해 주어야 가운데 정렬이 된다. text 요소엔 text-align이란 요소가 있긴 하다.
. padding은 안쪽 여백에 대한 것, margin은 바깥쪽 여백에 대한 공간인데 padding은 컨텐츠의 크기에 영향을 주고 margin은 영향을 주지 않는다.
. border-width, border-style, border-color는 border라는 단축 속성으로 한 번에 표현할 수 있다. border: 5px solid blue; // margin 속성도 마찬가지로 상-우-하-좌 순서로 각 margin을 하나의 속성에 구분해서 지정해줄 수 있다.

2018년 5월 12일 토요일

샤딩, 파티셔닝

Partitioning

파티셔닝은 데이터를 다수의 테이블로 쪼개는 행위를 뜻하는 일반적인 용어(term) 이다. 그리고 파티셔닝은 수직 파티셔닝과 수평 파티셔닝으로 구분된다. 수직 파티셔닝은 하나의 엔티티(table)에 저장된 데이터를 여러 개의 테이블로 분리하는 것을 의미하고, 수평 파티셔닝은 물리적으로 다른 데이터베이스에 데이터를 수평 분할하는 것을 의미한다. (스키마를 복제하고 샤드키를 기준으로 서버를 구분하는 방식.)마지막으로 샤딩은 수평 파티셔닝과 같은 의미로 사용된다.


Sharding

샤딩 (수평 파티셔닝)에 대해 더 알아보자. 샤딩은 서비스를 구성하는 특정 데이터가 서버 1대의 가용 범위를 넘어선다면 고려될 필요가 있다. 가장 기본적인 방법으로 데이터의 range와 서버의 개수를 고려해 0~10000번대로 분류되는 데이터는 하나의 샤드에 저장하고, 10001~20000번대로 분류되는 데이터는 다른 샤드에 저장하는 방식을 고려할 수 있다. 또는 지역 단위로 망원동 데이터는 A 서버에 저장하고, 합정동 데이터는 B 서버에 저장하는 방식을 고려할 수 있을 것이다. 마지막으로 일관된 해싱(consistent hashing) 알고리즘을 적용한 샤딩을 고려할 수 있다


Consistent Hashing

일관된 해싱은 메타 정보를 조회하지 않고 클러스터에서 키가 저장된 서버를 바로 찾아갈 수 있는 방법이다. 키의 해시 값을 구하고, 이 해시 값으로 서버를 찾는 방식인데 서버 목록을 ring 형태로 나열한 뒤 각 서버는 ring에서 각자 맡은 범위만 처리하는 방식이다. 중간에 서버가 추가되거나 삭제되는 과정에서도 일관된 해싱을 보장할 수 있어야 한다.


아마 초기 구현 단계에서 부터 데이터의 트래픽이나 볼륨이 예상 가능하다면 상대적으로 쉽게 샤딩을 디자인에(+stateless 한 구성) 반영할 수 있을 것이고, 그렇지 못한 상황에선 상당히 골치 아픈 일이 될 수 있다. (분산 환경을 고려하지 않았던 서비스 중간에 샤딩을 적용하는 등.) 샤딩을 고려하지 않은 채 디자인된 서비스에서는 join, 트랜잭션, 프로시져 등 데이터를 서버 단에서 처리하기 용이하도록 하는 기법을 사용했을 가능성이 높기 때문에 이러한 서버의 역할을 클라이언트로 내려주는 등의 노력이 필요하다.


2018년 5월 10일 목요일

[ML] Linear Regression

회귀 (regression)

한번 돌아 원래로 돌아오는 것.
회귀는 영구의 유전학자 갤톤이 유전의 법칙을 연구하다 나온 명칭이다. 갤톤은 부모와 자식간의 신장을 조사하였는데, 일반적으로 장신인 부모의 아이는 장신이지만, 그 평균 신장은 부모만큼 크지 않다는 것을 밝혀내었다. 아이의 신장은 항상 일반적인 평균으로 되돌아가는 경향이 있다고 하여, 이것을 평균으로의 회귀 (regression toward to the mean)라 하였다.

회귀의 법칙을 활용한다면 남녀 키의 평균 값을 가지고 알지 못하는 누군가의 키를 그냥 퉁쳐서 예측해볼 수 있을 것이다. 하지만 단순 평균만을 가지고 예측한다면 예측의 정확도는 떨어질 수 밖에 없다. 예측 정확도를 높이기 위해선 키에 영향을 주는 다른 요인을 활용해야만 한다.


회귀 분석

회귀 분석은 독립 변수 X와 종속 변수 y 간의 관계를 정량화 하는 작업이다. 다시 적으면 독립 변수가 종속 변수에 미치는 영향력의 크기를 파악하는 것이다.

회귀 분석을 하면 변수들 사이에서 나타나는 트렌드(trend)를 설명할 수 있다. 단순히 상관 관계의 유무를 넘어 어떤 관계인지 좀 더 자세히 살펴볼 수 있다.

독립 변수와 종속 변수 간에 어떤 관계가 있을지에 대한 여러 가설을 회귀 모델(모형)이라 부르며, 회귀 모델은 크게 트렌드를 나타내는 부분과 통제할 수 없는 오차를 나타내는 부분으로 분리된다. 좋은 회귀 모델을 찾아 변수 간 관계, 경향 등을 파악하는 것이 회귀 분석의 목적으로 이는 결국 오차를 최소화하면서 자료를 설명해줄 수 있는 중심 트렌드를 찾는 것을 의미한다.


회귀 분석의 전제 조건

회귀 분석엔 여러 가정과 전제 조건이 깔린다.
  . 수집된 데이터의 확률 분포는 정규분포를 이루고 있어야 하며 오차항(residuals)은 모든 독립 변수 값에 대하여 동일한 분산을 갖는다.
  . 종속 변수 값들은 서로 독립적이어야 한다.
  . 독립 변수가 여러 개인 경우 독립 변수 간에는 다중공선성이 없어야 한다. (독립 변수간에 서로 영향을 주지 않아야 한다.)
이러한 전제 조건은 사전에 파악하기 어렵기 때문에 우선 데이터를 돌려본 후 사후 검증 과정을 거치는 것이 일반적이다.


선형 회귀

선형 회귀(linear regression)는 종속 변수 y와 한 개 이상의 독립 변수 (설명 변수) X와의 선형 상관 관계를 모델링하는 회귀 분석 기법이다. 쉽게 말하면 주어진 데이터를 잘 설명하는 하나의 대표 직선을 찾는 것이다.

선형 회귀는 종속 변수가 독립 변수에 대해 선형 함수의 관계에 있을 것이라 가정하고 선형 예측 함수(1차 함수)를 사용해 회귀식을 모델링한다. 한 개의 독립 변수에 기반한 경우에는 단순 선형 회귀(Simple linear regression)라 하고, 둘 이상의 독립 변수에 기반하는 경우에는 다중 선형 회귀(Multiple linear regression)라 한다.

선형 회귀에선 최소 제곱법(least square method)을 사용하거나 경사 하강법을 이용해 손실 함수(loss function)을 최소화 하는 방식으로 모델을 세울 수 있다. 이는 모두 오류를 최소화 하는 최적의 회귀 직선을 찾기 위함이다.


최소 제곱법

최소 제곱법은 관측치 y와 예측 결과 값(회귀선) 간 오차의 제곱의 합이 최소가 되는 해를 구하는 방법이다. 분산을 구할 때 편차를 제곱해서 사용하는 것처럼 최소제곱법도 잔차를 제곱해서 사용한다. 양수와 음수가 섞여있으므로 전체적인 오차를 파악하기 힘들기 때문에 부호를 없애는 방법으로 제곱을 선택한다. 절대값을 사용하는 것 대비 부가 효과로 큰 폭의 오차에 대해 보다 더 큰 penalty를 줄 수 있다. 가능한 변동 폭이 적은 회귀선을 도출하기 위함이라 볼 수 있다.


정규화 선형 회귀

정규화(regularized) 선형 회귀 방법은 선형 회귀 계수(weight)에 대한 제약 조건을 추가함으로써 모형이 과도하게 최적화되는 현상, 즉 과최적화를 막는 방법이다. (Normalization이 아니고 Regularization임에 유의하자.)

실제로 데이터를 분석할 때 변수가 굉장히 많은 데이터에 회귀 분석 모델을 적용해야 하는 경우가 자주 발생하는데 변수가 많아질 때 필연적으로 생기는 문제점이 있다.
  1) 모델이 학습 데이터에 오버피팅 되는 경향이 생긴다.
  2) 모델을 해석하기 어려워진다. 만약 어떠한 현상을 설명하는 것이 목적이라면 적은 개수의 변수로 작은 모델을 만드는 것이 권장된다.

정규화 모형은 위 문제를 해소해 준다. 일반적으로 회귀 분석에서의 정규화는 회귀 계수가 커지면 커질수록 모델에 penalty를 주는 방법이다. (모델이 과도하게 최적화되면 모델 계수의 크기도 과도하게 증가하는 경향이 있다.) 따라서 기존 문제에서 오차를 최소화 하는 동시에 penalty에 대한 최소화도 동시에 고려해 주어야 한다.

정규화 선형 회귀의 방법으로 Ridge, Lasso, Elastic Net의 잘 알려진 방법이 있다. Ridge는 각각의 회귀 계수를 제곱한 값의 합에 비례하는 penalty를 주는 모델이다. Ridge 모델은 총 계수의 합을 줄여주는 것에 초점을 맞추고 있으며 가중치 계수를 한꺼번에 축소시키는 특성이 있다. Lasso는 모든 계수를 최대한 0으로 만들어 주는 것에 초점을 맞추고 있으며 일부 가중치 계수가 먼저 0으로 수렴하는 특성이 있다. 마지막으로 Elastic Net은 Ridge와 Lasso를 모두 합친 일종의 하이브리드 모델이라 할 수 있다.

샘플 코드 : http://scikit-learn.org/stable/auto_examples/linear_model/plot_ols.html


[용어 정리]

* 코스트 펑션 vs 로스 펑션 vs 오브젝티브 펑션: https://stats.stackexchange.com/questions/179026/objective-function-cost-function-loss-function-are-they-the-same-thing

* 오차(error): 회귀식의 값과 실제 값(모집단의 모수식으로 부터 나온 값)과의 차이. 모든 데이터를 하나의 회귀식으로 100% 설명할 수 없다.

* 잔차(residual): 표본의 회귀식으로 부터 나온 값. 관측 값의 y와 예측 값의 y 간의 차이. 표본에서는 오차(error) 대신 통계량의 개념을 갖는 잔차(residual)라는 용어를 사용한다.

* 표준화 (Standardization)
수식: (요소값 - 평균) / 표준편차
의미: 평균을 기준으로 얼마나 떨어져있는지를 나타내는 값. 2개 이상의 대상에 대해 단위가 다를 때 같은 기준으로 볼 수 있게 한다. 추가적인 효과로 로그보다는 덜하지만 간극이 큰 데이터의 진폭을 줄여주기도 한다.
→ 키와 몸무게에 대한 표준화, 서로 다른 두 주식 종목에 대한 표준화.

* 정규화 (Normalization)
수식: (요소값 - 최소값) / (최대값 - 최소값)
의미: 전체 구간을 동일하게 설정하여 데이터를 관찰하는 방법. 데이터 군 내에서 특정 데이터가 가지는 위치를 볼 때 사용한다.
→ 주식 시세, 과거 대비 현재 시세의 위치를 파악할 수 있음.