Spring Session + Redis - wolne działanie

0

Mam aplikację w spring boocie + trzymanie sesji w redisie.

Jestem trochę rozczarowany szybkością aplikacji, a dokładniej ilością operacji read/update z i do redisa. Dla logowania bez istniejącej sesji wygląda to następująco:

15:58:02.039 DEBUG io.lettuce.core.RedisChannelHandler - dispatching command AsyncCommand [type=HMSET, output=StatusOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]
15:58:02.161 DEBUG io.lettuce.core.RedisChannelHandler - dispatching command AsyncCommand [type=SADD, output=IntegerOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]
15:58:02.193 DEBUG io.lettuce.core.RedisChannelHandler - dispatching command AsyncCommand [type=SADD, output=IntegerOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]
15:58:02.226 DEBUG io.lettuce.core.RedisChannelHandler - dispatching command AsyncCommand [type=PEXPIRE, output=BooleanOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]
15:58:02.246 DEBUG io.lettuce.core.RedisChannelHandler - dispatching command AsyncCommand [type=APPEND, output=IntegerOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]
15:58:02.277 DEBUG io.lettuce.core.RedisChannelHandler - dispatching command AsyncCommand [type=PEXPIRE, output=BooleanOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]
15:58:02.309 DEBUG io.lettuce.core.RedisChannelHandler - dispatching command AsyncCommand [type=PEXPIRE, output=BooleanOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]
15:58:02.346 DEBUG io.lettuce.core.RedisChannelHandler - dispatching command AsyncCommand [type=PUBLISH, output=IntegerOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]
15:58:02.362 DEBUG io.lettuce.core.RedisChannelHandler - dispatching command AsyncCommand [type=HMSET, output=StatusOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]
15:58:02.487 DEBUG io.lettuce.core.RedisChannelHandler - dispatching command AsyncCommand [type=SADD, output=IntegerOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]
15:58:02.565 DEBUG io.lettuce.core.RedisChannelHandler - dispatching command AsyncCommand [type=PEXPIRE, output=BooleanOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]
15:58:02.596 DEBUG io.lettuce.core.RedisChannelHandler - dispatching command AsyncCommand [type=APPEND, output=IntegerOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]
15:58:02.627 DEBUG io.lettuce.core.RedisChannelHandler - dispatching command AsyncCommand [type=PEXPIRE, output=BooleanOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]
15:58:02.647 DEBUG io.lettuce.core.RedisChannelHandler - dispatching command AsyncCommand [type=PEXPIRE, output=BooleanOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]

dla porównania, jdbc:

16:37:53.821 DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [UPDATE SPRING_SESSION SET SESSION_ID = ?, LAST_ACCESS_TIME = ?, MAX_INACTIVE_INTERVAL = ?, EXPIRY_TIME = ?, PRINCIPAL_NAME = ? WHERE PRIMARY_ID = ?]
16:37:53.862 DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [INSERT INTO SPRING_SESSION_ATTRIBUTES(SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) SELECT PRIMARY_ID, ?, ? FROM SPRING_SESSION WHERE SESSION_ID = ?]
16:37:53.862 DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [INSERT INTO SPRING_SESSION_ATTRIBUTES(SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) SELECT PRIMARY_ID, ?, ? FROM SPRING_SESSION WHERE SESSION_ID = ?]
16:37:53.993 DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [SELECT S.PRIMARY_ID, S.SESSION_ID, S.CREATION_TIME, S.LAST_ACCESS_TIME, S.MAX_INACTIVE_INTERVAL, SA.ATTRIBUTE_NAME, SA.ATTRIBUTE_BYTES FROM SPRING_SESSION S LEFT OUTER JOIN SPRING_SESSION_ATTRIBUTES SA ON S.PRIMARY_ID = SA.SESSION_PRIMARY_ID WHERE S.SESSION_ID = ?]
16:37:53.993 DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [SELECT S.PRIMARY_ID, S.SESSION_ID, S.CREATION_TIME, S.LAST_ACCESS_TIME, S.MAX_INACTIVE_INTERVAL, SA.ATTRIBUTE_NAME, SA.ATTRIBUTE_BYTES FROM SPRING_SESSION S LEFT OUTER JOIN SPRING_SESSION_ATTRIBUTES SA ON S.PRIMARY_ID = SA.SESSION_PRIMARY_ID WHERE S.SESSION_ID = ?]
16:37:54.047 DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [SELECT S.PRIMARY_ID, S.SESSION_ID, S.CREATION_TIME, S.LAST_ACCESS_TIME, S.MAX_INACTIVE_INTERVAL, SA.ATTRIBUTE_NAME, SA.ATTRIBUTE_BYTES FROM SPRING_SESSION S LEFT OUTER JOIN SPRING_SESSION_ATTRIBUTES SA ON S.PRIMARY_ID = SA.SESSION_PRIMARY_ID WHERE S.SESSION_ID = ?]
16:37:54.047 DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [SELECT S.PRIMARY_ID, S.SESSION_ID, S.CREATION_TIME, S.LAST_ACCESS_TIME, S.MAX_INACTIVE_INTERVAL, SA.ATTRIBUTE_NAME, SA.ATTRIBUTE_BYTES FROM SPRING_SESSION S LEFT OUTER JOIN SPRING_SESSION_ATTRIBUTES SA ON S.PRIMARY_ID = SA.SESSION_PRIMARY_ID WHERE S.SESSION_ID = ?]

Czyli Redis potrzebuje 14 operacji, żeby zapisać sesję a w przypadku jdbc tych operacji wystarczy 7, czasowo wychodzi ~600ms vs ~200ms na niekorzyść redisa.

Aplikacja jest odpalona lokalnie, redis i baza danych jest na zewnętrznych serwerach.

Wydaje się, że problem nie jest z samym redisem ale faktyczną ilością calli do niego. Czy można zrobić coś, żeby przyspieszyć handlowanie sesji w przypadku redisa?

Jedyne co przychodzi mi do głowy to wystawienie slave'a redisa na tym samym hoście co aplikacja - wtedy zredukuje się czas odpytawania i spora ilość połączeń z redisem nie będzie aż tak boleć

0

Hmm w obu przypadkach czasy odpowiedzi są ogromne, a danych pewnie niewiele. Usługa na Mongo odpowiada przykładowo ok 10-20ms jak odczyt leci z indeksu. Jak to mierzysz?

0

Czasy odpowiedzi wyliczone są na podstawie zamieszczonych logów i potwierdzone przez czasy requestów w przeglądarce.

W przypadku JDBC 200ms moi zdaniem ujdzie, liczba calli do DB tez się wydaje sensowna. Natomiast 14 strzałów do Redisa jeden po drugim przy tworzeniu sesji to się wydaje sporo i trochę niezrozumiałe

1 użytkowników online, w tym zalogowanych: 0, gości: 1