voidlizard.online
117 subscribers
160 photos
6 videos
5 files
105 links
Haskell, распределённые системы.

Разработка P2P CAS hbs2 и приложений для него

Распределенный git aka hbs2-git

hbs2.net

Прочее https://t.me/genedrd47r (мото, EUC, скайдайвинг, дайвинг)
Download Telegram
stm-containers vs самодельное

test-ncq test:ncq2:concurrent1 32 10000

10000 блоков размера до 256Kb, 1..32 потока.

Подозреваю, что внутри stm-containers и увижу примерно тоже самое. Выплески отношу на счёт gc.

Ну как по мне с отдельной библиотекой ради такого связываться не стоит
Ноут догнивает — к чести марки, корпус держится на последних болтах, а электронной части хоть бы хны. Надеялся, что он доживёт до пришествия ноутов на ARM (мак не предлагать, не заходит), но видимо нет, Linux на ARM ноутах еще не заводится нормально. Думаю, не сделать ли мобильный сетап на безумной платформе типа
GPD Win Max 2 — а несовместимый с жизнью экранчик компенсировать AR очками, встречал описания подобного. Из опасений — на линуксе тоже не заведется. По начинке более чем достойно, кроме прямого применения (читать, немного писать в поездках) — просмотр видео 4K с гоупрох и таскать в мотоцикле (отсюда требования к минимальным размерам). Вроде в стимдеке примерно такая же платформа и всё работает. Обидно будет, если уже через год появятся ARM
Еще интересное. Конструкция TVar (Seq HashRef) ведёт себя не хуже TQueue/TBQueue очереди, однако позволяет естественно читать пачками с одного или другого конца, что удобно и позволяет простым образом чуток балансировать нагрузку CPU vs IO.
#haskell а, ну и fdWrite из System.Posix.IO.ByteString работает процентов на 15 быстрее, чем из Data.ByteString.hPutStr
аналог тайммашины для проекта нужен прямо сейчас. может, для nvim что-то такое есть — что бы были снапшоты с таймстемпами и можно было между ними быстро переключаться
Пока в соседнем чате идут споры (ну как — споры, просто появляются люди, которые абсолютно всё уже знают заранее, куда другим идти и что там делать и как) — и планируется построение глобальной распределенной системы в которой всё будет хорошо — корпорации и AI будут унижены и вообще общее благолепие — примерно скажу, как я всё это вижу.

А вижу я это как на этапе 0 — просто соглашение о структурах данных, и не так важно, как эти именно структуры доедут до конечного потребителя.

Идея, в общем, не нова — есть тот же nostr, на него любопытно посмотреть в плане того, во что можно превратить изначально вроде бы разумную идею.

В web в своё время появились гиперссылки — но по факту, ссылка же ничего физически не адресует и нет никакой гарантии, что для разных пользователей одна и та же ссылка будет указывать на одно и то же (что?). Сейчас ни домены, ни ip адреса, ни строчки после имени домена в URL (да и до него тоже) не имеют никакого смысла.

Сейчас — это когда мы вступаем в эпоху глобального мультичебурнета.

Хэш ссылка — напротив, адресует нечто конкретное, но тоже вопрос — а что именно?

Ну и нет какого-то всеобщего способа хэширования. Последняя проблема выглядит решаемой.

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

Система это, в общем-то некий глобальный CAS и основное, что он должен уметь делать — это отдавать контент по хэш-ссылке.

Второе, что он должен уметь делать — это поддерживать мутабельные переменные, и эта самая мутабельность в распределенных системах — целая отдельная большая тема.

Углубляться дальше пока незачем, т.е на фазе 0 — нужно хотя бы согласовать виды хэш-ссылок и подумать, как будут добавляться новые алгоритмы хэширования. Что-то мне подсказывает, что даже здесь нас ожидают проблемы, достаточно посмотреть на git, например.
Неловкий момент, когда высосал из пальца фильтр тупо на TVar + unboxed vector и он работает примерно так (первый тест — библиотечный блум фильтр bloomfilter)

Но потом говорящие собаки говорят, что ты высосал из пальца то, что уже используется в

- RocksDB (filter block)
- Parquet
- LSM-based системах

и вообще Твой подход — это blocked Bloom filter + multi-bit hashing

