-
Notifications
You must be signed in to change notification settings - Fork 6
Dynamic Create Drop ColumnFamily
一直以来,SidePlugin
不支持动态创建 ColumnFamily,这主要是出于性能方面的考虑,动态创建 ColumnFamily 的应用场景很少,但是它会引发一些性能开销,例如 MyRocks 中为处理该问题还使用了对象级 TLS 以改善它引起的性能问题。
在 MyTopling 中,我们彻底禁用了动态创建 ColumnFamily,彻底消除了这个问题。
ToplingDB 默认禁用了动态创建 ColumnFamily,要启用它:
make DEBUG_LEVEL=0 # must clean to delete old *.o files
make -j`nproc` EXTRA_CXXFLAGS='-DROCKSDB_DYNAMIC_CREATE_CF' rocksdbjava DEBUG_LEVEL=0
我们在 2023-06-08 新增了该功能,该功能原本只写了个空壳,现在已经完整实现:
struct DB_MultiCF { // 略去无关代码,使用动态创建 CF 功能时,仅有这些成员是可用的
virtual Status CreateColumnFamily(const std::string& cfname,
const std::string& spec,
ColumnFamilyHandle**) = 0;
virtual Status DropColumnFamily(const std::string& cfname) = 0;
virtual Status DropColumnFamily(ColumnFamilyHandle*) = 0;
DB* db = nullptr;
// 使用动态创建 CF 功能时,无法安全地访问 cf_handles,用户需要自行管
// 理 CreateColumnFamily 返回的 cf
std::vector<ColumnFamilyHandle*> cf_handles;
};
示例代码:dyna_new_cf.cc
// 省略其它方法,Java 中 无 DB_MultiCF 相应的 class,用户代码需要自行管理所有 CF 对象
public class SidePluginRepo extends RocksObject {
public ColumnFamilyHandle createCF(RocksDB db, String cfname, String spec) throws RocksDBException;
public void dropCF(RocksDB db, String cfname) throws RocksDBException;
public void dropCF(RocksDB db, ColumnFamilyHandle cfh) throws RocksDBException;
}
CreateColumnFamily/createCF 的参数 spec
用来指定 cf option,一般情况下是在 json/yaml 中定义的 CFOptions
对象名。
ToplingDB 通过 SidePlugin 进行配置管理,直接使用 DB::CreateColumnFamily,就会导致创建出来的 CF 在 SidePlugin 中感知不到:
- WebView 上看不到
- 各种元对象和配置参数也脱离了 SidePlugin 的控制
json/yaml 文件中可能只定义了最基础的 CF,甚至完全没有定义 CF,然后在运行中动态创建了很多 CF,但下一次 Open DB 时,又要指定所有 CF,而这几乎是不可能完成的事情。
为了解决该问题,我们在 json/yaml 中新增了一个参数 dyna_cf_opt
(完整配置):
## 省略...省略...省略...省略...省略...
databases:
db_bench_enterprise:
method: DB::Open
params:
db_options: "$dbo"
column_families: # for multi cf db
default: "$default"
dyna_cf_opt: "$default"
path: /dev/shm/db_bench_enterprise
open: db_bench_enterprise
这样,对于在 DB 中存在,但是在 json/yaml 中未定义的 CF,我们可以通过 ListColumnFamilies 获得 cf name,再将 dyna_cf_opt 作为 CFOption,来打开这些 CF。
RocksDB 原始接口中,不同的 CF 可以指定不同的 Option,ToplingDB 的 json/yaml 用 column_families 参数来实现这个目标。但是,通过 dyna_cf_opt,所有未定义的 CF 使用的就是完全相同的 Option,无法实现不同 CF 使用不同 Option。