레이블이 Shard인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Shard인 게시물을 표시합니다. 모든 게시물 표시

2018-04-14

2018년 15번째 주

이 포스팅은 그냥 지난 한 주간 읽었던 것들을 정리하는 포스트입니다. 그냥 예전에 봤던 글 중 나중에 필요한데 뭐였는지 기억 안 나는 글들이 있어서 쓰기 시작했습니다.

보통 하는 일과 관련된 글들이 올라오겠지만 딱히 정해둔 주제는 없고, 그때그때 관심 있었던 것을 읽었기 때문에 지난주에 쓰인 글일 수도 있고 몇 년 전에 쓰인 글일 수도 있습니다.


실제로 git을 사용하면서 단순히 커맨드를 외워서 사용하는 사람들을 많이 봤다. 보통 그 이유로 크게 두 가지를 든다. 첫 번째로 git의 mental model이 복잡하다는 것이다. git에서 변경된 내용은 크게 다음 상태 중 하나가 된다.

  1. 리모트에 존재하는 상태
  2. 로컬 브랜치에 있는 상태
  3. 브랜치에 머지되지 않았지만 add 돼 있는 상태
  4. 변경은 있지만 add 되지는 않은 상태
  5. stash에 들어있는 상태
  6. 예전에 커밋했었지만 지금은 브랜치로 따라갈 수 없는 상태

이 중에서 내가 수정했던 내용이 어떤 상태인지 모르는 것이 헷갈리게 하는 첫 번째 이유다.
하지만 반대로 왜 이렇게 많은 상태를 가지게 됐을지 생각해보면 git을 사용하는 데 도움이 된다. 이것들은 전부 그냥 추가된 것이 아니다. 애초에 git을 처음 만든 사람은 Linus Torvalds다. 그의 성격상 쓸모없는 것은 추가되지 않았다. 전부 제각각의 목적을 가지고 있다. 이 목적을 이해하는 것이 중요한데 아쉽게도 글로 잘 설명할 자신이 없다. 사실 이걸 이해하는 가장 빠르고 확실한 방법은 svn을 써보는 것이다. 쓰다 보면 불편한 부분들이 자주 생기는데, git에서는 위에서 말한 것들을 이용해 이를 쉽고 빠르게 해결할 수 있다.

사람들이 git을 어려워하는 두 번째 이유는 명령어가 복잡하다는 것이다. 이건 어쩔 수 없다. 사실 git의 명령어는 규칙성 없이 만들어졌다. 그래서 외우는 수밖에 없다. 하지만 어떤 상황에서 어떤 명령어를 써야 한다는 식으로 외우면 끝이 없다. 그보다는 각 명령어가 어떤 상태와 연관이 있는지를 보는 것이 좋다. git 명령어는 대부분 변화된 내용을 위의 상태 중 하나로 만들거나, 특정 상태로 로컬에 있는 파일을 변경하는 것이다. 따라서 현재 파일이 어떤 상태에 있고 명령어 이후 어떤 상태로 된다는 것을 인지하고 있으면 조금은 더 쉽게 적응할 수 있다.

News is bad for you – and giving up reading it will make you happier

뉴스가 사람의 정신건강에 해롭다는 기사다. 사람들이 흔히 정보를 얻으려고 뉴스를 읽지만, 실제로는 별 도움도 안 되고 시간만 낭비하게 하고 사람의 창의성을 없애고 수동적으로 만든다는 것이다.

Introduction to zkSNARKs

이더리움의 최근 움직임 중에서 zero-knowledge proof인 zkSNARKs을 도입하고자 하는 움직임이 있다. 위 자료는 이더리움 소속으로, 솔리디티 창시자 중 하나이며 zkSNARKs를 구횬하고 있는 Christian Reitwiessner이 zkSNARKs에 대해 간단히 소개한 발표자료다. 자료 이름은 zkSNARKs이지만 대부분의 내용을 zero-knwledge proof가 무엇인지에 설명하는 데 쓰고 있으므로 zero-knowledge proof가 무엇인지 알고 싶은 사람들이 보기에도 좋은 자료다.