См. статью: "Blocked Bloom Filters"

ну... пусть будет тогда, что ли. Так-то мне всего лишь надо было что бы фильтр в STM работал
Еще к фильтрам. Как и было изначально, .cq индексы сами по себе фильтры. Надо просто снижать их количество при помощи merge и/или делать поиск по ним параллельным, что и попробую сейчас запилить. Фильтры это хорошо, но с ними очень много проблем - и с масштабированием, и отсутствием готовых, и непонятно что с инкрементальностью. Иерархический блум например по сложности как весь ncq, + были придумки насчёт инкрементального куку-индекса, но он по сложности тоже больше самого ncq. Ладно...
Вот еще загадка века — зачем нужен PAXOS если есть PBFT. Гугл говорит нам, что

Finally, based on the evaluation results, it was found that the PBFT algorithm has a speed five times faster than Raft and six times faster than Paxos to reach consensus. So we consider the PBFT algorithm to have the best speed and scalability.


https://ieeexplore.ieee.org/document/9975938

Самое интересное в этом то, что PBFT это типа 2001-ый год, что ли. 1999!!

И он простой как тапок, там 20kloc это потому, что на C++, на х-ле сам алгоритм (минус gossip минус сеть минус сторейдж, чисто FSM) — строк триста. И главное его умом понять можно, а не как PAXOS.

Т.е оно проще даже Raft, кажется. Если же к согласуемому стейту применимы некоторыe принципы CRDT — то становится еще проще.
А как чисто технически СРКНы собираются мониторить "экстремисткие запросы" в гугл или duckduckgo ? TLS-то вроде еще работает, а логи гугл им не выдаёт. История браузера? Но кто в здравом уме будет такое делать не в incognito режиме? Он конечно так себе инкогнито, но историю точно не хранит. Опять же, LLM-ы охотно общаются на любые темы экстремисткие темы, это ж не про секс.
в 0.25.2 есть скрытый критичный баг в сторейдже. у кого не выстрелил — повезло. остальным не рекомендую 0.25.2, придется его пропустить и переходить сразу на 0.25.3
Desperation Driven Development всегда работает. Единственная проблема, что отчаяние должно быть неподдельным. Т.е заранее (что бы сэкономить время) не получится.
Ну и день. Когда тесты проваливаются, и ты патчишь код, но ничего не помогает, потому что ошибки в тестах. Ладно, эта пилорама — график пропускной способности NCQ2 от числа потоков.

Красным пунктиром — baseline, то есть просто берёт N блоков и пишем в файл через appendFile.

Это с пересчётом хэшей. Учитывая то, что лог реально пишется в один поток в один момент времени — и всё остальное это мои ухищрения с fsynс и батчингом.

Т.е клиент-то зовётся из N потоков, но в итоге реально на диск пишет один. То, что это быстрее, чем просто в файл записать, я считаю, победа. Ведь тут еще построение индексов идёт параллельно — и всё равно быстрее просто записи в файл
"Говорящая собака" пошло из интервью, кажись, с Марковым (?), который сравнил LLM с собакой, которая притаскивает хозяину всякие ништяки и ждёт, пока хозяин похвалит. LLM перебирает реплики, пока мясного не устроит результат и он не отвяжется
Хотел сделать бенчмарков относительно rocksdb, но по славной традиции ни один никсовый флейк не собирается, а в никсовом пакете нет db_bench. Я уже и забыл, что основной причиной не использовать rocksdb было то, что какой-то с ним вечно гемор. Софт на плюсах -> скорее всего не соберётся. ни сам, ни то, что с ним линкуется. Закон!
Сделал тест напротив rocksb, пока результаты приблизительные, т.к. в rocksdb черт ногу сломит, но вроде бы я попытался записать 100K значений размером 96K (среднее 64..256), потом для них lookup на холодную. ncq2: median 0.171 0.171 секунд на 100K чтений.

rocksdb: readrandom : 7.041 micros/op 142013 ops/sec 0.704 seconds 100000 operations; 8 - 0.704

тестовая обвязка для rocksdb http://hbs2.net/tree/En5Fy2s3RKJcc924wseYtwQ88M3sBLnz4UmHKx4Zz1Tj

заметим, что в тесте скорости ncq2 считает хэши, чего rocksdb не делает - и скорость в районе 900Mb/s,

ну... хрен знает. но вроде бы перспективно.

UPD: rocksdb - 1.4Gb/s, если ncq2 отключить генерацию рандомных строк и подсчёт хэшей - то 1.9 .. 2.2 Gb/s. Не, ну это норм, получается
JHC ожил. Какой-то чувак его форкнул и что-то туда поддерживает. Это я реддит почитал от прокрастинации. Ничего себе! Вообще нам бы не помешал еще один компилятор хаскелла. Даже у плюсов больше одного компилятора есть. Но так-то смотришь на список расширений языка в проекте и понимаешь, что безнадёжно
Интересно, если какие-то общепринятые/готовые/достаточно хорошие эвристики для сборки мусора в lsm-подобных иммутабельных файлах? Т.е с одной стороны их лучше держать размером поменьше. т.к. любая трансформация -> полное переписывание. С другой стороны их лучше бы держать размером побольше => т.к. меньше файлов -- быстрее лукап, а лукап тут O(n) от количества файлов. С третьей стороны, а что если файлы будут ОГРОМНЫЕ? С четвёртой тут можно эвристики придумывать бесконечно, надо с чем-то достаточно хорошим закрыть этот вопрос и дальше двигаться
Я был внутри двух мощных волн хайпа - SDN и БЧ. Если взять соотношение сигнал/шум оттуда и применить для анализа заявлений в рамках текущего хайпа - можно почти на все наплевать и игнорировать. Т.е делить надо где-то на два-три порядка, а настоящее начнется, когда волна схлынет. Если, конечно, подход применим. Помню, какой-то тётке в Стэнфорде дали (или заявили, что дали) 30 миллионов на БЧ, который решает все проблемы БЧ - когда надо быстрый, когда надо медленный. Где ее стартап? Где-где. Именно там, да.
Короче, сборка мусора. Придется всё переделывать. В новой модели: индекс (n) -> (k) данные т.е файл индекса индексирует множество данных. Связь не по соответствию индекса файлу, как в гите, а в каждой записи индекса - ссылка на ключ файла. Ключ - 32 битное целое, монотонный счётчик. Файлы данных мержатся редко и до определенного размера, индексы — (неограниченно? до какого-то лимита?). Данные не трогаем. Индексы мержим. Время доступа остаётся близким к O(1), мерж индекса - O(m+n), память O(1). Индекс где-то на два порядка меньше данных, 48 байт на запись. при населённости около 0.6 — 16Gb индекс может адресовать ~ 48 терабайт данных
Алгоритм мержа индекса: I, J ∣ T(I) > T(J) ⟹ K = I ∪ (J ∖ I), T(K) = T(I)
I,J - подряд идущие по таймстемпу файлы, K - новый файл. В стейте заменяем I, J на K, потом отложенно "актуализируем" стейт, т.е удаляем всё, что не в нём, если
refcount = 0.

Стейты пишутся срезами, один срез - один файл, в нём все адресуемые элементы — файлы данных, индексы, счётчик, и связи файлов с индексами, которые приходится ввести, т.к. больше индексы не соответствуют файлами по именам.

Удаление мусора: из индекса удаляются дублирующие (по ключу) данные. Если затираются томбом — ну, значит, остаётся томб.

Для любого томба — его можно удалить отдельным проходом, если больше нигде нет на него ссылок.

Сборка мусора для файлов данных: удаляем блоки, если их нет в индексе или они томбы.

Целостность обеспечивается стейтом. Т.е пишем файлы, добавляем в состояние. Источник правды — файл(ы) стейта, дамп стейта = коммит транзакции. Лишнее (отсутствующее в текущем стейте) удаляем отложенно и когда оно точно не используется.

Из плюсов — файлы индекса маленькие, их быстро мержить. Файлы данных можно мержить, можно нет, на скорости чтения особо сказываться не должно.

Такие дела
Что-то в нашем этом хаскелле не хватает гарантий хвостовой рекурсии. Я бы написал что-то такое tailrec (what ...) и что бы компилятор если не может гарантировать, что хвостовое — шоб ошибку генерил. А то палево прямо. Интересно, можно такое сделать? Это мне как в сишке не хватало гарантий экстента.