SlideShare une entreprise Scribd logo
1  sur  45
Télécharger pour lire hors ligne
Технические аспекты
                  знакомства с девушкой в
                        интернете
                                Алексей Найден, Алексей Носков
                                         Evil Martians



воскресенье, 16 декабря 12 г.
воскресенье, 16 декабря 12 г.
воскресенье, 16 декабря 12 г.
Wannafun.ru
            • Онлайн speed dating
            • Знакомство только с теми, кто в сети
            • Поток лиц aka «матрица»
            • 3 минуты чата для принятия решения
            • 48% / 52%
воскресенье, 16 декабря 12 г.
Проект в цифрах
            • 500 000 пользователей
            • 2000 онлайн
            • 2-3 события в секунду на юзера
            • Более 100 http-запросов в минуту на юзера
            • Более 5 000 000 чатов
            • Более 45 000 000 сообщений
воскресенье, 16 декабря 12 г.
На чем всё работает




            Erlang              Postgres    Redis
         EventMachine             Rails    Resque
воскресенье, 16 декабря 12 г.
воскресенье, 16 декабря 12 г.
Онлайн-взаимодействия
            • Знакомства: входящие/исходящие, сообщения
            • Контакт-лист: личные сообщения, онлайн/
                   оффлайн
            • Уведомления

