FastComments.com Blog
Sun Mar 29 2026
...

FastComments е готов за космоса!

! Тази статия съдържа технически термини

Какво ново

Всеки FastComments точка на присъствие сега записва локално и асинхронно репликира данните си към всички останали възли. Това ще предостави увеличена надеждност в сравнение с предишната система и ще ускори инструментите за модериране за потребителите в някои региони, с определени компромиси.

"Готов за космоса" е малко оптимистично, но идеята е, че бихме могли да разположим FastComments на различни планети и в крайна сметка системата ще се синхронизира. Потребителите на Плутон обаче ще трябва да изчакат около ден, за да видят промените в предстоящата си фактура, тъй като в момента само един мастър на регион може да агрегират информацията за фактуриране.

Някои история, защо промяната

Когато FastComments първоначално стартира, имахме много типична архитектура. Имахме прокси слой, слой на приложението, база данни, няколко реплики, а по-късно реплики в различни региони и облачни доставчици за допълнителна надеждност.

В крайна сметка преместихме репликите на DB във всички зони, където е основната част от нашите потребители, и разположихме приложението там, и създадохме собствена DNS и прокси система (описана в по-късен пост) за маршрутизиране на заявки към най-близкия възел на приложението. Това прави четенето бързо, но записването по-бавно, тъй като сега вместо да чакате един кръг HTTP до задния план, чакате кръг HTTP до близък възел, а този възел може да направи множество записвания на база данни обратно към основния. Не е добре!

Затова, за да се справим с това, реорганизирахме много области на приложението, за да приемат readPreference в аргументите на функция, така че повикващите да могат да решават колко остарели са готови да приемат прочитите си, и отгоре на това направихме повече записвания (като записване на статистика на модератора при действия на модератор) fire-and-forget. Не е идеално, но значително ускори нещата.

Един проблем, с който се сблъскахме при работа с Mongo глобално, са мрежовите разделения. Ако достатъчно възли бъдат откъснати, четенето спира, тъй като всеки възел става несигурен дали е приемливо да обслужва четения. Има някои решения за това, но краен случай се явява хаотичен. Това не е теоретичен проблем - случва се достатъчно често, че получихме 3AM страници, от които се уморихме, дори опитвайки да настроим Mongo да бъде наред с несигурността при избор на репликации до една минута разлика. За съжаление, мрежите от Сао Пауло до Фалкенщайн, например, просто не бяха много добри при някои от нашите хостинг доставчици. Настройването на контрол на натоварването и подобни помагаше, но не решаваше проблема.

Свещеният граал на решението, при условие че ви устройват определени компромиси, е способността да приемате записванията локално на този възел (който има доста добро оборудване, RAID и т.н., което е малко вероятно да се повреди) и да съобщите на потребителя, че данните му са запазени. Можете също така в точката на присъствие да имате втори възел като гореща реплика за надеждност.

Така че стигнахме до това. Орегон, Вирджиния, Фалкенщайн, Сао Пауло, Сингапур, всичките са свои собствени реплики и приемат записвания. Разгъването на ЕС (макар че има само три PoP) има същото поведение.

Как работи

Някои от това са покрити в предишния раздел, но TL;DR е, че е CRDT-lite. Създадохме прокси (на Rust, защото, разбира се), който стои между приложението и Mongo и го прави многомастърно. Проксирането е осведомено за връстници, управлява контрольни точки, репликация, мониторинг и начална синхронизация. Това е многомастърно заменяне за репликационната система на Mongo, включително за някои DDL команди.

Разликата от други инструменти е, че не следва oplog. Следването на oplog или използването на потоци от промени не би работило, защото те показват само крайното състояние на обекта след записването, което прави невъзможно справянето с конфликти. Трябва да уловите всяка операция $set, $inc и да репликирате самата операция.

Това е решение, специфично за домейна. То не би работило за всички продукти. Можете да кажете, че е домейнно съсредоточен дизайн :). То работи за нас, защото от самото начало много внимателно само $set полетата, които променяме в документите - никога не използваме replaceOne на Mongo, например. Същото важи и за броячите. Вие никога не правите SET VOTES = 5. Вместо това, ще напишете INCREMENT VOTES BY 5, тъй като това позволява в крайна сметка консистентност. Разпределените блокировки се обработват от не. Само един възел на кластера има флаг, зададен да изпълнява cron. Въпреки че това може да изглежда ограничено, можем да купим сървъри с терабайти RAM, така че можем да направим този компромис, за да намалим риска и сложността.

Четене на собствените си записвания

За разработчици, използващи API, трябва да можете да четете собствените си записвания, както преди (направете API повикване за създаване на коментар, след това изредете коментарите и вижте новия запис в този списък). Условието е, че не можете да направите това между регионите. Ако вашият бекенд работи в само един регион, като нас-запад, то тогава трябва да можете да четете собствените си записвания, освен в случая, че между записването и четенето, когато този възел падне и вашата DNS кеш се актуализира, за да сочи към най-близкия възел. При условие, че това не се случи, четенето на собствените ви записвания е надеждно.

Можете също така да прикрепите коя точка на присъствие ще използвате. Повече информация тук.

Тестване и миграция

Приблизително половината от кода в системата е тестовото оборудване, рамката и тестовете. Все пак, освобождаването беше малко неравно, като отне повече времена неработоспособност (1 час за ЕС и 20 минути за нас-глобално), отколкото желаното, но сме щастливи, че преминахме през този етап и благодаря за търпението ви!

В заключение и какво означава това за вас

FastComments сега трябва да бъде по-бърз и по-надежден от всякога, и сега можем да се върнем към работата по функции :)

Наздраве!