LINUX.ORG.RU

Репликация shared memory


1

4

Есть приложение из множеста процессов, которые общаются между собой и хранят всякие данные в shm. Возникла задача обеспечить high availability. Задумались над тем, как реплицировать наше хранилище.

Первый вариант: каким-то образом снять мгновенный snapshot.

Глобальный лок, естественно, не подходит, т.к. все надолго встанет (shm занимает не один Гиг).

Хотелось бы открыть shm на чтение так, чтобы страницы, измененные другими процессами, не менялись. Типа такой copy-on-write только «наоборот».

Второй вариант: подумать над записью дифов наших структур.

Но у нас несколько разных типов данных хранятся в разных shm, т.е. каждый раз придется заново реализовывать работу с дифами.

★★

От вас ушел архитектор сего приложения? Потому что сразу вопрос, какой ... выбрал shm для важных данных? Если используется временная память (shm, tmpfs, pmq, etc), то значит так из задумано было, что это некритичные данные. Критичные данные хранятся в БД, в файлах, которые как раз и умеют реплицироваться и т.д.

Хотелось бы открыть shm на чтение так, чтобы страницы, измененные другими процессами, не менялись.

Ну вот, началось, транзакции подавай. ACID в shm.

Допустим вы найдете решение, которое сможет читать данные и сбрасывать их. Вопрос, а что будет если в момент бэкапа система ляжет? Это к вопросу о глобальном локе/останове всех процессов.

Единственно верное решение, это научить каждый процесс скидывать свои данные и уметь с них начинать работу (т.е. читать, импортировать). При этом группа процессов должны уметь находить ведущего, который производит бэкап /восстановление (ну чтобы не было путанитцы) и если бэкапер отвалился, найти другой процесс на эту роль. Плюс, если все процессы помрут, логично сделать процесс-монитор, который скажет (читай позвонит на мобилу), что все пошло не так.

Что касается дифов, то если все это разместить в рабочем процессе, то ему несложно сложить в файлики структуры о том, что было 10 минут назад. Когда наступит момент сравнения просецесс загрузит данные из файла и сравнит с текущими. Вопрос оптимизаций я не рассматриваю, т.к. надо определиться с архитектурой.

Другой вариант: отдельный процесс с локами на отдельные участки памяти. В таком случае надо посмотреть на иерархию зависимостей каждого куска памяти. Может в вашем случае она линейна: у вас в совукопности одна точка входа данных и одна точка выхода (обработанные данные). Если множество, не пугаемся, смотрим сколько всего точек. Слишком много? Надо делать фриз всех процессов для получения верной и полной картинки? Значит надо это делать. Или не надо, если пересмотреть архитектуру всего приложения.

gh0stwizard ★★★★★
()
Ответ на: комментарий от gh0stwizard

Спасибо, за развернутый ответ.

В shm хранятся действительно временные данные. Например, там строиться сессионная таблица роутинга. Т.е. на старте сессии принимается решение и заносится запись, куда в будущем эту сессию пересылать. По завершении сессии - запись удаляется. Время жизни сессии от нескольких секунд до нескольких суток. И пересоздавать сессию только потому, что мы переключились на резервный узел, как-то не комильфо.

Это один из примеров данных в shm. И в этом случае можно придумать схему работы с дифами, т.к. структура по сути линейная с некоторой общей частью, которую в скопированном хранлище можно построить заново по итоговым данным. Но опять же повторюсь - м.б. есть какой-то механизм на уровне ядра по типу «copy-on-write», тогда не пришлось бы для каждого типа данных свой велосипед придумывать, а просто «снапшотить» shm без глобального лока.

kulti ★★
() автор топика

Предупреждаю: нихрена в низкоуровневом программировании не понимаю, могу и глупость сказать.

В современных ядрах shm - это tmpfs, ты её в mount увидеть можешь. Для ФС в линуксе внутренних средств создания снапшотов нету, иначе не пришлось бы LVM изобретать.

Вариант: вместо shm хранить данные в памяти какого-нибудь процесса, обмениваясь ими через пайпы. Если форкнуть этот процесс, и сразу после форка в копии перестать принимать данные - это и будет снапшот силами ядра. Кстати, copy-on-write там, по-моему, в том числе будет использоваться.

selivan ★★★
()
Ответ на: комментарий от kulti

м.б. есть какой-то механизм на уровне ядра по типу «copy-on-write»

На уровне ядра можно вообще сделать так как хотите. Я лично ничего такого не встречал.

