bambr / octopus

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

-*- mode: org -*-

Введение

octopus - дальнейшее развитие идеи silverbox/tarantool, фреймворк для создание in-memory баз данных.

В комплекте идет с двумя модулями feeder и box. Первый необходим для репликации, второй - key-value хранилище.

Пример конфигурации - doc/example.cfg

Запуск: ./octopus -c doc/example.cfg –init-storage # инициализируем хранилище ./octopus -c doc/example.cfg # запускаем сервер

Клиенты

client/libiproto

Клиентская библиотека протокола iproto

client/octobench

Бенчмарк для mod/box (silverbox)

ruby клиент для mod/box

пример сессии

$ irb -I mod/box/client/ruby -r silverbox irb(main):001:0> s = SilverBox.new ‘0:33013’ => #<SilverBox:0x000000025a3438 @object_space=0, @end_point=[“0”, 33013], @reconnect=true, @sock=#<TCPSocket:fd 4>> irb(main):002:0> s.ping => :pong irb(main):003:0> s.insert [1, “foo”, “bar”] => 1 irb(main):004:0> s.select 1 => “\x01\x00\x00\x00”, “foo”, “bar”

Репликация.

Основные настройки:

  1. wal_feeder_addr - адрес, откуда получаем данные.
  2. wal_feeder_filter - название фильтра. Фильтр - процедура, которая определена на мастере.
  3. wal_feeder_filter_type - тип фильтра - “lua”, “c” или “id” “id” - ничего не делать
    • ставится по умолчанию, если wal_feeder_filter пустой

    “lua” - вызывать Lua функцию

    • cтавится по умолчанию, если wal_feeder_filter не пустой.

    “c” - если используется кустомный фидер, то есть возможность вызвать функцию, написанную на “c”.

  4. wal_feeder_filter_arg - строка, передаваемая как дополнительный аргумент фильтру.

Фильтры

Фильтр - функция, котороя посторочно получает данные репликации и может их изменять.

Наиболее доступным является фильтр на Lua. Фильтр должен быть зарегистрирован в таблице replication_filter, простейщий способ - создавать функции с именем вида replication_filter.имя_фильтра.

Аргументы фильтра: (row, arg)

  • row - cdata<struct row_v12*>. Если фильтру передан дополнительный аргумент arg, то первый раз фильтр вызывается с row = nil
  • arg - дополнительный аргумент, переданный с клиента. Передаётся каждый раз.

Фильтр должен вернуть либо строку либо nil. В последнем случае строка реплике не передается. Обратите внимание, что в этом случае будут дырки SCN, соответсвенно на реплике надо отключить опцию конфигурации panic_on_scn_gap .

Пример фильтра можно посмотреть в mod/feeder/src-lua/feeder.lua и test/07_test_replication.rb

Переключение на ходу.

Возможно изменение источника репликации на ходу: правим конфиг + reload conf в админ. интерфейс.

Никаких проверок реплика не делает, она просто начинает репликацию с нового адреса используя SCN на единцу больший чем ее собственный. Соответсвенно, если новый мастер имеет, например, другие настройки object_space, то все сломается.

Переключение обратно на старый мастер тоже надо делать с осторожностью: если в нем будут несовместимые апдейты (которые могли появится после того, как реплику переключили на временный мастер), то все сломается.

Internals

LogIO

Состояние сервера сохраняется на диске в двух типах файлов snap и xlog. Имя файла формируется как LSN первой записи в нем плюс расширение. В snap файлах сохраняется единомоментный снимок памяти сервера, а в xlog - WAL всех изменений. Таким образом, для полного востановления сервера необходим snap + все записи их xlog старше его.

Блок схема

-------------------------- --------------- | |

loading-----------------v------------
remote_hot_stby
feederLOWRITEFEEDER
configuredv

--------------- | | ------- |

-------------—+connect<–
primary----–+
+-lock_WAL->LOWRITEfeeder

v | | | v v configured | ---------------- ------------- | ---- | |

local_hot_stby^ ^ok–>fail----+
----

---------------- | | --------------v---------------

-------lock_WAL---- -----------------------

Процедура востановления

-[Recovery recover_start] – Находим и читаем snapshot c наибольшим LSN -[Recovery recover_snap]

– находим самый свежий xlog, LSN которого меньше чем LSN снапшота. -[Recovery recover_cont] – сортируем все xlog файлы в порядке возрастания LSN и дочитываем оставшиеся файлы в цикле -[Recovery recover_remaining_wals] foreach xlog file -[Recovery recover_wal]

– Влючаем переодическое дочитываение xlog с диска. Для этого используются таймер + inotoify. [recover_follow]

Иерархия вызовов при востановлении xlog

while (row = -[XLogPuller fetch_row]) -[Recovery recover_row:row] -[Recovery apply_row:row] – Этот метод должен быть специфицирован в наследнике, и должен соответствующим образом менять состояние. -[Recovery apply] – обновление состояни Recovery: SCN, LSN, crc_hist

Особенности обновления run_crc

а -[Recovery apply:tag:] – нет.

Это связано со следующим фактом - мы обновляем эту crc сумму ввв

  1. Сохранение состояния на диск
    1. mod_prepare_update() – в этот момент модуль уже знает old_obj и obj
    2. -[Recovery submit_wal_row:] -[Recovery wal_pack_submit] – В случае успешной записи wal_pack_submit обновит run_crc_mod, если в переданной struct wal_row будут old_obj и obj != NULL
    3. mod_commit()
  2. Востановление с диска

    При проигрывании записей мы обязаны обновлять run_crc_mod аналогично тому, как это делает -[Recovery wal_pack_submit] . Задача осложняется тем, что у нас нет ссылок на old_obj и obj и их невозможно получить, до тех пор, пока модуль не применит обновление.

    Поэтому, обновление run_crc_mod отдано на откуп -[Recovery apply_row:].

  3. Репликация

    Неприятность в том, что когда мы реплицируемся по сети мы как пишем на диск и так и применяем записи. Для того, что бы мы не обновляли run_crc_mod дважды делаем следующее:

    1. Прикладываем строчки с помощью -[Recovery recover_row:] (т.к этот же метод используется при востановлении с диска, то мы обновим run_crc)
    2. в -[Recovery wal_pack_append] передаем struct wal_row без установленных old_obj и obj и вызываем -[Recovery wal_pack_submit_x] для того что бы избежать обновления SCN и LSN (они обновлены на предыдушем шаге)

Иерархия вызовов при сохранении состояния

About

License:Other


Languages

Language:Objective-C 61.7%Language:C 13.8%Language:Lua 8.5%Language:Python 5.3%Language:JavaScript 1.9%Language:Shell 1.7%Language:Makefile 1.7%Language:Ragel 1.3%Language:M4 1.2%Language:OCaml 1.1%Language:Perl 0.6%Language:GDB 0.5%Language:R 0.4%Language:Haskell 0.1%Language:CSS 0.1%Language:Raku 0.0%Language:C++ 0.0%