从零实现kv存储V2.0

简介: 从零实现kv存储V2.0

V1.0版本,我们实现了基于array的kv存储引擎。本文继续完善,增加rbtree、hash、skiptable引擎。


实际上,在框架确定的基础上,其他的引擎只需要添加接口即可。


一、架构设计



a8ab6fd6bf36d8595ae34ef458ff497d_5db4ccea2e294a75b58ff863e6ab0680.png

7437ee32a219af214b6c38f5fb372061_f6bc44cde6194c3b9a3ef0e2c86dc2fa.png


二、具体实现


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 网络层

纯c版本的协程实现NtyCo

// 为每一个连接端口创建一个协程
nty_coroutine_create(&co, server, port);

2.5 功能测试结果

9eafd6c34a4331cfab738c923161eac8_777eb14d62d9446e9863892b9dcd427c.png


2.6 qps测试结果

d8731f44677c68dccae99c68c653a1cf_4c144592ffbf4d75b2c98662d27c2908.png

增加了动态哈希


 ---------> 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存储引擎项目

目录
相关文章
|
存储 XML NoSQL
KV 存储那些事儿
开发中,我们总会需要存储些 KV 数据,虽然看上去简单,但考虑因素也是很多的,实现手段也就各有差异。今天,我们就来看看 Android 目前有哪些 KV 库可以供我们使用,以及其有哪些优缺点。
372 0
|
3月前
|
存储 Kubernetes 测试技术
在k8s中,有哪些存储?
在k8s中,有哪些存储?
|
存储 网络协议 NoSQL
从零实现kv存储V1.0:array初版
从零实现kv存储V1.0:array初版
86 1
|
6月前
|
存储 缓存 NoSQL
键值存储
键值存储
362 1
|
存储 NoSQL Java
从Redis源码上来聊聊KV模型-Hash数据类型
&gt;之前就说了要来西索Redis,现在来辣! &gt;本文的部分内容参考自《小林Coding》,部分地方根据源代码进行剖析。 &gt;Redis源码地址:https://github.com/redis/redis.git &gt;阅读本文之前建议先阅读我的上一篇文章:[神奇,Redis存储原理竟然是这样! – Karos (wzl.fyi)](https://www.wzl.fyi/2023/07/20/986/)
234 3
从Redis源码上来聊聊KV模型-Hash数据类型
|
存储 缓存 固态存储
一文看懂存储
一文看懂存储
234 1
|
存储 SQL NoSQL
存储的未来
存储的未来
119 1
|
存储 应用服务中间件 nginx
k8s--数据存储、EmptyDir存储
k8s--数据存储、EmptyDir存储
|
存储 C++
数据的存储详解
关于整型提升的详细解释和例题
82 0
数据的存储详解
|
存储 算法
实现分布式 kv—1 Standalone KV
TinyKV 是 PingCAP 的一个开源课程:https://github.com/tidb-incubator/tinykv,旨在实现一个简易的分布式 kv,其中很多代码框架它已经提供了,我们只需要填充具体的逻辑即可。
418 0