3 июня 2026 г.
Tarantool 2.x
Создадим кластер из двух master-хранилищ.
services:
tarantool-storage-1:
image: tarantool/tarantool:2.11
container_name: tarantool-storage-1
ports:
- "3301:3301"
volumes:
- ./init.lua:/opt/tarantool/init.lua
command: tarantool /opt/tarantool/init.lua
networks:
- tarantool-net
tarantool-storage-2:
image: tarantool/tarantool:2.11
container_name: tarantool-storage-2
ports:
- "3302:3301"
volumes:
- ./init.lua:/opt/tarantool/init.lua
command: tarantool /opt/tarantool/init.lua
networks:
- tarantool-net
networks:
tarantool-net:
driver: bridge
Создадим файл init.lua:
box.cfg({
listen = '0.0.0.0:3301',
replication = {
'tarantool-storage-1:3301',
'tarantool-storage-2:3301'
},
read_only = false,
memtx_memory = 128 * 1024 * 1024,
log_level = 5
})
Запуск контейнеров:
docker-compose up -d
Подключение к первому узлу:
docker exec -it tarantool-storage-1 tarantoolctl connect localhost:3301
Создаем тестовое пространство:
box.schema.space.create('test', {if_not_exists=true})
box.space.test:format({
{name='id', type='unsigned'},
{name='data', type='string'}
})
box.space.test:create_index('primary', {parts={1}})
Проверяем статус репликации:
box.info.status
box.info.replication
Затем на втором узле:
docker exec -it tarantool-storage-2 tarantoolctl connect admin:localhost:3301
И тоже проверяем статус репликации:
box.info.status
box.info.replication
Проверка master-master
На первом узле:
box.space.test:insert{1, 'Hello from master-1'}
На втором узле. Должны увидеть данные с первого узла:
box.space.test:select{}
box.space.test:insert{2, 'Hello from master-2'}
Снова на первом узле. Должны увидеть оба сообщения:
box.space.test:select{}
Tarantool 3.x
Теперь создадим кластер из двух master-хранилищ только под версию 3.x:
services:
tarantool-storage-1:
image: tarantool/tarantool:latest
container_name: tarantool-storage-1
environment:
TT_INSTANCE_NAME: tarantool-storage-1
TT_CLUSTER_COOKIE: my-secret-cookie
TT_CONFIG: /config/cluster.yaml
ports:
- "3301:3301"
volumes:
- ./init.lua:/opt/tarantool/init.lua
- ./config:/config
- tarantool-data-1:/var/lib/tarantool
command: tarantool /opt/tarantool/init.lua
networks:
- tarantool-net
tarantool-storage-2:
image: tarantool/tarantool:latest
container_name: tarantool-storage-2
environment:
TT_INSTANCE_NAME: tarantool-storage-2
TT_CLUSTER_COOKIE: my-secret-cookie
TT_CONFIG: /config/cluster.yaml
ports:
- "3302:3301"
volumes:
- ./init.lua:/opt/tarantool/init.lua
- ./config:/config
- tarantool-data-2:/var/lib/tarantool
command: tarantool /opt/tarantool/init.lua
networks:
- tarantool-net
depends_on:
- tarantool-storage-1
networks:
tarantool-net:
driver: bridge
volumes:
tarantool-data-1:
tarantool-data-2:
Создадим файл init.lua:
box.cfg()
if box.space.test == nil then
box.schema.space.create('test', { if_not_exists = true })
box.space.test:format({{name='id',type='unsigned'},{name='data',type='string'}})
box.space.test:create_index('primary',{parts={'id'}, if_not_exists=true})
pcall(box.space.test.insert, box.space.test, {1, 'Initial data'})
end
require('console').start()
Здесь происходит сразу заполнение данными. А также
безопасная вставка: если узел получит эту запись по репликации от соседа, он не упадет с ошибкой "Duplicate key".
Создадим файл конфигурации (config/cluster.yaml):
credentials:
users:
guest:
roles:
- super
groups:
my-group:
replicasets:
my-replicaset:
instances:
tarantool-storage-1:
database:
mode: rw # Первый мастер
iproto:
listen:
- uri: '0.0.0.0:3301'
advertise:
peer:
uri: 'tarantool-storage-1:3301'
login: 'guest'
tarantool-storage-2:
database:
mode: rw # Второй мастер
iproto:
listen:
- uri: '0.0.0.0:3301'
advertise:
peer:
uri: 'tarantool-storage-2:3301'
login: 'guest'
Запуск контейнеров:
docker-compose up -d
Подключение к первому узлу:
docker exec -it tarantool-storage-1 tt connect localhost:3301
Проверяем статус:
box.info.status
Вставляем данные:
box.space.test:insert{2, 'Hello from master-1'}
Проверяем:
box.space.test:select()
Аналогично подключаемcя ко второму узлу:
docker exec -it tarantool-storage-2 tt connect localhost:3301
Проверяем:
box.space.test:select()
Видим два сообщения. Добавляем сообщение со второго узла:
box.space.test:insert{3, 'Hello from master-2'}
Теперь на первом узле можно увидеть три сообщения.
Итого
Мы создали два рабочих кластера Tarantool в Docker: на версии 2.11 и на актуальной 3.x. Оба используют конфигурацию
master-master, где любой узел принимает запросы на запись, а данные автоматически синхронизируются.
Как это работает:
- Tarantool 2.11: файл init.lua содержит и конфигурацию (box.cfg), и создание пространства. Всё в одном месте.
- Tarantool 3.x: конфигурация вынесена в отдельный файл cluster.yaml (порты, режим read_only, репликация), а init.lua отвечает только за создание пространства и начальных данных. Такой подход чище разделяет ответственность.