code

Cassandra 데이터 모델을 설계 할 때 가장 좋은 방법은 무엇입니까?

codestyles 2020. 11. 25. 07:58
반응형

Cassandra 데이터 모델을 설계 할 때 가장 좋은 방법은 무엇입니까?


그리고 피해야 할 함정은 무엇입니까? 당신을위한 거래 중단이 있습니까? 예를 들어, Cassandra 데이터를 내보내거나 가져 오는 것이 매우 어렵다고 들었는데, 이것이 프로덕션 데이터를 개발 환경에 동기화하는 데 방해가 될지 궁금합니다.

BTW, Cassandra에 대한 좋은 자습서를 찾기가 매우 어렵습니다 . http://arin.me/code/wtf-is-a-supercolumn-cassandra-data-model 은 여전히 ​​매우 기본입니다.

감사.


저에게 가장 중요한 것은 OrderedPartitioner를 사용할 것인지 RandomPartitioner를 사용할 것인지 결정하는 것입니다.

RandomPartitioner를 사용하는 경우 범위 스캔이 불가능합니다. 즉, 오래된 데이터 정리를 포함하여 모든 활동에 대한 정확한 키를 알아야합니다.

따라서 많은 변동이 발생하는 경우 항목을 삽입 한 키를 정확히 알 수있는 마법의 방법이 없다면 임의 파티션 도구를 사용하여 항목을 쉽게 "잃어 버릴"수 있습니다. 이로 인해 디스크 공간 누수가 발생하고 결국 모든 스토리지를 소비합니다.

다른 한편으로, 주문 된 파티 셔너에게 "A와 B 사이의 열군 X에 어떤 키가 있습니까?"라고 물을 수 있습니다. -그리고 그것은 당신에게 말할 것입니다. 그런 다음 정리할 수 있습니다.

그러나 단점도 있습니다. Cassandra는 자동로드 밸런싱을 수행하지 않기 때문에 순서가 지정된 파티 셔 너를 사용하면 모든 데이터가 하나 또는 두 개의 노드에만 있고 다른 노드에는 없는데, 따라서 리소스를 낭비하게됩니다.

키의 시작 부분에 짧은 해시 값 (다른 데이터 소스에서 쉽게 열거 할 수있는 것)을 입력하여 경우에 따라 "양쪽 세계의 최고"를 얻을 수 있다는 점을 제외하면 쉬운 대답은 없습니다. 예를 들어 사용자 ID의 16 비트 16 진수 해시-4 자리 16 진수를 제공하고 그 뒤에 실제로 사용하고 싶은 키를 입력합니다.

그런 다음 최근에 삭제 된 사용자 목록이있는 경우 해당 ID와 범위 스캔을 해시하여 관련 항목을 정리할 수 있습니다.

다음으로 까다로운 부분은 보조 인덱스입니다. Cassandra에는 아무것도 없습니다. 따라서 Y로 X를 조회해야하는 경우 두 키 아래에 데이터를 삽입하거나 포인터가 있어야합니다. 마찬가지로, 이러한 포인터는 가리키는 것이 존재하지 않을 때 정리해야 할 수 있지만이를 기반으로 항목을 쿼리하는 쉬운 방법이 없으므로 앱은 Just Remember가 필요합니다.

그리고 애플리케이션 버그는 당신이 잊어 버린 고아 키를 남길 수 있으며, db의 모든 키를 주기적으로 스캔하는 가비지 수집기를 작성하지 않는 한 쉽게 감지 할 수있는 방법이 없을 것입니다. 더 이상 필요하지 않은 것을 확인하기 위해 청크로 할 수 있습니다.

이 중 어느 것도 실제 사용에 근거한 것이 아니며 연구 중에 알아 낸 것뿐입니다. 우리는 프로덕션에서 Cassandra를 사용하지 않습니다.

편집 : Cassandra는 이제 트렁크에 보조 인덱스가 있습니다.


