2. Column Families

Tasker_Jang·2024년 8월 31일
0

1) Column Families란 무엇인가

Column Families는 RocksDB에서 단일 데이터베이스 내의 데이터를 논리적으로 분리하여 관리할 수 있는 기능입니다. 사용자 프로필 데이터와 로그 데이터를 같은 데이터베이스 내에서 별도로 관리하려는 경우, 각각의 데이터를 서로 다른 Column Family에 저장할 수 있습니다. 이렇게 하면 각 Column Family에 대해 별도의 설정을 적용하거나 독립적으로 최적화할 수 있습니다.

예를 들어, 자주 조회되지만 자주 변경되지 않는 데이터를 하나의 Column Family에 저장하고, 빈번하게 변경되는 데이터를 다른 Column Family에 저장할 수 있습니다. 이렇게 하면 각 데이터의 특성에 맞는 최적화 설정을 적용할 수 있어 성능을 극대화할 수 있습니다.

RocksDB 3.0에서는 Column Families 기능을 추가하여, 각 키-값 쌍을 특정 Column Family에 연결할 수 있습니다. 기본 Column Family가 지정되지 않으면 "default"로 연결됩니다. Column Families는 데이터베이스를 논리적으로 분할하는 방법을 제공합니다. Column Families 간의 원자적 쓰기가 가능하고, 데이터베이스의 일관된 뷰를 유지하며, 독립적으로 설정을 구성할 수 있습니다. 또한, 새로운 Column Family를 동적으로 추가하거나 삭제할 수 있습니다.

RocksDB API는 Column Families를 지원하기 위해 업데이트되었지만, 기존 API와의 호환성을 유지합니다. 예를 들어, DB::Open 함수에서는 모든 Column Families를 지정해야 하며, DB::OpenForReadOnly는 읽기 전용 모드로 열 수 있습니다. Column Families는 쓰기 전용 로그를 공유하며, MemTables와 테이블 파일을 공유하지 않습니다. 이러한 구조로 인해, RocksDB는 원자적 쓰기의 이점을 누릴 수 있으며, 각 Column Family를 독립적으로 구성하고 빠르게 삭제할 수 있습니다.

2) Column Families를 다룰 수 있는 주요 메서드

Column Family 생성 및 삭제

  1. DB::create_column_family(): 새로운 Column Family를 생성합니다.
  2. DB::drop_column_family(): 기존의 Column Family를 삭제합니다.

Column Family 핸들 관리

  1. DB::list_column_families(): 현재 DB에 존재하는 모든 Column Families를 나열합니다.
  2. DB::open_column_family(): 특정 Column Family를 열어 ColumnFamilyHandle을 반환합니다.
  3. DB::open(): 여러 Column Family와 함께 DB를 엽니다.

데이터 읽기/쓰기

  1. DB::put_cf(): 특정 Column Family에 데이터를 저장합니다.
  2. DB::get_cf(): 특정 Column Family에서 데이터를 가져옵니다.
  3. DB::delete_cf(): 특정 Column Family에서 데이터를 삭제합니다.
  4. DB::write(): 여러 Column Family에 대한 원자적 쓰기 작업을 수행합니다.

이터레이션

  1. DB::new_iterator_cf(): 특정 Column Family에 대한 이터레이터를 생성합니다.
  2. DB::new_iterators(): 여러 Column Family에 대해 이터레이터를 생성합니다.

이 메서드들은 RocksDB의 Column Families 기능을 효과적으로 관리하고 조작할 수 있도록 도와줍니다.

3) Column Families의 핵심 기능들

핵심 기능:

  • 원자적 쓰기: Column Families 간의 원자적 쓰기를 지원합니다.
  • 독립적 구성: 각 Column Family를 개별적으로 설정할 수 있습니다.
  • 동적 관리: 새로운 Column Family를 추가하거나 삭제하는 것이 가능합니다.
  • 일관된 뷰: 여러 Column Families 간의 일관된 데이터베이스 뷰를 제공합니다.

이 기능들은 RocksDB를 복잡한 데이터베이스 환경에서 더욱 유연하고 강력하게 만들어 줍니다. RocksDB 3.0 이전 API를 사용하는 경우에도 이러한 기능을 활용할 수 있습니다.

4) 예제코드

use rocksdb::{DB, Options, ColumnFamilyDescriptor, ColumnFamilyHandle, DBWithThreadMode, SingleThreaded};

