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

2018년 8월 13일 월요일

UUID 64


UUID 64Bit





UUID generation is very important. It must be a truly unique identifier. Often, auto increment in an RDBMS is used to generate unique IDs, but this slows down as the number of rows grows, and slows down with increased access, and can cause single points of failure.

If using RDBMS across multiple shards instead of a single machine, unique ID generation should be different to avoid collisions. People want to use 128-bit UUIDs to avoid this, but 128 bits is too much overhead for most RDBMS where 64 bits is the limit for big ints before performance issues.

Unless performance is not a concern, 128-bit UUIDs are recommended. Doesn't Cassandra use uuid and timeuuid as default ID generation? Yet performance remains great.

So a 64-bit version can be created instead. Like timeuuid, have the timestamp in the top bits so later IDs come after earlier ones.

As long as the ID generator (Host) is different, collisions can be avoided, with 64K unique IDs per second possible. This should be sufficient for most use cases.

Here is example Go code implementing a 64-bit UUID version used successfully in production. The key is combining Timestamp (32 bits) | HostID (16 bits) | Atomic Sequence Number (16 bits) to generate unique IDs while avoiding collisions.


UUID 생성은 매우 중요하다.
말그대로 Unique Identifier가 되어야 하기 때문이다.

보통은 unique id생성을 위해서 RDBMS의 auto increment를 이용하는 경우가 많은데, 이것은 row수가 많아질수록 느리고, 많은 access가 생길수록 느려지고, single point of failure의 원인이 된다.

RDBMS를 single machine으로 쓰는 경우가 아니라, multiple shards환경에서 sharding을 하는 경우라면, unique id 생성을 다르게 해줘야 한다. id collision을 피해야 하기 때문이다.


uuid를 그래서 쓰고 싶어하지만, 128비트라서 부담스럽다.

보통의 RDBMS에서는 64bit가 big int로 지원되고, 그 이상은 퍼포먼스에 문제가 생길 수 있다. 퍼포먼스에 그다지 민감하지 않다면, 그냥 uuid 128 bit를 쓰길 권한다. Cassandra의 경우도uuid,timeuuid 를 기본적으로 id 생성으로 쓰지 않는가? 그래도 성능은 좋기만 하다.

그래서, 64 bit 버젼을 만들어서 쓴다.
timeuuid 처럼 timestamp값이 상위비트에 들어 있어서, 나중에 생긴 id가 뒤에 오도록 배려할 수 있다.
id 생성의 주체(Host)만 다르다면, collision을 피할 수 있고, 초당 64k개의 unique id를 생성할 수 있다.
이 정도면 충분하게 사용할 수 있다.

다음은 golang으로 구현한 uuid 64비트 버젼의 구현 코드이다.
실전에서도 잘 쓰이고 있다.

핵심은 Timestamp(32bit) | HostID(16Bit) | Atomic Sequence Number(16Bit) 으로 조합하여, 충돌을 피하면서, unique id를 생성하는 것이다.

---start of the code---
---end of the code---


2018년 8월 5일 일요일

Strength In Erlang





When working on projects not using Erlang, the toughest thing is releasing without complete unit tests, integration tests, and stress tests for all APIs.

Erlang projects also need those tests before release.

But a huge plus is updating without service interruption after issues arise. Especially great for socket services needing to maintain session context!

So despite lower computation speed than C++ servers, Erlang can't be beat. And it's not drastically slower - for I/O heavy work differences are small. With excellent multi-core support, Erlang can even outperform servers lacking it.

A paper comparing Go, Erlang, and Akka is a must-read!

Recommendations:

  • Use Erlang for socket services maintaining session context.
  • For HTTP REST services Erlang isn't critical.
  • Despite advantages, Erlang lacks explosive popularity due to difficult syntax and small community. Elixir helps but isn't sufficient yet and feels awkward to existing Erlang devs. Devs new or scared of Erlang can use Elixir.


Coverage Tests, Work load tests Before Release


실전에서 Erlang으로 서버를 만들지 않은 프로젝트를 접했을때,
가장 난감한 점은
"모든 API에 대한 유닛테스트와 전체 서비스에 대한 통합 테스트,그리고 스트레스 테스트를 반드시 통과해야 하지 않고서는 서비스 오픈이 겁난다"이다.

Erlang으로 했을 때에도, 유닛테스트,통합 테스트,스트레스 테스트를 하지 않는 것은 아니다.

Hot Code Reloading

그러나, 오픈후에 문제 상황 발생시에, 곧바로 원인을 파악하고, 서비스를 중단하지 않으면서 업데이트를 할 수 있다는 점은 엄청난 장점이 아닐 수 없다.
Session Context를 유지해야 하는 Socket 기반 서비스에서는 특히 그 장점이 빛이 난다.


Performance

따라서, C++ 서버(Native Binary를 지원하는)에 비해서 떨어지는 Computation 성능에도 Erlang을 선택하지 않을 수 없다.
그렇다고, 특별히 현저하게 성능이 떨어지는 것도 아니다. I/O bound job이 많은 경우에는 차이가 별로 나지 않을 뿐더러, Multi Core Support를 매우 훌륭하게 지원하기 때문에, Multi Core Support를 제대로 지원하지 않은 서버에 비하여 오히려 성능이 매우 우수하다.

Go , Erlang , Akka 를 비교한 논문이 있다. 꼭 읽어보길 바란다.

http://www.dcs.gla.ac.uk/~trinder/papers/sac-18.pdf

Recommendation

* Session Context를 유지해야 하는 Socket 기반 서비스에는 Erlang으로 구현한다.

* 그렇지 않은 http REST 기반 서비스는 Erlang이 아니어도 상관없을 듯 하다.
* 이러한 장점에도 불구하고, Erlang이 폭발적인 인기를 끌고 있지 못하는 이유는, 어려운 문법과 작은 커뮤니티일 것이다. Elixir가 그 단점을 커버하기 시작했지만, 충분하지 않고, 기존의 Erlang 개발자에게는 오히려 불편하다. Ruby 경험자나 Erlang을 처음 접하기 겁나는 개발자는 Elixir로 구현해도 될 듯하다.