2014-01-18

Об Ingress

ingress ['ɪngres]

Перевод из «Англо-русского словаря общей лексики «Lingvo Universal»» ABBYY Lingvo

сущ.


Когда-то давно, в том же Беркли, делали чудесную СУБД Ingres. Была она бабушкой нынешнего PostgreSQL... Но мы не об этом...


Вот уже третью неделю я занимаюсь совсем неподобающим делом. Где-то по пятнадцать минут в день. Хожу пешком по морозу. Играю во Вхождение, как вы уже поняли.


Это — массивная многопользовательская онлайновая игра. Чтобы играть вам нужен не сильно слабый телефон с не сильно старым Андроидом на борту (поддержку iOS обещают в этом году), GPS (ну и ГЛОНАСС лишним не будет) и хороший мобильный интернет. А также необходима сила воли, чтобы ходить пешком и не бояться выглядеть идиотом, пялящимся в экран смартфона, издающего странные звуки, в публичных местах. Не помешает также мощная батарейка для телефона, и, для сибирской зимы, перчатки без пальцев ;) Батарейка не помешает, потому что одновременно включенный экран, GPS и мобильный интернет, как вы, возможно, знаете по всяким навигаторам, едят батарейку как не в себя. Ах да, есть подозрение, что личный автотранспорт (или велотранспорт) дает некоторые преимущества в игре (и совершенно точно мощным преимуществом является разъездной характер работы). Ну и обязательно знание английского языка на уровне отличения одной кнопки от другой, ибо приложение до сих пор существует только на английском. В особо сложных полевых случаях может понадобится ноутбук с браузером и пара утилит для снятия скриншотов.


Игра возникла как стартап внутри Гугла где-то с год назад. Долго была в закрытом тестировании, только по приглашениям (помните первый год Гмейла?). Знаю людей в Омске, которые играют аж с тех времен. В ноябре 2013 вышла в публичную бету, теперь можно скачать и поставить из Гуглоплея. Все еще бета, хоть и играют уже более миллиона человек.


Сюжет такой. Где-то в CERN, на многострадальном БАК, наткнулись на некую Экзотическую Материю (eXotic Matter, XM). Эта материя (которая также и энергия, как обычно) проникает в наш мир через порталы. Порталы появляются в общественно значимых местах, таких как памятники, библиотеки, торговые центры, крупные транспортные узлы и т.п. За всей этой экзотической фигней стоят Формирователи (Shaper) — понятное дело, инопланетяне, только никто не знает, ни как они выглядят, ни чего хотят. А раз инопланетяне, то играющее человечество тут же делится на две фракции: Сопротивление (Resitance), которые против вторжения кого бы то ни было во внутренние дела человечества, и Просвещенные (Enlightened), которые за то, чтобы Формирователи пришли и все починили. Весь этот бэкграунд полон детективно-фантастического сюжета, разгадывая который, можно получать коды на получение всяких штук в игре. Но всем обычно пофигу и они играют в "Зарницу" за синеньких (Сопротивление) или зелененьких (Просвещенные).


Итак, играем. В самом начале нужно выбрать логин и фракцию. Важно, чтобы логин не соответствовал вашему реальному имени. Правила игры запрещают выдавать какую-либо частную информацию об игроке, что странно, ибо привязывается все к гуглоаккаунту и широко освещается в Гуглоплюсе, где как раз разрешены только реальные имена. Фракцию нужно выбирать основательно, сменить её потом будет почти невозможно. В плане механики игры фракции идентичны.


Ваш телефон с установленной игрой — это сканер. На нем вы видите карту (гугловую, но в черно-серых тонах), круг, отображающий дальность действия вашего сканера, порталы, резонаторы, прочие игровые предметы. Дальность действия сканера — метров двадцать. Чтобы совершить какие-то действия (над порталом) нужно подойти к нему на это расстояние. Поэтому придется походить пешком ;) Редко когда памятники стоят так близко к дороге, чтобы можно было не вылезать из авто.


Кроме персонального сканера есть еще карта: http://www.ingress.com/intel/. Intel, видимо, от intelligence. Собственно, ноутбук нужен для карты. А карта — это единственный честный (есть и нечестные) способ увидеть общую ситуацию. Карта нужна при планировании крупных стратегических операций.