воскресенье, 16 декабря 12 г.
Взаимодействие с браузером
         Pusher (http://pusher.com/)                         Faye (http://faye.jcoglan.com/)

                Push-канал к клиенту                                    Pub/sub

              Нет серверной логики                              Нет серверной логики


                                       Socket.io (http://socket.io/)

                                Абстракция над WebSocket, Flash и
                                             Polling

                                  Произвольная серверная логика

воскресенье, 16 декабря 12 г.
Серверная реализация socket.io
          • NodeJS
            • На тестах падала VM — epic fail
          • EventMachine
            • Не было актуальной версии
          • Erlang
            • Не было актуальной версии
воскресенье, 16 декабря 12 г.
Что хорошего в Erlang
            •      Нет коллбеков - простой последовательный код

            •      Нет разделяемого состояния, структуры данных
                   неизменяемы - concurrency проще

            •      Иерархия супервизоров - высокая устойчивость

            •      Прозрачная распределенность

            •      Бесшовный деплой


воскресенье, 16 декабря 12 г.
Архитектура чат-сервера




            •      Соединения обслуживаются Cowboy

            •      Каждая сессия - отдельный процесс

            •      Вспомогательные процессы для работы с БД, Redis

воскресенье, 16 декабря 12 г.
Начало знакомства




воскресенье, 16 декабря 12 г.
Одновременный ответ




воскресенье, 16 декабря 12 г.
Синхронная реализация




воскресенье, 16 декабря 12 г.
воскресенье, 16 декабря 12 г.
Очереди задач
            •      Resque

                 •       Быстро работает, использует Redis

                 •       Удобный Web UI

            •      Redis полезен и для других задач:

                 •       Хранение счетчиков

                 •       Синхронизация состояния

                 •       Кэширование

воскресенье, 16 декабря 12 г.
Уникальные задачи
            •      Сохранение сообщений

            •      Прогрев кэша

            •      Расчет статистики


                 Можно использовать Redis для блокировки



воскресенье, 16 декабря 12 г.
Обычный код
                       def perform
                         return unless redis.setnx("lock", true)

                         # do task actions
                       ensure
                         redis.del "lock"
                       end



                         Реализация: resque-lock (<= 1.0.0)


воскресенье, 16 декабря 12 г.
воскресенье, 16 декабря 12 г.
Правильный код
                                 http://redis.io/commands/setnx
      def perform
        now = Time.now.to_i
        timeout = now + 60

          unless redis.setnx("lock", timeout) # Lock is active
            return if now <= redis.get("lock").to_i # Lock is not expired
            return if now <= redis.getset("lock", timeout).to_i
          end

          # do task actions 11

        redis.del "lock"
      end

                                Реализация: resque-lock (>= 1.1.0)
воскресенье, 16 декабря 12 г.
воскресенье, 16 декабря 12 г.
Хорошие индексы
                  Хорошие = Ускоряющие необходимые запросы
                                create_table 'messages' do |t|
                                  t.references 'source'
                                  t.references 'destination'
                                  t.string 'body'
                                  t.timestamp 'created_at'
                                  t.timestamp 'read_at'
                                end


           # History of messages received from given user
           SELECT * FROM messages WHERE destination_id = ? AND source_id = ?
           ORDER BY created_at DESC LIMIT 10

           # Unread messages of user
           SELECT * FROM messages WHERE destination_id = ? AND read_at IS NULL
           ORDER BY created_at DESC LIMIT 10


воскресенье, 16 декабря 12 г.
Плохие индексы
              # History of messages received from given user
              add_index 'messages', ['source_id', 'destination_id']

              # Unread messages of user
              add_index 'messages', ['destination_id']

      Limit
        -> Sort
              Sort Key: created_at
              Sort Method: top-N heapsort Memory: 25kB
              -> Index Scan using messages_between_users on messages
                    Index Cond: ((source_id = ?) AND (destination_id = ?))
      Total runtime: 6.451 ms

      Limit
        -> Sort
              Sort Key: created_at
              Sort Method: quicksort Memory: 26kB
              -> Bitmap Heap Scan on messages
                    Recheck Cond: (destination_id = ?)
                    Filter: (read_at IS NULL)
                    -> Bitmap Index Scan on messages_unread
                          Index Cond: (destination_id = ?)
      Total runtime: 123.983 ms
воскресенье, 16 декабря 12 г.
Отличные индексы!
     # History of messages received from given user
     add_index 'messages', ['source_id', 'destination_id',
     'created_at'], :order => { 'created_at' => 'desc' }

     # Unread messages of user
     add_index 'messages', ['destination_id', 'created_at'],
       :order => { 'created_at' => 'desc' },:where => 'read_at IS
     NULL'

       Limit
         -> Index Scan using messages_between_users on messages
               Index Cond: ((source_id = ?) AND (destination_id = ?))
       Total runtime: 0.209 ms

       Limit
         -> Index Scan using messages_unread on messages
               Index Cond: (destination_id = ?)
       Total runtime: 0.183 ms



воскресенье, 16 декабря 12 г.
Массивы и hstore


            •      Как сериализация, только лучше

            •      Могут индексироваться




воскресенье, 16 декабря 12 г.
Размер таблиц
           create_table 'users_usual' do |t|
             t.boolean 'flag1'
             ...
             t.boolean 'flag20'
           end

           create_table 'users_hstore' do |t|
             t.hstore 'flags' # gem 'activerecord-postgres-hstore'
           end

           create_table 'users_array' do |t|
             t.integer_array 'flags' # gem 'activerecord-postgres-array'
           end


   5 000 000 записей, флаги независимы, P[flag=yes] = 0.01
        Usual table size: 249 MB
        Hstore table size: 219 MB
        Array table size: 257 MB


воскресенье, 16 декабря 12 г.
Индексирование
                                     Поля:
          Seq Scan on users_usual
            Filter: (flag2 AND flag7 AND flag13)
          Total runtime: 799.959 ms

                                     Hstore:
           Bitmap Heap Scan on users_hstore
             Recheck Cond: (flags @> '2=>y, 7=>y, 13=>y'::hstore)
             -> Bitmap Index Scan on users_hstore_flags
                   Index Cond: (flags @> '2=>y, 7=>y, 13=>y'::hstore)
           Total runtime: 350.778 ms

                                    Массив:
           Bitmap Heap Scan on users_array
             Recheck Cond: (flags @> '{2,7,13}'::integer[])
             -> Bitmap Index Scan on users_array_flags
                   Index Cond: (flags @> '{2,7,13}'::integer[])
           Total runtime: 48.118 ms

воскресенье, 16 декабря 12 г.
Кэширование
                                последовательностей
            •      Выбираем последовательность на несколько шагов
                   вперед

            •      Кэшируем идентификаторы в Redis
         id = redis.lpop(cache_key) # Get next value from cache

         unless id # No cached value
           ids = connection.select_values
         some_heavy_scope.select('id').to_sql
           id = ids.shift

           redis.multi do |r|
             ids.each{ |id| r.rpush cache_key, id }
             r.expire cache_key, 7200 # Expire cache after 2 hours
           end
         end


воскресенье, 16 декабря 12 г.
воскресенье, 16 декабря 12 г.
Кэширование матрицы
              • Проблема
               • Различные фильтры: мин/макс возраст
                           (от 16 до 70) + пол
              • 3080 возможных фильтров
               • (1 + 2 + … + 55) * 2 = 55 * 56
              • Решение: аппроксимация фильтров
воскресенье, 16 декабря 12 г.
Кэширование матрицы
              • Проблема
               • Различные фильтры: мин/макс возраст
                           (от 16 до 70) + пол
              • 3080 возможных фильтров
               • (1 + 2 + … + 55) * 2 = 55 * 56
              • Решение: аппроксимация фильтров
воскресенье, 16 декабря 12 г.
Кэширование с аппроксимацией
         • Возраст округляется до кратного X (= 4)
         • Минимальный - вниз, максимальный - вверх
           • 210 фильтров
             • (1 + 2 + … + 14) * 2 = 14 * 15
         • Кэшируется порция заведомо большего размера
         • После извлечения из кэша выкидываются лишние
                   записи

воскресенье, 16 декабря 12 г.
Обработка фотографий


            •      200–300 регистраций в минуту, половина грузит
                   JPG на 5 мегабайт
            •      Первым делом уменьшайте размер входящих
                   изображений
            •      CarrierWave лучше отделён от модели, чем
                   Paperclip, обратно совместим


воскресенье, 16 декабря 12 г.
Обработка фотографий

            •      RMagick MiniMagick не хранит в себе временного файла,
                   использует память отдельного процесса, не
                   поддерживает создание изображений

            •      GraphicsMagick — форк ImageMagick, ориентированный
                   на стабильность и производительность

            •      Прирост в скорости до 2-3 раз, но это не серебрянная
                   пуля: меньше фич, иногда производительность страдает



воскресенье, 16 декабря 12 г.
Отправка СМС

            •      SMPP – открытый протокол, поддерживаемый
                   большинством SMS-шлюзов
            •      Бинарный, за счет чего выше скорость передачи
                   и footprint воркеров
            •      github.com/raykrueger/ruby-smpp – реализация
                   для EventMachine


воскресенье, 16 декабря 12 г.
Тестирование

            •      Модульное
                 •       Ruby — RSpec
                 •       Erlang — EUnit
            •      Интеграционное?
            •      Нагрузочное?


воскресенье, 16 декабря 12 г.
RSpec для Rails и Erlang
            •      Запуск Erlang при создании сессии

            •      Отдельный поток с EM, обслуживающий все соединения

            •      Socket.io поверх em-websocket-client

            •      Очередь входящих сообщений
             s = open_session_with_chat

             # Delegates to ActionDispatch::Integration::Session
             s.post "/users/sign_in", email: '123@example.com', pass: '12345'

             # Wait for a message (with timeout)
             s.receive(:connect).should be

             # Send message
             s.send_event :contact_message, contact_id, text: "Hi!"



воскресенье, 16 декабря 12 г.
Боты-тестеры

               •      Нагрузочное тестирование чата

               •      Определение проблем с concurrency

               •      Помощь при ручном тестировании

               •      Настраиваемое поведение



воскресенье, 16 декабря 12 г.
Реализация ботов
            •      Акторы на основе EventMachine

            •      Socket.io поверх em-websocket-client

            •      Набор "шаблонов поведения"
                                class Caller < Wannafun::Actor
                                  behave :get_matrix
                                  behave :accept_calls
                                  behave :call_to_users
                                  behave :talk_in_calls
                                end

                                EventMachine.run do
                                  Wannafun::ActorSet.new(Caller, options).start!
                                end



воскресенье, 16 декабря 12 г.
Как ловить JS ошибки на клиенте
            •      В сложных приложениях — сложные сценарии и
                   граничные случаи
            •      Обратная связь пользователь - разработчик.
                   Максимум информации собирается
                   автоматически
            •      Echoes.js (github.com/kossnocorp/echoes). На
                   клиенте собираем логи, фильтруем важные и
                   прикладываем к запросу

воскресенье, 16 декабря 12 г.
Echoes.js
                echo.log('Test', 'logging', namespace: 'app.lol_module.45')
                echo.log(['trololo'])

                                [ { "timestamp":    1341468018606,
                                     "body":        ["Test", "logging"],
                                     "namespace":   "app.lol_module.45"
                                  },
                                  { "timestamp":    1341468018606,
                                     "body":        [["trololo"]],
                                     "namespace":   ""
                                  } ]


               echo.logs.grep 'some'
               #=> [{ body: ['Something'] }, { body: ['I want some LSD.']}]


воскресенье, 16 декабря 12 г.
Мониторинг приложения

            •      Длины очередей в Resque

            •      Кол-во несохраненных сообщений

            •      Кол-во знакомств в разных состояниях

            •      Длина очереди модерации




воскресенье, 16 декабря 12 г.
Head-huntung
                                Wannafun: red.scorpix@gmail.com

                                 Evil Martians: surrender@evl.ms




воскресенье, 16 декабря 12 г.
ВПРСВ НТ?

                                                 ЗБС!
                    Алексей Носков                                        Алексей Найден
                         @alno                                              @alexnayden
                    github.com/alno                                     github.com/anayden
                 alexey.noskov@evl.ms                                  alexey.nayden@evl.ms

                                Все изображения являются собственностью их авторов
воскресенье, 16 декабря 12 г.

Contenu connexe

Tendances

Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Yandex
 
Продуктовые проблемы при создании очередной Docker PaaS / Владимир Ярцев (Cas...
Продуктовые проблемы при создании очередной Docker PaaS / Владимир Ярцев (Cas...Продуктовые проблемы при создании очередной Docker PaaS / Владимир Ярцев (Cas...
Продуктовые проблемы при создании очередной Docker PaaS / Владимир Ярцев (Cas...Ontico
 
MariaDB 10.1 - что нового.
MariaDB 10.1 - что нового.MariaDB 10.1 - что нового.
MariaDB 10.1 - что нового.Sergey Petrunya
 
Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...
Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...
Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...Ontico
 
Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)
Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)
Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)Ontico
 
Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)
Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)
Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)Ontico
 
Эффективная отладка репликации MySQL
Эффективная отладка репликации MySQLЭффективная отладка репликации MySQL
Эффективная отладка репликации MySQLSveta Smirnova
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорьdrupalconf
 
Chef коротко об инфраструктуре
Chef коротко об инфраструктуреChef коротко об инфраструктуре
Chef коротко об инфраструктуреAndrey Subbota
 
Что нужно знать о трёх топовых фичах MySQL
Что нужно знать  о трёх топовых фичах  MySQLЧто нужно знать  о трёх топовых фичах  MySQL
Что нужно знать о трёх топовых фичах MySQLSveta Smirnova
 
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...Ontico
 
Продвинутое использование Celery — Александр Кошелев
Продвинутое использование Celery — Александр КошелевПродвинутое использование Celery — Александр Кошелев
Продвинутое использование Celery — Александр КошелевYandex
 
Работа с Akka Сluster, @afiskon, scalaby#14
Работа с Akka Сluster, @afiskon, scalaby#14Работа с Akka Сluster, @afiskon, scalaby#14
Работа с Akka Сluster, @afiskon, scalaby#14Vasil Remeniuk
 
Егор Львовский — «Кеширование на клиенте и сервере»
Егор Львовский — «Кеширование на клиенте и сервере»Егор Львовский — «Кеширование на клиенте и сервере»
Егор Львовский — «Кеширование на клиенте и сервере»Yandex
 
PaaS, выделенные сервера, облако и снова PaaS
PaaS, выделенные  сервера, облако и снова PaaSPaaS, выделенные  сервера, облако и снова PaaS
PaaS, выделенные сервера, облако и снова PaaSAlexey Vakhov
 
Service Discovery. More that it seems
Service Discovery. More that it seemsService Discovery. More that it seems
Service Discovery. More that it seemsAleksandr Tarasov
 
Alasql.js - SQL база данных на JavaScript / Андрей Гершун (МАГ КОНСАЛТИНГ)
Alasql.js - SQL база данных на JavaScript / Андрей Гершун (МАГ КОНСАЛТИНГ)Alasql.js - SQL база данных на JavaScript / Андрей Гершун (МАГ КОНСАЛТИНГ)
Alasql.js - SQL база данных на JavaScript / Андрей Гершун (МАГ КОНСАЛТИНГ)Ontico
 

Tendances (20)

Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
 
Продуктовые проблемы при создании очередной Docker PaaS / Владимир Ярцев (Cas...
Продуктовые проблемы при создании очередной Docker PaaS / Владимир Ярцев (Cas...Продуктовые проблемы при создании очередной Docker PaaS / Владимир Ярцев (Cas...
Продуктовые проблемы при создании очередной Docker PaaS / Владимир Ярцев (Cas...
 
Event Machine
Event MachineEvent Machine
Event Machine
 
MariaDB 10.1 - что нового.
MariaDB 10.1 - что нового.MariaDB 10.1 - что нового.
MariaDB 10.1 - что нового.
 
Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...
Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...
Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...
 
Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)
Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)
Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)
 
Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)
Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)
Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)
 
Chef
ChefChef
Chef
 
Эффективная отладка репликации MySQL
Эффективная отладка репликации MySQLЭффективная отладка репликации MySQL
Эффективная отладка репликации MySQL
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорь
 
Erlang tasty & useful stuff
Erlang tasty & useful stuffErlang tasty & useful stuff
Erlang tasty & useful stuff
 
Chef коротко об инфраструктуре
Chef коротко об инфраструктуреChef коротко об инфраструктуре
Chef коротко об инфраструктуре
 
Что нужно знать о трёх топовых фичах MySQL
Что нужно знать  о трёх топовых фичах  MySQLЧто нужно знать  о трёх топовых фичах  MySQL
Что нужно знать о трёх топовых фичах MySQL
 
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
 
Продвинутое использование Celery — Александр Кошелев
Продвинутое использование Celery — Александр КошелевПродвинутое использование Celery — Александр Кошелев
Продвинутое использование Celery — Александр Кошелев
 
Работа с Akka Сluster, @afiskon, scalaby#14
Работа с Akka Сluster, @afiskon, scalaby#14Работа с Akka Сluster, @afiskon, scalaby#14
Работа с Akka Сluster, @afiskon, scalaby#14
 
Егор Львовский — «Кеширование на клиенте и сервере»
Егор Львовский — «Кеширование на клиенте и сервере»Егор Львовский — «Кеширование на клиенте и сервере»
Егор Львовский — «Кеширование на клиенте и сервере»
 
PaaS, выделенные сервера, облако и снова PaaS
PaaS, выделенные  сервера, облако и снова PaaSPaaS, выделенные  сервера, облако и снова PaaS
PaaS, выделенные сервера, облако и снова PaaS
 
Service Discovery. More that it seems
Service Discovery. More that it seemsService Discovery. More that it seems
Service Discovery. More that it seems
 
Alasql.js - SQL база данных на JavaScript / Андрей Гершун (МАГ КОНСАЛТИНГ)
Alasql.js - SQL база данных на JavaScript / Андрей Гершун (МАГ КОНСАЛТИНГ)Alasql.js - SQL база данных на JavaScript / Андрей Гершун (МАГ КОНСАЛТИНГ)
Alasql.js - SQL база данных на JavaScript / Андрей Гершун (МАГ КОНСАЛТИНГ)
 

En vedette

Haml/Sassを使って履歴書を書くためのn個の方法
Haml/Sassを使って履歴書を書くためのn個の方法Haml/Sassを使って履歴書を書くためのn個の方法
Haml/Sassを使って履歴書を書くためのn個の方法Tomohiro Nishimura
 
«Работа с базами данных с использованием Sequel»
«Работа с базами данных с использованием Sequel»«Работа с базами данных с использованием Sequel»
«Работа с базами данных с использованием Sequel»Olga Lavrentieva
 
развертывание среды Rails (антон веснин, Locum Ru)
развертывание среды Rails (антон веснин, Locum Ru)развертывание среды Rails (антон веснин, Locum Ru)
развертывание среды Rails (антон веснин, Locum Ru)guest40e031
 
Top10 доводов против языка Ruby
Top10 доводов против языка RubyTop10 доводов против языка Ruby
Top10 доводов против языка Rubyguest5f907e
 

En vedette (7)

Wider than rails
Wider than railsWider than rails
Wider than rails
 
Mini Rails Framework
Mini Rails FrameworkMini Rails Framework
Mini Rails Framework
 
Haml/Sassを使って履歴書を書くためのn個の方法
Haml/Sassを使って履歴書を書くためのn個の方法Haml/Sassを使って履歴書を書くためのn個の方法
Haml/Sassを使って履歴書を書くためのn個の方法
 
Хэши в ruby
Хэши в rubyХэши в ruby
Хэши в ruby
 
«Работа с базами данных с использованием Sequel»
«Работа с базами данных с использованием Sequel»«Работа с базами данных с использованием Sequel»
«Работа с базами данных с использованием Sequel»
 
развертывание среды Rails (антон веснин, Locum Ru)
развертывание среды Rails (антон веснин, Locum Ru)развертывание среды Rails (антон веснин, Locum Ru)
развертывание среды Rails (антон веснин, Locum Ru)
 
Top10 доводов против языка Ruby
Top10 доводов против языка RubyTop10 доводов против языка Ruby
Top10 доводов против языка Ruby
 

Similaire à Технические аспекты знакоства с девушкой в Интернете

Building the Enterprise infrastructure with PostgreSQL as the basis for stori...
Building the Enterprise infrastructure with PostgreSQL as the basis for stori...Building the Enterprise infrastructure with PostgreSQL as the basis for stori...
Building the Enterprise infrastructure with PostgreSQL as the basis for stori...PavelKonotopov
 
A popular DNS security overview
A popular DNS security overviewA popular DNS security overview
A popular DNS security overviewPhilipp Kulin
 
Rails, Eventmachine, Erlang
Rails, Eventmachine, ErlangRails, Eventmachine, Erlang
Rails, Eventmachine, ErlangMax Lapshin
 
Нетрадиционное использование Ruby и PostgreSQL
Нетрадиционное использование Ruby и PostgreSQLНетрадиционное использование Ruby и PostgreSQL
Нетрадиционное использование Ruby и PostgreSQLIvan Evtukhovich
 
Frontera: распределенный робот для обхода интернета в больших объемах - Алекс...
Frontera: распределенный робот для обхода интернета в больших объемах - Алекс...Frontera: распределенный робот для обхода интернета в больших объемах - Алекс...
Frontera: распределенный робот для обхода интернета в больших объемах - Алекс...it-people
 
Frontera обход испанского интернета
Frontera обход испанского интернетаFrontera обход испанского интернета
Frontera обход испанского интернетаAlexander Sibiryakov
 
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...Yandex
 
Предметно-ориентированные языки программирования (DSL)
Предметно-ориентированные языки программирования (DSL)Предметно-ориентированные языки программирования (DSL)
Предметно-ориентированные языки программирования (DSL)Alexander Kirillov
 
MongoDB. Области применения, преимущества и узкие места, тонкости использован...
MongoDB. Области применения, преимущества и узкие места, тонкости использован...MongoDB. Области применения, преимущества и узкие места, тонкости использован...
MongoDB. Области применения, преимущества и узкие места, тонкости использован...phpdevby
 
Горизонтальное масштабирование: что, зачем, когда и как /Александр Макаров (Y...
Горизонтальное масштабирование: что, зачем, когда и как /Александр Макаров (Y...Горизонтальное масштабирование: что, зачем, когда и как /Александр Макаров (Y...
Горизонтальное масштабирование: что, зачем, когда и как /Александр Макаров (Y...Ontico
 
Daemons In Web on #devrus
Daemons In Web on #devrusDaemons In Web on #devrus
Daemons In Web on #devrusAlex Chistyakov
 
Tech Talks @NSU: Что такое Highload? Секреты высокой нагрузки.
Tech Talks @NSU: Что такое Highload? Секреты высокой нагрузки.Tech Talks @NSU: Что такое Highload? Секреты высокой нагрузки.
Tech Talks @NSU: Что такое Highload? Секреты высокой нагрузки.Tech Talks @NSU
 
Что такое Highload? Секреты высокой нагрузки
Что такое Highload? Секреты высокой нагрузкиЧто такое Highload? Секреты высокой нагрузки
Что такое Highload? Секреты высокой нагрузкиTech Talks @NSU
 
Обзор перспективных баз данных для highload / Юрий Насретдинов
Обзор перспективных баз данных для highload / Юрий НасретдиновОбзор перспективных баз данных для highload / Юрий Насретдинов
Обзор перспективных баз данных для highload / Юрий НасретдиновOntico
 
Tyurin Alexey - NTLM. Part 1. Pass-the-Hash
Tyurin Alexey - NTLM. Part 1. Pass-the-HashTyurin Alexey - NTLM. Part 1. Pass-the-Hash
Tyurin Alexey - NTLM. Part 1. Pass-the-HashDefconRussia
 
Распространенные ошибки применения баз данных (Сергей Аверин)
Распространенные ошибки применения баз данных (Сергей Аверин)Распространенные ошибки применения баз данных (Сергей Аверин)
Распространенные ошибки применения баз данных (Сергей Аверин)Ontico
 
Распространенные ошибки применения баз данных
Распространенные ошибки применения баз данныхРаспространенные ошибки применения баз данных
Распространенные ошибки применения баз данныхSergey Xek
 
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...Ruby Meditation
 

Similaire à Технические аспекты знакоства с девушкой в Интернете (20)

Building the Enterprise infrastructure with PostgreSQL as the basis for stori...
Building the Enterprise infrastructure with PostgreSQL as the basis for stori...Building the Enterprise infrastructure with PostgreSQL as the basis for stori...
Building the Enterprise infrastructure with PostgreSQL as the basis for stori...
 
A popular DNS security overview
A popular DNS security overviewA popular DNS security overview
A popular DNS security overview
 
Rails, Eventmachine, Erlang
Rails, Eventmachine, ErlangRails, Eventmachine, Erlang
Rails, Eventmachine, Erlang
 
Нетрадиционное использование Ruby и PostgreSQL
Нетрадиционное использование Ruby и PostgreSQLНетрадиционное использование Ruby и PostgreSQL
Нетрадиционное использование Ruby и PostgreSQL
 
Frontera: распределенный робот для обхода интернета в больших объемах - Алекс...
Frontera: распределенный робот для обхода интернета в больших объемах - Алекс...Frontera: распределенный робот для обхода интернета в больших объемах - Алекс...
Frontera: распределенный робот для обхода интернета в больших объемах - Алекс...
 
Frontera обход испанского интернета
Frontera обход испанского интернетаFrontera обход испанского интернета
Frontera обход испанского интернета
 
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...
 
Meteor
MeteorMeteor
Meteor
 
Предметно-ориентированные языки программирования (DSL)
Предметно-ориентированные языки программирования (DSL)Предметно-ориентированные языки программирования (DSL)
Предметно-ориентированные языки программирования (DSL)
 
MongoDB. Области применения, преимущества и узкие места, тонкости использован...
MongoDB. Области применения, преимущества и узкие места, тонкости использован...MongoDB. Области применения, преимущества и узкие места, тонкости использован...
MongoDB. Области применения, преимущества и узкие места, тонкости использован...
 
Горизонтальное масштабирование: что, зачем, когда и как /Александр Макаров (Y...
Горизонтальное масштабирование: что, зачем, когда и как /Александр Макаров (Y...Горизонтальное масштабирование: что, зачем, когда и как /Александр Макаров (Y...
Горизонтальное масштабирование: что, зачем, когда и как /Александр Макаров (Y...
 
Daemons In Web on #devrus
Daemons In Web on #devrusDaemons In Web on #devrus
Daemons In Web on #devrus
 
Nosql and Mongodb
Nosql and MongodbNosql and Mongodb
Nosql and Mongodb
 
Tech Talks @NSU: Что такое Highload? Секреты высокой нагрузки.
Tech Talks @NSU: Что такое Highload? Секреты высокой нагрузки.Tech Talks @NSU: Что такое Highload? Секреты высокой нагрузки.
Tech Talks @NSU: Что такое Highload? Секреты высокой нагрузки.
 
Что такое Highload? Секреты высокой нагрузки
Что такое Highload? Секреты высокой нагрузкиЧто такое Highload? Секреты высокой нагрузки
Что такое Highload? Секреты высокой нагрузки
 
Обзор перспективных баз данных для highload / Юрий Насретдинов
Обзор перспективных баз данных для highload / Юрий НасретдиновОбзор перспективных баз данных для highload / Юрий Насретдинов
Обзор перспективных баз данных для highload / Юрий Насретдинов
 
Tyurin Alexey - NTLM. Part 1. Pass-the-Hash
Tyurin Alexey - NTLM. Part 1. Pass-the-HashTyurin Alexey - NTLM. Part 1. Pass-the-Hash
Tyurin Alexey - NTLM. Part 1. Pass-the-Hash
 
Распространенные ошибки применения баз данных (Сергей Аверин)
Распространенные ошибки применения баз данных (Сергей Аверин)Распространенные ошибки применения баз данных (Сергей Аверин)
Распространенные ошибки применения баз данных (Сергей Аверин)
 
Распространенные ошибки применения баз данных
Распространенные ошибки применения баз данныхРаспространенные ошибки применения баз данных
Распространенные ошибки применения баз данных
 
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
 

Технические аспекты знакоства с девушкой в Интернете

  • 1. Технические аспекты знакомства с девушкой в интернете Алексей Найден, Алексей Носков Evil Martians воскресенье, 16 декабря 12 г.
  • 4. Wannafun.ru • Онлайн speed dating • Знакомство только с теми, кто в сети • Поток лиц aka «матрица» • 3 минуты чата для принятия решения • 48% / 52% воскресенье, 16 декабря 12 г.
  • 5. Проект в цифрах • 500 000 пользователей • 2000 онлайн • 2-3 события в секунду на юзера • Более 100 http-запросов в минуту на юзера • Более 5 000 000 чатов • Более 45 000 000 сообщений воскресенье, 16 декабря 12 г.
  • 6. На чем всё работает Erlang Postgres Redis EventMachine Rails Resque воскресенье, 16 декабря 12 г.
  • 8. Онлайн-взаимодействия • Знакомства: входящие/исходящие, сообщения • Контакт-лист: личные сообщения, онлайн/ оффлайн • Уведомления воскресенье, 16 декабря 12 г.
  • 9. Взаимодействие с браузером Pusher (http://pusher.com/) Faye (http://faye.jcoglan.com/) Push-канал к клиенту Pub/sub Нет серверной логики Нет серверной логики Socket.io (http://socket.io/) Абстракция над WebSocket, Flash и Polling Произвольная серверная логика воскресенье, 16 декабря 12 г.
  • 10. Серверная реализация socket.io • NodeJS • На тестах падала VM — epic fail • EventMachine • Не было актуальной версии • Erlang • Не было актуальной версии воскресенье, 16 декабря 12 г.
  • 11. Что хорошего в Erlang • Нет коллбеков - простой последовательный код • Нет разделяемого состояния, структуры данных неизменяемы - concurrency проще • Иерархия супервизоров - высокая устойчивость • Прозрачная распределенность • Бесшовный деплой воскресенье, 16 декабря 12 г.
  • 12. Архитектура чат-сервера • Соединения обслуживаются Cowboy • Каждая сессия - отдельный процесс • Вспомогательные процессы для работы с БД, Redis воскресенье, 16 декабря 12 г.
  • 17. Очереди задач • Resque • Быстро работает, использует Redis • Удобный Web UI • Redis полезен и для других задач: • Хранение счетчиков • Синхронизация состояния • Кэширование воскресенье, 16 декабря 12 г.
  • 18. Уникальные задачи • Сохранение сообщений • Прогрев кэша • Расчет статистики Можно использовать Redis для блокировки воскресенье, 16 декабря 12 г.
  • 19. Обычный код def perform return unless redis.setnx("lock", true) # do task actions ensure redis.del "lock" end Реализация: resque-lock (<= 1.0.0) воскресенье, 16 декабря 12 г.
  • 21. Правильный код http://redis.io/commands/setnx def perform now = Time.now.to_i timeout = now + 60 unless redis.setnx("lock", timeout) # Lock is active return if now <= redis.get("lock").to_i # Lock is not expired return if now <= redis.getset("lock", timeout).to_i end # do task actions 11 redis.del "lock" end Реализация: resque-lock (>= 1.1.0) воскресенье, 16 декабря 12 г.
  • 23. Хорошие индексы Хорошие = Ускоряющие необходимые запросы create_table 'messages' do |t| t.references 'source' t.references 'destination' t.string 'body' t.timestamp 'created_at' t.timestamp 'read_at' end # History of messages received from given user SELECT * FROM messages WHERE destination_id = ? AND source_id = ? ORDER BY created_at DESC LIMIT 10 # Unread messages of user SELECT * FROM messages WHERE destination_id = ? AND read_at IS NULL ORDER BY created_at DESC LIMIT 10 воскресенье, 16 декабря 12 г.
  • 24. Плохие индексы # History of messages received from given user add_index 'messages', ['source_id', 'destination_id'] # Unread messages of user add_index 'messages', ['destination_id'] Limit -> Sort Sort Key: created_at Sort Method: top-N heapsort Memory: 25kB -> Index Scan using messages_between_users on messages Index Cond: ((source_id = ?) AND (destination_id = ?)) Total runtime: 6.451 ms Limit -> Sort Sort Key: created_at Sort Method: quicksort Memory: 26kB -> Bitmap Heap Scan on messages Recheck Cond: (destination_id = ?) Filter: (read_at IS NULL) -> Bitmap Index Scan on messages_unread Index Cond: (destination_id = ?) Total runtime: 123.983 ms воскресенье, 16 декабря 12 г.
  • 25. Отличные индексы! # History of messages received from given user add_index 'messages', ['source_id', 'destination_id', 'created_at'], :order => { 'created_at' => 'desc' } # Unread messages of user add_index 'messages', ['destination_id', 'created_at'], :order => { 'created_at' => 'desc' },:where => 'read_at IS NULL' Limit -> Index Scan using messages_between_users on messages Index Cond: ((source_id = ?) AND (destination_id = ?)) Total runtime: 0.209 ms Limit -> Index Scan using messages_unread on messages Index Cond: (destination_id = ?) Total runtime: 0.183 ms воскресенье, 16 декабря 12 г.
  • 26. Массивы и hstore • Как сериализация, только лучше • Могут индексироваться воскресенье, 16 декабря 12 г.
  • 27. Размер таблиц create_table 'users_usual' do |t| t.boolean 'flag1' ... t.boolean 'flag20' end create_table 'users_hstore' do |t| t.hstore 'flags' # gem 'activerecord-postgres-hstore' end create_table 'users_array' do |t| t.integer_array 'flags' # gem 'activerecord-postgres-array' end 5 000 000 записей, флаги независимы, P[flag=yes] = 0.01 Usual table size: 249 MB Hstore table size: 219 MB Array table size: 257 MB воскресенье, 16 декабря 12 г.
  • 28. Индексирование Поля: Seq Scan on users_usual Filter: (flag2 AND flag7 AND flag13) Total runtime: 799.959 ms Hstore: Bitmap Heap Scan on users_hstore Recheck Cond: (flags @> '2=>y, 7=>y, 13=>y'::hstore) -> Bitmap Index Scan on users_hstore_flags Index Cond: (flags @> '2=>y, 7=>y, 13=>y'::hstore) Total runtime: 350.778 ms Массив: Bitmap Heap Scan on users_array Recheck Cond: (flags @> '{2,7,13}'::integer[]) -> Bitmap Index Scan on users_array_flags Index Cond: (flags @> '{2,7,13}'::integer[]) Total runtime: 48.118 ms воскресенье, 16 декабря 12 г.
  • 29. Кэширование последовательностей • Выбираем последовательность на несколько шагов вперед • Кэшируем идентификаторы в Redis id = redis.lpop(cache_key) # Get next value from cache unless id # No cached value ids = connection.select_values some_heavy_scope.select('id').to_sql id = ids.shift redis.multi do |r| ids.each{ |id| r.rpush cache_key, id } r.expire cache_key, 7200 # Expire cache after 2 hours end end воскресенье, 16 декабря 12 г.
  • 31. Кэширование матрицы • Проблема • Различные фильтры: мин/макс возраст (от 16 до 70) + пол • 3080 возможных фильтров • (1 + 2 + … + 55) * 2 = 55 * 56 • Решение: аппроксимация фильтров воскресенье, 16 декабря 12 г.
  • 32. Кэширование матрицы • Проблема • Различные фильтры: мин/макс возраст (от 16 до 70) + пол • 3080 возможных фильтров • (1 + 2 + … + 55) * 2 = 55 * 56 • Решение: аппроксимация фильтров воскресенье, 16 декабря 12 г.
  • 33. Кэширование с аппроксимацией • Возраст округляется до кратного X (= 4) • Минимальный - вниз, максимальный - вверх • 210 фильтров • (1 + 2 + … + 14) * 2 = 14 * 15 • Кэшируется порция заведомо большего размера • После извлечения из кэша выкидываются лишние записи воскресенье, 16 декабря 12 г.
  • 34. Обработка фотографий • 200–300 регистраций в минуту, половина грузит JPG на 5 мегабайт • Первым делом уменьшайте размер входящих изображений • CarrierWave лучше отделён от модели, чем Paperclip, обратно совместим воскресенье, 16 декабря 12 г.
  • 35. Обработка фотографий • RMagick MiniMagick не хранит в себе временного файла, использует память отдельного процесса, не поддерживает создание изображений • GraphicsMagick — форк ImageMagick, ориентированный на стабильность и производительность • Прирост в скорости до 2-3 раз, но это не серебрянная пуля: меньше фич, иногда производительность страдает воскресенье, 16 декабря 12 г.
  • 36. Отправка СМС • SMPP – открытый протокол, поддерживаемый большинством SMS-шлюзов • Бинарный, за счет чего выше скорость передачи и footprint воркеров • github.com/raykrueger/ruby-smpp – реализация для EventMachine воскресенье, 16 декабря 12 г.
  • 37. Тестирование • Модульное • Ruby — RSpec • Erlang — EUnit • Интеграционное? • Нагрузочное? воскресенье, 16 декабря 12 г.
  • 38. RSpec для Rails и Erlang • Запуск Erlang при создании сессии • Отдельный поток с EM, обслуживающий все соединения • Socket.io поверх em-websocket-client • Очередь входящих сообщений s = open_session_with_chat # Delegates to ActionDispatch::Integration::Session s.post "/users/sign_in", email: '123@example.com', pass: '12345' # Wait for a message (with timeout) s.receive(:connect).should be # Send message s.send_event :contact_message, contact_id, text: "Hi!" воскресенье, 16 декабря 12 г.
  • 39. Боты-тестеры • Нагрузочное тестирование чата • Определение проблем с concurrency • Помощь при ручном тестировании • Настраиваемое поведение воскресенье, 16 декабря 12 г.
  • 40. Реализация ботов • Акторы на основе EventMachine • Socket.io поверх em-websocket-client • Набор "шаблонов поведения" class Caller < Wannafun::Actor behave :get_matrix behave :accept_calls behave :call_to_users behave :talk_in_calls end EventMachine.run do Wannafun::ActorSet.new(Caller, options).start! end воскресенье, 16 декабря 12 г.
  • 41. Как ловить JS ошибки на клиенте • В сложных приложениях — сложные сценарии и граничные случаи • Обратная связь пользователь - разработчик. Максимум информации собирается автоматически • Echoes.js (github.com/kossnocorp/echoes). На клиенте собираем логи, фильтруем важные и прикладываем к запросу воскресенье, 16 декабря 12 г.
  • 42. Echoes.js echo.log('Test', 'logging', namespace: 'app.lol_module.45') echo.log(['trololo']) [ { "timestamp": 1341468018606, "body": ["Test", "logging"], "namespace": "app.lol_module.45" }, { "timestamp": 1341468018606, "body": [["trololo"]], "namespace": "" } ] echo.logs.grep 'some' #=> [{ body: ['Something'] }, { body: ['I want some LSD.']}] воскресенье, 16 декабря 12 г.
  • 43. Мониторинг приложения • Длины очередей в Resque • Кол-во несохраненных сообщений • Кол-во знакомств в разных состояниях • Длина очереди модерации воскресенье, 16 декабря 12 г.
  • 44. Head-huntung Wannafun: red.scorpix@gmail.com Evil Martians: surrender@evl.ms воскресенье, 16 декабря 12 г.
  • 45. ВПРСВ НТ? ЗБС! Алексей Носков Алексей Найден @alno @alexnayden github.com/alno github.com/anayden alexey.noskov@evl.ms alexey.nayden@evl.ms Все изображения являются собственностью их авторов воскресенье, 16 декабря 12 г.