|
|
|
@ -11,14 +11,136 @@
|
|
|
|
|
- [Differences from Ceph](#differences-from-ceph)
|
|
|
|
|
- [Implementation Principles](#implementation-principles)
|
|
|
|
|
|
|
|
|
|
## Server-side components
|
|
|
|
|
|
|
|
|
|
- **OSD** (Object Storage Daemon) is a process that directly works with the disk, stores data
|
|
|
|
|
and serves read/write requests. One OSD serves one disk (or one partition). OSDs talk to etcd
|
|
|
|
|
and to each other — they receive cluster state from etcd, and send read/write requests for
|
|
|
|
|
secondary copies of data to other OSDs.
|
|
|
|
|
- **etcd** — clustered key/value database, used as a reliable storage for configuration
|
|
|
|
|
and high-level cluster state. Etcd is the component that prevents splitbrain in the cluster.
|
|
|
|
|
Data blocks are not stored in etcd, etcd doesn't participate in data write or read path.
|
|
|
|
|
- **Монитор** — a separate node.js based daemon which monitors the cluster, calculates
|
|
|
|
|
required configuration changes and saves them to etcd, thus commanding OSDs to apply these
|
|
|
|
|
changes. Monitor also aggregates cluster statistics. OSD don't talk to monitor, monitor
|
|
|
|
|
only sends and receives data from etcd.
|
|
|
|
|
|
|
|
|
|
## Basic concepts
|
|
|
|
|
|
|
|
|
|
- OSD (Object Storage Daemon) is a process that stores data and serves read/write requests.
|
|
|
|
|
- PG (Placement Group) is a "shard" of the cluster, group of data stored on one set of replicas.
|
|
|
|
|
- Pool is a container for data that has equal redundancy scheme and placement rules.
|
|
|
|
|
- Monitor is a separate daemon that watches cluster state and handles failures.
|
|
|
|
|
- Failure Domain is a group of OSDs that you allow to fail. It's "host" by default.
|
|
|
|
|
- Placement Tree groups OSDs in a hierarchy to later split them into Failure Domains.
|
|
|
|
|
- **Pool** is a container for data that has equal redundancy scheme and disk placement rules.
|
|
|
|
|
- **PG (Placement Group)** is a "shard" of the cluster, subdivision unit that has its own
|
|
|
|
|
set of OSDs for data storage.
|
|
|
|
|
- **Failure Domain** is a group of OSDs, from the simultaneous failure of which you are
|
|
|
|
|
protected by Vitastor. Default failure domain is "host" (server), but you choose a
|
|
|
|
|
larger (for example, a rack of servers) or smaller (a single drive) failure domain
|
|
|
|
|
for every pool.
|
|
|
|
|
- **Placement Tree** (similar to Ceph CRUSH Tree) groups OSDs in a hierarchy to later
|
|
|
|
|
split them into Failure Domains.
|
|
|
|
|
|
|
|
|
|
## Client-side components
|
|
|
|
|
|
|
|
|
|
- **Client library** incapsulates client I/O logic. Client library connects to etcd and to all OSDs,
|
|
|
|
|
receives cluster state from etcd, sends read and write requests directly to all OSDs. Due
|
|
|
|
|
to the symmetric distributed architecture, all data blocks (each 128 KB by default) are placed
|
|
|
|
|
to different OSDs, but clients always knows where each data block is stored and connects directly
|
|
|
|
|
to the right OSD.
|
|
|
|
|
|
|
|
|
|
All other client-side components are based on the client library:
|
|
|
|
|
|
|
|
|
|
- **[vitastor-cli](../usage/cli.en.md)** — command-line utility for cluster management.
|
|
|
|
|
Allows to view cluster state, manage pools and images, i.e. create, modify and remove
|
|
|
|
|
virtual disks, their snapshots and clones.
|
|
|
|
|
- **[QEMU driver](../usage/qemu.en.md)** — pluggable QEMU module allowing QEMU/KVM virtual
|
|
|
|
|
machines work with virtual Vitastor disks directly from userspace through the client library,
|
|
|
|
|
without the need to attach disks as kernel block devices. However, if you want to attach
|
|
|
|
|
disks, you can also do that with the same driver and [VDUSE](../usage/qemu.en.md#vduse).
|
|
|
|
|
- **[vitastor-nbd](../usage/nbd.en.md)** — utility that allows to attach Vitastor disks as
|
|
|
|
|
kernel block devices using NBD (Network Block Device), which works more like "BUSE"
|
|
|
|
|
(Block Device In Userspace). Vitastor doesn't have Linux kernel modules for the same task
|
|
|
|
|
(at least by now). NBD is an older, non-recommended way to attach disks — you should use
|
|
|
|
|
VDUSE whenever you can.
|
|
|
|
|
- **[CSI driver](../installation/kubernetes.en.md)** — driver for attaching Vitastor images
|
|
|
|
|
as Kubernetes persistent volumes. Works through VDUSE (when available) or NBD — images are
|
|
|
|
|
attached as kernel block devices and mounted into containers.
|
|
|
|
|
- **Drivers for Proxmox, OpenStack and so on** — pluggable modules for corresponding systems,
|
|
|
|
|
allowing to use Vitastor as storage in them.
|
|
|
|
|
- **[vitastor-nfs](../usage/nfs.en.md)** — NFS 3.0 server allowing export of two file system variants:
|
|
|
|
|
the first is a simplified pseudo-FS for file-based access to Vitastor block images (for non-QEMU
|
|
|
|
|
hypervisors with NFS support), the second is **VitastorFS**, full-featured clustered POSIX FS.
|
|
|
|
|
Both variants support parallel access from multiple vitastor-nfs servers. In fact, you are
|
|
|
|
|
not required to setup separate NFS servers at all and use vitastor-nfs mount command on every
|
|
|
|
|
client node — it starts the NFS server and mounts the FS locally.
|
|
|
|
|
- **[fio driver](../usage/fio.en.md)** — pluggable module for fio disk benchmarking tool for
|
|
|
|
|
running performance tests on your Vitastor cluster.
|
|
|
|
|
- **vitastor-kv** — client for a key-value DB working over shared block volumes (usual
|
|
|
|
|
vitastor images). VitastorFS metadata is stored in vitastor-kv.
|
|
|
|
|
|
|
|
|
|
## Additional utilities
|
|
|
|
|
|
|
|
|
|
- **vitastor-disk** — утилита для разметки дисков под Vitastor OSD. С её помощью можно
|
|
|
|
|
создавать, удалять, менять размеры или перемещать разделы OSD.
|
|
|
|
|
|
|
|
|
|
## Общий процесс записи и чтения
|
|
|
|
|
|
|
|
|
|
- В Vitastor хранятся виртуальные диски, также называемые "образы" или "иноды".
|
|
|
|
|
- Каждый образ хранится в определённом пуле. Пул определяет параметры хранения образов в нём,
|
|
|
|
|
такие, как схему избыточности (репликация или EC — коды коррекции ошибок), домен отказа
|
|
|
|
|
и ограничения по выбору OSD для размещения данных образов. См. [Конфигурация пулов](../config/pool.ru.md).
|
|
|
|
|
- Каждый образ разбивается на объекты фиксированного размера, равного [block_size](../config/layout-cluster.ru.md#block_size)
|
|
|
|
|
(по умолчанию 128 КБ), умноженному на число частей данных для EC или на 1 для реплик.
|
|
|
|
|
То есть, например, если в пуле используется схема кодирования 4+2 (4 части данных + 2 чётности),
|
|
|
|
|
то при стандартном block_size образы разбиваются на части по 512 КБ.
|
|
|
|
|
- Клиентские запросы чтения/записи разделяются на части, соответствующие этим объектам.
|
|
|
|
|
- Для каждого объекта определяется номер PG, которой он принадлежит, путём простого взятия
|
|
|
|
|
остатка от деления ID образа и смещения на число PG в пуле, которому принадлежит образ.
|
|
|
|
|
- Клиент читает информацию о первичном OSD всех PG из etcd. Первичный OSD каждой PG назначается
|
|
|
|
|
монитором в процессе работы кластера, вместе с текущим целевым набором OSD этой PG.
|
|
|
|
|
- Клиент соединяется (если ещё не соединён) с первичными OSD всех PG, объекты которых участвуют
|
|
|
|
|
в запросе и одновременно отправляет им запросы чтения/записи частей.
|
|
|
|
|
- Если какие-то из первичных OSD недоступны, клиент повторяет попытки соединения бесконечно до
|
|
|
|
|
тех пор, пока они не станут доступны или пока PG не будут назначены другие первичные OSD.
|
|
|
|
|
- Клиент также повторяет запросы, если первичные OSD отвечают кодом ошибки EPIPE, означающим,
|
|
|
|
|
что запрос не может быть обработан в данный момент. Это происходит, если PG либо не активна
|
|
|
|
|
вообще, либо не активна на данном OSD в данный момент (например, если в этот момент меняется
|
|
|
|
|
её первичный OSD) или если в процессе обработки запроса сам первичный OSD теряет подключение
|
|
|
|
|
к репликам.
|
|
|
|
|
- Первичный OSD определяет, на каких OSD находятся части объекта. По умолчанию все объекты
|
|
|
|
|
считаются находящимися на текущем целевом наборе OSD соответствующей PG, но какие-то могут
|
|
|
|
|
находиться на других OSD, если эти объекты деградированы или перемещены, или идёт процесс
|
|
|
|
|
ребаланса. Запросы для проверки по сети не отправляются, информация о местоположении всех
|
|
|
|
|
объектов рассчитывается первичным OSD при активации PG и хранится в памяти.
|
|
|
|
|
- Первичный OSD соединяется (если ещё не соединён) с вторичными OSD, на которых располагаются
|
|
|
|
|
части объекта, и отправляет им запросы чтения/записи, а также читает/пишет из/в своё локальное
|
|
|
|
|
хранилище, если сам входит в набор.
|
|
|
|
|
- После завершения всех вторичных операций чтения/записи первичный OSD отправляет ответ клиенту.
|
|
|
|
|
|
|
|
|
|
### Особенности обработки запросов
|
|
|
|
|
|
|
|
|
|
- Если в пуле используются коды коррекции ошибок и при этом часть OSD недоступна, первичный
|
|
|
|
|
OSD при чтении восстанавливает данные из оставшихся частей.
|
|
|
|
|
- Каждый объект имеет номер версии. При записи объекта первичный OSD сначала читает из номер
|
|
|
|
|
версии объекта. Так как первичный OSD обычно сам хранит копию или часть объекта, номер
|
|
|
|
|
версии обычно читается из памяти самого OSD. Однако, если ни одна часть обновляемого объекта
|
|
|
|
|
не находится на первичном OSD, для получения номера версии он обращается к одному из вторичных
|
|
|
|
|
OSD, на которых копия объекта есть. Обращения к диску при этом всё равно не происходит,
|
|
|
|
|
так как метаданные объектов, включая номер версии, все OSD хранят в памяти.
|
|
|
|
|
- Если в пуле используются коды коррекции ошибок, перед частичной записью объекта для вычисления
|
|
|
|
|
чётности зачастую требуется чтение частей объекта с вторичных OSD или с локального диска
|
|
|
|
|
самого первичного OSD.
|
|
|
|
|
- Также, если в пуле используются коды коррекции ошибок, для закрытия Write Hole применяется
|
|
|
|
|
двухфазный алгоритм записи: сначала на все вторичные OSD записывается новая версия частей
|
|
|
|
|
объекта, но при этом старая версия не удаляется, а потом, после получения подтверждения
|
|
|
|
|
успешной записи от всех вторичных OSD, новая версия фиксируется и разрешается удаление старой.
|
|
|
|
|
- Если в кластере не включён режим immediate_commit, то запросы записи, отправляемые клиентами,
|
|
|
|
|
не считаются зафиксированными на физических накопителях сразу. Для фиксации данных клиенты
|
|
|
|
|
должны отдельно отправлять запросы SYNC (отдельный от чтения и записи вид запроса),
|
|
|
|
|
а пока такой запрос не отправлен, считается, что записанные данные могут исчезнуть,
|
|
|
|
|
если соответствующий OSD упадёт. Поэтому, когда режим immediate_commit отключён, все
|
|
|
|
|
запросы записи клиенты копируют в памяти и при потере соединения и повторном соединении
|
|
|
|
|
с OSD повторяют из памяти. Скопированные в память данные удаляются при успешном fsync,
|
|
|
|
|
а чтобы хранение этих данных не приводило к чрезмерному потреблению памяти, клиенты
|
|
|
|
|
автоматически выполняют fsync каждые [client_dirty_limit](../config/network.ru.md#client_dirty_limit)
|
|
|
|
|
записанных байт.
|
|
|
|
|
|
|
|
|
|
## Similarities to Ceph
|
|
|
|
|
|
|
|
|
|