Замена маршрутизатора:
Производитель A: 10% сломано Замена маршрутизатора (или прошивки) почти всегда решает проблему. |
Добавление усилителя Wi-Fi:
Маршрутизатор A: 90% работает Дополнительный маршрутизатор почти всегда ухудшает ситуацию. |
Все беспроводные сети, будь то LTE или mesh-сети, рано или поздно падают, но я могу поставить на то, что ваша сеть Wi-Fi менее надёжная, чем телефонное соединение LTE. На конференции Battlemesh v10 мы все сидели в комнате с десятками экспериментальных неправильно сконфигурированных маршрутизаторов Wi-Fi с открытыми сетями, которые могут дать выход в Интернет, а могут и не дать. Из-за чего сеть бывает надёжной или ненадёжной?
После нескольких лет возни с этими технологиями (в окружении кучи инженеров, работающих над другими проблемами распределённых систем, которые, как выяснилось, обладают теми же ограничениями), я думаю, что могу сделать выводы. Распределённые системы более надёжны, если вы можете получить сервис от одного узла ИЛИ от другого. Они становятся менее надёжными, если сервис зависит от одного узла И от другого. Числа сочетаются мультипликативно, так что чем больше у вас узлов, тем быстрее отвалится сервис.
Если взять пример, не связанный с беспроводными сетями, представьте работу веб-сервера с базой данных. Если они на двух компьютерах (реальных или виртуальных), то ваше веб-приложение упадёт, если веб-сервер И сервер базы данных не работают идеально. По существу, такое решение менее надёжно, чем система, которой нужен веб-сервер, но не нужна база данных. И наоборот, представьте, что вы организуете отказоустойчивую систему с двумя серверами баз данных, так что если один упадёт, то мы переключимся на другой. База данных будет работать, если основной ИЛИ вторичный сервер в строю, и это намного лучше. Но это всё ещё менее надёжно, чем если бы вам вообще не нужен был сервер баз данных.
Вернёмся к Wi-Fi. Представьте, что у меня маршрутизатор от производителя A. Маршрутизатор Wi-Fi обычно так себе, так что ради примера, предположим его надёжность на уровне 90%, и для простоты определим это как «он хорошо работает для 90% пользователей, а 10% испытывают досадные баги». Итак, 90% пользователей с маршрутизатором марки A будут довольны и никогда его ни на что не поменяют. Остальные 10% будут недовольны, так что купят новый маршрутизатор — от производителя B. Этот тоже хорошо работает у 90% пользователей, но баги не взимосвязаны, так что он будет работать у других 90%. Это значит, что 90% людей с маршрутизатором марки A довольны; и 90% из 10%, которые используют маршрутизатор марки B, тоже довольны. Получается уровень удовлетворения 99%! Даже хотя оба маршрутизатора надёжны всего на 90%. Так выходит, потому что у каждого есть выбор между маршрутизатором A ИЛИ маршрутизатором B, поэтому они выбирают хорошо работающий и выбрасывают другой.
Это одинаково применимо к программному обеспечению (прошивка вендора vs openwrt vs tomato) или версиям программы (люди могут не обновляться с v1.0 на v2.0, пока v1.0 не начнёт доставлять проблемы). В нашем проекте есть маршрутизатор v1 и маршрутизатор v2. Первая версия нормально работала для большинства пользователей, но не для всех. Когда вышла вторая версия, мы начали раздавать маршрутизаторы v2 всем новым пользователям, а также тем пользователям v1, кто жаловался на проблемы. Когда мы вывели график удовлетворённости пользователей, то увидели, что он подскочил сразу после выхода второй версии. Отлично! (Особенно отлично, потому что маршрутизатор v2 разрабатывала моя группа :)). Теперь обновить всех, правильно?
Вообще-то, не обязательно. Проблема в том, что мы исказили нашу статистику: мы обновили на v2 только тех пользователей v1, которые испытывали проблемы. Мы не «обновляли» на v1 пользователей v2 с проблемами (конечно, такие тоже были). Может быть, оба маршрутизатора были надёжны на 90%; вышеописанная история вполне могла сработать и наоборот. Тот же феномен объясняет, почему некоторые люди переходят с openwrt на tomato и восторженно отзываются, насколько эта прошивка более надёжная, и наоборот. То же самое с Red Hat и Debian или Linux и FreeBSD, и т. д. Этот феномен «У меня всё работает!» известен в мире open source; простая вероятность. Вам нужен стимул для перехода только если у вас сейчас какие-то проблемы.
Но обратная сторона уравнения тоже верна, и она имеет значение для mesh-сети. Когда вы устанавливаете многочисленные маршрутизаторы в ячеистую цепь, то зависите от нескольких маршрутизаторов одновременно, иначе ваша сеть разваливается. Wi-Fi печально известен этим: один маршрутизатор устанавливает соединения, но работает странно (например, не маршрутизирует пакеты), а клиенты по-прежнему привязаны к этому маршрутизатору, и ни у кого ничего не работает. Если увеличить количество узлов в цепочке, то вероятность такого исхода быстро возрастает.
Конечно, у базовых станций LTE тоже есть проблемы надёжности — и много. Но они обычно не организованы в виде ячеистой топологии, и каждая станция LTE обычно покрывает гораздо бóльшую площадь, так что образуется зависимость от меньшего количества узлов. Кроме того, каждый узел LTE обычно «слишком большой, чтобы упасть» — другими словами, это мгновенно доставит проблемы настолько большому количеству людей, что телефонная компания быстро всё починит. Единственный неисправный узел в mesh-сети действует только на небольшой площади, так что проблемы возникнут только при проходе через эту территорию, хотя в большинстве ситуаций проблем не будет. Всё это ведёт к смутному впечатлению, что «mesh-сети Wi-Fi глючные, а LTE надёжен», даже если ваш собственный mesh-узел работает бóльшую часть времени. Это всё игра статистики.
Решение: система-приятель
Пусть ваш приятель скажет, если вы стали задницей.
Маршрутизатор A: 90% работает
Маршрутизатор B: 90% работает
P(или A, или B работают):
1 − (1-0,9) × (1-0,9) = 99%
В последние примерно 15 лет теория и практика распределённых систем проделали большой путь. Теперь мы в основном знаем, как преобразовать ситуацию И в ситуацию ИЛИ. Если у вас массив RAID5 и один из дисков выходит из строя, вы выводите диск из обращения, так что можете заменить его, пока не вышел из строя другой. Если у вас сервис баз данных NoSQL на 200 узлов, вы проверяете, что к вышедшим из строя узлам не направляются запросы, так что другие узлы могут взять на себя их работу. Если один из ваших веб-серверов перегружен излишним кодом Ruby on Rails, то ваши балансировщики нагрузки перенаправляют трафик на другой узел, который менее нагружен, пока первый сервер не вернётся в нормальный режим.
То же самое должно быть с Wi-Fi: если ваш маршрутизатор работает странно, его нужно вывести из строя до починки.
К сожалению, производительность маршрутизатора Wi-Fi труднее измерить, чем производительность базы данных или веб-сервера. Сервер баз данных легко может протестировать сам себя; просто запустить пару запросов и убедиться, что сокет запросов в строю. Поскольку веб-серверы доступны через Интернет, можно запустить один проверочный сервис, который будет периодически опрашивать все сервера, и сигнализировать о необходимости перезагрузки, если сервер перестал отвечать. Но по определению не все узлы mesh-сети доступны по прямому линку Wi-Fi из одного места, так что единый проверочный сервис не будет работать.
Вот моё предложение, которое можно назвать «Wi-Fi система-приятель». Аналогия такая: как будто вы с друзьями пошли в бар, где вы слишком сильно напились и начали вести себя как придурок. Поскольку вы слишком пьяны, то необязательно знаете, что ведёте себя как придурок. Это может быть трудно определить. Но вы знаете, кто может это определить? Ваши друзья. Обычно даже в том случае, если они тоже напились.
Хотя по определению не все mesh-узлы доступны из одного места, вы можете также сказать, что по определению каждый mesh-узел доступен хотя бы для одного другого mesh-узла. Иначе это не будет ячеистой структурой, и у вас ещё более крупные проблемы. Это намекает, как исправить ситуацию. Каждый mesh-узел должен время от времени пытаться соединиться с одним или более соседними узлами, выдавая себя за конечного пользователя, и смотреть, прохожит маршрутизация трафика или нет. Если проходит, то отлично! Говорим этому узлу, что он хорошо справляется, пусть продолжает в том же духе. Если нет, то плохо! Говорим этому узлу, что ему лучше вернуться в вагон. (Строго говоря, наиболее безопасный способ реализовать это — отправлять только сообщения «ты хорошо справляешься» после опроса. Сбойный узел может быть неспособен получить сообщения «твои дела плохи». Нам нужна система вроде контролёра, которая перезагрузит узел, если он не получил сообщение «отлично!» за определённый промежуток времени).
В достаточно плотной mesh-сети — где всегда имеется два или более маршрута между заданной парой узлов — это преобразует поведение типа И в поведение типа ИЛИ. Теперь добавление узлов (таких, которые могут вывести себя из сети в случае проблемы) делает систему более надёжной, а не менее.
Это даёт mesh-сетям преимущество перед LTE, потому что у LTE меньшая избыточность. Если базовая станция выходит из строя, большая территория теряет связь, а телефонной компании нужно спешить исправлять это. Если mesh-узел выходит из строя, мы обходим проблему и исправляем её позже в свободное время.
Небольшой математический пример прошёл длинный путь!
Вам этого недостаточно?
Можете посмотреть все мои слайды (pdf) о потребительских Wi-Fi mesh-сетях (в том числе подробные заметки выступающего) с конференции Battlemesh v10 в Вене или моё выступление на YouTube:
Примечание
Так называемые «законы» — это особый случай более общих и поэтому более полезных теорем распределённых систем. Но это Интернет, так что я выбрал один особый случай и назвал его в свою честь. Давайте, попробуйте меня остановить.
Автор: m1rko