RSS is undead

RSS는 이미 수명이 끝났고, 다시 살아날 리 없다는 글이다. 지난번에 소개했던 It's Time for an RSS Revival이나 Why RSS Still Beats Facebook and Twitter for Tracking News의 반대편에 있는 입장이다.

RSS는 소규모 사이트의 글을 구독하는 데는 적절하지만, 대형 사이트의 특정 카테고리의 글을 구독하는 데는 적당한 UX를 제공하지 못하고, 퍼블리셔 입장에서 사용자의 패턴을 파악할 수 없을뿐더러 광고수익을 얻을 수 없기 때문에 사용자와 퍼블리셔 양쪽에게 손해라는 것이다.

What is a “box model”? (UI Element layout)

Web을 비롯하여 현대의 많은 UI framework들이 box model을 사용하기 때문에 프론트엔드 개발을 하려면 한 번 읽어두는 것이 좋다.

The Science of The Job Search, Part III: 61% of “Entry-Level” Jobs Require 3+ Years of Experience

경력 같은 신입을 원하는 건 우리나라뿐 아니라 전세계 공통인듯하다.

A fork on Github is no fork

Git은 decentralized 된 version control system이기 때문에 fork를 하면 어디서 fork 해왔는지와 완전히 독립적인 repository로 존재할 수 있다. 하지만 Github의 fork는 그 모든 설정과 권한이 원본 repository에 종속적이기 때문에 진짜 fork가 아니라는 글이다.
원칙적으로 맞기는 하지만 Github Enterprise나 private repository 유료 모델을 생각해보면 어쩔 수 없는 선택이었다고 생각한다.

Uninhabited types are ZSTs despite partial initialization being allowed in safe code.

Rust 1.24.0 이후 생긴 memory safety가 깨지는 버그다.

Rust는 무한루프나 내부에서 exit 하기 때문에 return 되지 않는 함수를 표현하기 위해서 uninhabited type을 도입했다. 이 uninhabited type으로 product type을 만들면 이 타입도 uninhabited type이 돼서 크기가 0인 type으로 계산되는데, 이 product type의 다른 field를 접근하는 게 가능해서 주소 계산이 잘못되는 버그가 발생했다. Rust에 zst(zero size type)가 도입됐을 때부터 메모리 주소 계산을 잘못 하는문제가 발생하지 않을까 생각했는데 정말로 터져버렸다.

현재 두 가지 해결 방안 중에서 어느 쪽으로 해결할지 논의 중이라고 하니까 다음 버전인 1.26.0에서는 수정될 것으로 보인다.

Top 10 Bugs in the C++ Projects of 2017

소프트웨어 분석 회사인 viva64에서 2017년 동안 발견했던 버그 중 가장 인상 깊은 버그 10개를 발표하였다. uninitialized memory부터 type error나 단순 실수까지 다양하게 있다.

Don’t Give Away Historic Details About Yourself

자기 정보를 쉽게 제공하지 말라는 글. 특히 우리나라 사람들은 주민등록번호 유출에조차 익숙해져서 그런지 자기 정보를 적는데 아무런 망설임이 없다.

Why Does "=" Mean Assignment?

수학에서는 보통 대입에는 :=를 사용하고 =는 비교에 사용한다. 근데 프로그래밍에서는 왜 =를 대입에 사용하게 됐는지에 관한 글이다. 뭐 지금은 다들 =를 대입연산자로 사용하고, ==를 비교연산자로 사용하는 데 익숙하기 때문에 별 의미는 없지만, 그냥 재미로 읽어봤다.

2018-04-12

이더리움 샤딩

현재 이더리움이 겪고 있는 가장 큰 문제는 scalability다. 이더리움이 인기를 끌면서 트랜잭션의 양도 늘어나고 참여하고 있는 노드의 수도 늘고 있는데 PoW를 쓰는 이더리움의 특성상 초당 트랜잭션 처리 수는 늘지 못한다. 그래서 지금 이더리움 코어 개발자들이 초점을 맞춰서 개발하고 있는 것이 ethereum sharding이다.

이더리움 샤딩을 간단히 설명하면 샤드별로 merkle patricia tree를 만들고 그 샤드의 root들로 만들어진 merkle partricia tree의 root만을 블록체인에 올리는 것이다. 이렇게 하면 모든 miner가 모든 트랜잭션을 실행할 필요 없이 각 샤드별로 miner를 분산시켜 실행할 수 있기 때문에 전체 실행 속도가 올라간다는 내용이다. 설명은 간단하지만 구현은 간단하지 않다.

이더리움은 replay attack을 막기 위해서 account nonce라는 것을 도입했다. 현재 state에서 account가 가지는 nonce보다 1 큰 nonce를 가지는 트랜잭션만 유효한 transaction이기 때문에, 같은 account에서 보내는 2개 이상의 트랜잭션은 동시에 처리될 수 없다. 즉, 한 account의 트랜잭션이 두 개 이상의 샤드에서 실행되면 안전하지 못하다는 것이고, account는 샤드에 종속돼야 한다. 또한, 샤드는 독립적으로 실행돼야 한다. 이 말은 한 샤드에서 실행된 트랜잭션이 다른 샤드에 영향을 주지 못 한다는 것이고, 다른 샤드에 존재하는 account 사이에서는 트랜잭션을 주고받을 수 없다는 것이다.

현재 제안된 샤드 간 통신은 receipt tree를 이용하는 것이다. 예를 들어 shard N의 account A에서 shard M의 account B로 송금하는 상황을 생각해보자. 이때 N은 account A의 계좌를 차감하는 transaction T1을 실행한다. T1M의 state를 변경할 수 없기 때문에 B에게 바로 입금할 수 없다. 따라서 T1MB에게 돈을 추가하라는 receipt만 남긴다. 그 후 M에서 B에게 입금하는 transaction T2를 실행하고 자신이 입금했다는 것을 다시 receipt에 적는다.

이렇게 하면 기존보다 비효율적이지만 샤드 간 송금은 처리할 수 있다. 하지만 아직 넘어야 할 산이 있다. 이더리움의 consensus 방식은 finality를 확률적으로만 보장한다. 위의 예제에서 T1을 실행됐으면 T2가 실행되고, T1이 실행되지 않았으면 T2도 실행돼서는 안 된다. 따라서 N에 문제가 생겨 reorganization이 발생하여 T1이 사라졌으면, M도 reorganization하여 T2를 지워야 한다. 이를 악용하면, 쉽게 DoS 공격이 가능해진다. 따라서 T2를 실행하기 전의 T1의 finality를 보장해야 하는데, 앞서 말했듯이 현재 이더리움에서는 방법이 없다. 완전히 PoS로 옮겨가거나 최소한 Friendly Finality Gadget이 들어가야 확실하게 finality를 보장할 수있게된다. 그래서 현재 진행중인 sharding phase 1에서는 샤드 간 통신은 구현이 없고 phase 4에서야 구현될 것이라고 한다.

샤드 간 송금은 finalty만 보장되면 위와 같은 방식으로 할 수 있지만, smart contract를 실행하는 것은 이것보다 더 복잡해진다. smart contract에서는 다른 smart contract를 호출할 수 있는데, smart contract도 각자 자신의 state를 가지고 있기 때문에, 모든 smart contract가 같은 shard에 있어야 한다. 이 문제를 해결하기 위해 smart contract를 lock 하여 실행시킬 shard로 가져오는 cross shard lock scheme이 제안은 됐지만, 아직 결정된 것은 아무것도 없다.