У вас, как у агента, есть уровень. Начинаете вы с Уровня 1 (L1). Максимальный доступный уровень (в настоящий момент) — У8. У большинства предметов в игре тоже есть уровень, вы не можете пользоваться предметами, чей уровень больше вашего. Новый уровень дают, когда наберете определенное количество ОД (Очков Доступа, Access Point, AP). А ОД дают за любое действие в игре. Пока вы не добрались до У8, основной вашей целью в игре является повышение уровня.


Кроме ОД у вас есть текущее количество энергии ЭМ (Экзотической Материи, XM). ЭМ нужна для многих действий. Набрать её можно, просто прохаживаясь с включенным сканером. Эти белые ползающие точки на карте — и есть ЭМ. Она автоматически собирается сканером. Ну а если ЭМ внезапно кончилась, а вам срочно нужна еще, воспользуйтесь энергокубом (Power Cube). Когда ЭМ уходит в ноль, ваш сканер отключается и вы ничего не можете сделать (эдакая временная смерть, умереть по-другому в игре нельзя).



Итак, теперь вы — агент. Синих или Зеленых. Первой вашей священной обязанностью, особенно если вы не обнаруживаете порталов вблизи вашего частого местонахождения, является создание новых порталов. Для этого вам нужно подать заявку организаторам. Сфотографируйте памятник, памятную табличку на здании, граффити, удивительное сооружение на детской площадке и пошлите фотографию в телефоне на NIA Super Ops, укажите местоположение и дайте описание. И ждите несколько недель. Не факт, что вашу заявку утвердят, правила весьма размыты. Но пробовать, безусловно, стоит. Только вы знаете интересные места в округе и вам же будет удобнее, если там будет портал. За создание портала дают ОД.


Порталы бывают синие — Сопротивления, зеленые — Просвещенных, и серые — ничейные. Любые порталы можно взламывать. Это первое, что стоит делать с любым порталом. И делать регулярно. Подойдите к ним, чтобы на вашем сканере портал попал в радиус действия. Тыкните в портал, чтобы выбрать его. Нажмите кнопку Hack. В результате взлома вам достанется некий случайный набор игровых предметов (или вообще ничего). И это единственный способ получения предметов (ну или выпросить у другого игрока). Вражеский портал может при взломе вас "укусить", отняв немного от вашего запаса ЭМ. Взламывать часто нельзя — портал "нагревается". После четырех взломов придется подождать несколько часов, чтобы он "остыл". За взлом вражеского портала дают ОД.


Ничейные порталы нужно захватывать. Ну или свои чинить, если они повреждены. Для этого вы должны разместить резонаторы. Каждый портал можно подпитать восемью резонаторами. Резонаторы тоже бывают разного уровня, от среднего уровня резонаторов зависит уровень портала — его возможности по установлению связей и самозащите. Интрига, усугубляющая коллективизм игры, заключается в том, что один игрок не может сделать мощный портал. Один агент может разместить только четыре резонатора второго уровня, два резонатора пятого уровня и лишь один резонатор седьмого или восьмого уровня на портал и т.п.. Т.е. самый мощный портал восьмого уровня могут создать лишь восемь игроков восьмого уровня.
Подойдите к порталу, чтобы он оказался на границе действия вашего сканера. Тыкните на портал, нажмите кнопку Deploy, выбирайте и размещайте резонаторы. Нет нужды ходить вокруг портала, резонаторы сами размещаются согласно восьми сторонам света. А вот расстояние от вас до портала — важно, именно на этом расстоянии от портала будут размещены резонаторы. А размещать их нужно как можно дальше друг от друга (т.е. от центра портала), потому что их так будет тяжелее уничтожить противнику.
Вы также можете замещать уже установленные резонаторы более мощными (если они у вас есть). Пользуйтесь кнопкой Upgrade.
Заряд резонатора со временем уменьшается. Сам по себе, или в результате атаки противника. Их надо заряжать. Все сразу или по одному. Жмите кнопку Recharge. На перезаряд тратится ЭМ из вашего сканера. Если у вас есть ключ от портала, можно заряжать резонаторы удаленно. Правда, ЭМ немного теряется на расстоянии, но не сильно, нормально заряжать с десятков километров.


