# Radix

В данном разделе приведены сведения о Radix, плагине для СУБД Picodata.

!!! tip "Picodata Enterprise"
    Функциональность плагина доступна только в коммерческой версии Picodata.

## Общие сведения {: #intro }

Radix — реализация [Redis](https://ru.wikipedia.org/wiki/Redis) на базе
Picodata, предназначенная для замены существующих инсталляций Redis.

Плагин Radix состоит из одноименного сервиса (`radix`), реализующего
Redis на базе СУБД Picodata. Каждый экземпляр Radix открывает еще один
порт для подключения в дополнение к уже открытым.

При использовании Picodata c плагином Radix нет необходимости в
отдельной инфраструктуре Redis Sentinel, так как каждый узел Picodata
выполняет роль прокси ко всем данным Redis.

## Установка {: #install }

### Предварительные действия {: #prerequisites }

Установка плагина Radix, в целом, соответствует общей процедуре
установки плагинов в Picodata, но имеет ряд особенностей.
<!-- вставить ссылку на туториал по плагинам, когда он будет залит -->

Процедура установки включает:

- установку адреса, который будет слушать Radix (например, `export
  RADIX_ADDR=0.0.0.0:7379`). Эта настройка также доступна для
  инвентарного файла Ansible (см. [ниже](#addr))
- установку у [тиров][tier], на которые предполагается развернуть
  плагин, 16384 [бакетов]. См. описание [bucket_count] и
  [default_bucket_count].
- запуск инстанса Picodata с поддержкой плагинов (параметр [`--share-dir`])
- распаковку архива Radix в директорию, указанную на предыдущем шаге
- подключение к [административной консоли][admin_console] инстанса
- выполнение SQL-команд для регистрации плагина, привязки его сервиса к [тиру][tier],
  выполнения миграции, включения плагина в кластере

[`--share-dir`]: ../reference/cli.md#run_share_dir
[admin_console]: ../tutorial/connecting.md#admin_console
[tier]: ../overview/glossary.md#tier
[бакетов]: ../overview/glossary.md#bucket
[bucket_count]: ../reference/config.md#cluster_tier_tier_bucket_count
[default_bucket_count]: ../reference/config.md#cluster_default_bucket_count

### Подключение плагина {: #plugin_enable }

Для подключение плагина последовательно выполните следующие SQL-команды
в административной консоли Picodata:


Для создания плагина в кластере и регистрации его сервиса на доступных тирах:

```sql title="В примере использованы два тира: `default` и `extra`"
CREATE PLUGIN radix 0.5.2;
ALTER PLUGIN radix 0.5.2 ADD SERVICE radix TO TIER default;
ALTER PLUGIN radix 0.5.2 ADD SERVICE radix TO TIER extra;
```

Для настройки миграций задайте значения для 16 параметров (по числу баз данных в Radix):

```sql
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_0='default';
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_1='default';
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_2='default';
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_3='default';
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_4='default';
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_5='default';
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_6='default';
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_7='default';
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_8='extra';
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_9='extra';
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_10='extra';
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_11='extra';
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_12='extra';
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_13='extra';
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_14='extra';
ALTER PLUGIN radix 0.5.2 SET migration_context.tier_15='extra';
```

Для выполнения миграции:

```sql
ALTER PLUGIN radix MIGRATE TO 0.5.2 OPTION(TIMEOUT=300);
```

Для включения плагина в кластере:

```sql title="Убедитесь, что задан адрес, который будет слушать Radix"
ALTER PLUGIN radix 0.5.2 ENABLE OPTION(TIMEOUT=30);
```

Чтобы убедиться в том, что плагин успешно добавлен и запущен, выполните запрос:

```sql
SELECT * FROM _pico_plugin;
```

В строке, соответствующей плагину Radix, в колонке `enabled` должно быть значение `true`.

## Настройка {: #configuration }

Для настройки плагина используйте файл конфигурации, который можно
применить к плагину с помощью [Picodata Pike] или [инвентарного файла
Ansible].

Пример файла конфигурации:

```yaml
addr: 0.0.0.0:7301 # адрес, который будет слушать Radix
clients:           # ограничения клиентских соединений
    max_clients: 10000
    max_input_buffer_size: 1073741824
    max_output_buffer_size: 1073741824
cluster_mode: true # какой флаг отдавать в команде `info cluster`
```

[Picodata Pike]: ../tutorial/create_plugin.md#pike_plugin_config_apply
[инвентарного файла Ansible]: ../tutorial/deploy_ansible.md#plugin_management

Для изменения доступны следующие параметры:

### addr

Адрес, по которому Radix откроет сокет и будет его слушать.

Имейте ввиду, что данные параметры одинаковы для всех узлов Picodata, на
которых развернут Radix. Следовательно, если у вас процессы не
изолированы каждый в своем сетевом пространстве имен (т.е. не
используется Docker или K8S), то вам надо отдельно для каждого узла
прописать переменную окружения `RADIX_ADDR` для того, чтобы не было
конфликтов по портам.

### clients

#### max_clients

Максимальное количество клиентов, которые могут подключиться к одному
узлу Radix. При достижении максимального числа `max_clients` новые
соединения будут отклоняться, пока количество клиентов не станет снова
меньше `max_clients`. Отклоненные соединения увеличивают счетчик метрики
`rejected_connections` (пока доступна только через `INFO STATS`).

#### max_input_buffer_size

Максимальный размер входящего буфера. Если данный параметр у соединения
будет превышен, то соединение будет закрыто. Закрытые по этой причине
соединения увеличивают счетчик метрики
`client_query_buffer_limit_disconnections` (пока доступна только через
`INFO STATS`).

#### max_output_buffer_size

Максимальный размер исходящего буфера. Если данный параметр у соединения
будет превышен, то соединение будет закрыто. Закрытые по этой причине
соединения увеличивают счетчик метрики
`client_output_buffer_limit_disconnections` (пока доступна только через
`INFO STATS`).

## Использование {: #usage }

В консоли для общения с Redis используется клиентская программа
`redis-cli.` Для подключения к инстансу Picodata по протоколу Redis
используйте адрес, заданный ранее в переменной `RADIX_ADDR`:

```shell
redis-cli -p 7379
```

## Поддерживаемые команды {: #supported_commands }

### Управление кластером {: #cluster_management }

#### ping

```sql
PING [message]
```

Возвращает `PONG`, если аргумент не указан, в противном случае
возвращает строкой аргумент, который пришел. Эта команда полезна для:

- проверки того, живо ли еще соединение
- проверки способности сервера обслуживать данные — ошибка возвращается,
  если это не так (например, при загрузке из постоянного хранилища или
  обращении к устаревшей реплике)
- измерения задержки

### Управление соединениями {: #connection_management }

#### select

```sql
SELECT index
```

Получение логической базы данных Redis с указанным нулевым числовым
индексом. Новые соединения всегда используют базу данных 0.

### Общие команды {: #general }

#### del

```sql
DEL key [key ...]
```

Удаляет указанные ключи. Несуществующие ключи игнорируются.

#### exists

```sql
EXISTS key [key ...]
```

Проверяет, существует ли указанный ключ `key` и возвращает число совпадений.
Например, запрос `EXISTS somekey somekey` вернет `2`.

#### expire

```sql
EXPIRE key seconds [NX | XX | GT | LT]
```

Устанавливает срок жизни (таймаут) для ключа `key`. По истечении таймаута ключ
будет автоматически удален. В терминологии Redis ключ с установленным
тайм-аутом часто называют _волатильным_.

Тайм-аут будет сброшен только командами, которые удаляют или
перезаписывают содержимое ключа, включая DEL, SET и GET/SET. Это
означает, что все операции, которые концептуально изменяют значение,
хранящееся в ключе, не заменяя его новым, оставляют таймаут нетронутым.

#### keys

```sql
KEYS pattern
```

Возвращает все ключи, соответствующие шаблону.

Поддерживаются шаблоны в стиле _glob_:

- `h?llo` соответствует hello, hallo и hxllo
- `h*llo` соответствует hllo и heeeello
- `h[ae]llo` соответствует hello и hallo, но не hillo
- `h[^e]llo` соответствует hallo, hbllo, ... но не hello
- `h[a-b]llo` соответствует hallo и hbllo

#### persist

```sql
PERSIST key
```

Удаляет существующий таймаут для ключа `key`, превращая его из непостоянного
(ключ с установленным сроком действия) в постоянный (ключ, срок действия
которого никогда не истечет, поскольку таймаут для него не установлен).

#### scan

```sql
SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]
```

Команда `SCAN` используется для инкрементного итерационного просмотра
коллекции элементов в выбранной в данный момент базе данных Redis.

#### ttl

```sql
TTL key
```

Возвращает оставшееся время жизни ключа `key`, для которого установлен
таймаут. Эта возможность интроспекции позволяет клиенту Redis проверить,
сколько секунд данный ключ будет оставаться частью набора данных.

Команда возвращает `-2`, если ключ не существует.

Команда возвращает `-1`, если ключ существует, но не имеет связанного с
ним истечения срока действия.

#### type

```sql
TYPE key
```

Возвращает строковое представление типа значения, хранящегося по адресу
ключа `key`. Могут быть возвращены следующие типы:

- `string`
- `list`
- `set`
- `zset`
- `hash`
- `stream`

### Хэш-команды {: #hash }

#### hdel

```sql
HDEL key field [field ...]
```

Удаляет указанные поля из хэша, хранящегося по адресу ключа `key`.
Указанные поля, которые не существуют в этом хэше, игнорируются. Удаляет
хэш, если в нем не осталось полей. Если `key` не существует, он
рассматривается как пустой хэш, и эта команда возвращает `0`.

#### hexists

```sql
HEXISTS key field
```

Возвращает, является ли поле `field` существующим полем в хэше, хранящемся по
адресу ключа `key`.


#### hget

```sql
HGET key field
```

Возвращает значение, связанное с полем `field` в хэше, хранящемся по
адресу ключа `key`.

#### hgetall

```sql
HGETALL key
```

Возвращает все поля и значения хэша, хранящегося по адресу ключа `key`. В
возвращаемом значении за именем каждого поля следует его значение,
поэтому длина ответа будет в два раза больше размера хэша.

#### hincrby

```sql
HINCRBY key field increment
```

Увеличивает число, хранящееся в поле `field`, в хэше, хранящемся в ключе
`key`, на инкремент. Если ключ не существует, создается новый ключ,
содержащий хэш. Если поле не существует, то перед выполнением операции
его значение устанавливается в `0`.

Диапазон значений, поддерживаемых `HINCRBY`, ограничен 64-битными
знаковыми целыми числами.

#### hkeys

```sql
HKEYS key
```

Возвращает все имена полей в хэше, хранящемся по адресу ключа `key`.

#### hlen

```sql
HLEN key
```

Возвращает количество полей, содержащихся в хэше, хранящемся по адресу
ключа `key`.

#### hscan

```sql
HSCAN key cursor [MATCH pattern] [COUNT count] [NOVALUES]
```

Работает подобно [SCAN](#scan), но с некоторым отличием: `HSCAN`
выполняет итерацию полей типа Hash и связанных с ними значений.

#### hset

```sql
HSET key field value [field value ...]
```

Устанавливает указанные поля в соответствующие им значения в хэше,
хранящемся по адресу ключа `key`.

Эта команда перезаписывает значения указанных полей, которые существуют
в хэше. Если ключ не существует, создается новый ключ, содержащий хэш.

### Команды для строк {: #string }

#### get

```sql
GET key
```

Получает значение ключа `key`. Если ключ не существует, возвращается
специальное значение `nil`. Если значение, хранящееся в ключе, не
является строкой, возвращается ошибка, поскольку `GET` работает только
со строковыми значениями.

#### set

```sql
SET key value [NX | XX] [GET] [EX seconds | PX milliseconds |
  EXAT unix-time-seconds | PXAT unix-time-milliseconds | KEEPTTL]
```

Сохраняет строковое значение в ключе. Если ключ уже содержит значение,
оно будет перезаписано, независимо от его типа. Любое предыдущее
ограничение таймаута, связанное с ключом, отменяется при успешном
выполнении операции `SET`.

Параметры:

- `EX` — установка указанного времени истечения срока действия в
  секундах (целое положительное число)
- `PX` — установка указанного времени истечения в миллисекундах (целое
  положительное число)
- `EXAT` — установка указанного времени Unix, в которое истекает срок
  действия ключа, в секундах (целое положительное число)
- `PXAT` — установка указанного времени Unix, по истечении которого срок
  действия ключа истечет, в миллисекундах (целое положительное число)
- `NX` — установка значение ключа только в том случае, если он еще
  не существует
- `XX` — установка значение ключа только в том случае, если он уже
  существует
- `KEEPTTL` — сохранить время жизни, связанное с ключом
- `GET` — возвращает старую строку, хранящуюся по адресу ключа, или
  `nil`, если ключ не существовал. Возвращается ошибка и `SET`
  прерывается, если значение, хранящееся по адресу ключа `key`, не
  является строкой.

<!--
Частично поддерживаемые команды:

    - cluster management:
        - auth (no-op, always returns ok)
    - scripting:
        - eval (can't call redis functions at the moment)

 -->
