Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: floyd supports one key for one data structure #240

Closed
wants to merge 20 commits into from

Conversation

Mixficsol
Copy link
Collaborator

@Mixficsol Mixficsol commented Mar 27, 2024

背景

当前 Pika 的一个 Key 可以对应多种数据结构,和 Redis 不一致

解决方案

Floyd 现有的设计之上,将之前 String 类型所在的Column-Family 用于存放所有的 KeyMeta 信息,其对应的 value 为数据类型 type,并在内存中建立一个所有 Keycuckoo bloom filter. 在增加一个 Key 时,先去读 cuckoo bloom filter 判断被增加的 Key 是否存在,如果不存在,则直接进行后续操作,如果存在,但可能是假阳性,所以需要一次读盘操作,去新增加的 Column-Family 中读取,验证被增加的 Key 是否真正存在,然后再进行后续的操作,单独设置 block cache ,为这个新增加的 Column-Family 单独设置一个,防止和别的数据共用,导致 KeyColunm-Family 淘汰出内存

修改前:
enum ColumnFamilyIndex {
    kStringsCF = 0,
    kHashesMetaCF = 1,
    kHashesDataCF = 2,
    kSetsMetaCF = 3,
    kSetsDataCF = 4,
    kListsMetaCF = 5,
    kListsDataCF = 6,
    kZsetsMetaCF = 7,
    kZsetsDataCF = 8,
    kZsetsScoreCF = 9,
};

修改后:
enum ColumnFamilyIndex {
    kMetaCF = 0,
    kHashesDataCF = 1,
    kSetsDataCF = 2,
    kListsDataCF = 3,
    kZsetsDataCF = 4,
    kZsetsScoreCF = 5,
};

kMetaCF 字段设计

修改前

String

key格式
| reserve1 | key | reserve2 | 
|    8B    |     |   16B    |

value格式
| value | reserve | cdate | timestamp | 
|       |   16B   |   8B  |    8B     |

Hash

key格式
| reserve1 | key | reserve2 | 
|    8B    |     |    16B   |

value格式
| hash_size | version |  reserve  | cdate | timestamp | 
|    4B     |    8B   |    16B    |   8B  |     8B    |

List

key格式
| reserve1 | key | reserve2 |
|    8B    |     |   16B    |

value格式
|list_size| version | left index | right index | reserve |  cdate | timestamp | 
|   8B    |   8B    |     8B     |     8B      |   16B   |   8B   |    8B     |

set

key格式
| reserve1 | key | reserve2 |
|    8B    |     |    16B    |

value格式
| set_size | version | reserve | cdate | timestamp | 
|    4B    |    8B   |   16B   |   8B  |    8B     |

zset

key格式
| reserve1 | key | reserve2 |
|    8B    |     |    16B   |  

value格式
| zset_size | version | reserve  | cdate | timestamp | 
|    4B     |    8B   |    16B   |   8B  |    8B     |

修改后

我们对每一种数据类型的 Metavalue 前增加一个字段 Type 用于区别每个 Key 对应的数据结构

Set 类型举例

key格式
| reserve1 | key | reserve2 |
|    8B    |     |    16B   |

value格式
| type | set_size | version | reserve | cdate | timestamp | 
|  1B  |    4B    |    8B   |   16B   |   8B  |    8B     |

String 的 Meta 格式

key格式
| reserve1 | key | reserve2 | 
|    8B    |     |   16B    |

value格式
| Type | value | reserve | cdate | timestamp | 
|  1B  |       |   16B   |  8B   |    8B     |

在解析的时候,先解析头部的第一个字节,然后根据类型判断是否需要继续解析下去

issue #269

@github-actions github-actions bot added the ✏️ Feature New feature or request label Mar 27, 2024
@Mixficsol
Copy link
Collaborator Author

Mixficsol commented Mar 27, 2024

第一次提交只修改了 SaddHset 这两个命令在遇到多 Key 时的判断,确保和 Redis 的返回值保持一致

PikiwiDB
截屏2024-03-27 16 21 59

Redis
截屏2024-03-27 16 18 40

@Mixficsol Mixficsol force-pushed the floyd-improve branch 2 times, most recently from 1721c06 to 4ebdfd8 Compare March 27, 2024 08:24
@Mixficsol
Copy link
Collaborator Author

目前遇到的一个问题是我们使用的是 RocksDBStatus 作为每一个命令的状态返回值,但是对于这种由于多 Key 问题导致的操作无法进行下去我们应该使用 RocksDB 中的哪种状态返回值呢?还是说修改 RocksDB 代码新加一种返回值

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


One problem currently encountered is that we are using Status of RocksDB as the status return value of each command, but for this kind of operation that cannot be carried out due to multiple Key problems, we should use RocksDB Which status return value does it have? Or should we modify the RocksDB code to add a new return value?

@hotjump
Copy link
Collaborator

hotjump commented Mar 27, 2024

如果要增加 cuckoo bloom filter ,建议增加性能对比的测试用例好判断是否有提升以及提升的幅度。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


