gpt4 book ai didi

mysql - Pinterests 使用位操作来创建全局 ID 以在 MySQL 上对其数据进行分片的原因是什么?它是如何工作的?

转载 作者:行者123 更新时间:2023-11-29 01:50:12 25 4
gpt4 key购买 nike

我正在阅读一篇关于 Pinterest 如何通过跨多个服务器和这些服务器中的数据库共享数据来设法使用 MySQL 进行扩展的文章。

我遇到的一个问题是他们如何通过位操作创建他们的全局 ID。

我理解运算符如何喜欢 & 和 |作品。而且我了解左移 << 和右移 >> 的工作原理。但我不明白他们在这个例子中是如何一起工作的。

文章中说:

https://medium.com/@Pinterest_Engineering/sharding-pinterest-how-we-scaled-our-mysql-fleet-3f341e96ca6f

We created a 64 bit ID that contains the shard ID, the type of the containing data, and where this data is in the table (local ID). The shard ID is 16 bits, type ID is 10 bits and local ID is 36 bits. The savvy additionology experts out there will notice that only adds to 62 bits. My past in compiler and chip design has taught me that reserve bits are worth their weight in gold. So we have two (set to zero).

因此分片ID为16位,最大值为65536 - 1,类型ID为10位,最大值为1024 - 1,本地ID为36位,最大值为68719476736 - 1。

最后一句是什么意思?

My past in compiler and chip design has taught me that reserve bits are worth their weight in gold. So we have two (set to zero).

下一行向我们展示了一种获取 64 位 ID 的方法:

ID = (shard ID << 46) | (type ID << 36) | (local ID<<0)

我很难理解这一点。为什么分片 ID 左移 46?为什么类型 ID 左移 36 位,本地 ID 左移 0 位,为什么我们在所有这些之间使用 OR?

下一部分是他们从全局 ID 241294492511762325 中提取本地 ID、类型 ID 和本地 ID:

Shard ID = (241294492511762325 >> 46) & 0xFFFF = 3429
Type ID = (241294492511762325 >> 36) & 0x3FF = 1
Local ID = (241294492511762325 >> 0) & 0xFFFFFFFFF = 7075733

所以这里他们做相反的事情,他们向右移动,与原来的左移相同的量,我不知道为什么要移动这些量,但我可以看到模式。但是现在他们用一些十六进制数来做&,这个我也不明白。

我正在尝试学习如何在 MySQL 中手动分片数据,如果我能理解他们为什么这样做的逻辑以及它是如何工作的,那就太好了。我明白 & 和 | 有多简单<< 和 >> 运算符起作用,我是通过阅读这篇文章了解到的:

https://code.tutsplus.com/articles/understanding-bitwise-operators--active-11301

但我不明白这一切是如何协同工作的,我不明白他们为什么使用那些移动的数字,以及为什么他们在末尾使用 & 和十六进制数字。

如果我能理解这个就好了。

最佳答案

Next line shows us a way to get a 64 bit ID:

ID = (shard ID << 46) | (type ID << 36) | (local ID<<0)

I am struggling to understand this. Why is the shard ID left shifted by 46? And why is the type ID left shifted by 36 and why is the local ID left shifted by 0, and why do we have an OR between all of these?

所以重申一下:

  • 本地ID:36位
  • 类型ID:10位
  • 分片ID:16位

完整 ID 包含顺序为“分片、类型、本地”的 ID。由于本地 ID 有 36 位,因此您必须将类型 ID 移动 36 位。类型 ID 有 10 位,因此您必须将类型 ID 额外移动 10 位(本地 ID 的 36 位 + 类型 ID 的 10 位)。

按位或 (|) 会将所有位设置为 1,这些位至少在一个操作数中设置为 1。

例如:

shard ID = 0b                         1011_1100_1001_0010
type ID = 0b 11_1010_0110
local ID = 0b1010_0100_1111_1101_1110_0011_1000_0000_0111

如果将这些值移动指定的位,则:

shard ID << 46 = 0b10_1111_0010_0100_1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000
type ID << 36 = 0b 11_1010_0110_0000_0000_0000_0000_0000_0000_0000_0000_0000
local ID << 0 = 0b 1010_0100_1111_1101_1110_0011_1000_0000_0111

如果你用 OR 那,你会得到结果:

  0b10_1111_0010_0100_1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000
| 0b 11_1010_0110_0000_0000_0000_0000_0000_0000_0000_0000_0000
| 0b 1010_0100_1111_1101_1110_0011_1000_0000_0111
= 0b10_1111_0010_0100_1011_1010_0110_1010_0100_1111_1101_1110_0011_1000_0000_0111

要再次提取 ID,您必须使用按位 AND (&) 运算符应用位掩码。它与 OR 运算符相反:只有当两个操作数都设置了该位时,它才会将位设置为 1。所以以你的例子为例:

Type ID = (241294492511762325 >> 36) & 0x3FF = 1

让我们先转换为二进制,以便运算符及其操作数的依赖关系变得清晰:

0b11_0101_1001_0100_0000_0001_0000_0000_0000_0110_1011_1111_0111_1001_0101

右移 36 位:

0b                                             11_0101_1001_0100_0000_0001

应用 10 位的位掩码 (0x3FF = 0b11_1111_1111):

  0b11_0101_1001_0100_0000_0001
& 0b 11_1111_1111
= 0b 00_0000_0001

用十进制表示法,也是 1。

关于mysql - Pinterests 使用位操作来创建全局 ID 以在 MySQL 上对其数据进行分片的原因是什么?它是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47296264/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com