Вы навзламывали кучку порталов и захватили один. Настало время их связать (link). Между своими порталами можно и нужно устанавливать связи. За это дают ОД. Вам нужно стоять у одного портала и иметь ключ от другого портала. Дальность возможной связи зависит от уровня того портала, возле которого вы стоите (максимум — километров 800, но возможны нюансы). Важно, что связи не могут пересекать никакие другие связи, как свои, так и вражеские. Получается некий планарный граф, что может быть важно при планировании больших операций. Подойдите к порталу, тыкните по нему, нажмите кнопку Link. Вам будет предложено несколько других порталов для установления связи. Либо ни одного, что тоже часто бывает.


Связи связями, но нужны поля (field). Если три связи образуют треугольник (но не четырехугольник или болееугольник), то образуется поле. За это дают очень много ОД. И поле накрывает какую-то площадь, с какой-то плотностью населения. Типа поле захватывает мозги этого населения и они, типа, переходят под контроль той фракции, чье это поле. За это начисляются Мозговые Единицы (Mind Unit, MU). И глобальный счет Просвещенных против Сопротивления измеряется как раз в этих МЕ. Получается, что как раз общий счет игры зависит от полей. С точки зрения игровой геометрии важно, что внутри полей нельзя создавать новые связи (только с вершинами поля). Однако само поле может покрыть уже существующие поля и связи.


Что делать с вражескими порталами? В первую очередь, понятно, взламывать. Во вторую очередь — бомбить. Нужны ЭМИ бомбы (XMP Burster, eXotic Matter Pulse Burster). Нужно встать поближе к резонатору (ну, если можете воспользоваться мощными бомбами, поближе к самому порталу) и бомбить (жать кнопку Fire). Могут понадобиться десятки бомб, чтобы вынести портал уровня выше вашего. Но портал не будет молчать. Он будет атаковать в ответ, отнимать вашу ЭМ. А когда закончится ваша ЭМ, закончится и атака. Так что нужно иметь в кармане еще и несколько энергокубов, чтобы оперативно пополнять свою энергию. Ну и помните, что при отрицательной температуре воздуха за время атаки вы можете не только отморозить руки, но и заморозить батарею телефона :)


Что делать, если ваш любимый захваченный портал начинают бомбить враги? Во-первых, иногда имеет смысл ничего не делать ;) Во-вторых, вы, в чате сканера (да, там еще и чат есть), видите, кто бомбит, и можете вежливо его попросить этого не делать. Вежливо, за оскорбления по правилам полагается бан. В-третьих, если у вас есть ключ от портала, вы можете подзарядить атакуемые резонаторы. Это может спасти портал от разрушения, но потребует от вас большой затраты ЭМ, используйте энергокубы. В-четвертых, если вы находитесь рядом с порталом можно схватить бомбиста устанавливать новые резонаторы взамен уничтоженных.



Ну, создавайте, взламывайте и захватывайте порталы, контролируйте Мозговые Единицы, прокачивайтесь, ходите пешком и дышите свежим воздухом.
А когда надоест, можете заняться художественным рисованием на картах:



2014-01-05

Об ACID в NoSQL

Все знают, что "классические" SQL БД поддерживают свойства ACID. О NoSQL базах говорят, что ACID в них нет, и переводят разговор на CAP теорему и Eventual Consistency. Действительно ли в NoSQL совсем нет ACID?


Что такое ACID?
A — Атомарность. Операция будет либо успешно завершена полностью, либо не завершена вообще.
С — Согласованность. После завершения операции в БД останутся только согласованные (с точки зрения бизнес логики) данные.
I — Изолированность. Другие клиенты (потоки, операции) не видят промежуточных несогласованных данных во время выполнения операции.
D — Надежность. Результаты выполненной операции навсегда останутся таковыми (надежно сохранены на диске).