이것은 주석으로 추가하기에는 너무 길어서 문제 목록에서 몇 가지 오해를 해결하기 위해 다음과 같이 대답했습니다.

  1. 모든 클라이언트는 모든 노드에 연결할 수 있습니다. 선택한 첫 번째 노드 (또는로드 밸런서를 통해 연결)가 다운되면 다른 노드에 연결하기 만하면됩니다. 또한 클라이언트가 직접 쓰기를 지시 할 수있는 "팻 클라이언트"API를 사용할 수 있습니다. 예는 http://wiki.apache.org/cassandra/ClientExamples 에 있습니다 .

  2. 서버가 무한정 중단되지 않고 응답하지 않을 때 시간 초과는 과부하 된 rdbms 시스템을 처리 한 대부분의 사람들이 원했던 기능입니다. Cassandra RPC 시간 제한은 구성 가능합니다. 원하는 경우 며칠로 설정하고 대신 무기한으로 매달리는 것을 처리 할 수 ​​있습니다. :)

  3. 아직 다중 삭제 또는 자르기 지원이없는 것은 사실이지만 검토중인 두 가지 모두에 대한 패치가 있습니다.

  4. 클러스터 노드간에로드 균형을 유지하는 데는 분명히 상충 관계가 있습니다.보다 완벽하게 균형을 유지하려고할수록 더 많은 데이터 이동을 수행 할 수 있으며 이는 자유롭지 않습니다. 기본적으로 Cassandra 클러스터의 새 노드는 불균형을 최소화하기 위해 토큰 링의 최적 위치로 이동합니다. 실제로 이것은 잘 작동하는 것으로 나타 났으며 클러스터가 클수록 두 배가 최적이라는 사실이 덜 사실입니다. 이것은 http://wiki.apache.org/cassandra/Operations 에서 자세히 다룹니다 .


당신을위한 거래 중단이 있습니까? 딜 브레이커는 아니지만 알아 두어야 할 사항

  1. 클라이언트는 가장 가까운 노드에 연결합니다.이 노드는이를 통해 프록시 된 다른 모든 Cassandra 노드와의 모든 통신을 미리 알아야합니다. ㅏ. 읽기 / 쓰기 트래픽은 노드간에 균등하게 분산되지 않습니다. 일부 노드는 자신이 호스트하는 것보다 더 많은 데이터를 프록시합니다. b. 노드가 다운되면 클라이언트는 무력하고 읽을 수 없으며 클러스터의 어디에도 쓸 수 없습니다.

  2. 카산드라가 "쓰기는 결코 실패하지 않는다"고 주장하지만, 적어도 말하는 순간에는 실패합니다. 대상 데이터 노드가 느려지면 요청 시간이 초과되고 쓰기가 실패합니다. 노드가 응답하지 않는 데는 여러 가지 이유가 있습니다. 가비지 수집기 시작, 압축 프로세스 등… 이러한 모든 경우에 모든 쓰기 / 읽기 요청이 실패합니다. 기존 데이터베이스에서는 이러한 요청이 비례 적으로 느려졌지만 Cassandra에서는 실패했습니다.

  3. 다중 가져 오기가 있지만 다중 삭제가 없으며 ColumnFamily 도자를 수 없습니다.

  4. 비어있는 새 데이터 노드가 클러스터에 들어 오면 키링에있는 하나의 인접 노드에있는 데이터의 일부만 전송됩니다. 이로 인해 데이터 배포가 고르지 않고로드가 고르지 않게됩니다. 항상 노드 수를 두 배로 늘려서 고칠 수 있으며 토큰을 수동으로 추적하고 현명하게 선택해야합니다.


또 다른 튜토리얼은 http://blog.evanweaver.com/articles/2009/07/06/up-and-running-with-cassandra/ 입니다.


최근에 Cassandra 1.2가 나왔기 때문에 업데이트 할 가치가 있다고 생각합니다.

저는 소셜 게임을 위해 지난 18 개월 동안 Cassandra를 프로덕션에 사용했습니다.

하지만 카산드라를 강점으로 사용해야한다는 것입니다. 따라서 어떤 데이터 모델을 사용할지 확인하거나 다른 DB 솔루션이 더 유용한 지 식별하는 것이 무엇이며 어떻게 수행되는지 잘 이해해야합니다.

OrderedPartitioner 는 애플리케이션이 키 범위 쿼리에 의존하는 경우에만 유용하지만이를 위해 Cassandra의 가장 강력한 기능 중 하나 인 자동 분할 및로드 밸런싱을 포기합니다. 행 키 범위 쿼리 대신 동일한 행 내에서 열 이름 범위를 사용하여 필요한 동일한 기능을 구현하려고합니다. TL; DR 읽기 / 쓰기는 이것을 사용하는 노드간에 균형을 이루지 않습니다.