Из того, что понял, на ум приходит только одно решение, которое может предоставить нечто подобное: berkeley db. Если файлы бд положить в tmpfs, то получим некоторую деградацию производительности и все плюшки этой бд. А именно транзакции, причем с разновидностями по этапам записи данных: до журнала, после журнала, после журнала и файла данных.

Это то, что вы хотите. С другой стороны, вопрос о тех же таблицах маршутизации, то почему бы их не кэшировать налету? Такие решения существуют: единый интерфейс (вход), а на выходе мульти хранилище от sql до shm/mmap/etc. Опять же за такое надо расплачиваться некой производительнстью. Хотя можно задавать кол-во и тип хранилищ обязательных для завершения операции (записи, обновления). Например, записать обязательно в shm и redis, для примера, а в sql записать по мере возможности.

Также на ум приходят всякие ActiveMQ, RabbitMQ. Посмотрите на их, может подойдут.

Вам что нужно failover раз сказали HA или все же горизонтальное масштабирование? Такое ощущение, что последнее.

gh0stwizard ★★★★★
()

Можно сохранять раз в N секунд копию памяти на внешний носитель, и при крахе одного узла запускать другой с этой копией, но нужно научить софт писать в память только диффы, при этом как-то синхронизируя их запись... лучше забей. Ничего у тебя не выйдет. Архитектура должна изначально проектироваться с учетом HA.

tailgunner ★★★★★
()
Ответ на: комментарий от gh0stwizard

Нужен именно failover. Переделать все на БД, и за счет нее получить нужный результат - не проблема. Просто мы любим экспериментировать с разными технологиями и хотим сделать все с shm ради спортивного интереса =)

Писать в два места сразу бессмысленно, т.к. данные могут меняться быстро: до несколькоких тысяч раз в секунду. Но спасибо за совет, т.к. это натолкнуло меня на мысль, что м. б. небольшая потеря данных в нашем случае не так страшна.

kulti ★★
() автор топика
Ответ на: комментарий от no-such-file

Спасибо, почитаю про это подробнее.

kulti ★★
() автор топика
Ответ на: комментарий от gh0stwizard

gridgain, hazelcast, infinispan, что там у нас еще? Все долбоебы, один ты умный? Уже давным-давно в памяти хранятся большие мсассивы данных, к которым прикручены те самые ACID, да так, что пользователю редко приходится впдать в ступор от кишок продукта.

Вот нетфликс, например, хранит в памяти большой кусок своих данных тоже.

Я тыкал все 3, и у всех есть (опционально отключаемая) репликация данных. В конфигах указываешь, на скольки нодах нужно хранить реплики ячеек (там интерфейс как у Map<K, V>, только везде еще свое поверху) и все само собой разруливается.

Насчет бэкапов, опять же - там, по-моему, везде можно выбрать тип бэкапа - или дифами, или полный. Для дифов, естественно, достаточно один раз сделать полный, а потом просто каждая транзакция в лог ложится (здесь минус в том, что при восстановлении требуется время на повтор всех транзакций (но такое бывает КРАЙНЕ редко, потому что для того, чтобы данные брались из бэкапа, нужно, чтобы живых нод не осталось)).

anonymous
()
Ответ на: комментарий от anonymous

Меня не так поняли. Что касается хранения данных в ОЗУ, то это быстрейшее хранилище для больших объемов данных. Это очевидные вещи (с)

Что касается gridgain, hazelcast, infinispan, то это совершенно другой уровень абстракции. У ТС, исходя из топика получается, что они использовали shm напрямую. Повтрю, shm не умеет acid из коробки. И проектировщику было это известно. Если поверх shm накрутить свой, назовем, драйвер с поддержкой acid, то это другая абстракция. Другое назначение. Другие возможности. Другие требования. Другие показатели производительности.

Если бы приложение ТС изначально включало в себя требования по HA, то в чистом виде, напрямую shm не использовали. А если и использовали, то и необходимые возможности были запланированы и реализованы. И этого топика не было.

Поскольку топик появился и надо искать уже «костыльные» решения, я высказал то, что думал об этом. Никаких д'Артаньянов. Никаких «самый умный». Только разум.

Почему «костыльные» потому что ваши решения это разворот на 180 градусов и перепиливание всего кода. Возможно, ТС это уже понял или знал изначально и ему не хотелось идти на этот эпический шаг. Все в его руках.

gh0stwizard ★★★★★
()
Ответ на: комментарий от gh0stwizard

Там всего кода сейчас 40 кb. Так что много перепиливать не придется. API у кода прсотой, релизацю можно ментяь как угодно. Другое дело, что текущая реализация ОЧЕНЬ эффективна по памяти. Все остальное будет существенно хуже.

vromanov ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.