Вообще-то, оригинальное определение ACID относится к транзакциям. Т.е. под "операцией" в определениях выше следует понимать множество мелких CRUD операций над данными. В NoSQL, как правило, такие "большие" транзакции не поддерживаются. Но отдельные операции модификации данных вполне могут удовлетворять некоторым свойствам ACID.
Отдельным исключением являются NewSQL и графовые БД. Часто они декларируют поддержку транзакций, полностью аналогичных таковым в SQL базах, и это действительно работает.


D — Надежность. Тут все просто. Оперативную память считаем не надежной. Диск — надежным. Отдельно можно рассматривать дублирование (репликацию) данных, как фактор надежности.
Хуже всего дела обстоят у in-memory баз данных. Для обеспечения надежности им приходится периодически сохранять данные из памяти на диск. Либо синхронно (в рамках вызова операции пользователем) реплицировать данные на другие узлы кластера.
Проще всего тем, кто непосредственно пишет на диск. Как правило так никто не делает, потому что медленно. Но, например, Aerospike, прекрасно существует, напрямую сохраняя данные на SSD. И при этом быстр.
Раз писать синхронно на диск медленно, будем писать асинхронно. Т.е. будем держать кэш (операций записи) в памяти. Так и поступают большинство БД (и SQL тоже). Чтобы обеспечить надежность в этом случае используется журнал (в PostgreSQL его называют красивой аббревиатурой WAL). В журнал на диске писать быстрее, чем в данные, потому что это строго последовательная запись.
Журнал от рождения есть у Кассандры, там он называется Commit Log. Кассандра считает запись на узел успешной (и возвращает ответ пользователю) немедленно после записи в этот лог.
А вот в Монге журнал появился лишь в версии 1.8. И при неправильном использовании он может не обеспечить полную надежность — запись может считаться успешной и до записи в журнал. Чтобы дождаться записи в журнал вы должны указать j: true в Write Concern. Если, конечно, вы готовы пожертвовать производительностью в угоду надежности.


C — Согласованность.
Если говорить о согласованности на уровне одного узла кластера, то тут все неоднозначно. В NoSQL, как правило, нет механизмов контроля целостности данных, нет схемы и нет констрейнтов. В NoSQL, как правило, нет JOINов, и, соответственно, нет внешних ключей. А значит, задача контроля целостности, правильного обновления данных в разных коллекциях и документах ложится на клиента.
Но стоит помнить, что данные можно организовать так, что, даже в отсутствие транзакций, можно обеспечить их согласованное обновление. Такого рода подходы используются, например, в FSFS в Subversion, а также в структуре репозитория Mercurial. Идея состоит в том, что если обновлять данные в правильном порядке, от "листов" к "корню" дерева зависимостей, а читать всегда от "корня", то даже если обновление было прервано, несогласованные данные не будут видны. Ну а если транзакция нужна явно, её можно и сэмулировать.
Если говорить о согласованности данных между узлами кластера, то буква C из ACID становится буквой C из CAP теоремы. Со всем этим грузом выбора между доступностью (и скоростью) и согласованностью. Как правило нам предоставляется лишь согласованность в конечном счете (eventual). Мы пишем на один узел кластера, и нам обещают, что эти изменения когда-нибудь дойдут до других узлов. Соответственно, клиенты, читающие с других узлов, видят несогласованные данные.
Однако, приличные NoSQL БД возволяют вам выбрать между C и A. Здесь действует "классическая" формула (изложенная у Фаулера): W + R > N. W — это количество узлов, на которые мы пишем (дожидаясь надежной записи на каждый из этих узлов). R — количество узлов, с которых читаем (убеждаясь, что они содержат одинаковые данные и разрешая конфликты, если это не так). N — количество одинаковых копий данных в кластере, т.е. replication factor. Например, если у нас в кластере хранится три копии данных, и мы пишем на два узла, а читаем также с двух (возможно, других) узлов, то мы получим вполне согласованные данные — чтение, произведенное после записи, гарантированно увидит изменения.
Именно так работает Кассандра. Для каждой операции вы можете указать Consistency Level, как для записи, так и для чтения. Можно указать явное число узлов, которые должны быть задействованы для операции, так и просто "кворум" — больше половины от replication factor.
В Монге все немного по-другому. Тут узлы в Replica Set не равнозначны, пишем мы всегда в Primary, а вот читать можем откуда хотим. Если мы хотим строгой согласованности, то мы либо можем читать также только из Primary, что происходит по умолчанию, но можно и явно указать Read Preference (для любой операции чтения) равным primary или primaryPreferredЛибо можно дожидаться записи в Secondary, указав в Write Concern (для любой операции записи) параметр w больше единицы (это число узлов, в которые должна быть произведена запись).


