<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          ToplingDB高性能 K-V 數(shù)據(jù)庫(kù)引擎

          聯(lián)合創(chuàng)作 · 2023-10-01 02:31

          ToplingDB 是由北京拓?fù)鋷X科技有限公司出品的一款開(kāi)源數(shù)據(jù)庫(kù)引擎。Fock 自 RocksDB 并進(jìn)行內(nèi)核改造,以獨(dú)有的“可檢索內(nèi)存壓縮”和“分布式 compact”等技術(shù)手段,大大提升數(shù)據(jù)庫(kù)引擎的性能和可用性。

          部署安裝 ToplingDB

          1. 服務(wù)器環(huán)境

            操作系統(tǒng): CentOS Linux release 8.4.2105

            g++版本: g++ (GCC) 8.4.1 20200928 (Red Hat 8.4.1-1)

          2. 安裝相關(guān)依賴(lài)

            ToplingDB 基于 RocksDB 構(gòu)建,我們需要用到壓縮庫(kù) snappy 和命令行參數(shù)解析工具 gflags 。除此之外,在編譯的過(guò)程中,還需要用到 libaio 的開(kāi)發(fā)包。

            • 安裝 snappy :

              1
              
              sudo yum install snappy snappy-devel
              
            • 安裝 gflags :

              • 對(duì)于 CentOS 8:

                1
                
                sudo dnf --enablerepo=powertools install gflags-devel
                
              • 對(duì)于 CentOS 7(需要 EPEL ):

                1
                
                sudo yum install gflags-devel
                
            • 安裝 libaio-devel :

              1
              
              sudo yum install libaio-devel
              
          3. 安裝 ToplingDB

            • 獲取項(xiàng)目源代碼:

              1
              2
              
              cd ~
              git clone https://github.com/topling/toplingdb.git
              
            • 更新依賴(lài)的子項(xiàng)目:

              1
              2
              
              cd toplingdb
              git submodule update --init --recursive
              
            • 編譯安裝動(dòng)態(tài)庫(kù):

              1
              2
              
              make shared_lib
              sudo make install
              
            • 設(shè)置環(huán)境變量:

              除了 librocksdb.so 之外,我們還會(huì)用到 topling-zip 編譯生成的 libterark-zbs-r.so 等動(dòng)態(tài)庫(kù)。在剛才的 make 過(guò)程中, topling-zip 已被克隆到 toplingdb/sideplugin 目錄下,它編譯得到的動(dòng)態(tài)庫(kù)位于 topling-zip/build/Linux-x86_64-g++-8.4-bmi2-1/lib_shared 。

              打開(kāi)文件 ~/.bashrc ,在文件的末尾增加下列兩行:

              1
              2
              
              export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
              export LD_LIBRARY_PATH=~/toplingdb/sideplugin/topling-zip/build/Linux-x86_64-g++-8.4-bmi2-1/lib_shared:$LD_LIBRARY_PATH
              

              保存后,執(zhí)行以下命令,更新我們的設(shè)置:

              1
              
              source ~/.bashrc
              

              需要注意的是, Linux-x86_64-g++-8.4-bmi2-1 這一目錄名稱(chēng)是根據(jù)編譯環(huán)境而自動(dòng)命名的。若您的編譯環(huán)境與本文環(huán)境不同,您需要自行查看具體的目錄,并調(diào)整之前設(shè)置的環(huán)境變量路徑。

          通過(guò)配置文件打開(kāi)數(shù)據(jù)庫(kù)

          ToplingDB 是一個(gè)嵌入式數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)的庫(kù)文件直接鏈接在應(yīng)用程序中,應(yīng)用程序通過(guò)調(diào)用 API 來(lái)進(jìn)行數(shù)據(jù)庫(kù)的讀寫(xiě)操作。

          在本文的所有示例中,我們將數(shù)據(jù)庫(kù)放置在路徑 /home/topling/db/ 下,也就是用戶(hù)主目錄下的 db 文件夾中。所有編寫(xiě)的代碼和配置文件也放在用戶(hù)主目錄 /home/topling/ 下。

          1. 創(chuàng)建配置文件和數(shù)據(jù)庫(kù)目錄

            執(zhí)行下列命令建立存放數(shù)據(jù)庫(kù)的文件夾。

            1
            2
            3
            
            cd ~
            mkdir -p db
            mkdir -p db/db_mcf
            

            在同一目錄下創(chuàng)建配置文件 toplingconf.json ,然后找到我們的示例配置文件,將它里面的配置信息復(fù)制進(jìn)來(lái)。

            接下來(lái),修改配置信息中的數(shù)據(jù)庫(kù)路徑信息 path ,它位于最末尾的 db_mcf 字段中。將它修改為你自己的用戶(hù)主目錄下的db文件夾下的 db_mcf 。

            1
            
            "path": "/home/topling/db/db_mcf"
            

            更多關(guān)于配置文件的信息,請(qǐng)參閱配置系統(tǒng)介紹

          2. 創(chuàng)建操作數(shù)據(jù)庫(kù)的 .cc/.cpp/.cxx 文件

            在用戶(hù)主空間下,創(chuàng)建包含 main 函數(shù)的文件 sample.cpp ,加載我們會(huì)用到的頭文件 topling/side_plugin_repo.h ,以及標(biāo)準(zhǔn)輸入輸出流的頭文件 iostream 。

            1
            2
            
            #include "topling/side_plugin_factory.h"
            #include <iostream>
            

            在主函數(shù)中,創(chuàng)建一個(gè) rocksdb::SidePluginRepo 類(lèi)的實(shí)例 repo 。調(diào)用它的成員函數(shù) ImportAutoFile ,從我們剛才寫(xiě)好的配置文件中加載配置信息。

            1
            2
            
            rocksdb::SidePluginRepo repo;    // Repo represents of ConfigRepository
            repo.ImportAutoFile("/home/topling/toplingconf.json");
            

            在示例的配置信息中,打開(kāi)的數(shù)據(jù)庫(kù)是 db_mcf ,這是一個(gè)包含多個(gè) ColumnFamily 的 DB ,對(duì)應(yīng)類(lèi)型 rocksdb::DB_MultiCF 。創(chuàng)建一個(gè)該類(lèi)型的指針 dbm 來(lái)接收打開(kāi)的數(shù)據(jù)庫(kù),并將返回的 rocksdb::Status 中的信息打印出來(lái)。如果返回的是 OK ,則表示打開(kāi)成功。

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            
            #include "topling/side_plugin_factory.h"
            #include <iostream>
            
            int main()
            {
                rocksdb::SidePluginRepo repo;
                repo.ImportAutoFile("/home/topling/toplingconf.json");
            
                rocksdb::DB_MultiCF *dbm;
                auto status = repo.OpenDB(&dbm);
                std::cout << status.ToString() << std::endl;
            
                return 0;
            }
            
          3. 編譯

            使用以下指令進(jìn)行編譯,輸出可執(zhí)行文件 sample.out 。

            1
            
            g++ sample.cpp -I ~/toplingdb/sideplugin/rockside/src -I ~/toplingdb -I ~/toplingdb/sideplugin/topling-zip/src -I ~/toplingdb/sideplugin/topling-zip/boost-include -l:librocksdb.so -DSIDE_PLUGIN_WITH_YAML=1  -DROCKSDB_NO_DYNAMIC_EXTENSION=1 -o sample.out
            

            使用命令 ./sample.out 執(zhí)行生成的二進(jìn)制文件。不出意外,我們將看到終端打印出 OK ,這表示我們正確地打開(kāi)了數(shù)據(jù)庫(kù)。

          4. 對(duì)數(shù)據(jù)庫(kù)的簡(jiǎn)單讀寫(xiě)操作

            在打開(kāi)數(shù)據(jù)庫(kù)后, dbm 中有兩個(gè)重要的成員變量:指向數(shù)據(jù)庫(kù)實(shí)例的指針 db 和儲(chǔ)存所有 ColumnFamilyHandle 的 vector 容器 cf_handles 

            1
            2
            
            auto db = dbm -> db;
            auto handles = dbm -> cf_handles;
            

            通過(guò)它們就可以像操作 RocksDB 一般,對(duì) ToplingDB 進(jìn)行讀寫(xiě)了。如果我們?cè)诖嘶A(chǔ)上增加對(duì)輸入命令的解析,就成了一個(gè)簡(jiǎn)單的服務(wù)式的 KV數(shù)據(jù)庫(kù)程序 。

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            
            // write
            db -> Put(rocksdb::WriteOptions(), handles[0], rocksdb::Slice("test"), rocksdb::Slice("default_cf");
            db -> Put(rocksdb::WriteOptions(), handles[1], rocksdb::Slice("test"), rocksdb::Slice("custom_cf");
            
            //read
            std::string value1 , value2;
            db -> Get(rocksdb::ReadOptions(), handles[0], rocksdb::Slice("test"), &value1);
            db -> Get(rocksdb::ReadOptions(), handles[1], rocksdb::Slice("test"), &value2);
            std::cout << value1 << std::endl;
            std::cout << value2 << std::endl;
            
            //delete
            status = db -> Delete(rocksdb::WriteOptions(), handles[0], rocksdb::Slice("test"));
            std::cout << status.ToString() << std::endl;
            status = db -> Delete(rocksdb::WriteOptions(), handles[0], rocksdb::Slice("not exist"));
            std::cout << status.ToString() << std::endl;
            

          更換 SST Table

          ToplingDB 支持旁路插件化,只通過(guò)更改配置文件就可以更換 SST 文件的 TableFactory ,無(wú)需修改代碼。

          • 使用 RocksDB 內(nèi)置的 SST

            修改配置文件中 TableFactory 的部分,增加不同 Table 類(lèi)型的配置。

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            
            "TableFactory": {
                "block_based": {
                    "class": "BlockBasedTable",
                    "params": {
                
                    }
                },
                "cuckoo": {
                    "class": "CuckooTable",
                    "params": {
                        
                    }
                },
                "plain": {
                    "class": "PlainTable",
                    "params": {
                        
                    }
                }
            },
            

            然后在 database 的部分中,使用我們新設(shè)置的 table :

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            
            "SliceTransform": {
                "default": {
                    "class" : "FixedPrefixTransform",
                    "params" :{
                        "prefix_len" : 10
                    }
                }
            },
            "database": {
                ...
                
                "column_families": {
                    "default": "$default",
                    "custom_cf" : {
                        "max_write_buffer_number": 4,
                        "target_file_size_base": "16M",
                        "target_file_size_multiplier": 2,
                        "table_factory": "block_based",
                        "ttl": 0
                    },
                    "cuckoo_cf" : {
                        "table_factory": "cuckoo"
                    },
                    "plain_cf" : {
                        "table_factory": "plain",
                        "prefix_extractor" : "$default"
                    }
                },
            }
            

            直接運(yùn)行我們之前的程序,現(xiàn)在打開(kāi)的數(shù)據(jù)庫(kù)中, cuckoo_cf  plain_cf 這兩個(gè) ColumnFamily 就已經(jīng)使用了新的 Table 而不是默認(rèn)的 BlockBasedTable 。

            如果您在這一步遇到了問(wèn)題,也可以參考 2-1-toplingconf.json 

          • 使用第三方 SST 文件

            只需要通過(guò) ROCKSDB_FACTORY_REG 宏注冊(cè)第三方的 Factory ,就可以像使用 RocksDB 內(nèi)置類(lèi)型一樣使用第三方 SST 文件。

            為了進(jìn)行一個(gè)簡(jiǎn)單的示范,我們稍微包裝一下 BlockBasedTable ,拿它當(dāng)作一個(gè)第三方 SST 文件。

            1. 創(chuàng)建 mysst.h

              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14
              15
              16
              17
              18
              
              // mysst.h
              
              #define ROCKSDB_PLATFORM_POSIX
              #include "table/block_based/block_based_table_factory.h"
              namespace rocksdb
              {
              struct MyBlockBasedTableOptions : public BlockBasedTableOptions {};
                  
              class MyBlockBasedTableFactory : public BlockBasedTableFactory
              {
              public:
              explicit MyBlockBasedTableFactory(
                    const MyBlockBasedTableOptions& table_options = MyBlockBasedTableOptions());
                    const char* Name() const;
              ~MyBlockBasedTableFactory() {};
              };
              
              }
              
            2. 創(chuàng)建 mysst.cpp

              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14
              15
              16
              17
              18
              19
              20
              
              // mysst.cpp
              
              #include "mysst.h"
              #include <iostream>
              
              namespace rocksdb
              {
              
              MyBlockBasedTableFactory::MyBlockBasedTableFactory(const MyBlockBasedTableOptions& _table_options)
                   : BlockBasedTableFactory(_table_options) 
                   {
                       std::cout << "Using MyBlockBasedTableFactory" << std::endl;
                   }
              
              const char* MyBlockBasedTableFactory::Name() const
              {
                  return "MyBlockBasedTableFactory";
              };
              
              }
              

              可以看到 MyBlockBasedTable 只是繼承了 BlockBasedTable 而已,沒(méi)有其它的改動(dòng)。只不過(guò)當(dāng)我們使用 MyBlockBasedTable 時(shí),執(zhí)行它的構(gòu)造函數(shù)會(huì)打印出 “Using MyBlockBasedTableFactory” 。

            3. 注冊(cè) MyBlockBasedTable

               mysst.cpp 文件中,增加以下部分:

              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              
              #include "topling/side_plugin_factory.h"
              namespace rocksdb
              {
              
              std::shared_ptr<TableFactory> ThirdSSTExample(const json& js , const SidePluginRepo& repo)
              {
                  return std::make_shared<MyBlockBasedTableFactory>(MyBlockBasedTableOptions());
              }
              ROCKSDB_FACTORY_REG("MyBlockBased", ThirdSSTExample);
              }
              

              修改完成后的代碼可以參考 2-2-3-mysst.cpp 

              這里為了方便起見(jiàn),我們總是使用默認(rèn)的配置項(xiàng)來(lái)構(gòu)造 MyBlockBasedTable 。在實(shí)際使用中,您應(yīng)該通過(guò) js 中保存的 json 信息來(lái)構(gòu)造您使用的 TableFactory ,它類(lèi)似這樣:

              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              
              std::shared_ptr<TableFactory> ThirdSSTExample(const json& js , const SidePluginRepo& repo)
              {
              	ThirdTableOptions table_options;
              	
                  // some code for modifying table_options by json
                  ...
                  ...
                  
                  return std::make_shared<ThirdTableFactory>(table_options);
              }
              ROCKSDB_FACTORY_REG("MyBlockBased", ThirdSSTExample);
              
            4. 編譯生成 libmysst.so

              執(zhí)行以下指令進(jìn)行編譯,生成自定義插件 MyBlockBasedTable 的動(dòng)態(tài)庫(kù) libmysst.so :

              1
              
              g++ mysst.cpp -I ~/toplingdb -I ~/toplingdb/sideplugin/rockside/src -I ~/toplingdb/sideplugin/topling-zip/src -I ~/toplingdb/sideplugin/topling-zip/boost-include -l:librocksdb.so -fPIC -shared -o libmysst.so
              
            5. 動(dòng)態(tài)加載 libmysst.so :

              設(shè)置環(huán)境變量 LD_PRELOAD 后,直接運(yùn)行我們之前的可執(zhí)行程序 sample.out :

              1
              
              LD_PRELOAD=./libmysst.so ./sample.out
              

              此時(shí) MyBlockBasedTable 已經(jīng)注冊(cè)進(jìn) ToplingDB ,現(xiàn)在就可以像之前使用 RocksDB 內(nèi)置的 PlainTable 、 CuckooTable 一般,直接在配置項(xiàng)中啟用 MyBlockBasedTable 了。

              在配置文件中進(jìn)行如下修改,將內(nèi)置類(lèi)型 BlockBasedTable 改為第 3 步中,我們用 ROCKSDB_FACTORY_REG 宏注冊(cè)的名稱(chēng) “MyBlockBased” 。

              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              
              "TableFactory": {
                  "block_based": {
                      "class": "MyBlockBased",
                      "params": {
                          
                      }
                  },
                  
                  ...
              }
              

              再次運(yùn)行 sample.out (不要忘記設(shè)置 LD_PRELOAD ?。?,就能看到 MyBlockBasedTable 在構(gòu)造函數(shù)中打印的提示信息了。

          使用 AnyPlugin 進(jìn)行 HTML 展示

          為了方便,本示例在 sample.cpp 的基礎(chǔ)上直接進(jìn)行修改,沒(méi)有單獨(dú)將 HTML 展示插件編譯為動(dòng)態(tài)庫(kù)。

          1. 注冊(cè) AnyPlugin 插件

             rocksdb 命名空間內(nèi),定義 AnyPlugin 的派生類(lèi) HtmlShowExample ,并修改它的 ToString 函數(shù)和 Name 函數(shù)。

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            
            namespace rocksdb {
            class HtmlShowExample : public AnyPlugin 
            {
            public:
                void Update(const json&, const SidePluginRepo&) {}
                std::string ToString(const json& dump_options, const SidePluginRepo&) const 
                {
                    return "This is an example of HTML show.";
                }
                const char* Name() const
                {
                    return "HtmlShowExample";
                }
            };
            }
            

            ToString 函數(shù)的返回值是 std::string 類(lèi)型,其返回的 string 字符串,會(huì)被無(wú)差別地打印在瀏覽器中。若返回值是一個(gè)序列化的 json 對(duì)象, AnyPlugin 還能夠以表格的形式展示數(shù)據(jù)。

            定義派生類(lèi) HtmlShowExample 之后,仍然在 rocksdb 命名空間中,使用下列的宏將其注冊(cè)。

            1
            2
            
            ROCKSDB_REG_DEFAULT_CONS(HtmlShowExample, AnyPlugin);
            ROCKSDB_REG_AnyPluginManip("HtmlShowExample");
            
          2. 開(kāi)啟 http 服務(wù)

            在加載配置文件后,調(diào)用 repo 的成員函數(shù) StartHttpServer 開(kāi)啟 http 服務(wù)。與打開(kāi) DB 相似,我們也可以打印出返回的 rocksdb::Status 的相關(guān)信息作為參考。

            1
            2
            
            auto http_status = repo.StartHttpServer();
            std::cout << http_status.ToString() << std::endl;
            

            修改后的源程序?yàn)?span> 3-2-sample.cpp 。

          3. 修改配置文件

            在配置文件的最外層中,增加我們的展示插件信息。

            1
            2
            3
            4
            5
            6
            7
            
            {
                "AnyPlugin": {
                    "html-show-example": "HtmlShowExample"
                },
                
                ...
            }
            
          4. 編譯并運(yùn)行項(xiàng)目

            使用我們之前的編譯指令編譯修改后的 sample.cpp ,并執(zhí)行程序。

            我們?cè)谑纠渲梦募性O(shè)置的監(jiān)聽(tīng)端口為 8081 ,訪(fǎng)問(wèn) 127.0.0.1:8081/AnyPlugin/html-show-example ,即可看到展示信息。

            如果您不是在本地上執(zhí)行程序,將 127.0.0.1 更改為您機(jī)器的訪(fǎng)問(wèn)ip。如果執(zhí)行程序打印的信息均為OK,但無(wú)法打開(kāi)頁(yè)面,請(qǐng)檢查防火墻設(shè)置。

          5. 其他信息展示

            ToplingDB 內(nèi)部集成了一個(gè) WebService 用于對(duì)外展示內(nèi)部信息,例如目前配置的參數(shù)選項(xiàng),LSM樹(shù)的狀態(tài),或者是分布式 compact 的執(zhí)行情況等等。另外,在 Statistic 下展示的監(jiān)控指標(biāo),還可以導(dǎo)入到 Prometheus + Grafana 中進(jìn)行監(jiān)控。

            若您還使用了第三方插件,在實(shí)現(xiàn)并注冊(cè)對(duì)應(yīng)的 PluginManipFunc 模板類(lèi)后,即可在對(duì)應(yīng)的 web 頁(yè)面下看到 ToString 成員函數(shù)返回的序列化信息。

          瀏覽 12
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天操天天撸 | 麻豆AV无码精品一区二区色欲 | 欧美性爱视频免费网站 | 玩熟女五十AV一二三区 | 日本三级在线网站 |