андрей паньгин

582
-1

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
582
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

андрей паньгин

  1. 1. Особенности разработки сервера на Java  Архитектура Одноклассников  Сокеты в Java: проблемы и решения  Альтернативный механизм сериализации  Кеширование данных и разделяемая память 2
  2. 2. Серверы Одноклассников • 4000 серверов • Web, Business logic, Download, Storage, Remote Services • Все ПО написано на JavaВысоконагруженный сервер • 20 тыс. одновременных подключений • 30 тыс. запросов в секунду • Трафик до 1 Gb/s 3
  3. 3. Remote Service • Компоненты портала как отдельные сервисы: система сообщений, граф дружб, поиск, лента и т. д. • Внутренняя коммуникация между сервисами long[] friendIds = getConnections (userId) Graph cluster Business logic server List<User> friends = getUsers (friendIds) User service cluster 4
  4. 4. RPC сценарий Read Request byte[] request = connection.read(…); Deserialize arguments request → Method method, Object[] args Invoke method Object result = method.invoke(args); Serialize result result → byte[] response Send response connection.write(response); 5
  5. 5. Особенности разработки сервера на Java  Архитектура Одноклассников  Сокеты в Java: проблемы и решения  Альтернативный механизм сериализации  Кеширование данных и разделяемая память 6
  6. 6. Разработка сервера на Java • java.net (Socket I/O) – Поток на каждое соединение – Максимум 10 тыс. потоков • NIO – Неблокирующие операции read / write – Selector • NIO frameworks – Apache MINA: http://mina.apache.org – Netty: http://netty.io 7
  7. 7. Blocking Socket Selector (BLOS) • Сочетает преимущества Selector + Blocking I/O • Поддерживается на уровне ОС, но не в Java Linux BSD Solaris Windows epoll kqueue /dev/poll Completion ports • JNI обертки над системными вызовами – Socket → SocketImpl impl → FileDescriptor fd → int fd 8
  8. 8. Архитектура BLOS сервера Acceptor thread Selector 1 Selector 2 read deserialize invoke serialize send read deserialize invoke serialize send Worker thread pool 9
  9. 9. Проблемы работы с сетью в Java • Socket – Finalizers => утечка памяти, влияние на GC – Не поддерживается прямой доступ к памяти (Direct ByteBuffers) • SocketChannel (NIO) – Не срабатывают таймауты на I/O операциях – Возможна утечка нативной памяти • Решение: JNI библиотека – Такой подход используется в Tomcat (APR + Tomcat native) – Управление сокетами вручную 10
  10. 10. Особенности разработки сервера на Java  Архитектура Одноклассников  Сокеты в Java: проблемы и решения  Альтернативный механизм сериализации  Кеширование данных и разделяемая память 11
  11. 11. Важность сериализации в RPC • Затрачиваемое время на кодирование и декодирование • Объем передаваемых по сети данных Read Request Deserialize arguments Invoke method Serialize result Send response 12
  12. 12. Способы сериализации в Java • Стандартная Java сериализация – Медленная – Большой объем получаемых данных • JBoss serialization – Не поддерживает простые изменения внутри класса: добавление поля, удаление, изменение типа или порядка полей • Avro, Thrift, Protocol Buffers • Ручная сериализация – Externalizable – Не вариант (тысячи классов!) 13
  13. 13. Архитектура сериализации • Типы сериализаторов – Встроенные (примитивные типы, массивы, коллекции) – Сериализатор класса по полям • Каждому сериализатору сопоставляется уникальный 64-битный ID – хеш от имен, типов и порядка полей class Event { String site = “mail.ru”; int year = 2012; UID 7 m a i l . r u 2012 1 boolean started = true; } 14
  14. 14. Процедура сериализации • Запись объекта: 1. Serializer serializer = Repository.getByClass(obj.getClass()); 2. outputStream.writeLong(serializer.uid); 3. serializer.write(obj, outputStream); • Чтение объекта: 1. long uid = inputStream.readLong(); 2. Serializer serializer = Repository.getById(uid); 3. Object obj = serializer.read(inputStream); may throw SerializerNotFoundException 15
  15. 15. Особенности реализации в Java • Чтение и запись private полей чужих классов – Reflection (медленно!) – sun.misc.Unsafe • Создание экземпляров класса – sun.misc.Unsafe.allocateInstance() – Динамическая генерация байткода ASM framework: http://asm.ow2.org • Обход Java верификатора – Наследование “магического” класса sun.reflect.MagicAccessorImpl 16
  16. 16. Производительность • Среднее время запроса: -20% • Сетевой трафик: -50% 17
  17. 17. Особенности разработки сервера на Java  Архитектура Одноклассников  Сокеты в Java: проблемы и решения  Альтернативный механизм сериализации  Кеширование данных и разделяемая память 18
  18. 18. Что кешировть? • Данные из медленного хранилища (БД) • Результаты вычисленийГде кешировть? • В оперативной памяти – Java Heap (не подходит для объемов > 10 GB) – Off-heap memory • На диске или флеш-накопителе 19
  19. 19. Доступ к off-heap памяти в Java • Native код (JNI обертки над malloc / free) – Платформозавимый • ByteBuffer.allocateDirect – Размер буфера ≤ 2 GB – Освобождается автоматически при GC – Освобождение вручную: ((sun.nio.ch.DirectBuffer) buf).cleaner().clean(); • MappedByteBuffer (FileChannel.map) • Unsafe.allocateMemory 20
  20. 20. Снимки (shapshots) • Решают проблему холодного старта • Должны быть целостными • Способы создания снимков – “Stop-the-world” – Запись по сегментам – Memory-mapped files (MappedByteBuffer.force) – Copy-on-write (fork trick) – Shared memory objects 21
  21. 21. Shared Memory • Механизм IPC – POSIX: shm_open + mmap – Windows: CreateFileMapping + MapViewOfFile – Linux: /dev/shm • Создание объекта Shared Memory в Java – new RandomAccessFile("/dev/shm/cache", "rw"); • Отображение в адресное пространство процесса – легальный способ: FileChannel.map – хитрый способ: sun.nio.ch.FileChannelImpl, методы map0 и unmap0 22
  22. 22. Реализация off-heap кеша в Javaна примере download сервера • Непрерывная область памяти с собственным аллокатором • FIFO (проще, чем LRU) • sun.misc.Unsafe (самый быстрый способ доступа) • Shared Memory (/dev/shm) • Сегментирование ключей по хеш-коду • Блокировка сегмента через ReadWriteLock / Semaphore 23
  23. 23. Структура кеша 24
  24. 24. Сравнение производительности • Условия – Linux JDK7u4 64-bit – 1 млн. операций – Значения от 0 до 8 KB 25
  25. 25. Примеры • https://github.com/odnoklassniki/shared-memory-cache.git • https://github.com/odnoklassniki/rmi-samples.gitСтатьи • http://habrahabr.ru/company/odnoklassniki/blog/148139/Контакты • andrey.pangin@corp.mail.ru • www.odnoklassniki.ru/ap 26
  26. 26. СПАСИБО! Андрей ПаньгинВедущий разработчик, Одноклассники andrey.pangin@corp.mail.ru

×