A — Атомарность. I — Изолированность. Обычно в NoSQL базовые операции над базовой единицей данных (например, обновление данных по ключу в key-value) являются атомарными и изолированными (в рамках данного узла). Именно тот факт, что хоть что-то тут атомарно, позволяет этими БД пользоваться :)
Однако нужно понимать, что атомарность в кластере NoSQL касается только одного узла. Если операция записи успешно завершилась на одном узле, она может сломаться на другом узле. Узнает об этом клиент или нет, зависит от его настроек (собирался ли он ждать записи на другой узел). В любом случае никто не будет откатывать изменение, произведенное на первом узле. После этого вопрос переходит в область обеспечения целостности данных. Обычно побеждает версия данных, записанная позднее.
Если помните, в SQL существуют уровни изолированности транзакций. NoSQL не может похвастаться таким диапазоном настроек. Тут, если не упоминается изолированность, речь, скорее всего идет о Read Uncommitted. Если же говорят об атомарности (изредка явно упоминая и об изолированности), то чаще всего подразумевается Read Committed. Более высоких уровней изолированности в NoSQL, как правило, не бывает.
В Монге все просто. Одна операция изменения одного документа является атомарной и изолированной. Примечательно, что в одной операции можно изменять множество полей документа, а также делать операции вроде инкремента числового поля. Однако одной операцией можно изменить и несколько документов (одной коллекции), в этом случае атомарность распространяется на каждый документ, но не на все множество изменений. Реализована атомарность весьма просто. На весь процесс mongod (а с версии 2.2 — на каждую БД) имеется один единственный lock. Т.е. в рамках одного хоста все операции записи сериализованы (но несколько чтений могут идти параллельно, конкурируя, кстати, с операциями записи).
История атомарности в Кассандре довольно длинна. В версии 1.0 изменения одной строки были атомарны, но не изолированны. Строки в Кассандре довольно длинны (могут содержать что-то около двух миллиардов колонок). Отсутствие изолированности означает, что пока Кассандра меняет колонки в одной строке, другие клиенты могут видеть эти промежуточные изменения. Атомарность же означает, что, если при обновлении какой-нибудь колонки произойдет ошибка, вся строка будет возвращена в первоначальное состояние. В версии 1.1 к атомарности изменения строки добавилась изолированность, используется техника copy-on-write, изменяемые данные дублируются в памяти. В версии 1.2 появились так называемые Atomic Batch — группа операций, которая будет выполнена атомарно (т.е. гарантированно до конца). Батчи существовали и ранее, но при сбоях на сервере их выполнение могло не дойти до конца. Атомные батчи — не изолированы — другие клиенты видят, как меняются строки.
В Кассандре 2.0 появились легковесные транзакции. Разработчики попытались сделать шаг в сторону полностью сериализуемых транзакций, используя модифицированную версию протокола Paxos. Пока что получилось реализовать операции типа read-modify-write — запись обновляется только в том случае, если существующий вариант записи удовлетворяет определенным условиям — что уже весьма неплохо. В Монге, кстати, давно уже есть команда readAndModify с аналогичным функционалом. Но в Монге, как мы помним, всегда есть мастер, владеющий "эталонной" копией данных, тогда как Кассандра — полностью распределенная система с равнозначными узлами.


В общем, транзакций в NoSQL нет. Но многие операции обладают отдельными свойствами ACID, чем нужно и можно пользоваться.



P.S. В Кассандре, кстати, есть счетчики — специальные типы данных для атомарных и согласованных операций инкремента и декремента.
P.P.S. Вот еще пара интересных ссылок:
How MongoDB’s Journaling Works
The Architecture of Open Source Applications: Mercurial