Функцион&#x4

Функцион&#x4

Функциональщина на C++


21.07.21 05:03:49
Сущность никто не использует какое-то время и ссылок на нее нет — всё, эту сущность можно убивать.
Ну так определи, что она не используется.
Ты про механизмы переиспользования памяти epoch-based/quiescent-state?
Нет. Давай я просто опишу задачу, чтобы было понятнее.
Есть CoW persistent tree. Если мы хотим удалять старые версии, нам нужен или трассирующий сборщик мусора, или ARC с атомарными счетчиками (если мы хотим иметь несколько писателей, которые будут удалять память) для каждого узла. Счетчик содержит количество ссылок на узел.
Если память никогда не удаляется, то счетчики не нужны и у нас будет только одна точка столкновения потоков  на «Ð³Ð¾Ð»Ð¾Ð²Ðµ» истории. Ну или на всей истории, если хочется читать произвольные версии.
Если ты хочешь сделать распределенный сборщик мусора для такой структуры данных, то тебе нужен либо трассирующий сборщик мусора (я б не стал, хотя и можно), либо атомарные идемпотентные счетчики. Но в любом случае тебе понадобится сильная консистентность. Ты же не хочешь, чтобы из-за неправильного подсчета ссылок у тебя удалились версии, которые не должны удаляться? «Ð ÑƒÐºÐ°Ð¼Ð¸ в конце дня» ты такие вещи не разрулишь.
Можно, наверное, предложить и другие схемы сборки мусора. Я тут не спец, мне эта тема не особо интересна. Мне Scale-Up интересен.
21.07.21 05:22:40
Не, про CAP-теорему тут не стоит. Её еще понимать надо правильно
Я уже пояснял про целостность. Целостность ACID  это целостность тухлых данных для аналитических запросов. Целостность CAP  это целостность актуальных данных, которая нужна для операций обновления с проверкой инвариантов, которую нельзя выполнить без доступа к этим актуальным данным. А ведь именно про эту вторую целостность мы и говорим. Если я правильно понял, конечно.
Так вот, мы стремимся к тому, чтобы вероятность сбоя софтового уровня из-за параметров потока запросов была существенно ниже вероятности сбоя системного/аппаратного уровня. И в этом, вероятностном смысле, мы можем иметь «Ð´Ð¾ÑÑ‚аточно сильную» консистентность и опираться на предоставляемые ею гарантии при разработки приложений
Кстати, да, ты интересный вопрос поднял. Даже один узел может быть сбойным, но при этом его сбойность незарегистрирована и он портит ответы на запросы. Потому ответы должны перепроверяться хотя бы еще одним узлом. Чего, насколько мне известно, не делает подавляющее большинство распределенных систем, поскольку эту жутко дорого.
Да, ECC в памяти позволяет снизить риск возникновения ошибки до практического нуля, но оператива, мягко говоря, является не единственным звеном. RAID-контроллер может зарегистрировать ошибку чтения, может зарегистрировать отличие томов при запланированной сверке, но он не сможет ничего сделать, если некорректные данные софт съел как корректные. Особенно если сам же этот софт эти некорректные данные туда и записал.
Маленькие кластеры из 3-5 машин многоядерных машин (или стоек, не важно) будут достаточно надежны, чтобы обеспечить весьма высокую производительность в рамках сильной консистентности
Два узла в постгресе в режиме синхронной реплики. Всё, это потолок. По мере роста числа машин производительность очень сильно падает и целостностью приходится жертвовать  так делает Galera, кооторая притворяется синхронным мультимастером, хотя на самом деле не является им, а только делает самые важные проверки по индексам и асинхронно реплицирует остальные данные, таким образом оставаясь без «ÑÐ¸Ð»ÑŒÐ½Ð¾Ð¹» целостности данных.
Важно то, что сильная консистентность упрощает дизайн софта и снижает стоимость его сопровождения
Важно то, что простую систему проще разрабатывать и сопровождать. Всё просто: простую распределенную систему просто делать и сопровождать  сложную распределенную систему со сложными алгоритмами выбора координатора сложно делать и сопровождать. Если же твоя распределенная система имеет единственного координатора, при падении которого отваливается вся система, то доступности у тебя не будет, но система будет сильно проще. Если с целью гарантий инвариантов (порядок, уникальность, сумма) ты делаешь требующие инвариантов записи строго последовательно на координаторе, то система оказывается простой и дешевой, но с низкой производительность и доступностью (по крайней мер при записи с проверкой инвариантов). И не обязательно при этом именно иметь строгую целостность, и не обязательно задействовать CRDT.
Причем, отсутствие наследия заметно снижает все стоимости  еще один фактор, не имеющий отношения к распределенности и целостности.
Если ты так уверен в расслабленных моделях консистентности, то CRDT-флаг тебе в руки :) Я же — пас. Если меня явно не попросят и не поклянутся мамой, что знают, на что идут, я этим заниматься не хочу
Так и я не буду. Готового решения-то у меня нет, и не факт что оно будет. Я предпочту полететь на боинге 737, чем на еще не выпущенном новом опытном самолете.
Гораздо проще ослабить консистентность изначально сильно консистентного хранилища, чем костылять усиление консистентности над EC-хранилищем. Хотя последние и быстрее
Даже монга на одном узле использует довольно хорошую целостность данных за счет движка WiredTiger. Просто, не нужно впадать в крайности вроде «Ñ‚Ð¾Ð»ÑŒÐºÐ¾ ACID» или «Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Eventual Consistency».
byko3y ★★★ (
21.07.21 05:37:32
Если ты хочешь сделать распределенный сборщик мусора для такой структуры данных, то тебе нужен либо трассирующий сборщик мусора (я б не стал, хотя и можно), либо атомарные идемпотентные счетчики. Но в любом случае тебе понадобится сильная консистентность. Ты же не хочешь, чтобы из-за неправильного подсчета ссылок у тебя удалились версии, которые не должны удаляться?
Я могу придумать сценарий, когда она не нужна. Собственно, я его уже описал в предыдущем сообщении: сборщик мусора периодически получает сообщения от распределенных агентов об их активности и о состоянии их локальных счетчиков/локальных ссылок/изменениях числа ссылок; ему не нужна эта информация прямо здесь и сейчас в самом актуальном виде, ему достаточно знать, что когда-то в прошлом никто не использовал некую версию и не мог получить к ней доступ в ближайшее время. Да, версии удалятся позже, возможно даже сильно позже, тем позже, чем слабее требования по предоставлению сообщений от распределенных агентов  но зато необходимость в строго целостности отпадает.
x86 на самом деле занимается примерно тем же, только «ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ» от распределенных агентов приходят очень быстро, порядка 30 циклов процессора для многоядерного однопроцессора, порядка сотен циклов для многопроцессорной системы  то есть, как бы «Ð¼Ð³Ð½Ð¾Ð²ÐµÐ½Ð½Ð¾», сравнимо со скоростью доступа к некэшированной памяти, и потому их можно синхронно подождать.
А в Firebird вообще сборка мусора по умолчанию отложена до следующего чтения кортежа  то есть, она может выполнится даже через год после того, как пропали все ссылки на версию кортежа. Хз, сколько это будет в циклах процессора.
byko3y ★★★ (
21.07.21 06:12:00
ему достаточно знать, что когда-то в прошлом никто не использовал некую версию и не мог получить к ней доступ в ближайшее время
Если мы говорим, о CoW-tree, то удаляем мы не версию, а узел дерева, который может косвенно принадлежать нескольким версиям. Сходу я не могу провалидировать твою схему. Можно потом будет попробовать промоделировать этот сценарий в Мемории вживую, я, наверное, могу сделать специальный Store для этого (тут могут быть легальные ограничения для меня, а не технические).
Насчет CRDT, ты можешь попробовать это все самому делать. Есть хранилища с различными свойствами, можно лепить CRDT-шки над ними. Riak, вроде как, прямо на это и заточен даже. Т.е. можно делать операционную БД «ÑÐ°Ð¼Ð¾Ð¼Ñƒ», и, более того, те, кто идет по модной сейчас дорожке микросервисов,
по факту будут делать свою операционную СУБД. Или это будут только микросервисы без состояния, то есть «Ð½Ðµ настоящие». Можно, конечно, отбрехаться, что облачные архитектуры всячески навязывают выделенную managed DB, и на долю девелоперов остаются только сервисы без состояния.
Но тот, кто вступит на эту дорогу, делать свою БД, узнает, что самое сложное тут  это вовсе не распределенность, а поддерживаемые всем стеком типы данных.
21.07.21 05:53:25
Просто, не нужно впадать в крайности вроде «Ñ‚Ð¾Ð»ÑŒÐºÐ¾ ACID» или «Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Eventual Consistency».
Можно так? «EC только при условии, что вы точно знаете, что вам нужно именно это и осознаете, во что это вам обойдется».
Насчет кластера из 3-5 узлов (или стоек), я не про Pg говорил. Этот еще лет 10 будет пытаться лечить ограничения своей архитектуры. Я говорил про то, что само такое железо, благодаря своему профилю отказоустойчивости, может
в принципе обеспечить высокую абсолютную производительность. Задача софта  утилизировать её. Pg в этом смысле  не лучший вариант. Хотя и хороший во всех остальных смыслах.
Дело в том, что имея Меморию на руках, я технически могу это железо утилизировать. Потому что Мемория дизайнится для scale-up-сценариев: я там контролирую весь путь от io uring/SPDK-exposed устройства и до обработки данных на акселераторах. Там по умолчанию SWMR-сериализованные транзакции с MVCC, но можно делать высокоуровневый шардинг, чтобы ослаблять консистентность там, где надо, и на столько, на сколько надо.
SWMR (single writer, multiple readers), кстати, очень классная схема. Вообще гениальная, если в сочетании с ПСД. Она позволяет атомарно сбрасывать состояние RAM на NVmem так, что новые данные никогда не перезатирают старые, и не требует сборки мусора (но все равно требует не-атомарных счетчиков).
Что касается софта в такой модели. Я буду на основе ПСД делать хранилище для системы сборки в своем форке Clang. Это будет BaaS для IDE-шек, который возьмет на себя весь цикл: редактирование, сборка, аналитика и т.д. Компилятор там умеет в метафункции и через них будет тесно интегрирован с системой сборки.
20.07.21 23:09:11
виртуальные адресные пространства, сегментные регистры - это костыли для совместимости
процессор 86 унаследовал часть команд процессора 8080, когда программировал на ассемблере меня удивило что большая часть кода команд 86 и z80 совпадало хотя ассемблер-мемоники команд разные (z80 также произошёл от 8080)
процессор 8080 мог адресовать только 64кб оперативы чтобы программы 8080 исполнялись на 86 добавили сегментные регистры (так ли это я информацией не владею, это моё мнение, в котором я абсолютно уверен)
Это всё равно что человек делал одноэтажные домики, а тут внезапно попросили сделать многоэтажку и он ставит один дом на другой склеивая их изолентой.
Самое удивительное при переходе с 86 на 386 intel их сохранил и расширил
слава богу что развитием 386 на 64 рулила AMD и в 64битном режиме от них избавились, был бы это intel и сегментные регистры появились бы и там
прелесть Си что он является универсальным языком для всех аппаратных платформ
надеюсь что в Си появятся абстракции для не синхронной быстрой памяти
21.07.21 01:41:13
несколько программ могут изменить один файл с непредсказуемыми последствиями — но никто об этом не парится
Вообще-то, об этом парятся разработчики операционных систем, позволяющие явно задать режим работы с файлом, что и делают все приличные программы.
Единственное что — это ОС проверяет конфликты имен файлов и не дает удалять непустые каталоги.
Слава богу, нет. Нормальные ОС поддерживают полностью атомарный режим работы с содержимым файлов.
LamerOk ★★★★★ (
21.07.21 09:50:20)
Последнее исправление: LamerOk
21.07.21 06:26:28
Насчет CRDT, ты можешь попробовать это все самому делать. Есть хранилища с различными свойствами, можно лепить CRDT-шки над ними
Чего ты прилип к CRDT? Смотри: для большей части данных строгая целостность не нужна, вроде комментария к заказу, сканов документов, фамилии заказчика  мы можем немного подождать их; для меньше части данных, вроде первичного ключа или уникального значения или резервирования товара на складе, мы можем применять небольшую БД со строгой целостностью. Всё, очень просто, очень тупо, не нужно даже таких заморочек и закоса под распределенность, как в ActorDB.
Необходимость более строго целостности данных, чем вообще-то нужно для задачи, возникает в реляционных СУБД потому, что запись в одной таблице должна ссылаться на ключ записи в другой таблице, и все данные утыканы с ног до головы этими ключами, за целостностью которых нужно следить. Всё становится просто в тот момент, когда ты понимаешь, что большая часть этих этих гарантий никому не нужны, кроме самой СУБД, проблемы которой мы вынуждены решать, а не наоборот, СУБД решает наши проблемы.
В чем было решающее преимущество MongoDB (название NoSQL базы сейчас не важно)? Она просто кидала цельный документ как единое значение, без необходимости поддерживать какие-то связи между этими документами. Далее изменение структуры данных не требовало вообще никаких операций над хранилищем  менялось только представление. Сравни это с подходом РСУБД, которые при смене структуры данных будут перекраивать все таблицы под новые условия.
Но тот, кто вступит на эту дорогу, делать свою БД, узнает, что самое сложное тут — это вовсе не распределенность, а поддерживаемые всем стеком типы данных
Да. Я уже давно оббил себе всё лицо этими граблями. БД начинались со встроенных баз, и закончатся ими же. РСУБД были временным помешательством, которому пора на помойку. Почему-то создатели СУБД часто считают, что пользователь может хранить в БД только данные плана «Ð¾Ð´Ð½Ð¾ число» или «ÑÑ‚Ñ€Ð¾ÐºÐ° длиной 10 символов». Так действительно было когда-то очень много лет назад, когда компьютеры толком мало что могли полезного делать.
По большей части, если подумать, реляционная модель как раз была придумана для того, чтобы натянуть сложные данные на скалярную модель. Но очень быстро выяснилось, что по мере роста сложности данных реляционная модель оказывается очень неэффективной, поскольку то, что могло быть выполнено линейным чтением очень быстро, выполняется кучей запросов по индексам. Ну то есть теоретически оно выполнимо, но практически смысла в этом нету.
Мало кто понимает, что Clickhouse  это самая обыкновенная СУБД, которая просто хранит данные в том виде, в котором они нужны, а не в том виде, в котором захотелось конкретной РСУБД. Упрощенный вариант такой СУБД, без репликации, без снимков, без поддержки SQL можно написать менее чем за неделю. Современное железо свободно обрабатывает сотни миллионов запросов к ассоциативному массиву в секунду, но какой-нибудь MySQL в тепличных условиях отрабатывает порядка сотни тысяч, или под миллион если дергать InnoDB API напрямую. То есть, три порядка потери производительности по сравнению с теорией даже на CPU, а если вспомнить про GPGPU, у которого производительность свыше миллиарда доступов к ключам в секунду?
byko3y ★★★ (
21.07.21 06:46:44
Можно так? «EC только при условии, что вы точно знаете, что вам нужно именно это и осознаете, во что это вам обойдется»
Насчет кластера из 3-5 узлов (или стоек), я не про Pg говорил. Этот еще лет 10 будет пытаться лечить ограничения своей архитектуры. Я говорил про то, что само такое железо, благодаря своему профилю отказоустойчивости, может в принципе обеспечить высокую абсолютную производительность. Задача софта — утилизировать её. Pg в этом смысле — не лучший вариант
Если говорить про асинхронную репликацию, то постгрес вполне справляется с задачей. Он может выдать и 5, и 10, и 20 узлов, на которых будут параллельно выполняться запросы.
byko3y ★★★ (

Related Keywords

, General Gaida, Sakhalin Region,