RandomPartioner (md5 해싱) 및 MurmurPartitioner ( 머머 해싱, 더 좋고 빠름)는 빅 데이터와 높은 액세스 빈도를 지원하려는 경우 반드시 가야하는 방법입니다. 포기하는 유일한 것은 키 범위 쿼리입니다. 동일한 행에있는 모든 항목은 여전히 ​​클러스터의 동일한 노드에 있으며 여기에 비교기 및 열 이름 범위 쿼리를 사용할 수 있습니다. TL; DR : 적절한 밸런싱을 위해 이것을 사용하십시오. 당신은 큰 것을 포기하지 않을 것입니다.


카산드라에 대해 알아야 할 사항 :

Cassandra는 결국 일관성이 있습니다. Cassandra는 고 가용성 및 우수한 파티셔닝 ( http://en.wikipedia.org/wiki/CAP_theorem )을 위해 일관성을 거래하기로 선택했습니다 . 그러나 카산드라에서 일관성을 얻을 수 있습니다. 읽고 쓸 때 일관성 정책이 전부입니다. 이것은 카산드라 사용에 대해 이야기 할 때 매우 중요하고 복잡한 주제이지만 http://www.datastax.com/docs/1.2/dml/data_consistency 여기에서 자세히 읽을 수 있습니다 .

경험상 (그리고 단순하게 유지하기 위해) QUORUM ConsistencyLevel에서 읽고 씁니다 (내 앱에서 읽기는 쓰기와 동일한 빈도로 진행되는 경향이 있기 때문입니다). 앱이 쓰기 무겁고 읽기 빈도가 훨씬 적다면 write at ONE을 사용하고 read at ALL을 사용하십시오. 또는 사용 사례가 반대 인 경우 (쓰기가 읽기보다 훨씬 적음) ONE에서 읽기를 시도하고 ALL에서 쓰기를 시도 할 수 있습니다. 쓰기에 대한 일관성 수준으로 ANY를 사용하는 것은 일관성이 해결하려는 경우 좋은 생각이 아닙니다. 변이가 ​​클러스터에 도달했음을 보장하지만 어디서든 작성되지 않았 음을 보장하기 때문입니다. 이것은 내가 카산드라에서 조용히 실패하는 유일한 경우입니다.

Those are simple rules to make it easy to get started with cassandra development. To get as much consistency and performance as possible from a production cluster you should study this topic hard and really understand it yourself.

If you need a human readable datamodel with complex relations between Entities (tables) then I do not think Cassandra is for you. MySQL and maybe NewSQL might be more helpful for your use case.

A good thing to know is how, roughly, cassandra saves and read data. Whenever you write (deletes are actually writes of a "tombstone" value in cassandra) the system will put the new value and its time stamp in a new physical location.

When you read, cassandra tries to pull all the writes for a certain key/column_name location and returns you the most recent he could find (the one with the highest timestamp, which has been given by the client). So the memory needed by a node is directly dependent on the frequencies of writes. There is a compaction process in cassandra that takes care of cleaning old mutations. Cassandra has an internal cache that is updated on reads with the latest value of the location.

The merging/compaction on disk of the SSTables (the data structures that persist the data) can be provoked by reads, but it's better not to count on it. The cleaning of tombstones and expired columns (using the time-to-live functionality) is a different mechanism managed by the garbage collector (see the GC grace time setting for more details).


This brings me to the last point I want to make: Be sure that your writes and read will be balanced across your cluster!

Let's assume that all your users need to update a single location very frequently.
DO NOT map that theoretical single location to only one row key! This would make all your writes fall on only one node in your cluster. If it doesn't bring everything down (because you have rockstar sysops) it will at least heavily cripple the cluster's performance.
My advice is to bucket your writes in enough different row keys that you will distribute your writes across all nodes in the cluster. To retrieve all data for that single theoretical location use a multi_get on all the "sub row keys".

Example :
I want to have a list of all active http sessions (which have uuid assigned to them). Do not save all into one "session" row key. What I use as a row key for my cassandra cluster of 6 nodes is : _sessions. Then I have a small 16 keys multi_get to retrieve all active sessions, or I can still tell if a session is active by just using a simple get (if I know its uuid of course). If your cluster is a lot bigger you might want to use a hash function for generation bucket keys.

참고URL : https://stackoverflow.com/questions/1502735/whats-the-best-practice-in-designing-a-cassandra-data-model

반응형