ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RocksDB Column Family 알아보기
    Database/RocksDB 2024. 1. 10. 09:19
    728x90
    반응형

    - 목차

     

    들어가며.

    RocksDB 의 Column Family 는 SQL 의 Table, NoSQL 의 Collection 과 유사합니다.

    즉, Key-Value Pair 들을 저장하는 논리적인 단위입니다.

    즉, RocksDB 의 데이터베이스는 Column Family 라는 단위로 데이터들이 저장될 파티션을 나누게 되구요.

    만약 명시적으로 Column Family 를 생성하지 않는다면 default Column Family 를 사용하게 됩니다.

     

    Column Family 는 여러가지 장점을 가집니다.

    장점들은 SQL Table 과 같이 데이터의 저장 단위를 분리하였기 때문에 파생되는 장점입니다.

    첫번째 장점은 Column Family 단위로 MemTable 과 SSTable 그리고 Bloom Filter 를 가집니다.

    MySQL 에 비유하자면, Table 마다 Tablespace 라는 idb 파일을 가지는 것과 유사한데요.

    Column Family 마다 메모리, 디스크의 고유한 저장소를 가지고,

    Compaction 을 수행하는 Background Process 를 가지기 때문에 관리가 수월해집니다.

    아래 그림처럼 하나의 Column Family 를 중심으로 파생된 여러 리소스들이 구성됩니다.

    따라서 Column Family 를 삭제할 시에 관련된 절차가 단순해집니다.

     

    그리고 Compression Algorithm, Compaction Filter, MemTable 의 Max Buffer Size 등의 개별적인 세팅이 가능해집니다.

     

    이번 글에서는 Column Family 에 대한 코드 구현을 진행해보려고 합니다.

     

    RocksDB Default Column Family.

    먼저 사용한 rocksdbjni 모듈은 아래와 같습니다.

    dependencies {
        // https://mvnrepository.com/artifact/org.rocksdb/rocksdbjni
        implementation group: 'org.rocksdb', name: 'rocksdbjni', version: '7.0.3'
    
    }

     

    RocksDB Java Module 은 아래 링크에서 자세한 사용법을 확인하실 수 있으십니다.

    https://github.com/facebook/rocksdb/wiki/RocksJava-Basics

     

    RocksJava Basics

    A library that provides an embeddable, persistent key-value store for fast storage. - facebook/rocksdb

    github.com

     

     

    RocksDB 는 Default Column Family 를 가집니다.

    아래 예시는 RocksDB 의 Default Column Family 에 데이터를 추가하고 조회하는 예시 코드입니다.

    (key1, 1), (key2, 2), (key3, 3) Key-Value Pair 들을 저장합니다.

    package com.westlife;
    
    import org.rocksdb.*;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    public class RocksdbTest {
      public static void main(String[] args) throws RocksDBException {
    
        String dbPath = "src/main/resources/rocksdb";
    
        RocksDB.loadLibrary();
        final DBOptions options = new DBOptions();
        options.setCreateIfMissing(true);
        ColumnFamilyOptions cfOpts = new ColumnFamilyOptions().optimizeUniversalStyleCompaction();
        List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOpts));
        List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
        RocksDB rocksDb = RocksDB.open(options, new File(dbPath).getAbsolutePath(), cfDescriptors, cfHandles);
        rocksDb.put(rocksDb.getDefaultColumnFamily(), "key1".getBytes(), "value1".getBytes());
        rocksDb.put(rocksDb.getDefaultColumnFamily(), "key2".getBytes(), "value2".getBytes());
        rocksDb.put(rocksDb.getDefaultColumnFamily(), "key3".getBytes(), "value3".getBytes());
        System.out.println("### key1 : " + new String(rocksDb.get(rocksDb.getDefaultColumnFamily(), "key1".getBytes())));
        System.out.println("### key2 : " + new String(rocksDb.get(rocksDb.getDefaultColumnFamily(), "key2".getBytes())));
        System.out.println("### key3 : " + new String(rocksDb.get(rocksDb.getDefaultColumnFamily(), "key3".getBytes())));
    
        rocksDb.close();
      }
    }
    ### key1 : value1
    ### key2 : value2
    ### key3 : value3

     

     

    새로운 Column Family 생성하기.

    아래 예시는 "newColumnFamily" 라는 새로운 Column Family 를 생성합니다.

    그리고 "newColumnFamily" Column Family 에 (key0: 0) ~ (key9: 9) 의 데이터 10 개를 저장하고 조회하는 예시입니다.

     

    package com.westlife;
    
    import org.rocksdb.*;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    
    public class RocksdbTest {
      public static void main(String[] args) throws RocksDBException {
    
        String dbPath = "src/main/resources/rocksdb";
    
        RocksDB.loadLibrary();
        String newColumnFamilyName = "newColumnFamily";
        final DBOptions options = new DBOptions();
        options.setCreateIfMissing(true);
        options.setCreateMissingColumnFamilies(true);
        ColumnFamilyOptions cfOpts = new ColumnFamilyOptions().optimizeUniversalStyleCompaction();
        List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
                new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOpts),
                new ColumnFamilyDescriptor(newColumnFamilyName.getBytes(), cfOpts)
        );
        List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
        RocksDB rocksDb = RocksDB.open(options, new File(dbPath).getAbsolutePath(), cfDescriptors, cfHandles);
        ColumnFamilyHandle newColumnFamilyHandle = cfHandles.stream().filter(h -> {
          try {
            return new String(h.getName()).equals(newColumnFamilyName);
          } catch (RocksDBException e) {
            throw new RuntimeException(e);
          }
        }).collect(Collectors.toList()).get(0);
    
        for (int i = 0; i < 10; i++) {
          rocksDb.put(newColumnFamilyHandle, ("key" + i).getBytes(), ("" + i).getBytes());
        }
        for (int i = 0; i < 10; i++) {
          byte[] result = rocksDb.get(newColumnFamilyHandle, ("key" + i).getBytes());
          System.out.println(String.format("### key%s : %s", i, new String(result)));
        }
        rocksDb.close();
      }
    }
    ### key0 : 0
    ### key1 : 1
    ### key2 : 2
    ### key3 : 3
    ### key4 : 4
    ### key5 : 5
    ### key6 : 6
    ### key7 : 7
    ### key8 : 8
    ### key9 : 9

     

     

    반응형
Designed by Tistory.