๐ ํด์+ํด์ ํํฐ์ ๋+์ค๋ฉ
14903 ๋จ์ด yugabytedbdatabasesqldistributed
PostgreSQL์๋ ํด์ ๋ถํ ๋ ์์ง๋ง ์ฃผ์ ๋ชฉํ๊ฐ ๋ฐฐํฌ์ด๊ธฐ ๋๋ฌธ์ YugabyteDB์์ ์ฌ์ฉํ์ง ์์ ์ ์์ต๋๋ค. ์ด๋ ๋ ๋ง์ ํํฐ์ , ์๋ ์ฌ์กฐ์ , ๊ธ๋ก๋ฒ ์ธ๋ฑ์ค ๋ฑ ํ๋ธ๋ฆฟ์ผ๋ก ์ค๋ฉํ๋ ๊ฒ์ด ๋ ์ข์ต๋๋ค.
ํ์ง๋ง ํด์ ํํฐ์ ๋๊ณผ ํด์ ์ค๋ฉ์ด ํ์ํ๋ค๊ณ ์๊ฐ๋๋ฉด ์ ๋ ์ ๋๋ค๊ณ ๋งํ์ง ๋ง์ญ์์ค. ํด์ฑ ๋ฐฉ๋ฒ์ด ๋ถ์ฐ ๋ฐ์ดํฐ์ ํจ๊ป ์ ์๋ํ๋์ง ํ์ธํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ ํํฐ์ ๋ด์์ ํ๋ธ๋ฆฟ์ผ๋ก์ ์ค๋ฉ์ด ๊ท ํ์ ์ด๋ฃจ๊ธฐ๋ฅผ ์ํฉ๋๋ค. ํ ๊ฐ์ง ๋ฐฉ๋ฒ์ ์๊ณ ๋ฆฌ์ฆ์ ๋ณด๋ ๊ฒ์ ๋๋ค. ๋ค๋ฅธ ํ๋๋ ํน์ ๋ฐ์ดํฐ ์ ํ๋ง ํ ์คํธํ๋ ๊ฒ์ ๋๋ค.
์ฌ๊ธฐ์๋
n
ํํฐ์
์ด ์๋ ํ
์ด๋ธ์ ๋ง๋ค๊ณ ๋ฐฑ๋ง ๊ฐ์ ํ์ผ๋ก ์ฑ์ฐ๊ณ YugabyteDB ํด์ ํจ์์ธ ๊ฐ๊ฐ์ yb_hash_code()
๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.์ด๊ฒ์ ๋ด๊ฐ ์คํํ ์คํฌ๋ฆฝํธ์ด๋ฉฐ 1๊ฐ์์ 50๊ฐ ํํฐ์ ๊น์ง ์ด ์์ ์ ์ํํฉ๋๋ค.
c=1000000
for n in {1..50} ; do
echo "
$n Partitions, $c rows:"
{
cat <<SQL
drop table demo;
create extension if not exists pgcrypto;
create table demo (id uuid default gen_random_uuid(), val int) partition by hash(id);
SQL
for i in $(seq 0 $(( $n -1 ))) ; do
cat <<SQL
create table demo$i partition of demo for values with (modulus $n , remainder $i);
SQL
done
cat <<SQL
insert into demo ( val) select generate_series(1,$c);
SQL
for i in $(seq 0 $(( $n -1 ))) ; do
cat <<SQL
select format('Partition %s / %s : min= %s max= %s -> %s %% rows',to_char($i,'99'),to_char($n,'99'),min(yb_hash_code(id)),max(yb_hash_code(id)),100*count(*)/$c) from demo$i;
SQL
done
} | psql -p 5433
done | grep Partition | tee hash-hash.log
๊ฒฐ๊ณผ:
1 Partitions, 1000000 rows:
Partition 0 / 1 : min= 0 max= 65535 -> 100 % rows
2 Partitions, 1000000 rows:
Partition 0 / 2 : min= 0 max= 65535 -> 49 % rows
Partition 1 / 2 : min= 0 max= 65535 -> 50 % rows
3 Partitions, 1000000 rows:
Partition 0 / 3 : min= 0 max= 65535 -> 33 % rows
Partition 1 / 3 : min= 0 max= 65535 -> 33 % rows
Partition 2 / 3 : min= 0 max= 65535 -> 33 % rows
4 Partitions, 1000000 rows:
Partition 0 / 4 : min= 0 max= 65535 -> 25 % rows
Partition 1 / 4 : min= 0 max= 65535 -> 24 % rows
Partition 2 / 4 : min= 0 max= 65535 -> 24 % rows
Partition 3 / 4 : min= 0 max= 65535 -> 24 % rows
5 Partitions, 1000000 rows:
Partition 0 / 5 : min= 0 max= 65535 -> 19 % rows
Partition 1 / 5 : min= 0 max= 65535 -> 20 % rows
Partition 2 / 5 : min= 0 max= 65535 -> 20 % rows
Partition 3 / 5 : min= 0 max= 65535 -> 19 % rows
Partition 4 / 5 : min= 0 max= 65535 -> 20 % rows
6 Partitions, 1000000 rows: [183/1982]
Partition 0 / 6 : min= 0 max= 65535 -> 16 % rows
Partition 1 / 6 : min= 0 max= 65535 -> 16 % rows
Partition 2 / 6 : min= 0 max= 65535 -> 16 % rows
Partition 3 / 6 : min= 0 max= 65535 -> 16 % rows
Partition 4 / 6 : min= 0 max= 65535 -> 16 % rows
Partition 5 / 6 : min= 0 max= 65534 -> 16 % rows
7 Partitions, 1000000 rows:
Partition 0 / 7 : min= 0 max= 65535 -> 14 % rows
Partition 1 / 7 : min= 0 max= 65535 -> 14 % rows
Partition 2 / 7 : min= 0 max= 65535 -> 14 % rows
Partition 3 / 7 : min= 0 max= 65535 -> 14 % rows
Partition 4 / 7 : min= 0 max= 65535 -> 14 % rows
Partition 5 / 7 : min= 0 max= 65535 -> 14 % rows
Partition 6 / 7 : min= 0 max= 65534 -> 14 % rows
8 Partitions, 1000000 rows:
Partition 0 / 8 : min= 2 max= 65535 -> 12 % rows
Partition 1 / 8 : min= 0 max= 65535 -> 12 % rows
Partition 2 / 8 : min= 0 max= 65535 -> 12 % rows
Partition 3 / 8 : min= 0 max= 65535 -> 12 % rows
Partition 4 / 8 : min= 0 max= 65535 -> 12 % rows
Partition 5 / 8 : min= 0 max= 65535 -> 12 % rows
Partition 6 / 8 : min= 0 max= 65535 -> 12 % rows
Partition 7 / 8 : min= 0 max= 65535 -> 12 % rows
...
50 Partitions, 1000000 rows:
Partition 0 / 50 : min= 2 max= 65534 -> 1 % rows
Partition 1 / 50 : min= 2 max= 65531 -> 2 % rows
Partition 2 / 50 : min= 5 max= 65527 -> 1 % rows
Partition 3 / 50 : min= 3 max= 65534 -> 2 % rows
Partition 4 / 50 : min= 2 max= 65532 -> 2 % rows
Partition 5 / 50 : min= 0 max= 65530 -> 1 % rows
Partition 6 / 50 : min= 6 max= 65534 -> 2 % rows
Partition 7 / 50 : min= 0 max= 65526 -> 2 % rows
Partition 8 / 50 : min= 3 max= 65535 -> 2 % rows
Partition 9 / 50 : min= 3 max= 65535 -> 1 % rows
Partition 10 / 50 : min= 4 max= 65534 -> 1 % rows
Partition 11 / 50 : min= 2 max= 65535 -> 1 % rows
Partition 12 / 50 : min= 2 max= 65533 -> 2 % rows
Partition 13 / 50 : min= 0 max= 65535 -> 1 % rows
Partition 14 / 50 : min= 14 max= 65529 -> 2 % rows
Partition 15 / 50 : min= 0 max= 65530 -> 1 % rows
Partition 16 / 50 : min= 0 max= 65535 -> 2 % rows
Partition 17 / 50 : min= 4 max= 65528 -> 1 % rows
Partition 18 / 50 : min= 1 max= 65533 -> 1 % rows
Partition 19 / 50 : min= 6 max= 65532 -> 1 % rows
Partition 20 / 50 : min= 0 max= 65533 -> 2 % rows
Partition 21 / 50 : min= 0 max= 65535 -> 1 % rows
Partition 22 / 50 : min= 4 max= 65534 -> 2 % rows
Partition 23 / 50 : min= 1 max= 65529 -> 2 % rows
Partition 24 / 50 : min= 2 max= 65530 -> 2 % rows
Partition 25 / 50 : min= 5 max= 65529 -> 2 % rows
Partition 26 / 50 : min= 3 max= 65518 -> 1 % rows
Partition 27 / 50 : min= 4 max= 65534 -> 1 % rows
Partition 28 / 50 : min= 0 max= 65529 -> 1 % rows
Partition 29 / 50 : min= 6 max= 65530 -> 2 % rows
Partition 30 / 50 : min= 7 max= 65522 -> 2 % rows
Partition 31 / 50 : min= 11 max= 65533 -> 2 % rows
Partition 32 / 50 : min= 2 max= 65534 -> 1 % rows
Partition 33 / 50 : min= 1 max= 65526 -> 2 % rows
Partition 34 / 50 : min= 3 max= 65535 -> 2 % rows
Partition 35 / 50 : min= 4 max= 65534 -> 2 % rows
Partition 36 / 50 : min= 2 max= 65534 -> 2 % rows
Partition 37 / 50 : min= 0 max= 65528 -> 1 % rows
Partition 38 / 50 : min= 2 max= 65532 -> 2 % rows
Partition 39 / 50 : min= 0 max= 65534 -> 2 % rows
Partition 40 / 50 : min= 1 max= 65527 -> 2 % rows
Partition 41 / 50 : min= 1 max= 65535 -> 1 % rows
Partition 42 / 50 : min= 0 max= 65535 -> 2 % rows
Partition 43 / 50 : min= 5 max= 65533 -> 2 % rows
Partition 44 / 50 : min= 7 max= 65533 -> 1 % rows
Partition 45 / 50 : min= 10 max= 65534 -> 2 % rows
Partition 46 / 50 : min= 2 max= 65534 -> 2 % rows
Partition 47 / 50 : min= 4 max= 65534 -> 1 % rows
Partition 48 / 50 : min= 1 max= 65526 -> 1 % rows
Partition 49 / 50 : min= 4 max= 65528 -> 2 % rows
๊ฐ ํํฐ์ ์๋ ์ค๋ฉ(ํด์ ์ฝ๋ ๋ฒ์ ๊ธฐ์ค)์ ์ฌ์ฉ๋๋ ์ ์ฒด ๋ฒ์์ ํด์ ์ฝ๋(0์์ 65535๊น์ง)๊ฐ ์์ผ๋ฉฐ ํํฐ์ ์ ๋ํ ํ ๋ถํฌ๋ ๊ท ํ์ด ์ ๋ง์ต๋๋ค.
ํํฐ์ ํ๋๋ฅผ ์ ํํ๊ณ yb_hash_code() ์ฌํํฐ์ ์ ์ดํด๋ด ๋๋ค.
yugabyte=#
select n,count(h) from (
select yb_hash_code(id) h,count(*) n
from demo42 group by yb_hash_code(id)
) x group by n order by n;
n | count
---+-------
1 | 14791
2 | 2216
3 | 233
4 | 18
5 | 3
(5 rows)
์ด ํํฐ์ ์ 20009์ ์๋ 14791๊ฐ์ ํ์ ๋ํด yb_hash_code()๋ ํ ํ์๋ง ๋งคํ๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ 5๊ฐ์ ํ์ ๋งคํ๋๋ yb_hash_codes()๋ 3๊ฐ๋ฟ์ ๋๋ค. ์ด๋ ํํฐ์ ์ด ์ด๋ฏธ ํด์ ๋ถํ ์ ๊ฒฐ๊ณผ์ธ ๊ฒฝ์ฐ์๋ ํํฐ์ ๋ด์์ ์ํธํ ๋ถํฌ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
๊ฐ ํํฐ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ฌ๊ธฐ์์ ์ด ํํฐ์ ์
yb_hash_code()
์ 3๊ฐ์ง ๋ฒ์์์ 3๊ฐ์ ์ ์ ๋ก ๋ถํ ๋ฉ๋๋ค. hash_split: [0x0000, 0x5555)
๋ 0์์ 21844๊น์ง, hash_split: [0x5555, 0xAAAA)
๋ 21845์์ 43689๊น์ง, hash_split: [0xAAAA, 0xFFFF]
๋ 43690์์ 65535๊น์ง์
๋๋ค. ๋ฐ์ดํฐ๊ฐ ๋ ๋ง์์๋ก ๋ ๋๋๋๋ค.ํด์ฑ ์๊ณ ๋ฆฌ์ฆ์ ๋งค์ฐ ๋ค๋ฆ ๋๋ค. PostgreSQL์ ๋ชจ๋๋ก ์จ ํด์ ๊ฐ์ ์ฌ์ฉํฉ๋๋ค. ์ด๋ฅผ ์ํด์๋ ํํฐ์ ์ ๊ฐ์๋ฅผ ์ฒ์๋ถํฐ ์๊ณ ์์ด์ผ ํฉ๋๋ค. YugabyteDB๋ ๋ฒ์๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ๋ ์ฝ๊ฒ ๋ถํ ํ ์ ์์ต๋๋ค. ์ฐจ์ด์ ์ ๋ํ ์ข์ ์ ๋ณด๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. https://ben.kirw.in/2018/12/02/hash-range-partitioning/
์์ฝํ๋ฉด Hash Partitioning + Hash Sharding์ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ฐ์ํค๋ ์ญํ ์ ํฉ๋๋ค. ํํฐ์ ํค์ ๋ฐ์ดํฐ ์ ํ์ ๋ํด ํ ์คํธํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ฐ์ฅ ์ค์ํ ๊ฒ์ ํ์ํ์ง ์์์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ํด์ ์ค๋ฉ๋ง์ผ๋ก๋ ์ถฉ๋ถํฉ๋๋ค. ํด์ ์ค๋ฉ์ ์ฌ์ฉํ๋ฉด ๋ง์ ํ๋ธ๋ฆฟ์ ๋ณด์ ํ ์ ์์ต๋๋ค. 65535 ํด์ ์ฝ๋ ๊ฐ๊ณผ recommended tablet count and size ์ ์ฌ์ฉํ์ฌ ๋งค์ฐ ํฐ ํ ์ด๋ธ์ ๋ฐฐํฌํ ์ ์์ต๋๋ค. ํ์ง๋ง ๊ทธ๋ ๊ฒ ์๊ฐํ์ ๋ค๋ฉด ์ ์ค ์ผ์ด์ค์ ๋ํด ์๊ณ ์ถ์ต๋๋ค.
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ ํด์+ํด์ ํํฐ์ ๋+์ค๋ฉ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://dev.to/yugabyte/hashhash-partitioningsharding-256aํ ์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค