Компания
1 155,30
рейтинг
5 февраля 2014 в 11:28

Разное → В Облака на Zeppelin: опыт создания облачного сервиса Mail.Ru Group



Мы начали работать над Облаком Mail.Ru в июне 2012. За полтора года мы прошли долгий и тернистый путь от первого прототипа до публичного сервиса, выдерживающего нагрузки свыше 60 Гбит/с. Сегодня мы хотим поделиться с вами рассказом о том, как это было.

Ты помнишь, как все начиналось


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



Сервер метаданных


Прототип приблизился к продуктовой версии, когда мы написали свой сервер для хранения метаданных. Его можно назвать продвинутым key-value storage, где ключом является двенадцатибайтный идентификатор дерева, а значением — иерархия файлов и каталогов отдельного пользователя. С помощью этого дерева эмулируется файловая система (добавляются и удаляются файлы и каталоги). Для общения с сервисом первый клиент использовал бинарный сессионно-ориентированный протокол: устанавливалось TCP-соединение, в него сваливались нотификации об изменениях, чтобы два клиента могли синхронизироваться, и клиенты писали команды в это поддерживаемое соединение. Этот прототип проработал еще пару месяцев.

Разумеется, мы прекрасно понимали, что клиенты не могут позволить себе держать постоянное TCP-соединение с сервером. Более того, на тот момент у нас не было никакой аутентификации: мы верили клиенту. Это было хорошо для разработки, но совершенно неприемлемо для продакшна.

HTTP-обертка


Следующим шагом мы обернули отдельные пакеты, из которых состоял наш бинарный протокол, HTTP-заголовками, и стали общаться с сервером по HTTP, сообщая в строке запроса, с каким деревом мы хотим работать. Эта обертка на данный момент реализована с помощью модуля Nginx, который поддерживает TCP-соединение с сервером метаданных; сервер ничего не знает про HTTP.

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

Также на этом этапе мы столкнулись с необходимостью стороннего HTTP-нотификатора. Мы взяли Nginx HTTP Push-Module — это Comet-сервер для нотификации — и стали в него слать нотификации из нашего сервера метаданных.

Когда это не просто заработало, а стало нормально переживать падения и рестарты Comet-сервера, мы приступили к следующему этапу.

Авторизация


Следующим этапом стало внедрение авторизации как на сервере, так и на клиенте. Вооружившись Nginx, исходниками модуля, производящего похожие действия, и мануалом по работе с нашим внутренним интерфейсом авторизации и проверки сессии, мы написали модуль авторизации. Реализованный модуль на входе получал куку пользователя, а на выходе вычислял идентификатор этого пользователя, получал его email и производил другие полезные действия.

Мы получили сразу две приятные плюшки: авторизация заработала одновременно и при работе с сервером метаданных, и при работе с сервером нотификаций.

Loader


На загрузку файлов работал DAV-модуль Nginx, который получал файлы с хэшами и складывал их локально в одну директорию. На тот момент ничего не бэкапилось, все работало до первого вылета диска. Поскольку тогда было далеко даже до закрытого внутреннего тестирования, и системой пользовались только сами разработчики, такой вариант был приемлем. Конечно, в продакшн мы вышли с полностью фолт-толерантной схемой, сегодня каждый файл пользователя хранится в двух копиях на разных серверах в разных дата-центрах (ДЦ).

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

Мы хотели сделать загрузчик надежным и функциональным, но в то же время достаточно простым, поэтому не стали строить витиеватых переплетений между иерархией директорий и телами файлов. Мы решили ограничить круг задач загрузчика следующим: принять входящий файл, посчитать его хэш и параллельно записать на два бэкенда. Эту сущность мы назвали Loader, и его концепция не сильно поменялась с тех времен. Первый работающий прототип Loader’а был написан в течение двух недель, а уже через месяц мы полностью перешли на новый загрузчик.

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

Иногда мы получаем восторженные отзывы о том, что, например, гигабайтный фильм залился в Облако мгновенно. Это происходит благодаря механизму заливки, который поддерживают наши клиентские приложения: перед заливкой они считают хэш файла, а затем «спрашивают» у Loader-а, есть ли у нас в Облаке такой хэш; нет — заливают, есть — просто обновляют метаданные.

Zeppelin: Python vs C


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

Решение казалось очевидным: написать свой демон на Python. Так делают все, это модно, популярно, а самое главное – быстро. Задача демона — выяснять, на каком сервере метаданных живет пользователь, и перенаправлять все запросы туда. Чтобы не заниматься роутингом пользователей на серверах данных, мы написали прослойку на Twisted (это асинхронный фреймворк для Python). Однако выяснилось, что либо мы не умеем готовить Python, либо Twisted тормозной, либо существуют другие неведомые причины, но больше тысячи запросов в секунду эта штука не держала.

Тогда мы решили, что будем как хардкорные ребята писать на С с использованием Metad-фреймворка, позволяющего писать асинхронный код в синхронной манере (выглядит это примерно как state threads). Первая рабочая версия сишного Zeppelin-а (к выбору такого названия нас привела цепочка ассоциаций Облако — дирижабли — Zeppelin) появилась на тестовых серверах уже через месяц. Результаты были вполне ожидаемыми: имеющиеся полторы-две тысячи запросов в секунду обрабатывались легко и непринужденно при близкой к нулевой загрузке процессора.

Cо временем функционал Zeppelin-а расширился, и сегодня он отвечает за проксирование запросов в Metad, работу с веблинками, согласование данных между Metad-ом и filedb, авторизацию.

Генератор миниатюр (Thumbnailer)


Кроме того, мы хотели научить Облако отображать превью картинок. Мы рассмотрели два варианта — хранить миниатюры или генерировать их на лету и временно кэшировать в оперативной памяти — и остановились на втором. Генератор был написан на Python и использует библиотеку GraphicsMagick.

Для того чтобы обеспечить максимальную скорость, миниатюры генерируются на той машине, где физически лежит файл. Поскольку стораджей очень много, нагрузка по генерации миниатюр «размазана» примерно равномерно, и, по нашим ощущениям, генератор работает достаточно быстро (ну, может, за исключением тех случаев, когда запрашивается файл 16 000 x 16 000 пикселей).

Первый стресс-этап: закрытая бета


Серьезной проверкой наших решений стал выход на закрытое бета-тестирование. Бета началась как у людей – пришло больше народа, чем мы ожидали, они создали больше трафика, чем мы ожидали, нагрузки на диск оказались больше, чем мы ожидали. С этими проблемами мы героически боролись, и за полтора-два месяца побороли многие из них. Мы очень быстро доросли до ста тысяч пользователей и в октябре сняли инвайты.

Второй стресс-этап: публичный релиз


Вторым серьезным тестом стал публичный релиз: вернулись проблемы с дисками, которые мы в очередной раз решили. Со временем ажиотаж начал угасать, но тут подвернулся Новый год, и мы решили раздать по терабайту всем желающим. 20-е числа декабря в связи с этим выдались очень веселыми: трафик превысил все наши ожидания. На тот момент у нас было в районе 100 стораджей, в которых было около 2400 дисков, при этом трафик на отдельные машины превысил гигабит. Общий трафик вышел за отметку 60 Гбит.

Мы такого, конечно, не ждали. Ориентируясь на опыт коллег по рынку, можно было предположить, что в сутки будет заливаться около 10 ТБ. Сейчас, когда пик уже спал, у нас заливается 100 ТБ, а в наиболее напряженные дни доходило до 150 ТБ/сутки. То есть каждые десять дней мы делаем петабайт данных.

Опись имущества



Итак, на данный момент у нас используется:

● Самописная база данных. Зачем нужно было писать свою базу? Изначально мы хотели запуститься на большом количестве дешевых машин, поэтому при разработке мы боролись за каждый байт оперативной памяти, за каждый такт процессора. Делать это на существующих реализациях, вроде MongoDB, которые хранят JSON, пусть даже бинарно упакованный, было бы наивно. Кроме того, нам нужны были специфические операции, такие как юникодный case folding, реализация файловых операций.

Это можно было бы сделать, расширяя существующую noSQL базу данных, но в таком случае логику vfs просто-напросто пришлось бы вписывать в уже существующую солидных объемов кодовую базу, либо расширять серверный функционал через встроенные скриптовые языки, эффективность которых вызывала некоторые сомнения.

В традиционных SQL базах данных хранить древовидные структуры не слишком-то удобно, да и довольно неэффективно — nested sets положат базу на апдейтах.

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

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

Именно поэтому мы решили написать свой велосипед. Он получился достаточно простым и делает ровно то, что нам от него нужно. Благодаря имеющейся архитектуре можно, например, заглянуть в метаданные пользователя на момент времени в прошлом. Помимо этого, можно реализовать версионирование файлов.

● Tarantool key-value storage

● Широко используется Nginx (замечательная российская разработка, идеальная до тех пор, пока не придется писать под нее расширения)

● В качестве рудимента временно применяется старый нотификатор на внутренней разработке Mail.Ru Imagine

● Более трех тысяч пар дисков. Пользовательские файлы и метаданные у нас хранятся в двух экземплярах на разных машинах, в каждой из которых 24 диска емкостью 2 или 4 ТБ (все новые серверы сетапим с дисками на 4ТБ).

Неожиданные открытия


Мы пишем подробные логи на каждый запрос. У нас есть отдельная команда, которая пишет анализатор, строящий различные графики для выявления и анализа проблем. Графики отображаются в Graphite, помимо этого мы используем Radar и другие системы.
Исследуя то, как пользуются нашим Облаком, мы сделали несколько любопытных открытий. Например, самое популярное расширение файлов в Облаке — .jpg. Это и неудивительно — люди любят фоточки. Что интереснее, в топ-10 популярных расширений входят .php и .html. Уж не знаем, что там хранится — кодовая база или бэкапы с хостинга, но факт остается фактом.

Мы замечаем существенные скачки трафика в дни, когда появляются обновленные моды, выпущенные к апдейтам популярных онлайн-игр: кто-то загружает очередной аддон, а потом армия геймеров дружно скачивает его из нашего Облака. Доходило до того, что в отдельные дни до 30% заходов к нам совершали для скачивания этих обновлений.

Вопросы и ответы


Мы подумали о списке вопросов, которые вам, возможно, захочется задать.

Как насчет расширения HTTP?
У нас нигде не расширяется протокол HTTP. Когда мы начинали разработку Облака, все работало на открытых каналах данных без HTTPS (в продакшн мы вышли, разумеется, с полным SSL-шифрованием всего трафика между клиентом и сервером). Поэтому, когда у кого-то возникало желание вытащить что-нибудь в заголовок, угроза дикой прокси, которая порежет все кастомные заголовки, быстро его отбивала. Так что все, что нам нужно, сосредоточено либо в URL, либо в теле.

Что используется в качестве идентификатора файла?
Идентификатором файла у нас служит SHA-1.

Что будет с пользовательскими данными, если «накроется» сервер или дата-центр Облака целиком?
У нас все устроено абсолютно фолт-толерантно, и выход из строя сервера или даже целого ДЦ почти никак не влияет на работу пользователя. Все данные пользователя дублируются на разных серверах в разных ДЦ.

Какие планы на будущее?
В наших ближайших планах развития запуск WebDAV, дальнейшая оптимизация всего и вся, и много интересных фич, о которых вы скоро узнаете.

Если мы что-то упустили, постараемся ответить в комментариях.
Автор: @TeamMRG

Комментарии (54)

  • –4
    Так и не понял, вы уже с виртуалкой вышли в продакшн или какая-то поздняя отметка была?
    • +19
      Ну конечно с виртуалкой. И еще 3000 дисков в нее воткнули.
      • +1
        Остро :-)
        Эта система, написанная на коленке за две недели, проработала несколько месяцев.

        Вот потому и спросил.
        • +3
          Наверное, мы не совсем четко сформулировали. Разумеется, проработала в тесте, не на продакшне.
          • 0
            Видимо уже привык к стартапам и гибкой разработке: каждый месяц релиз, каждую фичу сразу в деплой )
            А вы основательно тестировали.
            • +3
              Ну, разумеется. Тем более, сервис, который хранит личные данные, надо очень тщательно тестировать.
            • 0
              У Mail.Ru Group есть более 3000 сотрудников, которых можно использовать в качестве бета-тестеров. Не у каждого стартапа в первые месяцы набирается столько пользователей ;-)
  • +2
    оскольку стораджей очень много, нагрузка по генерации миниатюр «размазана» примерно равномерно, и, по нашим ощущениям, генератор работает достаточно быстро (ну, может, за исключением тех случаев, когда запрашивается файл 16 000 x 16 000 пикселей).

    Сейчас проверил, для панорамы в 14000х9000 не создается превью вообще. Кроме этого, она вообще не открывается через веб интерфейс, элемент не реагирует на щелчок мышью.

    Но это редкий случай, главная проблема в другом:
    Кроме мелких превью (иконка файла), не предусмотрено создание превью для веба и самое ужасное — для мобильного приложения. Всегда грузится вся фотография целиком. Если для домашнего компьютера с нормальной скоростью интернета, это еще терпимо, а вот для смартфона, с низкой скоростью интернета, это не совсем правильно.

    P.S. ну и немного поною по поводу отсутствия ландшафтной ориентации в android приложении, это позор )
    • +2
      Мы как раз работаем наб обеими проблемами в Андроид-приложении. В следующей версии планируется и ландшафтный дизайн и загрузку миниатюр.
      • 0
        Вот это отлично, а то посмотрел папочку с фотографиями со смартфона, и 500 мб в кэш легло )
        Где нибудь можно в бета тесте поучаствовать?
        • +2
          У нас есть сообщество на Google+ plus.google.com/u/0/communities/109819884866346500127 в нем мы раздаем бета-версии Android приложения
          • 0
            Может быть я что то делаю не так, но по ссылке «бета версия приложения» — 404 ( play.google.com/apps/testing/ru.mail.cloud )
            • +4
              в сообщество нужно было вступить, оказывается. Вопрос снят. Уже тестирую.
        • +1
          Меня выше поправили. Бета тестирование есть, но только для Андроида.
  • +6
    То что генератор миниатюр работает на лету ощущается, но это простительно по сравнению с предоставляемым местом в 1ТБ. Mail.Ru умеет приятно удивлять :)
    • НЛО прилетело и опубликовало эту надпись здесь
      • +17
        «Высказанный комментарий абсолютно не отражает позиции Mail.Ru Group. В данном случае сотрудник существенно превысил свои полномочия и высказался на тему, не относящуюся к сфере его компетенций. После обсуждения инцидента мы приняли решение расстаться — больше Михаил Кочергин не работает в компании». От пресс-службы Мейл.ру
      • +1
        Комментарий на тему «отсебячины» сотрудника или техническая статья? Хм… я даже не знаю :)
        Для такого рода комментариев есть профильные ресурсы — Roem, Цукерберг и прочая.
        Хабр, имхо — это информация для технической аудитории в первую очередь.
      • 0
        Обыскал ближайшие посты от Mail.ru про WoT, можете дать ссылку?
    • +1
      Мы планируем в ближайшем будущем серьезно ускорить показ миниатюр. Причем, со стороны сервера уже должно работать быстро. Но есть небольшие проблемы производительности на стороне client-side'а, которые мы решаем.
  • 0
    А чего на картинке кот такой недовольный?
    • 0
      Кот важный просто, а вот у программиста волосы дыбом встали почему-то.
      • 0
        Программист уже просто в облаке, а коту тоже хочется)
    • +1
      Это Grumpy cat
  • +4
    Имея терабайт в «облаке», очень хочется иметь к нему еще и открытое API для того, чтобы найти этому терабайту хорошее применение, а не делать просто хранилище фоточек :)
  • +8
    Тяжелый день для публикации.
  • +6
    Ждем webdav)
    • +5
      Очень. Именно его отсутствие пока останавливает от использования сервиса.
  • –38
    Дико извиняюсь, но из-за дурной репутации вашей организации, читать пост просто нет никакого желания. Отвращение, что-ли.

    Уверен, что под катом много годноты от хороших программистов, но ребят…
    • +22
      Зря вы так. Вся команда Облака пришла в Mail.Ru 1-1,5 года назад, проект писался полностью с нуля. К прошлым пригрешениям Mail.Ru ребята отношения не имеют.
      • –25
        Я не имею притензий к команде, я говорю о том, что у меня из-за кармы компании, нету желания слышать «mail.ru»
        • +18
          Я понимаю вашу точку зрения. Но, не наступая на свободу слова, хочу лишь высказать мысль, что ребятам, принимающим участие в проекте, могут быть обидны ваши высказывания про компанию, где они работают.
          • 0
            >>ребятам, принимающим участие в проекте, могут быть обидны ваши высказывания про компанию, где они работают
            И ребята набежали и «вогнали в краску» неосторожного комментатора? Вместо тысячи слов…
            • 0
              Мы не знаем, кто вогнал в краску. У статьи более 15000 просмотров. А разработчиков в ОблакеMail.Ru в 100 раз меньше.
        • –5
          Этот мир жесток
  • 0
    А если не секрет, сколько человек у вас занимается разработкой этого проекта?
    Самописную базу данных в open source не собираетесь выкладывать? или она узко специализирована?
    • +6
      Разработчиков на всем проекте 15 человек (включая сервер-сайд, базу, хранилище, веб, мобильную разработку, десктоп-разработку). Про выкладывание в open source думаем, но пока наша база достаточно узко специализирована. Как только найдем ей применение в более чем одном проекте, то можно будет всерьез этим заняться.
  • +1
    Изначально мы хотели запуститься на большом количестве дешевых машин

    А как в итоге получилось?

    У нас есть отдельная команда, которая пишет анализатор, строящий различные графики для выявления и анализа проблем.

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

    И хотелось бы как-то понять, какой технологический стек получился в итоге. Правильно ли я понял, что в backend всё написано на C? За исключением, наверное, аналитики.
    • +4
      Так и получилось изначально. Максимальная оптимизация кода проходит красной нитью через всю нашу разработку с самого старта.

      Насчет команды статистики — используем Perl. Много самописных инструментов, но есть и сторонние, например, graphite. Когда-нибудь мы напишем про это подробную статью.

      Насчет технологического стека. В самом низу (хранилища и база) — старый добрый C. Чуть повыше — С++ и Perl. С самого верху все более или менее стандартно, веб — HTML/JavaScript, iOS — Objective C, Android — Java, десктопные приложения — C++.
      • +1
        Спасибо за ответ! Созрел еще один вопрос.

        оптимизация кода проходит красной нитью

        А вы это как-нибудь поддерживаете в Continuous Integration? Синтетические тесты? Нагрузочные тесты?
        • +4
          Синтетические нагрузочные тесты. Но они до конца еще не внедрены в Continuous Integration и проводятся только тогда, когда мы делаем серьезное изменение в коде.
          Кроме того, у нас масса графиков, фиксирующих малейшие изменения в производительности или скорости ответа. Админы в них поглядывают + получают смс в случае совсем критичных изменений, и сообщают все разработчикам, которые быстро разбираются в неоптимальностях в коде.
          И кроме того, у нас есть сплит-тестирование. Мы очень любим внедрять новые фичи или серьезные изменения в серверном коде на часть аудитории, чтобы следить в том числе за нагрузкой.
  • +1
    Какая выгода с подобного проекта? Ну кроме доступа и ретрансляции файлов…
    Способов применения действительно много и оно полезно для использования, но что же движет этим проектом?
    • +4
      Как минимум выгода в привлечении и удержании аудитории на портале Mail.Ru, и в т.ч. на главной странице и почте. А главная страница, портал, почта — это доходы от рекламы.
  • +5
    Запилите уже WebDAV, я буду счастлив :)
    • +1
      Да ладно Вы, так ведь все, все будут счастливы!

      Наконец duplicati опять сможет работать, т.е. шифрование данных в «облаке» можно будет реализовать почти прозрачно — и хранить, таким образом, что хочешь, а не только то, что «не жалко отдать толпе».

      Правда, трафик тогда еще подрастет, CPU нагрузятся, дедупликация задумается (как же, поищите в криптоконтейнерах одинаковые блоки!) — в общем, площадка рада не очень будет, зато особо параноидальные пользователи сервиса (думаю, на Хабре таких хватает) перестанут переживать.

      И количество просьб провести еще одну раздачу «1000 Гб бесплатно» резко возрастет )
  • 0
    Вот бы еще сделали чтоб можно было делиться «совсем» прямыми ссылками…
  • 0
    И консольный клиент для пингвиноводов! А то на сервер без гуя не поставить!
  • +17
    На мой взгляд, несмотря на малый рейтинг, пока это лучшая статья на Хабре за весь — пока недолгий — 2014 год. Во-первых, вы изложили всё очень простым языком (так, что даже я, 5 лет назад отошедший от разработки словно почувствовал себя на вашем месте).

    Во-вторых, в статье описано именно то, что достойно называться словом highload. Потому что в большинстве случаев называть этим словом обычный сложный проект не всегда корректно. Возможно, сейчас это звучит еще не как общее место и даже отчасти спорно, но на мой взгляд, к 2014 году не так уж просто найти ИТ-задачу на производительность, которую невозможно было бы «в лоб» решить тем, что по большому счету можно хотя бы с натяжкой назвать вертикальным масштабированием. Иными словами, побольше денег вложить в «железо» и дорогостоящие проприетарные технологии (в духе «run SAP HANA and don't care»). И совсем другое дело, когда бизнес требует от CTO реального технологического прорыва потому что вертикальное масштабирование банаљно нерентабељно, а CTO ничтоже сумняшеся принимает решение изготовить «самописную базу данных» потому что «так дешевле». Не знаю как по-вашему, а по-моему, для этого нужны стальные яйца.

    Вы молодцы не только в том, что впервые с 1997 года выпустили под лейблом mail.ru действитељно крутой проект, но и в том, что очень харизматично его представили широкой публике. Последние годы меня сложно было назвать хоть сколько-нибудь лояльным Mail.Ru Group (взять хотя бы историю с Хабром или Вконтакте), но именно этот ваш продукт меня в буквальном смысле подкупает. Мне кажется, я не один такой. Удачи!
    • +6
      В свою очередь скажу, что я за этот год не встречал еще на Хабре такой развернутой, точной и существенной рецензии на статью.
      Спасибо вам огромное!
  • 0
    Есть планы поддержки доступа по IPv6, и если есть, то примерно когда? Спасибо.
    • 0
      Планы есть. Сроков назвать, к сожалению, не можем.
  • +2
    Не узнаю mail.ru. Правда, так много времени это название служило символом… ну, все знают, чего. И в смысле толп «хомячков» со званиями экспертов на всяких «ответах» (а оттого — и контента там же) так оно и по сию пору. Но техническая часть (которую мы, как читатели Хабра, видим только «из глаз» рассказчика, да и то видим фрагментально) хороша, интересна, заслуживает уважения и вообще вызывает желание работать с вами и сейчас, и далее.

    Скажите, это у вас курс сменился в компании — «вперед, к обелению нашего имени!», или вы всегда были белые и пушистые, просто по какой-то сложной причине никому об этом не рассказывали?
    • +5
      скажем так, в прошлом мы совершали много ошибок, но последние несколько лет мы сознательно и активно над ними работаем. в том числе большие изменения происходят в области технологий, техническая команда значительно усилилась и сейчас не соврем, если скажем, что это одна из лучших команд в России, а в некоторых направлениях и вообще, наверное, лучшая :)
  • 0
    Cкажите, а есть ли официальная страничка проекта, с новостями а-ля 'вышла новая версия'?

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разное