乐趣区

关于后端:ToplingDB-的-SidePlugin-配置系统

ToplingDB 配置零碎
对于 ToplingDB 配置零碎 的设计动机,请参考 Motivation To Solution

  1. 概要
    ToplingDB 配置零碎采纳 json/yaml 格局定义配置项,将 ToplingDB/RocksDB 的所有元对象均纳入此配置零碎。总体而言,ToplingDB 配置零碎实现了以下指标:

ToplingDB/RocksDB 的所有配置需要
无缝插件化:用户代码无需批改,即可插入第三方模块(例如 ToplingZipTable)
可视化:通过 Web Service 展现引擎外部状态(相干文档)
监控:通过 Web Service 将引擎指标导出到 Prometheus,进而应用 grafana 可视化
简化多语言 Binding(只须要 bind conf 对象即可)

  1. 具体介绍
    ToplingDB/RocksDB 的根配置对象是 DBOptions 和 ColumnFamilyOptions,额定的 Options 对象是 DBOptions 和 ColumnFamilyOptions(简称 CFOptions) 的结合体(从后两者继承而来)。

DBOptions 和 CFOptions 中蕴含二级配置对象,有些二级对象还进一步蕴含三级配置对象。所有这些对象,都定义为 json 中以其基类名命名的一级 json 对象的子对象,另外,json 中还有另外几个非凡的一级 json 对象(http,setenv,databases,open)。能够在 json 对象中援用其它 json 对象,这些援用将转化成 C++ 对象间的援用关系。

2.1. json 配置示例
{

"http": {
  "document_root": "/path/to/dbname",
  "listening_ports": "8081"
},
"setenv": {
  "DictZipBlobStore_zipThreads": 8,
  "StrSimpleEnvNameNotOverwrite": "StringValue",
  "IntSimpleEnvNameNotOverwrite": 16384,
  "OverwriteThisEnv": { "overwrite": true,
    "value": "overwrite is default to false, can be manually set to true"
  }
},
"permissions": {"web_compact": true},
"Cache": {
  "lru_cache": {
    "class": "LRUCache",
    "params": {
      "capacity": "4G", "num_shard_bits": -1, "high_pri_pool_ratio": 0.5,
      "strict_capacity_limit": false, "use_adaptive_mutex": false,
      "metadata_charge_policy": "kFullChargeCacheMetadata"
    }
  }
},
"WriteBufferManager" : {
  "wbm": {
    "class": "Default",
    "params": {"//comment": "share mem budget with cache object ${lru_cache}",
      "buffer_size": "512M", "cache": "${lru_cache}"
    }
  }
},
"Statistics": {"stat": "default"},
"TableFactory": {
  "bb": {
    "class": "BlockBasedTable",
    "params": {"block_cache": "${lru_cache}" }
  },
  "fast": {
    "class": "ToplingFastTable",
    "params": {"indexType": "MainPatricia"}
  },
  "zip": {
    "class": "ToplingZipTable",
    "params": {
      "localTempDir": "/dev/shm/tmp",
      "sampleRatio": 0.01, "entropyAlgo": "kNoEntropy"
    }
  },
  "dispatch" : {
    "class": "DispatcherTable",
    "params": {
      "default": "bb",
      "readers": {"ToplingFastTable": "fast", "ToplingZipTable": "zip"},
      "level_writers": ["fast", "fast", "bb", "zip", "zip", "zip", "zip"]
    }
  }
},
"CFOptions": {
  "default": {
     "max_write_buffer_number": 4, "write_buffer_size": "128M",
     "target_file_size_base": "16M", "target_file_size_multiplier": 2,
     "table_factory": "dispatch", "ttl": 0
  }
},
"databases": {
  "db1": {
    "method": "DB::Open",
    "params": {
      "options": {"write_buffer_manager": "${wbm}",
        "create_if_missing": true, "table_factory": "dispatch"
      }
    }
  },
  "db_mcf": {
    "method": "DB::Open",
    "params": {
      "db_options": {
        "create_if_missing": true,
        "create_missing_column_families": true,
        "write_buffer_manager": "${wbm}",
        "allow_mmap_reads": true
      },
      "column_families": {
        "default": "$default",
        "custom_cf" : {
          "max_write_buffer_number": 4,
          "target_file_size_base": "16M",
          "target_file_size_multiplier": 2,
          "table_factory": "dispatch", "ttl": 0
        }
      },
      "path": "'dbname' passed to Open. If not defined, use 'db_mcf' here"
    }
  }
},
"open": "db_mcf"

}
2.2. 非凡对象
2.2.1. http
在这个示例中,第一个 json 子对象是:

“http”: {

 "document_root": "/", "listening_ports": "8081"

}
这个 http 对象定义了用作 Web 展现的 Http Web Server 配置。残缺的 http 参数请参考:CivetWeb UserManual。

2.2.2 setenv
“setenv”: {

 "DictZipBlobStore_zipThreads" : 8

}
setenv 的每个子对象定义一个环境变量。

2.2.3. permissions
permissions 的每个子对象定义一个权限。

2.2.4. databases
能够在 databases 之下定义多个 database 对象,database 对象分为两大类:

