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

27

Upload: kuchinskaya

Post on 18-Nov-2014

791 views

Category:

Documents


3 download

DESCRIPTION

 

TRANSCRIPT

Page 1: андрей паньгин
Page 2: андрей паньгин

Особенности разработки сервера на Java

Архитектура Одноклассников

Сокеты в Java: проблемы и решения

Альтернативный механизм сериализации

Кеширование данных и разделяемая память

2

Page 3: андрей паньгин

Серверы Одноклассников

• 4000 серверов

• Web, Business logic, Download, Storage, Remote Services

• Все ПО написано на Java

Высоконагруженный сервер

• 20 тыс. одновременных подключений

• 30 тыс. запросов в секунду

• Трафик до 1 Gb/s

3

Page 4: андрей паньгин

Remote Service

• Компоненты портала как отдельные сервисы:

система сообщений, граф дружб, поиск, лента и т. д.

• Внутренняя коммуникация между сервисами

4

Business logic server

Graph cluster

User service cluster

long[] friendIds = getConnections (userId)

List<User> friends = getUsers (friendIds)

Page 5: андрей паньгин

RPC сценарий

5

Read Request

Deserialize arguments

Invoke method

Serialize result

Send response

Object result = method.invoke(args);

byte[] request = connection.read(…);

request → Method method, Object[] args

result → byte[] response

connection.write(response);

Page 6: андрей паньгин

Особенности разработки сервера на Java

Архитектура Одноклассников

Сокеты в Java: проблемы и решения

Альтернативный механизм сериализации

Кеширование данных и разделяемая память

6

Page 7: андрей паньгин

Разработка сервера на Java

• java.net (Socket I/O) – Поток на каждое соединение

– Максимум 10 тыс. потоков

• NIO – Неблокирующие операции read / write

– Selector

• NIO frameworks – Apache MINA: http://mina.apache.org

– Netty: http://netty.io

7

Page 8: андрей паньгин

Blocking Socket Selector (BLOS)

• Сочетает преимущества Selector + Blocking I/O

• Поддерживается на уровне ОС, но не в Java

• JNI обертки над системными вызовами – Socket → SocketImpl impl → FileDescriptor fd → int fd

8

Linux BSD Solaris Windows

epoll kqueue /dev/poll Completion ports

Page 9: андрей паньгин

Архитектура BLOS сервера

9

Acceptor thread

Selector 1

Selector 2

read deserialize invoke serialize send

read deserialize invoke serialize send

Worker thread pool

Page 10: андрей паньгин

Проблемы работы с сетью в Java

• Socket – Finalizers => утечка памяти, влияние на GC

– Не поддерживается прямой доступ к памяти (Direct ByteBuffers)

• SocketChannel (NIO) – Не срабатывают таймауты на I/O операциях

– Возможна утечка нативной памяти

• Решение: JNI библиотека – Такой подход используется в Tomcat (APR + Tomcat native)

– Управление сокетами вручную

10

Page 11: андрей паньгин

Особенности разработки сервера на Java

Архитектура Одноклассников

Сокеты в Java: проблемы и решения

Альтернативный механизм сериализации

Кеширование данных и разделяемая память

11

Page 12: андрей паньгин

Важность сериализации в RPC

• Затрачиваемое время на кодирование и декодирование

• Объем передаваемых по сети данных

12

Read Request

Deserialize arguments

Invoke method

Serialize result

Send response

Page 13: андрей паньгин

Способы сериализации в Java

• Стандартная Java сериализация – Медленная

– Большой объем получаемых данных

• JBoss serialization – Не поддерживает простые изменения внутри класса:

добавление поля, удаление, изменение типа или порядка полей

• Avro, Thrift, Protocol Buffers

• Ручная сериализация – Externalizable – Не вариант (тысячи классов!)

13

Page 14: андрей паньгин

Архитектура сериализации

• Типы сериализаторов – Встроенные (примитивные типы, массивы, коллекции)

– Сериализатор класса по полям

• Каждому сериализатору сопоставляется уникальный

64-битный ID – хеш от имен, типов и порядка полей

14

UID 2012 7 m a i l . r u 1

class Event { String site = “mail.ru”; int year = 2012; boolean started = true; }

Page 15: андрей паньгин

Процедура сериализации

• Запись объекта: 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);

15

may throw SerializerNotFoundException

Page 16: андрей паньгин

Особенности реализации в Java

• Чтение и запись private полей чужих классов – Reflection (медленно!)

– sun.misc.Unsafe

• Создание экземпляров класса – sun.misc.Unsafe.allocateInstance()

– Динамическая генерация байткода

ASM framework: http://asm.ow2.org

• Обход Java верификатора – Наследование “магического” класса sun.reflect.MagicAccessorImpl

16

Page 17: андрей паньгин

Производительность

• Среднее время запроса: -20%

• Сетевой трафик: -50%

17

Page 18: андрей паньгин

Особенности разработки сервера на Java

Архитектура Одноклассников

Сокеты в Java: проблемы и решения

Альтернативный механизм сериализации

Кеширование данных и разделяемая память

18

Page 19: андрей паньгин

Что кешировть?

• Данные из медленного хранилища (БД)

• Результаты вычислений

Где кешировть?

• В оперативной памяти – Java Heap (не подходит для объемов > 10 GB)

– Off-heap memory

• На диске или флеш-накопителе

19

Page 20: андрей паньгин

Доступ к 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

Page 21: андрей паньгин

Снимки (shapshots)

• Решают проблему холодного старта

• Должны быть целостными

• Способы создания снимков – “Stop-the-world”

– Запись по сегментам

– Memory-mapped files (MappedByteBuffer.force)

– Copy-on-write (fork trick)

– Shared memory objects

21

Page 22: андрей паньгин

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

Page 23: андрей паньгин

Реализация off-heap кеша в Java

на примере download сервера

• Непрерывная область памяти с собственным аллокатором

• FIFO (проще, чем LRU)

• sun.misc.Unsafe (самый быстрый способ доступа)

• Shared Memory (/dev/shm)

• Сегментирование ключей по хеш-коду

• Блокировка сегмента через ReadWriteLock / Semaphore

23

Page 24: андрей паньгин

Структура кеша

24

Page 25: андрей паньгин

Сравнение производительности

• Условия – Linux JDK7u4 64-bit

– 1 млн. операций

– Значения от 0 до 8 KB

25

Page 26: андрей паньгин

Примеры

• https://github.com/odnoklassniki/shared-memory-cache.git

• https://github.com/odnoklassniki/rmi-samples.git

Статьи

• http://habrahabr.ru/company/odnoklassniki/blog/148139/

Контакты

[email protected]

• www.odnoklassniki.ru/ap

26

Page 27: андрей паньгин

Андрей Паньгин

Ведущий разработчик, Одноклассники

[email protected]

СПАСИБО!