fn main() {
    // DB Options 설정
    let mut opts = Options::default();
    opts.create_if_missing(true);

    // Column Family를 정의
    let cf_descriptors = vec![
        ColumnFamilyDescriptor::new("default", Options::default()),
        ColumnFamilyDescriptor::new("cf1", Options::default()),
    ];

    // Column Families로 DB 열기
    let db = DBWithThreadMode::<SingleThreaded>::open_cf_descriptors(&opts, "path/to/db", cf_descriptors).unwrap();

    // Column Family handle 가져오기
    let cf1_handle = db.cf_handle("cf1").unwrap();

    // Column Family에 데이터 쓰기
    db.put_cf(&cf1_handle, b"key1", b"value1").unwrap();

    // Column Family에서 데이터 읽기
    let value = db.get_cf(&cf1_handle, b"key1").unwrap().unwrap();
    println!("Value for 'key1': {:?}", value);

    // Column Family 삭제
    db.drop_cf("cf1").unwrap();
}

아래는 예제 코드의 한 줄씩 상세한 설명입니다:

use rocksdb::{DB, Options, ColumnFamilyDescriptor, ColumnFamilyHandle, DBWithThreadMode, SingleThreaded};
  • 설명: RocksDB와 관련된 여러 가지 구조체와 함수를 가져옵니다. DB는 데이터베이스를 관리하는 기본 구조체입니다. Options는 데이터베이스 설정을 구성합니다. ColumnFamilyDescriptor는 Column Family를 정의하는 데 사용되며, ColumnFamilyHandle은 특정 Column Family를 참조합니다. DBWithThreadModeSingleThreaded는 RocksDB의 스레드 모드를 설정합니다.
let mut opts = Options::default();
  • 설명: RocksDB의 기본 옵션을 설정합니다. 이 옵션은 데이터베이스 생성 시 사용되며, 예를 들어 데이터 압축 여부나 캐시 크기 등을 설정할 수 있습니다.
opts.create_if_missing(true);
  • 설명: 데이터베이스 파일이 없을 경우 새로 생성하도록 옵션을 설정합니다. 기본적으로 데이터베이스가 없으면 오류가 발생하지만, 이 옵션을 통해 데이터베이스가 자동으로 생성됩니다.
let cf_descriptors = vec![
    ColumnFamilyDescriptor::new("default", Options::default()),
    ColumnFamilyDescriptor::new("cf1", Options::default()),
];
  • 설명: 두 개의 Column Family를 정의합니다. 첫 번째는 기본 Column Family "default"이며, 두 번째는 "cf1"이라는 이름의 새로운 Column Family입니다. 각 Column Family는 독립적인 설정을 가질 수 있습니다.
let db = DBWithThreadMode::<SingleThreaded>::open_cf_descriptors(&opts, "path/to/db", cf_descriptors).unwrap();
  • 설명: 정의된 Column Family와 함께 RocksDB 데이터베이스를 엽니다. 이때 지정된 옵션을 사용하며, "path/to/db" 경로에 데이터베이스가 생성됩니다. unwrap()은 오류 발생 시 패닉(panic)을 발생시키며, 이는 간단한 예제에서 오류 처리를 생략하기 위한 방법입니다.
let cf1_handle = db.cf_handle("cf1").unwrap();
  • 설명: "cf1"이라는 이름의 Column Family 핸들을 가져옵니다. 이 핸들은 이후 해당 Column Family에 접근할 때 사용됩니다.
db.put_cf(&cf1_handle, b"key1", b"value1").unwrap();
  • 설명: "cf1" Column Family에 "key1"이라는 키와 "value1"이라는 값을 저장합니다. put_cf 메서드는 지정된 Column Family에 데이터를 저장하는 기능을 제공합니다.
let value = db.get_cf(&cf1_handle, b"key1").unwrap().unwrap();
  • 설명: "cf1" Column Family에서 "key1" 키에 해당하는 값을 가져옵니다. 두 번의 unwrap()은 각각 ResultOption 타입의 값을 풀어서 실제 데이터를 반환합니다.
println!("Value for 'key1': {:?}", value);
  • 설명: "key1" 키에 해당하는 값을 출력합니다. 이때 {:?}는 값의 디버그 표현을 출력하는 형식 지정자입니다.
db.drop_cf("cf1").unwrap();
  • 설명: "cf1" Column Family를 삭제합니다. Column Family를 삭제하면 관련된 데이터는 즉시 삭제되지 않으며, 마지막 핸들이 삭제될 때 실제 데이터가 제거됩니다.

이 코드는 RocksDB에서 여러 Column Family를 사용하여 데이터를 저장하고 조회하는 방법을 보여줍니다. ColumnFamilyDescriptor를 사용해 Column Family를 정의하고, put_cfget_cf를 사용해 특정 Column Family에 데이터를 쓰고 읽습니다. 마지막으로 drop_cf를 사용해 Column Family를 삭제합니다.

profile
터널을 지나고 있을 뿐, 길은 여전히 열려 있다.

0개의 댓글