카산드라의 저장 경로는 4 단계로 구성된다.


1. 커밋로그에 데이터를 추가한다.

2. 멤테이블에 데이터를 저장한다.

3. 멤테이블에서 데이터를 플러시한다.

4. 불변 SSTables에 데이터를 저장한다.



카산드라의 저장 경로의 1번째 컴포넌트는 커밋 로그이다. 저장이 추가되는 추가 전용 로그 구조이다. 커밋로그는 특정 크기로 사전 할당 된 다양한 세그먼트 파일로 설정된다. 세그먼트 파일이 가득 차면 저장이 다음 세그먼트에 저장된다. 세그먼트 내의 모든 저장이 각각의 멤테이블에서 플러시될 때, 세그먼트의 이름이 바뀌고 재활용된다. 재활용된 세그먼트를 다시 사용할 준비가 되었다. 시스템 재시작할 때 모든 멤테이블은 지워진다.


커밋로그 세그먼트가 리플레이된 다음 멤테이블이 디스크에 플러시된다. 그 다음에 커밋로그 세그먼트는 재사용을 위해 재활용된다. 이는 시스템 장애이 발생할 때에 내구성을 제공한다. 키스페이스를 생성할 때 영구 저장을 false로 설정하여 커밋로그 기능을 비활성화할 수 있지만. 성능이 저하될 수 있어서 권장하지 않는다.


커밋 로그에 데이터를 추가하는 것 외에도 카산드라는 멤테이블이라 불리는 인메모리 구조에 데이터를 저장한다. 멤테이블이 특정 임계 값 크기에 도달하면 디스크에 플러시된다. 일부 멤테이블 관련 설정 매개 변수를 조정할 수 있다. 멤테이블 할당 타입을 지정해 힙(heap) 또는 오프-힙(off-heap) 메모리를 사용할 수 있다. 멤테이블에 할당될 힙 또는 오프-힙 메모리 크기를 지정할 수 있다. 


멤테이블 플러시는 멘테이블의 전체 크기 값과 클린업(cleanup) 임계 값을 기반으로 일어난다. 커밋로그 크기를 설정 매개 변수로 지정할 수도 있다. 멤테이블 플러시는 커밋 로그 크기를 기반으로 발생한다. 기본적으로 플러시는 이전에 설명한 대로 설정 가능한 특정 임계 값을 기반으로 자동으로 발생한다. 그러나 nodetool 유틸리티를 사용해 수동으로 플러시를 동작시킬 수도 있다.


플러시 임계 값에 도달하면 멤테이블은 SSTables(Sorted String Tables)라는 불변 파일에 플러시된다. 멤테이블은 토큰 값으로 정렬되고 순차적으로 디스크에 저장된다. SSTable은 변경 불가능하기 때문에 동일한 파티션 키에 변경이 일어나면 특정 레코드는 여러 SSTable에 분산될 수 있다. 카산드라는 SSTable로 플러시할 때 파티션 인덱스, 파티션 요약, 블룸 필터와 같은 여러 구조를 생성한다. 해당 구조는 읽기 속도를 높이고 디스크 검색을 줄이는 데 도움을 준다.




멤테이블의 플러시 전략은  https://docs.datastax.com/en/cassandra/3.0/cassandra/operations/opsMemtableThruput.html 에 소개되어 있다.  멤테이블의 전체 크기 값은  (https://docs.datastax.com/en/cassandra/3.0/cassandra/configuration/configCassandra_yaml.html#configCassandra_yaml__commitlog_total_space_in_mb) 과 클린업 임계 값(https://docs.datastax.com/en/cassandra/3.0/cassandra/configuration/configCassandra_yaml.html#configCassandra_yaml__memtable_cleanup_threshold)을 기반으로 한다.

commitlog_total_space_in_mb 
(Default: 32MB for 32-bit JVMs, 8192MB for 64-bit JVMs)note Total space used for commit logs. If the total space used by all commit logs goes above this value, Cassandra rounds up to the next nearest segment multiple and flushes memtables to disk for the oldest commitlog segments, removing those log segments from the commit log. This reduces the amount of data to replay on start-up, and prevents infrequently-updated tables from keeping commitlog segments indefinitely. If thecommitlog_total_space_in_mb is small, the result is more flush activity on less-active tables.

Related information: Configuring memtable thresholds



memtable_cleanup_threshold 
(Default: 1/(memtable_flush_writers + 1))note. Ratio used for automatic memtable flush. Cassandra adds memtable_heap_space_in_mb to memtable_offheap_space_in_mb and multiplies the total bymemtable_cleanup_threshold to get a space amount in MB. When the total amount of memory used by all non-flushing memtables exceeds this amount, Cassandra flushes the largest memtable to disk.

For example, consider a node where the total of memtable_heap_space_in_mb andmemtable_offheap_space_in_mb is 1000, and memtable_cleanup_threshold is 0.50. The memtable_cleanup amount is 500MB. This node has two memtables: Memtable A (150MB) and Memtable B (350MB). When either memtable increases, the total space they use exceeds 500MB and Cassandra flushes the Memtable B to disk.

A larger value for memtable_cleanup_threshold means larger flushes, less frequent flushes and potentially less compaction activity, but also less concurrent flush activity, which can make it difficult to keep your disks saturated under heavy write load.

This section documents the formula used to calculate the ratio based on the number of memtable_flush_writers. The default value in cassandra.yaml is 0.11, which works if the node has many disks or if you set the node's memtable_flush_writers to 8. As another example, if the node uses a single SSD, the value for memttable_cleanup_threshold computes to 0.33, based on the minimum memtable_flush_writers value of 2.


Posted by '김용환'
,