cassandra-2.0 카산드라 - Cassandra 테이블에서 행 수를 얻는 방법




cql add (6)

피하기 위해 copy를 사용할 수 있습니다 countandra 타임 아웃은 대개 count (*)에서 발생합니다.

cqlsh -e "copy keyspace.table_name (first_partition_key_name) to '/dev/null'" | sed -n 5p | sed 's/ .*//'

이것은 기본적인 기본 질문이지만 실제로 며칠 동안 나를 괴롭 히고 있습니다. Cassandra에서 주어진 테이블의 COUNT(*) 에 해당하는 것을 얻을 수있는 좋은 방법이 있습니까?

몇 가지로드 테스트를 위해 C *에 수억 개의 행을 옮길 것이며 네트워크를 통해 엄청난 양의 데이터를 이동하기 전에 일부 샘플 ETL 작업에 대한 행 수를 얻고 싶습니다.

필자가 가지고있는 가장 좋은 아이디어는 기본적으로 파이썬으로 각 행을 반복하고 자동으로 카운터를 증가시키는 것입니다. C * 테이블의 행 크기를 결정 (또는 예측)하는 더 좋은 방법이 있습니까? 또한 Datastax Ops Center에서 행 크기를 결정할 수 있는지 살펴 보았습니다. 가능한 경우 어떻게 될지 모르겠습니다.

C *에서 테이블의 count(*) 를 얻는 데 필요한 다른 사람은 누구입니까? 그렇다면 어떻게 그 일을 시작 했습니까?


nodetool cfstats | grep -A 1000 KEYSPACE

해당 KEYSPACE의 모든 테이블에 대한 세부 사항을 보려면 KEYSPACE를 교체하십시오.


정확한 카운트가 필요하지 않은 경우 nodetool cfhistograms 에서 일부 추정치를 얻을 수도 있습니다 (이 값은 추정치 임).

DSE를 실행 중이면 spark를 사용할 수도 있습니다.


예, COUNT(*) 사용할 수 있습니다. 여기에 documentation 있습니다.

COUNT (*)를 사용하는 SELECT 식은 쿼리와 일치하는 행 수를 반환합니다. 또는 COUNT (1)을 사용하여 동일한 결과를 얻을 수 있습니다.

사용자 테이블의 행 수 계산 :

SELECT COUNT(*) FROM users;

C # Linq 구성 요소 어댑터를 사용하는 경우 다음을 사용할 수 있습니다.

var t = new Table<T>(session);
var count = t.Count().Execute();

후드에서 일괄 처리가 어떻게 작동하는지 이해하려면 일괄 처리의 개별 단계를 살펴 보는 것이 좋습니다.

클라이언트

배치는 CQL3 또는 최신 Cassandra 클라이언트 API를 사용하여 지원됩니다. 각각의 경우에 배치의 일부로 실행하려는 명령문 목록, 모든 명령문에 사용되는 일관성 레벨 및 선택적 시간 소인을 지정할 수 있습니다. INSERT, DELETE 및 UPDATE 문을 일괄 적으로 실행할 수 있습니다. 타임 스탬프를 제공하지 않기로 선택하면 현재 시간이 자동으로 사용되어 배치와 연결됩니다.

일괄 처리를 성공적으로 실행할 수없는 경우 클라이언트가 두 가지 예외를 처리해야합니다.

  • UnavailableException - 지정된 배치 CL로 모든 갱신을 실행하기 위해서 충분한 수의 노드가 존재하지 않는 경우
  • WriteTimeoutException - 배치 로그를 쓰거나 배치 내의 모든 업데이트를 적용하는 동안 시간 초과. 이는 예외의 writeType 값 ( BATCH_LOG 또는 BATCH )을 읽음으로써 점검 할 수 있습니다.

batchlog 단계 중 실패한 쓰기는 Java 드라이버의 DefaultRetryPolicy 에 의해 자동으로 한 번 재 시도 됩니다. Batchlog 생성은 코디네이터가 작업 중간에 실패 할 경우 배치가 항상 완료되도록하는 데 중요합니다. 이유를 알아 내기 위해 계속 읽어보십시오.

코디네이터

클라이언트가 보내는 모든 배치는 모든 쓰기 작업과 마찬가지로 코디네이터에 의해 실행됩니다. 일반적인 쓰기 작업과 다른 점은 Cassandra는 현재 실행중인 보류중인 모든 배치 (배치 로그라고 함)를 포함하는 전용 로그를 사용한다는 것입니다. 이 로그는 로컬 시스템 키 공간에 저장되며 각 노드가 개별적으로 관리합니다. 각 배치 실행은 코디네이터가 아닌 두 노드에서 전체 일괄 처리로 로그 항목을 작성하는 것으로 시작됩니다. 코디네이터가 다른 노드에서 배치 로그를 작성할 수있게되면 배치의 실제 문을 실행하기 시작합니다.

일} 처리의 각 명령문은 전체 일} 처리의 CL W 시간 소인을 사용하여 복제본에 기록됩니다. 그 외에도,이 시점에서 일어나는 쓰기에 대해서는 특별한 것이 없습니다. 쓰기가 암시되거나 클라이언트가 처리 할 수있는 WriteTimeoutException을 던질 수도 있습니다 (위 참조).

