/
uid.go
71 lines (58 loc) · 2.93 KB
/
uid.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/*
Copyright 2019 PlanetScale Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package vttablet
import (
"crypto/md5"
"encoding/binary"
"fmt"
planetscalev2 "planetscale.dev/vitess-operator/pkg/apis/planetscale/v2"
)
/*
UID deterministically generates a 32-bit unsigned integer that should uniquely
identify a given tablet within a Vitess cluster.
The tablet's identity is defined as the tuple (cell,keyspace,shard,pool,index).
Any such tuple must map to only one uint32 value (the same tuple always results
in the same integer), and there must be a negligible probability of accidental
collisions within a given Vitess cluster.
The approach we use here is to take the first 32 bits of a hash of those tuple
elements, which is essentially how YouTube did it. If we assume the first 32
bits of the hash fall in a uniform distribution, the probability of at least
one collision in a cluster with 1000 total tablets is about 0.0001. That means
we should expect to have one cluster experience a collision by the time we reach
10,000 clusters if each cluster has 1000 tablets. This should provide enough
lead time to develop a smarter way to handle tablet identity and MySQL server
IDs in Vitess itself.
WARNING: DO NOT change the behavior of this function, as that may result in
the deletion and recreation of all tablets.
*/
func UID(cellName, keyspaceName string, shardKeyRange planetscalev2.VitessKeyRange, tabletPoolType planetscalev2.VitessTabletPoolType, tabletIndex uint32) uint32 {
h := md5.New()
fmt.Fprintln(h, cellName, keyspaceName, shardKeyRange.String(), string(tabletPoolType), tabletIndex)
sum := h.Sum(nil)
return binary.BigEndian.Uint32(sum[:4])
}
/*
UIDWithPoolName function generates a 32-bit unsigned integer similar to the UID function above.
However, it additionally takes the poolName as an input.
This allows the generation of a unique UID for a tablet that belongs to a different pool
but shares other common attributes.
To preserve the existing UID, it is recommended to use the UID function instead of this function
when the poolName is set to its default value of an empty string.
*/
func UIDWithPoolName(cellName, keyspaceName string, shardKeyRange planetscalev2.VitessKeyRange,
tabletPoolType planetscalev2.VitessTabletPoolType, tabletName uint32, poolName string) uint32 {
h := md5.New()
fmt.Fprintln(h, cellName, keyspaceName, shardKeyRange.String(), string(tabletPoolType), tabletName, poolName)
sum := h.Sum(nil)
return binary.BigEndian.Uint32(sum[:4])
}