只蕴含默认 ColumnFamily 的 DB
蕴含多个 ColumnFamily 的 DB(DB_MultiCF)
这两类 database 通过其是否蕴含子对象 column_families 来辨别。哪怕一个 database 实际上只有一个 ColumnFamily,但它将该 ColumnFamily 定义在子对象 column_families 中,那它也是 DB_MultiCF。

database 对象通过 method 指定的函数关上,C++ 代码中 method 是重载的,在 json 中 method 也是重载的,雷同的 method,对 DB 和 DB_MultiCF 别离重载。

2.2.5. open
尽管咱们能够在 json 中定义多个 database,但很多时候,咱们只会关上其中的一个 database,当应用无 database 名字的 OpenDB api 时,这个 open 对象用来指定关上哪个 database。当用户应用了带 db 名字的 OpenDB api 时,这个 open 对象就被疏忽。

2.3. 个别对象
json 的一级对象中,除以上 4 种非凡对象,其它都是个别对象,每个一级的个别对象的名字是 ToplingDB/RocksDB 中此类对象的基类的类名。例如示例中的 “Cache”, “Statistics”, “TableFactory”,这些一级对象自身相当于一个容器,其中每个子对象定义了真正的 C++ 对象。这样的每个“容器”相当于一个 namespace,不同 namespace 下能够有同名的对象。

json 对象对应的 C++ 对象蕴含类名和参数,别离通过 “class” 和 “params” 来表白。仔细的用户能够发现,对象名为 “stat” 的 json 是字符串 “default”,这是为了简化,对于无参的 class,能够间接应用其类名的字符串来定义(此处 ”default” 是 stat 的注册类名,对应的 C++ 类是 StatisticsImpl),当然,这种对象也能够用一个蕴含 “class” 和 “params” 的残缺正规的 json 对象来定义。

DBOptions 和 CFOptions 是比拟非凡的个别对象,因为其 “class” 是确定的,所以免去了 “class” 和 “params”,间接将 “params” 中的成员晋升到外层。

2.4. 对象援用
在 C++ 对象中,一个对象援用另一个对象通过指针来实现,在 json 中,通过对象名来实现,对象援用的正式的齐全的写法是 ”${varname}”,简化写法能够是 ”$varname” 或 “varname”,其中,”varname” 可能会导致歧义,因为一个 json 字符串也可能表白的是 “class_name”。咱们的解决形式是:先看该字符串是否是一个已定义的对象,如果是,就依照 ”varname” 解决,否则依照 “class_name” 解决。

2.4.1. 内嵌对象
除了定义命名的对象,而后按名字援用对象,咱们也能够定义内嵌对象,例如示例中的:

“custom_cf” : {

  "max_write_buffer_number": 4,
  "target_file_size_base": "16M",
  "target_file_size_multiplier": 2,
  "table_factory": "dispatch", "ttl": 0

}
“custom_cf” 能够定义为一个 CFOptions 对的援用,然而在这里,把它定义为一个内嵌对象更加不便简洁。

2.4.2. CFOptions::ttl
CFOptions 中没有 ttl 成员,但咱们在 json 中为它定义了 ttl,这是因为,database 的 “method” 除了能够指定为 “DB::Open”,还能够指定为其它很多函数:

“DB::OpenForReadOnly” // 等效于在 params 中定义 read_only: true
“DBWithTTL::Open” // 须要 CFOptions::ttl
“TransactionDB::Open”
“OptimisticTransactionDB::Open”
“BlobDB::Open”
用户还能够扩大定义本人的 Open 例如:MyCustomDB::Open。

2.5. DispatcherTable
“dispatch” : {

"class": "DispatcherTable",
"params": {
  "default": "bb",
  "readers": {"ToplingFastTable": "fast", "ToplingZipTable": "zip"},
  "level_writers": ["fast", "fast", "bb", "zip", "zip", "zip", "zip"]
}

}
顾名思义,DispatcherTable 用来进行理论的 Table(SST) 散发及调度,对用户来讲,最要害的是 level_writers:在相应的 level 上应用相应的 Table。

default 用来定义当 level < 0 时(level 是 TableBuilderOptions 的成员),或者 level_writer 创立 builder 失败时,作为 fallback。

readers 用来定义 class_name 到 varname 的映射,因为在外部实现中,加载 Table 是通过 DispatcherTable::NewTableReader 实现的,作为 dispather,天然须要晓得加载的 Table 具体是哪种 Table,这是通过 TableMagicNumber 来辨别的,是编译期动态确定的,然而 TableFactory 是运行时创立的,并且每个具体的 TableFactory class 能够有多个(params 不同的) object,所以,咱们须要在这里指定相应的 TableFactory class 应用哪个 TableFactory object 来加载。

在这个 DispatcherTable 定义中,L0~L2 应用 fast,L3~L6 应用 zip。

  1. Yaml 文件
    相熟 Kubernetes 的用户,可能更喜爱 Yaml,作为配置文件,Yaml 的可读性更好,ToplingDB 配置零碎也反对 Yaml。
  2. 几个理论的配置文件
    Json Yaml 阐明
    etcd_dcompaction.json yaml 带分布式 Compact
    lcompact_sample.json yaml 不带分布式 Compact
    todis-community.json yaml todis 社区版(无性能组件)
    todis-enterprise.json yaml todis 企业版(有性能组件)
退出移动版