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 "Within the same Redis database, a single key name can only have one type of data structure" #2609

Merged
merged 16 commits into from May 20, 2024

Conversation

Mixficsol
Copy link
Collaborator

@Mixficsol Mixficsol commented Apr 17, 2024

背景

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

解决方案

Floyd 现有的设计之上,将之前 String 类型所在的Column-Family 用于存放所有的 KeyMeta 信息

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

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

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     |

Stream

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

value格式
|  group_id_ | entries_added_ | first_id_ms | first_id_seq | last_id_ms | last_id_seq | max_deleted_entry_ms | max_deleted_entry_seq | length | version |
|     4B     |       8B       |     8B      |      8B      |     8B     |      8B     |         8B           |          8B           |   4B   |    4B   |


修改后

我们对每一种数据类型的 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     |

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

@github-actions github-actions bot added the ✏️ Feature New feature or request label Apr 17, 2024
@Mixficsol Mixficsol force-pushed the floyd-imoprove branch 2 times, most recently from 50d9c4b to d22ff2f Compare April 23, 2024 09:44
@Mixficsol Mixficsol force-pushed the floyd-imoprove branch 16 times, most recently from 2f7a9c8 to 0e6b16f Compare April 24, 2024 13:48
@Mixficsol
Copy link
Collaborator Author

Mixficsol commented Apr 25, 2024

  1. Cmd 层多加了一次对返回值的判断(用于判断多 key 的错误信息)
else if (s_.ToString() == ErrTypeMessage) {
  res_.SetRes(CmdRes::kMultiKey);
} 
  1. Cache 层删除了 Redis 前缀
// 修改前:
std::string CachePrefixKeyK = PCacheKeyPrefixK + key_;
db_->cache()->SetBitIfKeyExist(CachePrefixKeyK, bit_offset_, on_);

// 修改后
db_->cache()->SetBitIfKeyExist(key_, bit_offset_, on_);
  1. Storage 层对 Expire, Del, Exists, Expireat, Persist, TTL, GetType 这几个之前需要遍历每种数据类型的接口修改成指定操作某一个具体类型的接口
修改前:
// Keys Commands
int32_t Storage::Expire(const Slice& key, int64_t ttl, std::map<DataType, Status>* type_status) {
  type_status->clear();
  int32_t ret = 0;
  bool is_corruption = false;

  auto& inst = GetDBInstance(key);
  // Strings
  Status s = inst->StringsExpire(key, ttl);
  if (s.ok()) {
    ret++;
  } else if (!s.IsNotFound()) {
    is_corruption = true;
    (*type_status)[DataType::kStrings] = s;
  }

  // Hash
  s = inst->HashesExpire(key, ttl);
  if (s.ok()) {
    ret++;
  } else if (!s.IsNotFound()) {
    is_corruption = true;
    (*type_status)[DataType::kHashes] = s;
  }

  // Sets
  s = inst->SetsExpire(key, ttl);
  if (s.ok()) {
    ret++;
  } else if (!s.IsNotFound()) {
    is_corruption = true;
    (*type_status)[DataType::kSets] = s;
  }

  // Lists
  s = inst->ListsExpire(key, ttl);
  if (s.ok()) {
    ret++;
  } else if (!s.IsNotFound()) {
    is_corruption = true;
    (*type_status)[DataType::kLists] = s;
  }

  // Zsets
  s = inst->ZsetsExpire(key, ttl);
  if (s.ok()) {
    ret++;
  } else if (!s.IsNotFound()) {
    is_corruption = true;
    (*type_status)[DataType::kZSets] = s;
  }

  if (is_corruption) {
    return -1;
  } else {
    return ret;
  }
}

修改后
// Keys Commands
int32_t Storage::Expire(const Slice& key, int64_t ttl) {
  auto& inst = GetDBInstance(key);
  Status s = inst->Expire(key, ttl);
  if (s.ok()) {
    return 1;
  } else if (!s.IsNotFound()) {
    return -1;
  }
  return 1;
}
  1. Redis 层每次需要对 Key 进行修改时,新增了对 meta-key 类型的判断
if (!ExpectedMetaValue(Type::kSet, meta_value)) {
  return Status::InvalidArgument("WRONGTYPE Operation against a key holding the wrong kind of value");
}

@Mixficsol Mixficsol force-pushed the floyd-imoprove branch 2 times, most recently from 36b9ffe to ad99b09 Compare April 25, 2024 10:35
@AlexStocks AlexStocks changed the base branch from unstable to floyd_unique_type May 16, 2024 07:00
@AlexStocks AlexStocks changed the base branch from floyd_unique_type to unstable May 16, 2024 10:06
@Mixficsol Mixficsol force-pushed the floyd-imoprove branch 4 times, most recently from 269e045 to af67771 Compare May 16, 2024 16:29
@Mixficsol Mixficsol force-pushed the floyd-imoprove branch 5 times, most recently from df416fc to 53dd707 Compare May 20, 2024 02:47
@@ -1242,7 +1242,7 @@ int64_t Storage::Scan(const DataType& dtype, int64_t cursor, const std::string&
LOG(WARNING) << "Invalid key_type: " << key_type;
return 0;
}
std::copy(pos, iter_end, std::back_inserter(types));
std::copy(pos, iter_end - 2, std::back_inserter(types));
Copy link
Collaborator

Choose a reason for hiding this comment

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

这个地方为什么减2?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

这个是因为之前DataType类型只有all+五种数据类型,然后现在我复用了这个DataType需要加一个none类型,然后-2是因为之前可以直接到迭代器尾端,但是现在得在末端前两个

@Mixficsol Mixficsol force-pushed the floyd-imoprove branch 2 times, most recently from 0f46c45 to 8380ad5 Compare May 20, 2024 03:58
src/pika_kv.cc Outdated
@@ -224,19 +222,15 @@ void DelCmd::DoUpdateCache() {
if (s_.ok()) {
std::vector<std::string> v;
Copy link
Collaborator

Choose a reason for hiding this comment

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

这里既然只存在一种类型,那直接delete key就好了,没必要用v转换一下

src/pika_list.cc Outdated
@@ -663,6 +676,10 @@ void BRPopCmd::Do() {
return;
} else if (s_.IsNotFound()) {
continue;
} else if (s_.IsInvalidArgument()) {
// TODO use return or continue; Mixficsol
Copy link
Collaborator

Choose a reason for hiding this comment

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

这里确认了 就把注释删了吧

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 AlexStocks merged commit e38e255 into OpenAtomFoundation:unstable May 20, 2024
14 checks passed
QlQlqiqi pushed a commit to QlQlqiqi/pika that referenced this pull request May 22, 2024
…me can only have one type of data structure" (OpenAtomFoundation#2609)

* floyd supports one key for one data structure
* Modified the criteria for determining multiple keys
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.

None yet

5 participants