If you want to add cuckoo bloom filter, it is recommended to add test cases for performance comparison to judge whether there is improvement and the extent of improvement.

@Mixficsol
Copy link
Collaborator Author

Mixficsol commented Mar 28, 2024

第二次提交把除 string 以外的四种数据结构都加上了多 key 的判断,并修复测试用例通过
截屏2024-03-28 15 17 30

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


The second submission added multi-key judgment to the four data structures except string, and tried to repair the test cases.

@Mixficsol
Copy link
Collaborator Author

如果要增加 cuckoo bloom filter ,建议增加性能对比的测试用例好判断是否有提升以及提升的幅度。

嗯嗯,这个算是第二期的任务,第一期先把CF弄好

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


If you want to add cuckoo bloom filter, it is recommended to add test cases for performance comparison to judge whether there is improvement and the extent of improvement.

Hmm, this is considered the task of the second period. In the first period, we should finish the CF first.

src/storage/src/lists_meta_value_format.h Outdated Show resolved Hide resolved
src/storage/src/base_meta_value_format.h Outdated Show resolved Hide resolved
src/storage/src/base_meta_value_format.h Outdated Show resolved Hide resolved
src/storage/src/storage.cc Show resolved Hide resolved
@Mixficsol
Copy link
Collaborator Author

第三次提交,新设计了 StringMetaCF, 对于之前 Floyd 中的 Del, Exists, Expire 等之前需要操作每一个数据类型的 CF,做了优化,只需要判断第一个字节 Type,然后调用相应的接口即可,当然还有后续类似的命令也需要进行优化

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


The third submission, newly designed MetaCF of String, and optimized the CF of Del, Exists, Expire in Floyd that previously needed to operate each data type. , you only need to determine the first byte Type, and then call the corresponding interface. Of course, subsequent similar commands also need to be optimized.

@Mixficsol
Copy link
Collaborator Author

Mixficsol commented Mar 29, 2024

第四次提交合并了一下代码的冲突,但是发现 ListGO 测试通过失败了,但是本地手动复现是没问题的,本地开启了 Debug 模式也是没问题的

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


The fourth submission merged some code conflicts.

@Mixficsol
Copy link
Collaborator Author

Mixficsol commented Mar 29, 2024

第五次提交移植了 redisTCL 测试,目前还在调试
WechatIMG1034

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


The fifth submission requires changing Persist, TTL, GetType, Keys, ScanDatabase, DoCompactRange, GetCurrentTaskType, IsExist, which were previously traversal data type interfaces, into pairs Specify the data type interface to operate

@github-actions github-actions bot added the 📒 Documentation Improvements or additions to documentation label Mar 29, 2024
@github-actions github-actions bot added the 📒 Documentation Improvements or additions to documentation label Apr 10, 2024
}
client->SetRes(CmdRes::kErrOther, cnt);
}
auto res = PSTORE.GetBackend(client->GetCurrentDB())->GetStorage()->Persist(client->Key());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

删除 map

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@AlexStocks
Copy link
Contributor

image

from #144

@Mixficsol Mixficsol removed the 📒 Documentation Improvements or additions to documentation label Apr 12, 2024
@qqricky
Copy link

qqricky commented Apr 21, 2024

第一次提交只修改了 SaddHset 这两个命令在遇到多 Key 时的判断,确保和 Redis 的返回值保持一致

PikiwiDB 截屏2024-03-27 16 21 59

Redis 截屏2024-03-27 16 18 40

🐮

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


The first submission only modified the judgment of Sadd and Hset when encountering multiple Key, ensuring that it is consistent with the return value of Redis

PikiwiDB Screenshot 2024-03-27 16 21 59

Redis Screenshot 2024-03-27 16 18 40

🐮

@@ -1210,55 +1129,19 @@ int64_t Storage::DelByType(const std::vector<std::string>& keys, const DataType&

int64_t Storage::Exists(const std::vector<std::string>& keys) {
int64_t count = 0;
int32_t ret;
uint64_t llen;
std::string value;
Status s;
bool is_corruption = false;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_corruption没有用到的变量

@@ -1515,225 +1398,48 @@ Status Storage::Scanx(const DataType& data_type, const std::string& start_key, c
int32_t Storage::Expireat(const Slice& key, uint64_t timestamp) {
Status s;
int32_t count = 0;
bool is_corruption = false;

auto& inst = GetDBInstance(key);
s = inst->StringsExpireat(key, timestamp);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里调用stringsexpireat是说expireat接口只支持string类型?


if (is_corruption) {
return -1;
return 1;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

是不是少了corruption的情况?

if (s.ok()) {
ParsedHashesMetaValue parsed_hashes_meta_value(&meta_value);
auto type = static_cast<enum Type>(static_cast<uint8_t>(meta_value[0]));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我看类似的逻辑在挺多的地方都有调用,而且得到的type变量其实也没有其他地方在用,是不是封装一个函数出来?

@Mixficsol Mixficsol closed this May 17, 2024
@Mixficsol Mixficsol reopened this May 23, 2024
@Mixficsol Mixficsol closed this May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✏️ Feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants