在V1.0版本,我们实现了基于array的kv存储引擎。本文继续完善,增加rbtree、hash、skiptable引擎。
实际上,在框架确定的基础上,其他的引擎只需要添加接口即可。
一、架构设计
二、具体实现
2.1 引擎层
//------------------------ array ------------------ typedef struct kvs_array_item_s { char *key; char *value; } kvs_array_item_t; // kvs_array_table 存储插入的 kv kvs_array_item_t kvs_array_table [KVS_ARRAY_ITEM_SIEZ] = {0}; //--------------------- rbtree hash skiptable-------------- void init_kvengine(void) { init_rbtree(&tree); init_hashtable(&hash); init_skiptable(&table); } void dest_kvengine(void) { dest_rbtree(&tree); dest_hashtable(&hash); dest_skiptable(&table); }
2.2 接口层
接口尽量做到一致,方便管理拓展。
//------------------------------ array -------------------------------- // 查找 key 在 kvs_array_table 的位置 kvs_array_item_t *kvs_array_search_item (char *key); // KVS_CMD_EXIST: 判断 key 是否存在,存在返回 1 int kvs_array_exist (char *key); // KVS_CMD_SET:插入 kv int kvs_array_set (char *key, char *value); // KVS_CMD_GET:获取 key 对应的value char *kvs_array_get(char *key); // KVS_CMD_COUNT:统计以及插入多少个 key int kvs_array_count (void) ; // KVS_CMD_DELETE:删除 key int kvs_array_delete(char *key); //------------------------------ rbtree-------------------------------- // KVS_CMD_REXIST int kvs_rbtree_exist (char *key) { return exist_kv_rbtree(&tree, key); } // KVS_CMD_RSET int kvs_rbtree_set (char *key, char *value) { return put_kv_rbtree(&tree, key, value); } // KVS_CMD_RGET char *kvs_rbtree_get (char *key) { return get_kv_rbtree(&tree, key); } // KVS_CMD_RCOUNT int kvs_rbtree_count(void) { return count_kv_rbtree(&tree); } // KVS_CMD_RDELETE int kvs_rbtree_delete(char *key) { return delete_kv_rbtree(&tree, key); } //------------------------------ hash-------------------------------- int kvs_hash_set(char *key, char *value) { return put_kv_hashtable(&hash, key, value); } char *kvs_hash_get(char *key) { return get_kv_hashtable(&hash, key); } int kvs_hash_count(void) { return count_kv_hashtable(&hash); } int kvs_hash_exist(char *key) { return exist_kv_hashtable(&hash, key); } int kvs_hash_delete(char *key) { return delete_kv_hashtable(&hash, key); } //------------------------------ skiptable-------------------------------- int kvs_skiptable_set(char *key, char *value) { return put_kv_skiptable(&table, key, value); } char *kvs_skiptable_get(char *key) { return get_kv_skiptable(&table, key); } int kvs_skiptable_count(void) { return count_kv_skiptable(&table); } int kvs_skiptable_exist(char *key) { return exist_kv_skiptable(&table, key); } int kvs_skiptable_delete(char *key) { return delete_kv_skiptable(&table, key); }
2.3 协议层
// 根据msg,解析其具体的命令协议 int kvs_parser_protocol (char *msg, char **tokens, int count) ; /*分割msg,比如 msg为 SET NAME ZXM ,分割为SET,NAME,ZXM,分别存储在tokens[] * tokens[0]: SET --------- 对应的是命令 cmd * tokens[1]: NAME --------- 对应的是命令 key * tokens[2]: ZXM --------- 对应的是命令 value */ int kvs_spilt_tokens (char **tokens, char *msg) ; // 解析协议 int kvs_protocol (char *msg, int length);
2.4 网络层
// 为每一个连接端口创建一个协程 nty_coroutine_create(&co, server, port);
2.5 功能测试结果
2.6 qps测试结果
增加了动态哈希
---------> array testcase 10w <----------- time_used: 5897, qps: 16000 (request/second) ---------> rbtree testcase 10w <----------- time_used: 6886, qps: 14000 (request/second) ---------> hash testcase 10w <----------- time_used: 9696, qps: 10000 (request/second) ---------> dhash testcase 10w <----------- time_used: 6042, qps: 16000 (request/second) ---------> skiptable testcase 10w <----------- time_used: 12958, qps: 7000 (request/second)
三、完成代码
Github地址:KV存储引擎项目