|
| 1 | +## Факты |
| 2 | + |
| 3 | +Была обновлена система с Monterey на Sonora, а также почищен диск |
| 4 | + |
| 5 | +В связи с чем результаты значительно выросли, |
| 6 | +особеннно в области **GET** запросов, которые очень много работают с диском |
| 7 | + |
| 8 | +Получается достаточное количества места на диске важный параметр |
| 9 | + |
| 10 | +Либо стоит благословить Купертино |
| 11 | + |
| 12 | +## Нагрузка |
| 13 | +### Характеристики |
| 14 | +Macbook Pro M1 16GB после перезапуска |
| 15 | + |
| 16 | + |
| 17 | +## Старый код |
| 18 | +До этого мы тестировали при 1 подключении и 1 потоке |
| 19 | + |
| 20 | +Соответственно у нас было 2 ограничения: |
| 21 | +1. Мы могли упираться в производительность wrk2 |
| 22 | +2. Наш код работал только в одном потоке, несмотря на количество селекторов, т.к. подключение 1 |
| 23 | + |
| 24 | +Поэтому перезапустим старый код и найдем новые rps |
| 25 | +### PUT |
| 26 | + |
| 27 | +По [локам](old_base_lock.html) переодически можно заметить flush, который тормозит селекторы |
| 28 | + |
| 29 | +Как мы видим [15000](old_base_wrk.txt) нагрузка настолько слабая, |
| 30 | +что нам не понадобились даже все селекторы (их только 4) |
| 31 | +[cpu](old_base_cpu.html) |
| 32 | + |
| 33 | +Немного поискав |
| 34 | +* [30000](old_30000_wrk.txt) |
| 35 | +* [60000](old_60000_wrk.txt) |
| 36 | +* [52000](old_52000_wrk.txt) |
| 37 | + |
| 38 | +остановился на [48000](old_stable_wrk.txt) RPS |
| 39 | + |
| 40 | +[lock](old_stable_lock.html) из интересного можно заметить, |
| 41 | +что по окончании работы закрывается множество сессий |
| 42 | + |
| 43 | +информация об этом пишется в лог и можно сделать выводы о том, что: |
| 44 | +1. не стоить злоупотреблять логами |
| 45 | +2. по этому столбику в целом можно смотреть о проблемности остальных локов |
| 46 | + *(чем он больше, тем менее значимы остальные локи)* |
| 47 | + |
| 48 | +По [cpu](old_stable_cpu.html) видно, что большая часть ресурсов уходит на обработку подключений |
| 49 | + |
| 50 | +5 min: [rps](old_stable_long_wrk.txt), |
| 51 | +[alloc](old_stable_long_alloc.html) |
| 52 | +[cpu](old_stable_long_cpu.html), |
| 53 | +[lock](old_stable_long_lock.html) |
| 54 | + |
| 55 | +Как мы видим просадки теперь намного значительнее, т.к. flush блокирует все потоки |
| 56 | + |
| 57 | +### GET |
| 58 | + |
| 59 | +Немного поискав |
| 60 | +[60000](old_get_60000_wrk.txt) |
| 61 | +[80000](old_get_80000_wrk.txt) |
| 62 | +[85000](old_get_85000_wrk.txt) |
| 63 | +[90000](old_get_90000_wrk.txt) |
| 64 | +[100000](old_get_100000_wrk.txt) |
| 65 | + |
| 66 | +Остановился на 80000 rps |
| 67 | +5 min: |
| 68 | +[alloc](old_get_stable_long_alloc.html) |
| 69 | +[cpu](old_get_stable_long_cpu.html) |
| 70 | +[lock](old_get_stable_long_lock.html) |
| 71 | +[rps](old_get_stable_long_wrk.txt) |
| 72 | + |
| 73 | +Как мы видим из [lock](old_get_stable_long_lock.html) никаких локов на гет запросах нет, как и из кода |
| 74 | + |
| 75 | +В целом ничего, кроме огромного роста производительности отметить нечего |
| 76 | + |
| 77 | +И если в случае с **PUT** запросами он был всего в несколько раз, |
| 78 | +то здесь рост достаточно линеен, что может говорить о высоком параллелизме кода |
| 79 | + |
| 80 | +## Новый код |
| 81 | + |
| 82 | +### ArrayBlockingQueue |
| 83 | + |
| 84 | +Производительность только упала |
| 85 | + |
| 86 | +#### PUT |
| 87 | + |
| 88 | +Как показали опыты: poolSize имеет значение. |
| 89 | +* 16: |
| 90 | +* * 43000: [alloc](new_put_a_16_43000_alloc.html), |
| 91 | + [cpu](new_put_a_16_43000_cpu.html), |
| 92 | + [lock](new_put_a_16_43000_lock.html), |
| 93 | + [rps](new_put_a_16_43000_wrk.txt) |
| 94 | +* * 48000: [alloc](new_put_a_16_48000_alloc.html), |
| 95 | + [cpu](new_put_a_16_48000_cpu.html), |
| 96 | + [lock](new_put_a_16_48000_lock.html), |
| 97 | + [rps](new_put_a_16_48000_wrk.txt) |
| 98 | +* * [50000](new_put_a_16_50000_wrk.txt) |
| 99 | +* 32 |
| 100 | +* * [42000](new_put_a_32_42000_wrk.txt) |
| 101 | +* * 43000: [alloc](new_put_a_32_43000_alloc.html), |
| 102 | + [cpu](new_put_a_32_43000_cpu.html), |
| 103 | + [lock](new_put_a_32_43000_lock.html), |
| 104 | + [rps](new_put_a_32_43000_wrk.txt), |
| 105 | +* * [45000](new_put_a_32_45000_wrk.txt) |
| 106 | +* * [50000](new_put_a_32_50000_wrk.txt) |
| 107 | + |
| 108 | +Чем больше потоков, тем сильнее они мешают друг-другу, что приводит к значительному снижению производительности |
| 109 | + |
| 110 | +Так мы добрались до 8 максимальных (т.е. по числу ядер). |
| 111 | +* [alloc](new_put_a_2_8_48000_alloc.html) |
| 112 | +* [cpu](new_put_a_2_8_48000_cpu.html) |
| 113 | +* [lock](new_put_a_2_8_48000_lock.html) |
| 114 | +* [rps](new_put_a_2_8_48000_wrk.txt) |
| 115 | + |
| 116 | +5 min: [alloc](new_put_a_2_8_stable_long_alloc.html), |
| 117 | +[cpu](new_put_a_2_8_stable_long_cpu.html), |
| 118 | +[lock](new_put_a_2_8_stable_long_lock.html), |
| 119 | +[rps](new_put_a_2_8_stable_long_wrk.txt) |
| 120 | + |
| 121 | +Основные проблемы и заполнение очереди происходили при flush'ах таблицы, что вполне ожидаемо |
| 122 | + |
| 123 | +#### GET |
| 124 | + |
| 125 | +Здесь обратная ситуация, наши ответы достаточно долгие, а запросы наоборот быстрые, т.к. никаких данных считывать нам не нужно |
| 126 | + |
| 127 | +И чем больше poolSize, тем больше допустимый RPS |
| 128 | + |
| 129 | +### LinkedBlockingQueue |
| 130 | + |
| 131 | +Несложно заметить, что у нас большие проблемы с локами. Связано это с тем, что в `ArrayBlockingQueue` |
| 132 | +одна блокировка на чтение и запись, поэтому окончательно разделить селекторы от воркеров не получилось |
| 133 | + |
| 134 | +Воспользуемся `LinkedBlockingQueue`, у которой уже 2 разные блокировки на чтение и запись |
| 135 | + |
| 136 | +#### PUT |
| 137 | + |
| 138 | +Как мы видим, несмотря на то, что время самих блокировок для селекторов значительно уменьшилось |
| 139 | + |
| 140 | +Что повысило скорость поступления новых задач (поэтому был повышел queueCapacity до 200, т.к. он набирался слишком быстро). |
| 141 | + |
| 142 | +Однако, сама очередь достаточно медлена. Из-за чего общая производительность страдает. |
| 143 | + |
| 144 | +* [40000](new_put_l_32_40000_wrk.txt) |
| 145 | +* 45000: [alloc](new_put_l_32_45000_alloc.html), |
| 146 | + [cpu](new_put_l_32_45000_cpu.html), |
| 147 | + [lock](new_put_l_32_45000_lock.html), |
| 148 | + [rps](new_put_l_32_45000_wrk.txt) |
| 149 | +* [48000](new_put_l_32_48000_wrk.txt) |
| 150 | +* [60000](new_put_l_32_60000_wrk.txt) |
| 151 | + |
| 152 | +#### GET |
| 153 | + |
| 154 | +На удивление, **GET'у** стало чуть лучше, но мне кажется, все в рамках погрешности |
| 155 | + |
| 156 | +[rps](new_get_l_32_60000_wrk.txt), |
| 157 | +[alloc](new_get_l_32_60000_alloc.html), |
| 158 | +[cpu](new_get_l_32_60000_cpu.html), |
| 159 | +[lock](new_get_l_32_60000_lock.html) |
| 160 | + |
| 161 | +### Давайте попробуем поделить |
| 162 | + |
| 163 | +Поделим селекторы и воркеров на группы, чтобы уменьшить блокировку |
| 164 | + |
| 165 | +Как мы видим, мы смогли замедлить downgrade касательно времени работы |
| 166 | + |
| 167 | +Однако, как-то значительно улучшить производительность это нам не помогло |
| 168 | + |
| 169 | +#### PUT |
| 170 | + |
| 171 | + |
| 172 | +* 40000: |
| 173 | + [alloc.html](1709758164_alloc.html) |
| 174 | + [cpu.html](1709758164_cpu.html) |
| 175 | + [lock.html](1709758164_lock.html) |
| 176 | + [wrk.txt](1709758164_wrk.txt) |
| 177 | +* 50000: |
| 178 | + [alloc](1709758118_alloc.html), |
| 179 | + [cpu](1709758118_cpu.html), |
| 180 | + [lock](1709758118_lock.html), |
| 181 | + [rps](1709758118_wrk.txt) |
| 182 | + |
| 183 | + * 60000: [alloc](1709758089_alloc.html), |
| 184 | + [cpu](1709758089_cpu.html), |
| 185 | + [lock](1709758089_lock.html), |
| 186 | + [rps](1709758089_wrk.txt) |
| 187 | + |
| 188 | +Локи в селекторах теперь незначительно, но тольку то ;) |
| 189 | + |
| 190 | +## Вывод |
| 191 | + |
| 192 | +Несмотря, на очевидность преимуществ, которые нам может подарить разделение селекторов |
| 193 | + |
| 194 | +Оказывается, что на самом деле это довольно тонкая тема, в связи с многопоточностью и блокировками, |
| 195 | +которые нужно не забывать учитывать |
| 196 | + |
| 197 | +К сожалению, не успел посмотреть `DiscardPolicy` с обрывом сокета для первой в очереди. |
| 198 | +Это вполне могло повлиять на среднее время ответа |
0 commit comments