0

我正在使用 GO 开发一种新型数据库。我想做的一件事是拥有一个分布式磁盘,这样我就可以在多台机器上分发查询(想想 Pi 类型的架构)。这意味着在原始磁盘上构建我自己的结构。

我的挑战是我找不到可以让我从指向结构的指针写入 N 个字节的 GO 包。所有的 IO 包都限制了对 []byte 切片的访问。

这对保护很好,但是如果我必须通过某种形式的编码通过字节数组缓冲所有内容,它将减慢对特定对象的访问速度。

有人对如何进行原始 IO 有任何想法吗?还是我将不得不将 GOB 作为我的 IO 单元来处理并遭受编码/解码的惩罚?

4

3 回答 3

3

首先是大警告:不要这样做:它既不安全也不便携

对于给定的结构,您可以对其进行反射以计算出实际结构的内存大小,然后不安全地将其强制转换为[]byteusing unsafe

例如:(*[in-mem size]byte)(unsafe.Pointer(&mystruct))

这会给你一些 C-ish,绝对没有安全保证或可移植性。

我将引用Go 规范

使用 unsafe 的包必须经过手动审查以确保类型安全,并且可能不可移植。

您可以在这篇Go 和内存布局文章中找到更多详细信息,包括将结构不安全地视为字节所需的所有步骤。

总体而言,在低级别检查 Go 的功能是很有趣的,但在您的情况下这样做绝对是错误的。任何真正的数据基础设施都需要比将内存结构转储到磁盘更复杂的存储逻辑方式。

于 2018-01-06T19:32:51.917 回答
2

通常,您不能对 Go 结构(即 memdump)进行原始 IO。这是因为 Go 中很多东西都包含指针,而实际数据在内存中并不连续。

例如,像这样的结构:

type Person struct {
    Name string
}

包含一个字符串,该字符串又包含一个指向字符串字节的指针。原始 memdump 只会转储指针。

解决方案是序列化。这从来都不是免费的,尽管有些实现做得很好。

与您所描述的最接近的是go-memdump,但我不建议将其用于生产。

否则,我建议查看高性能序列化技术。(Go 的 gob 编码并不是最好的。)

于 2018-01-06T20:46:42.277 回答
0

...或者我是否将不得不将 GOB 作为我的 IO 单元来处理并遭受编码/解码的惩罚?

只需使用 GOB。过早的优化是万恶之源。

于 2018-01-08T21:14:02.127 回答