Top Banner
31 ОКТЯБРЯ, 2015 ЭКСТРЕМАЛЬНАЯ ОПТИМИЗАЦИЯ ПРОИЗВОДИТЕЛЬНОСТИ на примере MongoDB Java Driver
35

Экстремальная оптимизация производительности на примере MongoDB Java Driver

Apr 12, 2017

Download

Technology

Vitebsk DSC
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Экстремальная оптимизация производительности на примере MongoDB Java Driver

31 ОКТЯБРЯ, 2015

ЭКСТРЕМАЛЬНАЯ

ОПТИМИЗАЦИЯ

ПРОИЗВОДИТЕЛЬНОСТИ

на примере MongoDB Java Driver

Page 2: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Евгений Берлог

Java-разработчик

EPAM

Page 3: Экстремальная оптимизация производительности на примере MongoDB Java Driver

План выступления

С чего все начиналось

Выбор стандартного решения

Что-то пошло не так…

Что мы могли сделать?

Что мы сделали?

Выводы

Page 4: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Исходные условия

OracleCoherence

WEB RESTInternal

Tool

х 15 х 15 х 10

Page 5: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Исходные условия

OracleCoherence

WEB RESTInternal

Tool

MongoDB

х 15 х 15 х 10

Page 6: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Особенности системы

Большие размеры объектов (~1MB)

Много уровней вложенности

Зависимости между объектами

Вложенные массивы

Множество сценариев использования

Ограниченный объем RAM

Page 7: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Выбор фреймворка

M

MORPHIA SPRING DATA

Многообещающий

красавчикУверенный в себе

крепыш

«Плоский» и

гибкий работяга

JAVA DRIVER

+ самописный ORM

Page 8: Экстремальная оптимизация производительности на примере MongoDB Java Driver

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

100% запросов на чтения

50 параллельных потоков

1 млн запросов

Page 9: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Morphia, секJava-драйвер +

самописный ORM, сек

Документ 10KB 14,0 13,7 (-2,2%)

Документ 100KB 120,0 115,9 (-3,5%)

Документ 1MB 927,2 887,0 (-4,4%)

Суммарное время выполнения запросов

Результаты тестирования

Page 10: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Morphia, секJava-драйвер +

самописный ORM, сек

Документ 10KB 0,101 0,097 (-4,0%)

Документ 100KB 1,044 0,995 (-4,7%)

Документ 1MB 9,377 8,811 (-6,1%)

Суммарное время работы сборщика мусора (GC)

Результаты тестирования

Page 11: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Plain MongoDB driver

Большой объем потребляемой памяти

Сборщик мусора отрабатывает часто

Непредсказуемая производительность и

стабильность

Page 12: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Что же делать?

Page 13: Экстремальная оптимизация производительности на примере MongoDB Java Driver

JUST OPTIMIZE IT.

Page 14: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Что не так с Plain driver?

MongoDB

MongoDB

DriverConverter Service

byte[ ] DBObject Domain

Page 15: Экстремальная оптимизация производительности на примере MongoDB Java Driver

А что, если…

MongoDB

MongoDB

DriverConverter Service

byte[ ] DBObject

ByteArrayToDomainConverter

Domain

Page 16: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Что получилось

MongoDB

DomainMagic

ConverterImproved

MongoDB Driver

byte[ ]

Service

Page 17: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Другие улучшения

Создание строк

Кэширование строк

«Ленивая» загрузка документов

«Ленивая» десериализация

Page 18: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Создание строк?

Page 19: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Да, создание строк

Текущая реализация в драйвере

String createString() {byte[] bytes = new byte[size];readBytes(bytes); // copy bytes from input streamreturn new String(bytes, UTF8_CHARSET);

}

Page 20: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Создание строк

Попытка #1 – Чуть-чуть лучше

String createString() {char[] array = new char[bytes.length];for (int i = 0; i < bytes.length; i++) {

array[i] = (char) bytes[i];}return new String(array);

}

Page 21: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Создание строк

Попытка #2 – Оптимально

String createString() throws IllegalAccessException {char[] array = new char[bytes.length];for (int i = 0; i < bytes.length; i++) {

array[i] = (char) bytes[i];}

String s = new String();Field field = String.class.getDeclaredField("value"); field.set(s, array);return s;

}

Page 22: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Создание 1 млрд строк

Общее время, сек Время GC, сек

new String(byte[ ], UTF-8) 95,8 0,884

new String(char[ ]) 93,0 (-3,0%) 0,861 (-3,0%)

Reflection 92,1 (-3,9%) 0,568 (-36,0%)

Page 23: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Кэширование строк

0xffaa11 0xccff2e

String 1

String 2

... ... ... ...

ConcurrentHashMap

• Ключ – hash от строки

• Значение – CopyOnWriteArrayList<String>

Page 24: Экстремальная оптимизация производительности на примере MongoDB Java Driver

«Ленивая» подгрузка

Domain1

Item*

Page 25: Экстремальная оптимизация производительности на примере MongoDB Java Driver

«Ленивая» подгрузка

Domain Proxy LinkResolver Template

load()

readIds()

resolve()

findByIds(ids)

setItems(resolved)

getItems()

Page 26: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Что получилось

{"_id": "Java","type": "language","father": {

"class": "JavaContributor","name": "James","surname": "Gosling","hasBeard": true

},"features": /* массив байт */

}

Business rules

Page 27: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Что получилось

{"_id": "Java","type": "language","father": {

"class": "JavaContributor","name": "James","surname": "Gosling","hasBeard": true

},"features": /* массив байт */

}

Optional

No package

Reflections

Page 28: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Что получилось

{"_id": "Java","type": "language","father": {

"class": "JavaContributor","name": "James","surname": "Gosling","hasBeard": true

},"features": /* массив байт */

}

Lazy de-serialization

Page 29: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Что получилось

{"_id": "Java","type": "language","father": {

"class": "JavaContributor","name": "James","surname": "Gosling","hasBeard": true

},"features": [

"object-oriented","static type-checking"

]}

De-serialized array

Page 30: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Что получилось

Java-драйвер + самописный ORM,

сек

«Улучшенный»Java-драйвер,

сек

Документ 10KB 13,7 12,7 (-7,3%)

Документ 100KB 115,9 105,2 (-9,2%)

Документ 1MB 887,0 791,4 (-10,7%)

100% запросов на чтения

50 параллельных потоков

1 млн запросов

Суммарное время выполнения запросов

Page 31: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Что получилось

100% запросов на чтения

50 параллельных потоков

1 млн запросов

Суммарное время работы сборщика мусора (GC)

Java-драйвер + самописный ORM,

сек

«Улучшенный»Java-драйвер,

сек

Документ 10KB 0,097 0,087 (-10,0%)

Документ 100KB 0,995 0,791 (-20,5%)

Документ 1MB 8,811 5,861 (-33,5%)

Page 32: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Недостатки решения

Сложность поддержки

Сложность тестирования

• Соответствие BSON формату

• Коллизии кэширования

• Многопоточность

Page 33: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Java Driver 3.0+

Апрель 2015

API упрощающий интеграцию

Page 34: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Выводы

Page 35: Экстремальная оптимизация производительности на примере MongoDB Java Driver

Вопросы ?