Contenu connexe Similaire à Трудовые будни инженера производительности (20) Трудовые будни инженера производительности1. © 2015 NetCracker Technology Corporation Confidential
Трудовые будни performance engineer
Владимир Ситников
jokerconf university 2015
2. 2© 2015 NetCracker Technology Corporation Confidential
Кто я
• Владимир Ситников
• Инженер-ускорятор в NetCracker
• sitnikov@netcracker.com
• @VladimirSitnikv
3. 3© 2015 NetCracker Technology Corporation Confidential
Характерные требования в enterprise
• Время отклика
‒ 100мс … 1с … 1ч
• Частота выполнений
‒ 1/день … 1/с … 100/с
• Объём обрабатываемых данных
‒ 10КиБ … 1Миб … 1ГиБ
4. 4© 2015 NetCracker Technology Corporation Confidential
Основная ошибка при проверке производительности
Проверку требований нужно выполнять на
приближенных к боевым условиях
5. 5© 2015 NetCracker Technology Corporation Confidential
Основная ошибка при проверке производительности
Проверку требований нужно выполнять на
приближенных к боевым условиях
• Та же версия java, OS, application server
6. 6© 2015 NetCracker Technology Corporation Confidential
Основная ошибка при проверке производительности
Проверку требований нужно выполнять на
приближенных к боевым условиях
• Та же версия java, OS, application server
• Тот же объём данных
7. 7© 2015 NetCracker Technology Corporation Confidential
Основная ошибка при проверке производительности
Проверку требований нужно выполнять на
приближенных к боевым условиях
• Та же версия java, OS, application server
• Тот же объём данных
• Та же входная нагрузка
8. 8© 2015 NetCracker Technology Corporation Confidential
Основная ошибка при проверке производительности
Проверку требований нужно выполнять на
приближенных к боевым условиях
• Та же версия java, OS, application server
• Тот же объём данных
• Та же входная нагрузка
• Тот же процент ошибочных сценариев
9. 9© 2015 NetCracker Technology Corporation Confidential
Проблемы в Production
• Создан работающий код
• Пройдено тестирование
10. 10© 2015 NetCracker Technology Corporation Confidential
Проблемы в Production
• Создан работающий код
• Пройдено тестирование
• Production
Проблемы производительности,
недоступность приложения, и т.п.
11. 11© 2015 NetCracker Technology Corporation Confidential
Проблемы в Production
• Создан работающий код
• Пройдено тестирование
• Production
Проблемы производительности,
недоступность приложения, и т.п.
• Customer Support передает проблему в System Performance
12. 12© 2015 NetCracker Technology Corporation Confidential
Проблемы в Production
• Создан работающий код
• Пройдено тестирование
• Production
Проблемы производительности,
недоступность приложения, и т.п.
• Customer Support передает проблему в System Performance
• SP находит причину, и автор кода о ней не знает
13. 13© 2015 NetCracker Technology Corporation Confidential
Сложение строк
• StringBuilder vs StringBuffer
• String + String vs SB.append
14. 14© 2015 NetCracker Technology Corporation Confidential
Сложение строк
• StringBuilder vs StringBuffer
• Без разницы
• String + String vs SB.append
• В циклах лучше SB
15. 15© 2015 NetCracker Technology Corporation Confidential
Когда же нужен StringB***er?
String res = "";
String names[] = ...;
for(int i=0; i<length; i++) {
res += (i==0 ? "" : ", ") + names[i];
}
StringBuilder полезен в циклах/if’ах
16. 16© 2015 NetCracker Technology Corporation Confidential
Когда же нужен StringB***er?
String res = "";
String names[] = ...;
for(int i=0; i<length; i++) {
res += new SB()
.append(i==0 ? "" : ", ")
.append(names[i]).toString();
}
StringBuilder полезен в циклах/if’ах
17. 17© 2015 NetCracker Technology Corporation Confidential
Когда же нужен StringB***er?
StringBuilder res = new StringBuilder();
String names[] = ...;
for(int i=0; i<length; i++) {
res
.append(i==0 ? "" : ", ")
.append(names[i]);
}
StringBuilder полезен в циклах/if’ах
18. 18© 2015 NetCracker Technology Corporation Confidential
Добавляем вишенку
StringBuilder res = new StringBuilder(100500);
String names[] = ...;
for(int i=0; i<length; i++) {
res
.append(i==0 ? "" : ", ")
.append(names[i]);
}
StringBuilder полезен в циклах/if’ах
19. 19© 2015 NetCracker Technology Corporation Confidential
GC друг или враг?
• Основная масса проблем с java в enterprise – java GC или OS
swap
20. 20© 2015 NetCracker Technology Corporation Confidential
GC друг или враг?
• Основная масса проблем с java в enterprise – java GC или OS
swap
• Для анализа всегда сохраняем логи работы GC: -Xloggc
21. 21© 2015 NetCracker Technology Corporation Confidential
GC друг или враг?
• Основная масса проблем с java в enterprise – java GC или OS
swap
• Для анализа всегда сохраняем логи работы GC: -Xloggc
• Открываем программой GCViewer
22. 22© 2015 NetCracker Technology Corporation Confidential
GC друг или враг?
• Основная масса проблем с java в enterprise – java GC или OS
swap
• Для анализа всегда сохраняем логи работы GC: -Xloggc
• Открываем программой GCViewer
• GC наносит ответный удар: лог пишется синхронно
• Не стоит размещать gc.log на сетевых дисках (NFS):
http://mail.openjdk.java.net/pipermail/hotspot-gc-use/2014-
April/001849.html
23. 23© 2015 NetCracker Technology Corporation Confidential
GCViewer: пример случая, когда «всё пропало»
• Без GC логов не понять хватило ли памяти
24. 24© 2015 NetCracker Technology Corporation Confidential
Где может встретиться regexp
• «Маскирование» (~засекречивание) данных:
pin коды, номера карт, …
• Обработка XML: логирование, проверка success/fail, …
• Много где ещё
25. 25© 2015 NetCracker Technology Corporation Confidential
Решили использовать regexp
Стоит избегать .*, .+ и подобных не специфичных конструкций
http://www.regular-expressions.info/catastrophic.html
26. 26© 2015 NetCracker Technology Corporation Confidential
Решили использовать regexp
Стоит избегать .*, .+ и подобных не специфичных конструкций
http://www.regular-expressions.info/catastrophic.html
Пример медленного выражения:
Pattern.compile(
"<(S+:)?processID.*>(d+)</(S+:)?processID>"
27. 27© 2015 NetCracker Technology Corporation Confidential
Решили использовать regexp
Стоит избегать .*, .+ и подобных не специфичных конструкций
http://www.regular-expressions.info/catastrophic.html
Пример медленного выражения:
Pattern.compile(
"<(S+:)?processID.*>(d+)</(S+:)?processID>"
Встречались экземпляры, работающие 30 секунд на 100КиБ строке
Встречались SQL запросы, работающие по 30 минут вместо 30 секунд
28. 28© 2015 NetCracker Technology Corporation Confidential
/^.*ab$/.match("ab")
|ab
.*ab
a|b
.*ab
ab|
.*ab
ab|
.*ab
a|b
.*ab
откатились
a|b
.*ab
не помогло
|ab
.*ab
откатились
ab|
.*ab
Ура!
.* – жадная конструкция. Ест как не в себя
29. 29© 2015 NetCracker Technology Corporation Confidential
Чиним
Стоит избегать .*, .+ и подобных неспецифичных конструкций
http://www.regular-expressions.info/catastrophic.html
Пример быстрого выражения:
Pattern.compile(
"[:<]processID[^>]*>(d+)</([^>:]+:)?processID>"
Решение: [^>]* и [^>:]+ остановятся на первом неподходящем
символе. За границу xml тэга наш regexp не уйдёт.
30. 30© 2015 NetCracker Technology Corporation Confidential
Чиним ещё чуть-чуть
Добавляем плюсик для отмены откатов:
Pattern.compile(
"[:<]processID[^>]*+>(d+)</([^>:]++:)?processID>“
Меньше вариантов на проверку – быстрее работает
31. 31© 2015 NetCracker Technology Corporation Confidential
График скорости .*, .*?, [^>]
0
100
200
300
400
1 КиБ 2 КиБ 3 КиБ 4 КиБ
Быстрее,оп/мс
.*
.*?
[^>]*
32. 32© 2015 NetCracker Technology Corporation Confidential
График скорости .*, .*?, [^>], шаблон не найден
0
10
20
30
40
50
1 КиБ 2 КиБ 3 КиБ 4 КиБ
Быстрее,оп/мс
.*
.*?
[^>]*
Поиск тормозил, т.к.
шаблон не нашёлся
33. 33© 2015 NetCracker Technology Corporation Confidential
График скорости .*, .*, [^>], шаблон не найден
0
20
40
60
80
100
1 КиБ 2 КиБ 3 КиБ 4 КиБ
Быстрее,оп/мс
.*
.*?
[^>]*
(?>
<ROW>(?>.*?<RSACCTNMBR>)
(?>[^<]*</RSACCTNMBR>)…
34. 34© 2015 NetCracker Technology Corporation Confidential
Признаки хорошего регулярного выражения
• Кушает только нужные символы
• [^>]* vs .*
• .(!=hello)
35. 35© 2015 NetCracker Technology Corporation Confidential
Признаки хорошего регулярного выражения
• Кушает только нужные символы
• [^>]* vs .*
• .(!=hello)
• Не содержит лишних конструкций
• <MACd{5} vs (<MACd{5}s)
36. 36© 2015 NetCracker Technology Corporation Confidential
Признаки хорошего регулярного выражения
• Кушает только нужные символы
• [^>]* vs .*
• .(!=hello)
• Не содержит лишних конструкций
• <MACd{5} vs (<MACd{5}s)
• Не выполняется вообще
• Например, если мы маскируем значения, то делать это нужно только если
реально выводим данные
• Если XML всё равно парсить, то стоит посмотреть на XPath
37. 37© 2015 NetCracker Technology Corporation Confidential
А давайте ускорим String?
String.format("...") использует
java.util.regex.Pattern для разбора формата
formatSpecifier = "%(d+$)?([-#+
0,(<]*)?(d+)?(.d+)?([tT])?([a-
zA-Z%])";
38. 38© 2015 NetCracker Technology Corporation Confidential
Откуда взять тестовые данные?
Возьмём шаблон из Java Microbenchmark
Harness:
(min, avg, max) = (%s, %s, %s), stdev = %s%n
CI (99.9%%): [%s, %s] (assumes normal
distribution)
39. 39© 2015 NetCracker Technology Corporation Confidential
Добавляем плюсов по вкусу
formatSpecifier = "%(d+$)?([-#+
0,(<]*)?(d+)?(.d+)?([tT])?([a-
zA-Z%])";
fastSpecifier = "%(d++$)?+([-#+
0,(<]+)?+(d++)?+(.d++)?+([tT])?+([a-zA-
Z%])";
40. 40© 2015 NetCracker Technology Corporation Confidential
Бесплатный сыр
Benchmark Cnt Score Error Units
jdk18u45 60 1,067 ± 0,025 us/op
optimized 60 0,917 ± 0,021 us/op
41. 41© 2015 NetCracker Technology Corporation Confidential
HashMap$Entry
• HashMap создаёт вспомогательные Entry объекты для
хранения связки ключ-значение
42. 42© 2015 NetCracker Technology Corporation Confidential
HashMap$Entry
• HashMap создаёт вспомогательные Entry объекты для
хранения связки ключ-значение
• Если большинство ключей оказываются одинаковыми,
то очень хочется не хранить ключи в каждом
отдельном объекте Map
43. 43© 2015 NetCracker Technology Corporation Confidential
HashMap
HashMap Entry[]
Entry
id
41
Entry
name
qwe
44. 44© 2015 NetCracker Technology Corporation Confidential
HashMap: entry лишние
HashMap Entry[]
Entry
id
41
Entry
name
qwe
45. 45© 2015 NetCracker Technology Corporation Confidential
HashMap
HashMap Entry[]
Entry
id
41
Entry
name
qwe
46. 46© 2015 NetCracker Technology Corporation Confidential
CompactMap
CMap1 Object[]
41
qwe
CMap2
keypos
id=0
name=1
Object[]
42
rty
47. 47© 2015 NetCracker Technology Corporation Confidential
CompactHashMap: границы применимости
• Работает, если форма (состав ключей) у многих
объектов одинаковая
• Например, у всех объектов есть запись “width”=“100%”
• https://github.com/vlsi/compactmap
• См. v8/design.html#prop_access
48. 48© 2015 NetCracker Technology Corporation Confidential
CompactHashMap: первые тесты
HashMap -> CompactHashMap в реальном
проекте:
• 500МиБ –> 290МиБ
• 3.0 сек / 1M обращений -> 150 сек / 1M обращений
49. 49© 2015 NetCracker Technology Corporation Confidential
CompactHashMap
HashMap -> CompactHashMap в реальном
проекте:
• 500МиБ –> 290МиБ
• 3.0 сек / 1M обращений -> 150 сек / 1M обращений
50. 50© 2015 NetCracker Technology Corporation Confidential
ReservedCodeCacheSize
• Если у JIT компилятора заканчивается память,
то он перестаёт компилировать
51. 51© 2015 NetCracker Technology Corporation Confidential
ReservedCodeCacheSize
• Если у JIT компилятора заканчивается память,
то он перестаёт компилировать
• В приложении с большим количеством кода
стандартных 64M мало
52. 52© 2015 NetCracker Technology Corporation Confidential
ReservedCodeCacheSize
• Если у JIT компилятора заканчивается память,
то он перестаёт компилировать
• В приложении с большим количеством кода
стандартных 64M мало
• -XX:+ReservedCodeCacheSize=128m/192m
53. 53© 2015 NetCracker Technology Corporation Confidential
CompactHashMap
HashMap -> CompactHashMap, -
XX:+ReservedCodeCacheSize=128m:
• 500МиБ –> 290МиБ
• 3.0 сек / 1M обращений -> 3.5 сек / 1M обращений
55. 55© 2015 NetCracker Technology Corporation Confidential
Типичные проблемы в SQL
• Выборка лишних данных
• max(order_number)+1, count(*)>0, большая иерархия
• Нет ясного порядка выполнения запроса
• Лишние таблицы в части FROM
• Неверное использование связанных переменных
56. 56© 2015 NetCracker Technology Corporation Confidential
Типичные проблемы в SQL
• Выборка лишних данных
• max(order_number)+1, count(*)>0, большая иерархия
• Нет ясного порядка выполнения запроса
• Лишние таблицы в части FROM
• Неверное использование связанных переменных
57. 57© 2015 NetCracker Technology Corporation Confidential
Один запрос – один правильный план выполнения
1. В “Folder for Orders” найти Order, ссылающийся на нужный Instance
Как бы решал человек:
1. По ссылкам находим ордера, и проверяем Folder
58. 58© 2015 NetCracker Technology Corporation Confidential
Один запрос – один правильный план выполнения
2. В “Service Order’е” найти компоненту, ссылающуюся на нужный
Template
Как бы решал человек:
2. Находим дочерние компоненты и проверяем Template
10
101
59. 59© 2015 NetCracker Technology Corporation Confidential
Один запрос – один правильный план выполнения
Задачи:
1. В “Folder for Service Orders” найти Service Order, ссылающийся на нужный
Service Instance
2. В “Service Order’е” найти компоненту, ссылающуюся на нужный Template
В обоих случаях может получиться одинаковый запрос (например, EAV):
select o.object_id
from objects o, references ref
where o.parent_id = :1
and o.object_id = ref.object_id
and ref.reference = :2
and ref.property = :3
60. 60© 2015 NetCracker Technology Corporation Confidential
Один запрос – один правильный план выполнения
• Разработчик должен хотя бы задумываться о плане выполнения
• Без explain plan никуда
61. 61© 2015 NetCracker Technology Corporation Confidential
Один запрос – один правильный план выполнения
• Разработчик должен хотя бы задумываться о плане выполнения
• Без explain plan никуда
• Если в запросе несколько условий, то хинты обязательны
62. 62© 2015 NetCracker Technology Corporation Confidential
Один запрос – один правильный план выполнения
• Разработчик должен хотя бы задумываться о плане выполнения
• Без explain plan никуда
• Если в запросе несколько условий, то хинты обязательны
• Основные хинты:
• leading(a b c) – указываем с каких таблиц начинать
выполнение запроса
• index(o index_name) – указываем какой индекс нужно
использовать
• no_merge – запрещаем раскрывать подзапросы
• use_nl/use_hash – основные способы объединения таблиц
63. 63© 2015 NetCracker Technology Corporation Confidential
А нужны ли хинты?
•База умная,
сама ускорит запросы
64. 64© 2015 NetCracker Technology Corporation Confidential
А нужны ли хинты?
•База умная, статистику собрали,
сама ускорит запросы
65. 65© 2015 NetCracker Technology Corporation Confidential
А нужны ли хинты?
•База умная, статистику собрали,
собираем статистику регулярно,
запросы сами будут хорошие
66. 66© 2015 NetCracker Technology Corporation Confidential
А нужны ли хинты?
•База умная, статистику собрали,
собираем статистику регулярно,
запросы сами будут хорошие
база не понимает бизнес-смысл
•Без хинтов не взлетит
67. 67© 2015 NetCracker Technology Corporation Confidential
А нужна ли тогда статистика?
•Если всё равно хинты, то зачем
статистика?
68. 68© 2015 NetCracker Technology Corporation Confidential
А нужна ли тогда статистика?
•Если всё равно хинты, то зачем
статистика?
69. 69© 2015 NetCracker Technology Corporation Confidential
А нужна ли тогда статистика?
•Если всё равно хинты, то зачем
статистика?
• Повторяемость production и dev/test
окружений
70. 70© 2015 NetCracker Technology Corporation Confidential
А нужна ли тогда статистика?
•Если всё равно хинты, то зачем
статистика?
• Повторяемость production и dev/test
окружений
• Отсутствие out-of-thin air проблем
71. 71© 2015 NetCracker Technology Corporation Confidential
А как же любимые cost/rows?
• База оценивает количество строк на основе собранной статистики
72. 72© 2015 NetCracker Technology Corporation Confidential
А как же любимые cost/rows?
• База оценивает количество строк на основе собранной статистики
• В статистику входят
• Общее количество строк
• Количество уникальных записей в колонке
• Количество null записей в колонке
73. 73© 2015 NetCracker Technology Corporation Confidential
А как же любимые cost/rows?
• База оценивает количество строк на основе собранной статистики
• В статистику входят
• Общее количество строк
• Количество уникальных записей в колонке
• Количество null записей в колонке
• Rows – оценка базы о том, сколько строк вернёт запрос
• Cost – оценка базы о том, сколько дисковых операций потребуется
для выполнения запроса
74. 74© 2015 NetCracker Technology Corporation Confidential
А как же любимые cost/rows?
• База оценивает количество строк на основе собранной
статистики
• В статистику входят
• Общее количество строк
• Количество уникальных записей в колонке
• Количество null записей в колонке
• Бизнес-смысл данных в статистику не входит!
• Rows – оценка базы о том, сколько строк вернёт запрос
• Cost – оценка базы о том, сколько дисковых операций
потребуется для выполнения запроса
75. 75© 2015 NetCracker Technology Corporation Confidential
Кто я
• Владимир Ситников
• Инженер-ускорятор в NetCracker
• sitnikov@netcracker.com
• @VladimirSitnikv
Notes de l'éditeur 9мин 15.4 18.2 18.2 26 26