Giriş
Vitess Youtube içinde Go programlama dili ile geliştirilmiş. Şeklen
şöyle.
Aslında vttablet MySQL sunucusundan farklı bir bilgisayar üzerinde de çalışabilir ancak bu çoğu zaman gereksiz.
Ne Zaman Kullanışlı
Veri tek bir MySQL sunucusuna sığmıyorsa birden fazla veri tabanını tek bir sunucu gibi kullanmak için çok kullanışlı.
Bileşenler
Bunlar şöyle
vttablet
vtgate
topo
Distributed key/value store
- Stores the state of vitess : schemas, shards, sharding scheme, tablets, roles etc.
- etcd/consul/zookeeper
- Small dataset, mostly cached by vtgate
cell
- A group of servers and network infrastructure
- A failure domain : isolated from failures in other cells
- Examples :
- a full data center
- a subset of data center, aka availability zone
- a Kubernetes cluster
keyspace
- logical database
- If no sharding, keyspace => single MySQL database
- If using sharding, keyspace => multiple MySQL databases (all with identical schema)
- In either case, a keyspace appears as a single database from the standpoint of the application
keyspace ID
- Interval to vitess, the application does not need to know anything about it
- Not stored, computed
Vschema
Shard'ın nasıl olacağını belirtir. Json dosyasıdır. SQL ile belirtilemediği için gerekir.
Vindex - Sharding Kullanıyorsak Gerekir
- A way to compute keyspace ID for any row in a table
- Vindex for a table is defined by
- Column name
- Sharding function name
Açıklaması
şöyle. Yani kısaca hangi shard'e erişilmesi gerektiğini belirtir.
A VIndex is Vitess’ concept of a distributed index. Much as a database index uses information within the query to find the row you’re looking for efficiently, a VIndex uses that same information to find the correct shard.
Another interesting problem was VIndexes didn’t support NULL fields.
Lookup VIndex - Sharding Kullanıyorsak Gerekir
A Lookup VIndex is a special VIndex that’s backed by a database table and intended to solve this very problem. The way it works is quite simple: the eggs table would be configured at the Vitess level to have a Lookup VIndex, let’s call it eggs_egg_id_lookup. This would correspond to a table that has an egg_id and dino_id column. Now whenever the eggs table is changed, the lookup table will be updated to have the appropriate pair of fields. Now, when you perform your query, Vitess knows that there’s a VIndex on the eggs tables’ egg_id column and will consult it to find the dino_id associated with it.
Sharding functions
- binary
- numeric
- numeric_static_map
- unicode_loose_md5 - text, varchar sütun için
kullanılır- reverse_bits
Shard'ın farklı cell'lerde olması tercih edilir
CREATE TABLE
Açıklaması
şöyle. Yani tüm vtablet'lere dağıtılır
Use the standard MySQL CREATE TABLE syntax. The query goes through the same migration flow as ALTER TABLE does. The tablets eventually run the query directly on the MySQL backends.
Örnek - Unsharded Table
CREATE TABLE name_user_idx(name VARCHAR(128), user_id BIGINT, PRIMARY KEY(name, user_id));
VSchema için şöyle
yaparız. Burada sharded false deniliyor ve tablo isimleri sıralanıyor
{
"sharded": false,
"tables": {
"name_user_idx": {}
}
}
Örnek - Sharded Table
CREATE TABLE user(user_id BIGINT,name VARCHAR(128), PRIMARY KEY(user_id));
VSchema için şöyle
yaparız. Burada sharded true deniliyor ve vindex isimleri sıralanıyor. vindex hangi sharding metodunun kullanılacağını belirtir. Daha sonra tablolar belirtiliyor ve column_vindexes ile hangi sütunun hangi vindex ile eşleceği belirtiliyor.
{
"sharded": true,
"vindexes": {
"hash": {
"type": "hash"
}
},
"tables": {
"user": {
"column_vindexes": [
{
"column": "user_id",
"name": "hash"
}
]
}
}
}
Helm
Sequence
vttablet için açıklama
şöyleIf a select next... is received, the sequence specific functionality will be triggered.
Her sequence için bir tablo yaratılır. Sequence tabloları unsharded olmak zorundadır.
Örnek
CREATE TABLE customer_seq(id BIGINT, next_id BIGINT, cache BIGINT, PRIMARY KEY(id))
COMMENT 'vitess_sequence';
INSERT INTO customer_seq(id, next_id, cache) VALUES(0, 1, 3);
Note the special comment vitess_sequence. This instructs vttablet that this is a special table.
The table needs to be pre-populated with a single row where:
- id must always be 0
- next_id should be set to the next (starting) value of the sequence
- cache is the number of values to cache before updating the table for the next value. This value should be set to a fairly large number like 1000. We have set the value to 3 mainly to demonstrate how the feature works.
- İlk sütun niye hep 0 anlamadım.
- İkinci sütun başlangıç değeri,
- Üçüncü sütun ise sanırım bir seferde kaç tane değer çekileceğini belirtir. Böylece bazı değerler önceden ayrılabilir.
- Sequence için cycle özelliğini tanımlamak sanırım mümkün değil.
vchema.json dosyasında sequence tanımlamak için şöyle
yaparız{
"sharded": false,
"tables": {
"product": {},
"customer_seq": { "type": "sequence" },
"corder_seq": { "type": "sequence" },
"corder_event_seq": { "type": "sequence" },
"corder_keyspace_idx": {}
}
}
Since this is a special table, we have to inform the vschema by giving it a sequence type.
"customer_seq": { "type": "sequence" }
vchema.json dosyasında sequence kullanmak için şöyle
yaparız{
"sharded": true,
"vindexes": {
...
},
"tables": {
"customer": {
"column_vindexes": [{
"column": "customer_id",
"name": "hash"
}],
"auto_increment": {
"column": "customer_id",
"sequence": "product.customer_seq"
}
},
...
}
}
}
Eğer SQL ile sequence değerini çekmek istersek şöyle
yaparızSELECT NEXT VALUE FROM customer_seq;
Bir diğer farklı kullanım
şöyle/* Returns the next value for the sequence */
SELECT NEXT VALUE FROM my_sequence;
/* Returns the next value for the sequence, and also reserve 4 values after that. */
SELECT NEXT 5 VALUEs FROM my_sequence;
Örnek
Sharded keyspace içinde 3 tane tablo
olsunCREATE TABLE `puppers` (
`id` bigint(22) NOT NULL,
`name` varchar(256) DEFAULT NULL,
`image` varchar(256) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
CREATE TABLE `ratings` (
`id` bigint(22) DEFAULT NULL,
`user_id` bigint(22) DEFAULT NULL,
`rating` bigint(20) DEFAULT NULL,
`pupper_id` bigint(22) DEFAULT NULL,
KEY `pupper_id` (`pupper_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
CREATE TABLE `users` (
`id` bigint(22) NOT NULL,
`email` varchar(64) DEFAULT NULL,
`password` varbinary(256) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
Bu tablolar için json dosyası verelim ve kullanılacak sequence'ları belirtelim. Şöyle
yaparız{
"sharded": true,
"vindexes": {
"binary_md5_vdx": { "type": "binary_md5" },
"hash_vdx": { "type": "hash" }
},
"tables": {
"puppers": {
"columnVindexes": [{ "column": "id", "name": "hash_vdx" }],
"autoIncrement": { "column": "id", "sequence": "pupper_seq" }
},
"ratings": {
"columnVindexes": [{ "column": "pupper_id", "name": "hash_vdx" }],
"autoIncrement": { "column": "id", "sequence": "rating_seq" }
},
"users": {
"columnVindexes": [{ "column": "id", "name": "binary_md5_vdx" }]
}
}
}
CREATE TABLE IF NOT EXISTS pupper_seq (
id INT,
next_id BIGINT,
cache BIGINT,
PRIMARY KEY(id)
) comment 'vitess_sequence';
INSERT INTO pupper_seq (id, next_id, cache) VALUES (0, 1, 3);
CREATE TABLE IF NOT EXISTS rating_seq (
id INT,
next_id BIGINT,
cache BIGINT,
PRIMARY KEY(id)
) comment 'vitess_sequence';
INSERT INTO rating_seq (id, next_id, cache) VALUES (0, 1, 3);
Sequence için kullanılacak keyspace unsharded tanımlanmalı. Şöyle
yaparız{
"sharded": false,
"tables": {
"pupper_seq": {
"type": "sequence"
},
"rating_seq": {
"type": "sequence"
}
}
}