이더리움의 성능 문제가 현재 이더리움이 가지는 가장 큰 문제인 것은 확실하다. 이더리움의 트랜잭션 양은 늘어나고 있는데 아직도 이더리움의 초당 트랜잭션 처리 속도는 20tx/s를 넘지 못하고 있다. 하지만 샤딩만으로 얼마나 성능을 향상할 수 있을지는 의문이다. 샤드를 N개 만들었을 때, 최상의 결과는 N배 빨라지는 것이다. 이것도 정말 이상적인 것이고 실제로 이만한 성능 향상을 얻지는 못할 것이다. 따라서 성능을 많이 올리고 싶으면 샤드의 개수를 늘려야 한다.

하지만 위에서 말했듯이 샤드를 도입하면, 샤드 간 transaction은 지금의 이더리움보다 처리 속도가 느려진다. 현재 제안된 casper에서 finality를 보장하기 위해서는 최소 50 block을 기다린다. 샤드 간 통신에서는 두 번째 트랜잭션이 실행되기 전에 finality가 보장돼야 하니, 샤드 간 통신의 finality를 보장하기 위해서는 최소 10분을 더 기다려야 한다는 것이다. 과연 이 overhead를 감수하면서 샤드가 가지고 올 성능 향상이 크지는 않을 것 같다.

2014-08-07

[MongoDB] Sharding (3) - shard key

 MongoDB는 auto sharding을 해주기 때문에 사용자가 어떤 shard에 저장할지 신경 쓰지 않아도 된다.
 그렇다면 어떤 document를 어떤 shard에 저장할지 어떻게 결정할까?

Shard Key

 MongoDB는 shard key를 이용하여 구분한다.
 별도로 지정하지 않았다면 shard key는 object ID(_id)이다. 하지만 해당 collection에 모든 document에 존재하는 field index 혹은 compound field index라면 shard key로 지정할 수 있다.
 하지만 compound index는 shard key로 지정할 수 없다.

Shard key의 제약 조건

 shard key에는 몇 가지 제약이 있다. 우선 shard key는 512 byte를 넘을 수 없다.
 하지만 이는 시스템적 제약조건이지 실제로 512 byte를 넘는 field를 shard key로 만들 일은 거의 생기지 않는다. (사실 512 byte가 넘는 index를 지정하는 일도 거의 생기지 않는다.)

 또한 한번 sharding한 collection에 shard key는 변경할 수 없다.
 만약 변경하고 싶다면 새 collection을 만들어 shard key를 설정하고 collection 전체를 복사해서 새로운 collection을 만들어야 한다.

 그다음 제약은 꽤 까다로운데 shard key로 지정된 field의 value는 변경할 수 없다. Update 때 document를 다른 shard로 옮겨야 할 일이 없도록 하기 위해서다. 변경할 일 없는 field들만을 shard key로 지정해야 한다.

 특별히 튜닝해야 할 일이 없다면 기본값인 object id를 shard key로 사용하는 것을 추천한다.

MongoDB Sharding

2014-08-06

[MongoDB] Sharding (2) - Primary shard

 MongoDB는 collection 별로 sharding을 할지 안 할지를 결정할 수 있다.
 이때 sharding되지 않은 collection들이 저장되는 shard를 "Primary Shard"라고 부른다.

 sharding되지 않은 data들이 들어 있기 때문에 이는 Single point of failure이다.

 혹시 primary shard인 머신을 down시켜야 한다면 movePrimary command로 다른 shard를 primary로 만들고 down시켜야 한다. movePrimary는 sharding되지 않은 collection들을 모두 copy해가기 때문에 무거운 작업이다. 될 수 있으면 movePrimary를 호출할 상황이 오지 않도록 노력해야 한다.

 별도로 primary shard를 정하지 않았다면, 가장 먼저 cluster에 붙은 shard가 primary shard가 된다.


 p.s. 솔직히 말하면 난 아직 primary shard를 사용해야 하는 경우를 보지 못했다.
 아마 내 MongoDB 튜닝 경험이 적어서 그럴 것이다.
 혹시 primary shard를 이용해야 했던 경험이 있다면 공유해주기 바란다.

MongoDB Sharding