배치가 실행 된 후에는 생성 된 모든 배치 로그를 안전하게 제거 할 수 있습니다. 따라서 코디네이터는 이전에 batchlog를받은 노드에 성공적인 실행시 batchlog 삭제 메시지를 보냅니다. 이것은 백그라운드에서 발생하며 실패 할 경우를 대비하여 눈에 띄지 않게됩니다.

배치 실행 중에 코디네이터가 수행하는 작업을 마무리 할 수 ​​있습니다.

  • 배치 로그를 두 개의 다른 노드 (다른 랙에 배치하는 것이 바람직 함)로 보냅니다.
  • 모든 문을 일괄 적으로 실행
  • 성공적인 일괄 처리 실행 후 노드에서 batchlog를 다시 삭제합니다.

배치 로그 복제본 노드

위에서 설명한 것처럼 배치 로그는 배치 실행 전에 다른 두 노드 (클러스터 크기가 허용하는 경우)를 통해 복제됩니다. 아이디어는 일괄 처리의 모든 문을 완료하기 전에 코디네이터가 중단 될 경우 이러한 노드 중 하나가 보류중인 일괄 처리를 선택할 수 있다는 것입니다.

무엇이 좀 복잡하다고 생각하는 이유는 노드가 코디네이터가 더 이상 살아 있지 않다는 것을 알지 못하기 때문입니다. 배치 로그 노드가 배치 실행의 현재 상태로 업데이트되는 유일한 지점은 코디네이터가 배치가 성공적으로 실행되었음을 나타내는 삭제 메시지를 발행 할 때입니다. 그러한 메시지가 도착하지 않으면, batchlog 노드는 어떤 이유에서 배치가 실행되지 않았다고 가정하고 로그에서 배치를 재생합니다.

Batchlog 재생은 매분마다 잠재적으로 발생합니다. 즉, 로컬 batchlog에 보류 중 일괄 처리가있을 가능성이있는 코디네이터에 의해 삭제되지 않은 경우, 노드가 확인할 간격입니다. 배치 로그 작성과 실제 실행 사이에 코디네이터에게 약간의 시간을주기 위해 고정 된 유예 기간이 사용됩니다 ( write_request_timeout_in_ms * 2 , 기본값 4 초). batchlog가 4 초 후에도 남아있는 경우 재생됩니다.

카산드라의 쓰기 작업과 마찬가지로 시간 제한이 발생할 수 있습니다. 이 경우 노드는 제한 시간 초과 작업에 대한 쓰기 힌트로 되돌아갑니다. 시간 초과 된 복제본이 다시 올라 오면 기록은 힌트에서 다시 시작될 수 있습니다. 이 동작은 hinted_handoff_enabled 가 활성화되어 있는지 여부에 관계없이 영향을 미치지 않는 것으로 보입니다. 또한 힌트와 관련된 TTL 값이있어 긴 기간 후에 힌트가 삭제됩니다 (관련 CF의 경우 GCGraceSeconds 가 가장 GCGraceSeconds ).

이제는 동시에 두 노드에서 배치를 재생하는 것이 잠재적으로 위험하지 않은지 궁금해 할 것입니다. 두 노드에서 배치 로그를 복제하면 발생할 수 있습니다. 여기에서 유의해야 할 중요한 점은 제한된 종류의 지원되는 작업 (업데이트 및 삭제)과 일괄 처리와 관련된 고정 타임 스탬프로 인해 각 일괄 처리 실행이 멱등 할 것이라는 점입니다. 노드와 코디네이터가 동시에 배치 실행을 재 시도하더라도 충돌은 없습니다.

원 자성 보장

"원자 배치"의 원 자성 측면으로 돌아가서 원자 ( source )로 정확히 무엇이 의미되는지 검토 할 수 있습니다.

"데이터베이스 의미에서"원 자성 (atomic) "이란 의미는 배치의 일부가 성공할 경우 모든 것이 가능하다는 것을 의미합니다. 다른 보장은 내포되지 않으며, 특히 격리가 없으며 다른 클라이언트가 첫 번째 일괄 처리에서 행을 업데이트하고 나머지는 진행 중입니다. "

그래서 어떤 의미에서 우리는 "전부 아니면 아무것도"보장하지 않습니다. 대부분의 경우 코디네이터는 일괄 처리의 모든 문을 클러스터에 작성합니다. 그러나 쓰기 타임 아웃의 경우 writeType 값을 읽음으로써 어떤 시점에서 타임 아웃이 발생했는지 확인해야합니다. 배치가 배치 로그에 기록되어 그 보증이 계속 적용되는지 확인해야합니다. 또한이 시점에서 다른 클라이언트는 배치에서 부분적으로 실행 된 결과를 읽을 수도 있습니다.

질문으로 돌아가서, Cassandra는 어떻게 일괄 적으로 모든 또는 전혀 진술이 실행되지 않을 것이라고 보장 할 수 있습니까? 원자 배치는 기본적으로 성공적인 복제 및 멱등 원 문장에 의존합니다. 이론 상으로는 여전히 불일치가 발생할 수있는 scenarios 가있을 수 있으므로 100 % 보장 된 솔루션은 아닙니다. 그러나 Cassandra의 많은 유스 케이스는 어떻게 작동하는지 알고 있다면 매우 유용한 도구입니다.