HP Vertica. K-Safety, Segmentation и Buddy Projection. Практический пример.

Одним из важных для понимания HP Vertica терминов является K-Safety. В этой статье я кратко объясню его суть и покажу как он влияет на хранение данных в БД.

K-Safety — это мера отказоустойчивости БД. Это число, которое определяет количество реплик оригинальных данных внутри кластера БД. В общем случае, если число сбойных нодов внутри кластера будет больше чем это число K, некоторые данные в кластере могут стать недоступными и БД автоматически остановит работу. Однако, в частном случае БД может продолжать работу и при большем количестве сбойных нодов.

Например, если K-Safety вашего кластера = 1 и в нем 6 нодов(1, 2, 3, 4, 5, 6), ноды 2, 4 и 6 могут быть недоступны, но кластер все равно продолжит работу, т.к. копии данных этих нодов будут на других нодах — 3, 5 и 1 соответственно. Это значит, что максимальное количество сбойных нодов при K-Safety = 1 может достигать половины в наилучшем случае и 2(K-Safety+1) в наихудшем.

Существует 3 значения K-Safety, которое поддерживает HP Vertica: 0, 1 и 2.
K-Safety = 0 означает что данные по-умолчанию не будут реплицироваться на соседние ноды, а кластер завершит работу при сбое любого из нодов.

Для распределения данных по кластерам используется их сегментация(Segmentation), а точнее сегментация проекций(Projection) в которых они находятся. Задача разработчика — подобрать такой список полей и/или такую функцию(например, хэш-функцию), благодаря которым данные равномерно распределятся по нодам кластера. HP Vertica рекомендует использовать встроенные функции HASH и MODULARHASH для этих целей.

Для обеспечения K-Safety > 0 создаются сообщные проекции(Buddy Projection). Проекции называются сообщными, если они имеют в себе одинаковые наборы полей и одинаковое выражение сегментации, но хранятся на разных нодах. Сообщные проекции позволяют создать те самые реплики, которые позволяют работать БД в выбранном режиме K-Safety.

Рассмотрим K-Safety, сегментацию, и сообщные проекции на практическом примере.
Дано: Кластер на 3-х нодах. K-Safety = 1.

Создадим простую таблицу.

create table test(n integer primary key);

Вообще, синтаксис создания таблицы позволяет включать в себя выражения влияющие на проекцию(order, hash, ksafe…), для того чтобы проекции создавались автоматически в момент создания таблицы, но в этом примере я создаю проекции вручную.

Далее создадим две сообщные проекции.

create projection p_test_b0 as
select n from test order by n
segmented by hash(n) all nodes;

create projection p_test_b1 as
select n from test order by n
segmented by hash(n) all nodes offset 1;

Во-первых, выбрано сегментирование по функции hash от поля n. Во-вторых, те же данные, которые хранятся в проекции p_test_b0 на текущем ноде, хранятся в проекции p_test_b1(создана с offset 1) на следующем ноде. Иными словами текущий нод содержит в сегменте проекции p_test_b1 данные предыдущего нода. Пока может быть не очень понятно, ниже покажу на рисунке.
Если захотите сделать опыт и создать только одну проекцию, получите ошибку =) Одной проекции недостаточно для обеспечения K-Safety = 1.
Здесь же отмечу, что выражение сортировки order by у сообщных проекций не обязательно должно совпадать. Благодаря этому вы сможете совместить приятное с полезным — обеспечить K-Safety и оптимизировать выполнение многообразных запросов, выполняемых в системе.

Вставим тестовые данные:

insert into test values(1);
insert into test values(2);
insert into test values(3);
insert into test values(4);
insert into test values(5);
insert into test values(6);
insert into test values(7);
insert into test values(8);
insert into test values(9);
insert into test values(10);

И посмотрим как они распределились по нодам:

select node_name, projection_name, row_count
from projection_storage 
where projection_name like 'p_test_b%'
order by node_name, projection_name;
v_antifraud_node0001 p_test_b0 1
v_antifraud_node0001 p_test_b1 4
v_antifraud_node0002 p_test_b0 5
v_antifraud_node0002 p_test_b1 1
v_antifraud_node0003 p_test_b0 4
v_antifraud_node0003 p_test_b1 5
репликация


Итак, имеем 10 строк. Благодаря хэш-функции данные в проекции p_test_b0 распределились следующим образом: 1 строка на ноде 1, 5 на ноде 2 и 4 на ноде 3. При этом благодаря параметру «offset 1» объявленному в проекции p_test_b1 данные, которые уже хранятся на текущем ноде, хранятся и на следующем.

Аналогичным образом можно было создать проекции для кластера с K-Safety = 2, создав при этом третью сообщную проекцию, и указав для неё желаемый offset, например 2. В случае с тремя нодами при K-Safety = 2 все данные хранились бы на всех нодах.

Надеюсь теперь вам понятен принцип, по которому распределяются данные внутри кластера в зависимости от K-Safety.

P.S: На деле проекции можно так же создавать на выбранных нодах, перечислив их номера в команде создания проекции. Также можно не создавать проекции по отдельности, а добавить при создании первой проекции параметр ksafe — вторая создастся автоматически.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *