Обновление Safe Network 🇷🇺 1 сентябрь 2022 г

Это машинный перевод. Оригинал на английском здесь: Update 01 September, 2022

Это была хорошая неделя для отслеживания незначительных аномалий и ошибок, и мы просим @joshuef объяснить, как мы решаем проблемы, связанные с сериализацией сообщений и нагрузкой на сеть. Что-то :bulb: это…

Общий прогресс

@davidrusu исправлял проблему, из-за которой взрослые пропускали антиэнтропийные зонды перед разделением, поэтому у них не всегда была необходимая подготовка. актуальная информация о разделах.

Тем временем @bochaco работает над списком улучшений в отношении как мы храним регистры (изменяемые данные — CRDT), включая изменение некоторых внутренних API-интерфейсов хранилища. чтобы избежать клонирования некоторых объектов, записи отдельных операций (вместо этого в виде одного файла, который может быть перезаписан другим незавершенным CRDT), удаления некоторых неиспользуемых типов ошибок хранения и добавления дополнительной контекстной информации к другим, а также разрешения хранения команд редактирования регистров для всех случаев (теперь порядок входящих команд должен быть менее важным, т. е. нет условия гонки, чтобы иметь CreateRegister Cmd перед EditRegister, который есть на main).

А @chriso улучшил обработку ошибок в sn_node, включая типы сообщений об ошибках, которые отправляются клиенту, чтобы упростить работу пользователей. чтобы увидеть, что происходит.

Сериализация сообщений

Из зондирования @southside мы видели, что сеть, похоже, испытывает нагрузку из-за больших PUT данных. Его тесты загрузок более 2 ГБ пролили свет на проблему, которая может быть частью причины… и это может быть просто слишком много сообщений.

Это не означает, что мы отправляем слишком много (хотя мы могли бы отправлять меньше). Но похоже, что напряжение при формировании сообщений и скорость, с которой мы это делаем, чертовски высоки.

Это было то, что мы видели в heaptraces использования памяти узла в течение некоторого времени, но путь исправления был не совсем ясен.

Мы сериализуем каждое сообщение в байты, и, учитывая, что нам нужно создавать разные MsgHeader для каждого узла, не так много способов обойти это.

А что, если бы мы этого не сделали?

Тем не менее, тыкание @southside снова выдвинуло вопрос на первый план, и @joshuef, который некоторое время был раздражен количеством мемов, используемых сериализацией, решил снова удариться об него головой.

И на этот раз пришла другая идея. Ранее мы пытались устранить необходимость в Dst (назначение, информация о том, куда должно быть отправлено сообщение)… но мы не можем этого сделать и сохранить наши потоки Anti-Entropy живыми. Так что это был нестартер.

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

ТАКОЕООООО…

Таким образом, после небольшого рефакторинга в qp2p, нашей сетевой оболочке, теперь мы можем отправлять три разных набора байтов по нашим соединениям, и из них только один (наш Dst) действительно нужно изменить, если мы повторная отправка одного и того же сообщения на разные узлы!

Это означает, что вместо 7-кратной работы при отправке сообщения старейшинам раздела, это 1x - и мы повторно используем Bytes для наших MsgHeader и Payload! Нужно только перекодировать Dst каждый раз.

Аккуратный.

Но подождите… это еще не все!

Теперь это приличное снижение вычислительных затрат на отправку сообщения. Но у него также есть еще одна проблема с точки зрения памяти. Ранее во время сериализации MsgHeader мы сформировали наш one набор Bytes, скопировав payload (фактическое сообщение, которое мы отправляем… так что ~ 1 МБ на кусок), так что это некоторая работа по выделению памяти, и это означает каждое сообщение имело свой собственный уникальный набор байтов, представляющих одинаковую полезную нагрузку. Таким образом, отправка одного фрагмента четырем взрослым будет иметь пять копий этого фрагмента в памяти. :frowning:

Но теперь мы используем дешевую копию Bytes (который является типом указателя на базовые данные…), поэтому дублирование памяти не требуется! Таким образом, для отправки одного фрагмента четырем взрослым теперь нужна только одна копия данных :tada:

В конце

Вот как выглядит main. Здесь мы видим три прогона 250 клиентских тестов (один PUT размером 5 МБ и 250 клиентов, одновременно пытающихся получить эти данные), а затем 10 прогонов полного стандартного набора тестов sn_client.

А это на ожидающемся PR:

Вы можете видеть, что пики для этих тестов достигаются быстрее и с меньшей общей памятью (~ 900 МБ против 1800 МБ). И вместе с этим наш новый тест измеряет пропускную способность при отправке одного WireMsg 1000 различных Dst.

  • основная пропускная способность: 7,5792 МБ/с
  • Пропускная способность PR: 265,25 МБ/с

Что тоже весьма приятно.

Ветвь еще не объединена, нужно сделать последнюю уборку, прежде чем мы ее добавим, но это похоже на многообещающее изменение, которое может помочь узлам работать на более компактном оборудовании (или, надеюсь, позволить @southside загружать больше в свои локальные тестовые сети!? :скрещенные пальцы: )


Полезные ссылки

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

Как проект с открытым исходным кодом, мы всегда ждем отзывов, комментариев и предложений сообщества - так что не стесняйтесь, присоединяйтесь и давайте вместе создадим безопасную сеть!