Инструменты пользователя

Инструменты сайта


databases:tarantool

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
databases:tarantool [2021/12/23 05:20]
admin
databases:tarantool [2021/12/29 10:52] (текущий)
admin [Примеры]
Строка 21: Строка 21:
  
  
-Все строится вокруг инстанса (приложения).\\ +Все строится **вокруг инстанса** (приложения). Пользователи/роли/объекты **заводятся внутри него** и относятся к нему. В инстансе задается порт прослушиваниясистемные конфиги и т.\\
-Пользователи/роли/объекты заводятся внутри него и относятся к нему.\\ +
-Для хранения конфигурации есть две папки "instances.available" и "instances.enabled", из второй приложения автозапускаются при старте службы.\\ +
-Для управления служит утилита "tarantoolctl", либо "systemctl tarantool@<name_app>".\\+
  
-Параметры приложению можно заливать при создании, в основном файле ".lua", в интерактивном режимелибо скриптами в процессе работы, утилитой "tarantoolctl eval app_name"+Для хранения конфигурации есть две папки "**instances.available**" и "**instances.enabled**", из второй приложения **автозапускаются при старте** службы. (по логике файлы создаются в первой, и при активации ссылка создается в **enabled**, но так чето не работает, даже если создать ссылку вручную, пока что работает если файл сразу поместить в **enabled**.)\\
  
 +Для управления служит утилита "**tarantoolctl**", либо "systemctl tarantool@<name_app>".\\
  
 +Параметры приложению можно заливать **при создании**, в основном файле ".lua", в **интерактивном режиме**, либо **скриптами** в процессе работы, утилитой **"tarantoolctl eval app_name"**.\\
 +Примененные впоследствии скрипты **не сохраняют своего действия** при перезагрузке приложения + перезагрузка **основной службы не влияет на работу приложений** (инстансов).\\
 +
 +Система может выполняться:
 +  * интерактивно- просто запустить tarantool
 +  * в режиме скрипта- подать аргументом скрипт, ПО выполнит его и завершится
 +  * в режиме серверного приложения, принимая tcp-запросы - в конфигурации нужен блок "box.cgf", с указанием порта и т.д. Для фонового исполнения нужно еще добавить параметры (разделяются ; либо ,):
 +      * background
 +      * log
 +      * pid_file
  
  
-Конфигурация находится в файлах *.lua, есть две папки: **etc/tarantool/instances.available** и **etc/tarantool/instances.enabled**, по логике файлы создаются в первой, и при активации ссылка создается в **enabled**, но так чето не работает, даже если создать ссылку вручную. Пока что работает если файл сразу поместить в **enabled**.\\ 
  
-В конфиге описываются все параметры инсталляции, прослушиваемый порт, параметры памяти, пользователи/привилегии и т.д.\\ 
  
 <details> <details>
-<summary> :!: Пример конфига + пару пространств</summary>+<summary> :!: Пример конфиг инстанса создание структуры БД</summary>
 За основу можно взять файл "example.lua", в папке "available" За основу можно взять файл "example.lua", в папке "available"
 <code lua> <code lua>
Строка 74: Строка 80:
 </code> </code>
 </details> </details>
- 
- 
-Управление происходит командой **tarantoolctl**, есть параметры **start/stop/check** и т.д.\\ 
  
  
Строка 86: Строка 89:
   * **TREE** - не уникальны, получается массив, у которого могут быть пропущены элементы   * **TREE** - не уникальны, получается массив, у которого могут быть пропущены элементы
   * **RTREE** и **BITSET** - поиск на двумерной плоскости и работа с битовыми данными   * **RTREE** и **BITSET** - поиск на двумерной плоскости и работа с битовыми данными
 +
 +Есть два движка хранения данных: **"memtx"** и **"vinyl"**, первый хранит данные в ОЗУ, асинхронно записывая на диск для сохранности, второй классический вариант хранения на диске, оптимизирован для большого кол-ва операций.\\
 +
 +
  
  
Строка 92: Строка 99:
 После запуска инсталляции, подключится в **режиме консоли** можно:  После запуска инсталляции, подключится в **режиме консоли** можно: 
 <code bash># tarantoolctl enter <name></code> <code bash># tarantoolctl enter <name></code>
 +
 +Перечень запущенных инстансов можно просмотреть в списке процессов ОС:
 +<code bash># ps -ef | grep tarantoolctl</code>
 +
 +Запуск в докере "картриджа"
 +<code bash># docker run -p 3301:3301 -p 8081:8081 tarantool/getting-started</code>
 +
 +Подключение к консоли по сети (из другой консоли)
 +<code bash>
 +# Пока под вопросом. вроде работает но какая то специфика тут есть
 +tarantool> net_box = require('net.box')
 +tarantool> conn = net_box.connect(3301)
 +
 +# Работает но непонятно с кластером в связке с Докером
 +$ tarantoolctl connect user:passwd@host:port
 +
 +# Внутри консоли так работает:
 +tarantool> console = require('console')
 +tarantool> console.connect('user:passwd@host:port')
 +</code>
 +
 +
 +
 +
 +
 +
 +<code bash># </code>
 +
  
  
Строка 130: Строка 165:
  
 Пару примеров: Пару примеров:
-<code bash>> box.schema.user.grant('U','read,write,execute,create,drop','universe'+<code bash>> box.schema.user.grant('User','read,write,execute,create,drop','universe'
-> box.schema.user.grant('U','write', 'space', '_schema'+> box.schema.user.grant('User','write', 'space', '_schema'
-> box.schema.user.grant('U','create,read','space','T'+> box.schema.user.grant('User','create,read','space','T'
-> box.schema.user.grant('U','drop','sequence'+> box.schema.user.grant('User','drop','sequence'
-> box.schema.user.grant('U','execute','function','F'+> box.schema.user.grant('User','execute','function','F'
-> box.schema.user.grant('U','create','role') </code>+> box.schema.user.grant('User','create','role') </code>
  
  
Строка 193: Строка 228:
 -- Даже после связки ролей, изменения применятся -- Даже после связки ролей, изменения применятся
 > box.schema.role.grant('Role2', 'read,write', 'space', 'T')</code> > box.schema.role.grant('Role2', 'read,write', 'space', 'T')</code>
 +
 +
 +
 +==== Потоки/процессы ====
 +
 +В консольном режиме "fiber= require('fiber')", и далее через эту переменную можно получить информацию о работающих потоках, есть целый ряд методов.\\
 +
 +
 +
 +
 +
 +==== Скрипты ====
 +
 +Интерпретатор скриптов: "/usr/bin/evn tarantool", с помощью его можно иcполнить любой скрипт на lua.\\
 +Можно просто дать скрипт аргументом процессу он его выполнить и завершится: "tarantool my-script.lua"\\
 +
 +Вызов функции внутри **pcall()**- обеспечивает безопасное поведение в случае ошибки.\\
 +
 +
 +
 +
 +
 +
 +==== Кластер серверов ====
 +
 +[[https://www.tarantool.io/ru/doc/latest/getting_started/|Оф документация]]\\
 +Ставим Tarantool, Cartridge-Cli, после запуска UI доступен в веб странице по порту 8081.\\
 +В кластере есть две служебные роли:
 +  * **Storage** - хранилище данных
 +  * **Router** - посредник между клиентами и хранилищем
 +
 +Масштабирование кластера собсна и происходит добавлением доп хранилищ (шард), в настройках параметр "Replica set weight" регулирует приоритет использования, по всей видимости, можно вкл/выкл и данные "перетекают" из одного шарда в другой.\\
 +
 +
  
  
Строка 245: Строка 314:
  
 Остались вопросы: Остались вопросы:
-  * перечень запущенных/рабочих инстансов +  * подключение к консоли кластера 
-  как выполняются скрипты, ведь не только инстансоминстанс полагаю это как база данных +  * либо нужно разобраться как поднимать кластер из обычной установки 
-  + 
 + 
 + 
 + 
 +===== Примеры ===== 
 + 
 + 
 + 
 + 
 +<details> 
 +<summary> :!: "**Вставка 1 млн кортежей** с помощью хранимой процедуры" </summary> 
 +Серверное приложение, создание одного спейса, пара функций, генерация рандомной символьной строки, вставка таких строк в цикле, + показан пример замера времени работы скрипта 
 + 
 +Файл конфига сервер-аппа: 
 +<code lua> 
 +box.cfg { 
 +        listen = '*:3311'; 
 +        --slab_alloc_arena= 0.2; 
 + 
 +        io_collect_interval = nil; 
 +        readahead = 16320; 
 +        memtx_memory = 128 * 1024 * 1024; 
 +        memtx_min_tuple_size = 16; 
 +        memtx_max_tuple_size = 128 * 1024 * 1024; 
 +        vinyl_memory = 128 * 1024 * 1024; 
 +        vinyl_cache = 128 * 1024 * 1024; 
 +        vinyl_max_tuple_size = 128 * 1024 * 1024; 
 +        vinyl_write_threads = 2; 
 +        wal_mode = "none"; 
 +        wal_max_size = 256 * 1024 * 1024; 
 +        checkpoint_interval = 60 * 60; 
 +        checkpoint_count = 6; 
 +        force_recovery = true; 
 +        log_level = 5; 
 +        log_nonblock = false; 
 +        too_long_threshold = 0.5; 
 +
 + 
 +local function startbuild() 
 +        --local space = box.schema.create_space('example'
 +        --space:create_index('primary'
 + 
 +        -- Создание пользователя 
 +        box.schema.user.create('user2', {password = 'user2'}) 
 +        box.schema.user.grant('user2', 'read,write,execute,create,session', 'universe'
 + 
 +        --------------------------- 
 +        ----- Пространство стикеров 
 +        local tester = box.schema.create_space('tester'
 +                -- Индекс для файла 
 +                tester:create_index('primary', {type= 'TREE', parts= {1, 'unsigned'}}) 
 +end 
 + 
 +function string_function() 
 +        local random_number 
 +        local random_string 
 +        random_string = "" 
 +        for x = 1,10,1 do 
 +                random_number = math.random(65, 90) 
 +                random_string = random_string .. string.char(random_number) 
 +        end 
 +        return random_string 
 +end 
 + 
 +function main_function() 
 +        local string_value,
 +        for i = 1,1000000,1 do 
 +                string_value = string_function() 
 +                t = box.tuple.new({i,string_value}) 
 +                box.space.tester:replace(t) 
 +        end 
 +end 
 + 
 +-- Создание пространства и привилегий 
 +box.once('wtf', startbuild) 
 +</code> 
 + 
 +Использование: 
 +<code lua>tarantool> start_time = os.clock() 
 +tarantool> main_function() 
 +tarantool> end_time = os.clock() 
 +tarantool> 'insert done in ' .. end_time - start_time .. ' seconds' 
 +tarantool> box.space.tester:select{1}</code> 
 +</details> 
 + 
 + 
 + 
 +<details> 
 +<summary> :!: **Подсчет значений поля** в пространстве </summary> 
 + 
 +Подсчет происходит в этой функции\\ 
 +"Pairs()" типа массив всех строк, по которым и делаем цикл\\ 
 + 
 + 
 +<code lua> 
 +json= require('json'
 +function sum_json_field(field_name) 
 +        local v, t, sum, field_value, is_valid_json, lua_table 
 +        sum= 0 
 +        for v, t in box.space.tester:pairs() do 
 +                is_valid_json, lua_table= pcall(json.decode, t[2]) 
 +                if is_valid_json then 
 +                        field_value= lua_table[field_name] 
 +                        if type(field_value)== "number" then sum= sum + field_value end 
 +                end 
 +        end 
 +        return sum 
 +end 
 +</code> 
 + 
 +В двух записях намерено допущены ошибки, эти строки пропускаются 
 +<code lua> 
 +-- Создание/Заполнение пространства 
 +box.space.tester:drop() 
 +box.schema.space.create('tester'
 +box.space.tester:create_index('primary'{parts = {1, 'unsigned'}}) 
 + 
 +box.space.tester:insert{445, '{"Item": "widget", "Quantity": 7}'} 
 +box.space.tester:insert{446, '{"Item": "golf club", "Quantity": "sunshine"}'
 +box.space.tester:insert{447, '{"Item": "waffle iron", "Quantit": 3}'} 
 + 
 +-- Вызов ф-ции 
 +sum_json_field("Quantity"
 +</code> 
 +</details> 
 + 
 + 
 + 
 +<details> 
 +<summary> :!: **Хранимые процедуры на С** </summary> 
 +Проверьте наличие пакета "tarantool-dev"\\ 
 + 
 +Создайте и скомпилируйте следующий модуль (easy.c): 
 +<code c> 
 +#include "module.h" 
 +int easy(box_function_ctx_t *ctx, const char *args, const char *args_end) 
 +
 +        printf("hello world\n"); 
 +        return 0; 
 +
 + 
 +int easy2(box_function_ctx_t *ctx, const char *args, const char * args_end) 
 +
 +        printf("hello world -- easy2\n"); 
 +        return 0; 
 +
 +</code> 
 + 
 +Скомпилировать можно командой: 
 +<code bash>$ gcc -shared -o easy.so -fPIC easy.c</code> 
 + 
 +Далее откройте клиент tarantool в интерактивном режиме: 
 +<code bash> 
 +box.cfg{listen=3306} 
 +box.schema.space.create('capi_test'
 +box.space.capi_test:create_index('primary'
 +net_box = require('net.box'
 +capi_connection = net_box:new(3306) 
 + 
 +box.schema.func.create('easy', {language = 'C'}) 
 +box.schema.user.grant('guest', 'execute', 'function', 'easy'
 +capi_connection:call('easy'
 +</code> 
 + 
 +Находясь в той же директории где скомпилирован модуль С, тарантул находит указанные файлы.\\ 
 +Если название функции отличается он файла, то нужно указывать его: 
 +<code bash> 
 +box.schema.func.create('easy.easy2', {language = 'C'}) 
 +box.schema.user.grant('guest', 'execute', 'function', 'easy.easy2'
 +capi_connection:call('easy.easy2'
 +</code> 
 +</details> 
 + 
 + 
 + 
 +<details> 
 +<summary> :!: **Еще пример использования С** </summary> 
 + 
 +В основном используются API функции [[https://github.com/tarantool/msgpuck|модуля msgpuck]]\\ 
 + 
 + 
 +"hardest.c" 
 +<code c> 
 +#include "/usr/include/tarantool/module.h" 
 +#include "/var/msgpuck/msgpuck.h" 
 + 
 +int hardest(box_function_ctx_t *ctx, const char *args, const char *args_end) 
 +
 +        uint32_t space_id= box_space_id_by_name("capi_test", strlen("capi_test")); 
 +        char tuple[1024]; 
 +        char *tuple_pointer= tuple; 
 +        tuple_pointer= mp_encode_array(tuple_pointer, 2); 
 +        tuple_pointer= mp_encode_uint(tuple_pointer, 10000); 
 +        tuple_pointer= mp_encode_str(tuple_pointer, "String 2", 8); 
 +        int n= box_insert(space_id, tuple, tuple_pointer, NULL); 
 +        return n; 
 +
 +</code> 
 + 
 +После компиляции модуля выполните в терминале тарантула: 
 +<code lua> 
 +box.schema.func.create('hardest', {language = "C"}) 
 +box.schema.user.grant('guest', 'execute', 'function', 'hardest'
 +box.schema.user.grant('guest', 'read,write', 'space', 'capi_test'
 +capi_connection:call('hardest'
 + 
 +-- Выполнение 
 +box.space.capi_test:select() 
 +</code> 
 +</details> 
 + 
 + 
 +<details> 
 +<summary> :!: **Использование SQL** </summary> 
 + 
 +Подключаемся к консоли, двумя командами задаем язык и разделитель команд:\\ 
 +<code bash> 
 +tarantool> \set language sql 
 +tarantool> \set delimiter ; 
 +</code> 
 + 
 +Далее выполняем команды в формате SQL 
 +<code sql> 
 +tarantool> create table table1 (column1 integer primary key, column2 varchar(100)); 
 +tarantool> insert into table1 values (1, 'A'); insert into table1 values (2, 'B');  
 +tarantool> update table1 set column2='AB' where column1='2'; 
 +tarantool> select from table1; 
 +</code> 
 +Результат аналогичен использованию команд типа "box.space..."\\ 
 +Здесь создается пространство "table1", и вставка пары кортежей (записей).\\ 
 +</details>
  
-===== ===== 
  
  
databases/tarantool.1640236832.txt.gz · Последнее изменение: 2021/12/23 05:20 — admin