数据库
#database #性能 #体系结构 #rust

这是对专有的内部项目的描述,其内容未许可使用。

所以,我一直在努力为我一直在研究的数据库工具的当前状态而设置所有设置。
我将在此处包括一些摘录,并在内部读书中使用示例用法,但是正在抛弃一些鲜肉的零件。

该项目

该项目的高级目标是创建一个简单而快速的数据库。为了实现这些目标
它将用于生锈的逻辑,rocksdb,用于数据层,用于传输的GRPC,以及作为存储格式的序列化Protobuf消息。

使用RustRocksDBgRPC提供的优点是正确的,速度和稍微存储的大小。

在当今的数据库气候中,我们有很多不同的“营地”,对“ what是正确的”的感觉非常强烈。但是,
实际的“正确”答案是解决问题最适合用户的答案,因此它不会在
中重新排列或放置“否”字母 归根结底,我们只需要快速响应,并最大程度地减少我们需要管理自己的数量,以扩展我们的系统。

像你5岁那样和你说话,再次

我认为值得认识到数据中的所有内容都将其缩短回“地址”和“ plact in该地址”(或“键”和“ value”,但
如果您说“所有数据存储都还原为钥匙值存储”,则“灯就是life”或“ .NET MCV承包商” GenXers开始大喊大叫,并且“我只知道

如何使用Activerecord和Prisma“千禧一代开始哭泣)。

在分布式系统中,数据中的一个毛茸茸的问题正在弄清楚如何将它们全部拆分到任何地方。在许多系统中,您必须考虑某种形式的碎片,复制,
位置等。等等。因此,我们需要一种最小复杂的方法来扩展数据,但是我们还需要以稍后可以迅速检索的方式存储数据。所以,握住
在我们当前的世界中,这两件事在我们当前的世界中,我们经常提出不理想的解决方案,而我们的碎片策略变得非常具体,或者由开发人员告知

偏好,以及我们最终需要进行的许多更改,因为它们需要迁移,代码更新,打破更改以及等等,等等,等等,等等,等等,等等,等等。

考虑到这一点,我认为我们确实需要退后一步,开始评估在“骨架”上建立的想法 - 构成“心灵”的骨架

在该系统的数据中,然后...随着我们在骨干顶上的视图而变得更加舒适的鹅(不从来没有放置“骨干数据”

在危险之中)。我们的“骨干”将是我们的SSO或“真理的单一来源”。老实说...我认为建造这样的骨干的最简单方法是使用分布式的KV商店。
分布式的KV商店可以水平扩展,以最小的复杂性:即前缀IP_ADDRESS#RECORD_A的框地址,并且可以解释IP_ADDRESS
在负载平衡器上,您基本上只是扩展了PK(这不是我这样做的方式,这只是传达一个想法的伪)。

为什么GRPC和Protobuf?

好吧,将分布式内容留在后面,因为目前该项目仅专注于一次支持一个实例(还没有自动化的内容 知道,有一天很快)GRPC效果很好,因为它的运输效率比HTTP上的JSON更有效,而Protobuf消息大小更紧凑 /二进制格式实际上使它成为一个很好的候选人
用于存储。另一个很酷的是,GRPC有像gzip编解码器一样,因此可能以稍后作为配置选项显示。

“云中的头”

也有一些很酷的计算和数据存储的机会。我有思考将运行时螺栓固定在其侧面,这允许
为了使主机查询能够直接在磁盘上击中数据(当它分发时,它仍然会感觉并为开发人员行事,但是

节点本身可能需要去查找当前不拥有的记录,在其他节点上,所有这些都不是不透明的,而不是相互关联的计算函数)。所以你说,
“哦,这些只是大楼”,我会说:“是的!只是你们中知道什么是什么的人,每当我开始说那是什么时,真的很讨厌。”

如果您需要理解为什么我认为这是一个好主意(可悲的是,这不是我的主意...当我认为是时,我真的很兴奋),那就不过是Postgres的创建者。
Michael StonebrakerVoltDB(或我认为他们将其名称更改为Volt Active Data)已使用基于JVM的
支持 在很长的屁股上,Sprocs就像其主要凉爽的零件之一一样。不仅如此,Postgres(我真的不知道为什么没有人这样做 让您这样做)使用plv8
Postgres RDS实例的扩展。

无论如何,将计算与数据相处很酷,并且有先例。

在理论上加倍

我可能会选择选择JavaScript + WebAssembly运行时,而不是JVM。 JVM很酷,但是我需要一种在沙盒周围运送的方法,Wasm的
现在最好的,轻巧的方法。我还认为您需要一个良好的“快速移动并破坏事物”的脚本语言来完成某些任务(尽管我感觉

对于那些没有幻想的人,您的Facebook点击

,最近越来越少)和JavaScript/Typecript似乎是非常明智的默认 生活的意义(或您撒谎的任何谎言告诉自己现在的机器学习实际上正在为世界所做的什么)。

实际用法

要设置数据库,您可以定义一个带有消息的.proto文件。这些消息中的每一个都对应于“模型”。如果您想拥有逻辑
系统中House的概念,您将编写以下原始文件:

// schema.proto
syntax = "proto3";
package database;

message House {
    // required. this is the key you query by later
    string pk = 1;

    string color = 2;
    string address = 3;
}

然后您将运行以下内容:

## haven't settled on a name, so I'm just swapping out my `cargo run` with a made up one. "sean-db" def not gonna be it tho
sean-db create schema.proto

运行该命令,将为您的消费服务创建服务器二进制文件和原始文件。因此,在out/中,您将拥有serverdatabase.proto

database.proto是任何熟悉GRPC的开发人员都可以用来代码 - 基因并建立数据库的客户端。现在,数据库
IS 非常轻巧,具有 no 给药基础架构,权限,AUTH或MTL;因此,您只想像私人那样运行它
子网在与消费者或其他类似的VPC中相同...但是我打算随着时间的流逝而发展一切。

跑步

一旦Rocksdb终于完成了建筑(圣洁的他妈的花费太长了,我需要弄清楚如何喜欢Cache或有些人做一些
其他可以停止的Rustacean Magic),您应该能够使用:
运行服务器

./out/server

客户

由于数据库服务器只是GRPC服务器,因此您可以将所有GRPC库用于您喜欢的任何语言。
实际上,您也可以滚动到您的首选GRPC客户端并输入localhost::50051,因为我们实现了
服务器反射,当您插入URL(如果您的工具支持)时,它可以自动加载所有可用的RPC
甚至生成伪造的内容。

例子

这里最简单的示例(因为现在是“只是KV商店”,我不会向所有人解释std)只是1个模型,
所以我们要选择Dog

模式

// cli/test.proto
syntax = "proto3";
package database;

message Dog {
  string pk = 1;

  string name = 2;
  uint32 age = 3;
  string breed = 4;
}

如果我们运行以上命令来生成./out/server./out/database.proto,我们可以为我们的客户端获得实际有用的原始定义(./out/database.proto):

sean-db create schema.proto

原始

当我们使用schema.proto运行脚本时,它会出现这个新的原始原型(database.proto)。在这个新原型中,是数据库的实际基础
互动,并拥有我们在应用领域需要做的所有有趣的事情。

此文件不应直接被开发人员修改,并且可能会破坏Lotta的内容。

syntax = "proto3";
package database;

message Dogs { 
  repeated Dog dogs = 1; 
}
message Dog {
  string pk = 1;
  string name = 2;
  uint32 age = 3;
  string breed = 4;
}

message IndexQuery {
  oneof expression {
    string eq = 1;
    string gte = 2;
    string lte = 3;
    string begins_with = 4;
  }
}

message Empty {}

service Database {
  rpc GetDogsByPk(IndexQuery) returns (Dogs) {}
  rpc DeleteDogsByPk(IndexQuery) returns (Empty) {}
  rpc PutDog(Dog) returns (Empty) {}
  rpc BatchPutDogs(Dogs) returns (Empty) {}
}

客户

我要为每种语言整理一个完整的代码示例,但这很累,grpcurl给了您这个想法。

基本上,我们有4个RPC:

  • GetXByPk
  • DeleteXByPk
  • PutX
  • BatchPutX

然后,您拥有IndexQuery助手,基本上允许您进行密钥范围的查询。

这是真正的基本示例:

## PutDog
grpcurl -plaintext -d '{
  "pk": "DOG#1",
  "name": "Rover",
  "age": 3,
  "breed": "Golden Retriever"
}' localhost:50051 database.Database.PutDog

## BatchPutDogs
grpcurl -plaintext -d '{
  "dogs": [
    {
      "pk": "DOG#2",
      "name": "Buddy",
      "age": 2,
      "breed": "Labrador"
    },
    {
      "pk": "DOG#3",
      "name": "Max",
      "age": 4,
      "breed": "Poodle"
    }
  ]
}' localhost:50051 database.Database.BatchPutDogs

## GetDogs
grpcurl -plaintext -d '{"begins_with": "DOG#"}' localhost:50051 database.Database.GetDogsByPk

## DeleteDogs
grpcurl -plaintext -d '{"eq": "DOG#3"}' localhost:50051 database.Database.DeleteDogsByPk

结论

实际上,我要做的就是建造一个用Rust,Grpc和Rocksdb的糟糕的KV商店ORM。但是(也许)有趣的是
实际上,我们根据我们的访问模式创建代码路径,而不是离开查询计划以
进行解析和解释 运行时或使用结构化字符串,我们将访问模式“编译”到数据库服务器本身中。

这有挑战,目前我们只支持一组非常狭窄的访问模式...但是使用模型和场宏¢
我认为我们将能够为更广泛的访问模式进行更多的优化。

该项目的目标是对我们在这些基础上的最大程度上了解我们所做的以构建我们的应用程序,

这样我们就可以接受这些学习并在我们的数据库上游“拉回”并弄清楚,这是多少重复性
我们可以汇编的工作 - 我们将其委派给开发人员。

警告

我没有想到的一件事是迁移。原因是我有很高的信心
“不要违反Protobufs的规则”是一个足够合理的约束。只要他们永远不会打破Protobufs的规则
我认为
他们的整个狗屎应该永远没事。

PS

请不要挑战我关于人际关系,分类,搜索,分析或您认为我没有考虑过的任何其他胡说八道。我已经是
考虑这些事情,并为如何管理每个事情(主要是与我之前提到的#ModelandFieldMacros一起使用)。如果你有
任何想法,想法或建设性的反馈,我总是向那些人开放。

如果可以用代码写入,则可以是指示代码变化x而不是代码变化y的纯文本注释。我也只是

认为值得注意的是,您可能担心的大多数功能,因为“这是您最喜欢的其他系统_____的部分”。 在这些地址上有东西“(又称“钥匙值存储”),所以...很好。我喜欢构建东西,知道还有更多工作要做。