์ต๊ทผ AWS์ Redis Service์ธ ElastiCache๋ฅผ ์ฌ์ฉํ๋ฉด์ ๊ฒช์๋ ์ ์ง๊ด๋ฆฌ ๊ธฐ๊ฐ(Maintenance)์ ๋ํ ์ด์ ํด๊ฒฐ๊ณผ์ ์ ์ ์ด๋ณด๊ณ ์ ํฉ๋๋ค.
https://aws.amazon.com/ko/elasticache/elasticache-maintenance/
๋ณด์ ํจ์น๋ ์์ ์ฑ์ ์ํด ์ด์ฉ์๊ฐ ์ง์ ํ ์๊ธฐ์ ๋ ธ๋๋ฅผ ๊ต์ฒดํ๊ฑฐ๋ ํด๋ฌ์คํฐ๊ฐ ๋ค์ด๋๊ฑฐ๋ ํน์ ์ค๋์ ๋ ธ๋๋ค์ด ๋ณ๊ฒฝ๋ฉ๋๋ค. ๋ฌธ์์์์ ๋ช ์ด์ ๋ค์ดํ์์ด ๋ฐ์ํ๋ค๊ณ ํ๋๋ฐ์.
์ ๊ฐ ๊ฒฝํํ ๋ฐ๋ก๋ ์ฝ๊ฐ ํ๋ฆฐ ์ (?)์ด ์์์ต๋๋ค.
- Redis Server: AWS ElastiCache Cluster
- Redis Client: lettuce
5.3.7
โป lettuce์ ๊ฒฝ์ฐ, ์ฌ์ฉํ๊ณ ์๋ ๋ฒ์ (5.1.1
)์์ ๋ฒ๊ทธ๊ฐ ์์ด 5.3.7
์ผ๋ก ๋ณ๊ฒฝํ์๋๋ฐ์. ์์ธํ ๋ด์ฉ์ ์๋์ ๋ค์ ์ค๋ช
๋๋ฆฌ๊ฒ ์ต๋๋ค.
Maintenance๋ ์์ผ๊ณผ ์๊ฐ๋(1์๊ฐ ๊ฐ๊ฒฉ)๋ฅผ ์ง์ ํด๋๋ฉด, AWS์์ event ์๋ฆผ๊ณผ ํจ๊ป Maintenance ์ค์ผ์ค์ ์ก์ต๋๋ค. (๋ฌผ๋ก , ๊ฐ์์ค๋ฝ๊ฒ ์ค์ผ์ค์ด ์กํ๊ณ ๊ทธ๋ฌ์ง ์์ต๋๋ค.) ์ด ๋, ํด๋ฌ์คํฐ๊ฐ ๋ด๋ ค๊ฐ๊ฑฐ๋ ์ค๋์ ๋ ธ๋๋ค์ด ๋ณ๊ฒฝ๋๊ฑฐ๋ ์ฌ๋ฐฐ์นํ๊ฒ ๋๋๋ฐ์. lettuce client์์๋ ๊ฐ ๋ ธ๋๋ค์ ์บ์ฑํ๊ณ ์๋ ์ ๋ณด๋ค(Partitions)์ ๋ฆฌ๋ก๋ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์ด์ ๋ง๋ ์ถ๊ฐ ์ต์ ์ด ํ์ํฉ๋๋ค.
spring-data-redis
๋ฅผ ์ฌ์ฉํ๋ค๋ฉด, ๋ค์๊ณผ ๊ฐ์ด ์ ์ฉํ ์ ์์ต๋๋ค.
private static LettuceClientConfiguration lettuceClientConfiguration() {
final ClusterClientOption clientOptions =
ClusterClientOptions.builder()
.topologyRefreshOptions(
ClusterTopologyRefreshOptions.builder()
.enablePeriodicRefresh(...) // <--
.enableAllAdaptiveRefreshTriggers() // <--
.build())
.timeoutOptions(...)
.build();
return LettuceClientConfiguration.builder()
.commandTimeout(...)
.shutdownTimeout(...)
.clientOptions(clientOptions)
.build();
}
์ฃผ๊ธฐ์ ์ผ๋ก connection์ ๊ฐฑ์ ํด์ฃผ๋ ์ต์ ํ์ฑํ์ ๊ธฐ๊ฐ์ ์ง์ ํ ์ ์์ต๋๋ค. ๊ธฐ๊ฐ์ ๊ธฐ๋ณธ 60์ด์ ๋๋ค.
๋ฌธ์ ๊ฐ ๋ ๋งํ operation์ด ๋ฐ์ํ๋ค๋ฉด ์ฆ์ connection์ ๊ฐฑ์ ํด์ฃผ๋ ์ด๋ฒคํธ๋ฅผ ํธ๋ฆฌ๊ฑฐ ์์ผ์ฃผ๋ ์ค์ ์ ๋๋ค. ํด๋น ๊ธฐ๋ฅ์ rate-limit ๊ฐ์(?) ์ฒ๋ฆฌ๊ฐ ๋์ด ์์ด์ ํผํฌ๋จผ์ค์ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค.
aws์์๋ aws-cli
๋ฅผ ํตํด test-failover
๋ผ๋ ์ปค๋งจ๋๋ฅผ ์ ๊ณตํด์ฃผ๊ณ ์์ผ๋ฉฐ, ์ด๋ฅผ ํตํด ์ ํ์์ ์ฌํํด๋ณผ ์ ์์ต๋๋ค.
ํด๋น ๊ธฐ๋ฅ์ ์ฒซ ์๋ ๊ธฐ์ค 5ํ์ ์ ํ์ ๋๊ณ ์๊ธฐ ๋๋ฌธ์ ๋ฌด๋ถ๋ณํ ์๋๋ ์ํ๋๊ฒ ์ข์ต๋๋ค.
aws-cli
๋ฅผ ํตํด test-failover
๋ฅผ ์คํํ๋ฉด ํด๋ฌ์คํฐ๊ฐ ๋ด๋ ค๊ฐ๋๋ค. ํด๋น ๊ฐญ์ 1๋ถ ์ ๋ ๋๋๋ฐ์. ์ ๋ฌธ์์์ ์๊ธฐํ ๋ช ์ด์ ๋ค์ดํ์๋ณด๋ค ๋ง์ ์๊ฐ์ด ์์๋จ์ ์ ์ ์์ต๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ ๋ฐฉ๋ฒ์ ๋ฑํ ์๋ ๊ฑธ๋ก ๋ณด์ฌ '์๋น์ค ์ด์์์ ์์ด ๋ค์ดํ์์ ์ต์ํ ํ๋ค'๋ผ๋ ๊ฒ์ ์์๋ฅผ ๋๊ณ ํด๋น ์ด์๋ฅผ ๋ง๋ฌด๋ฆฌ ์ง๊ธฐ๋ก ํ์ต๋๋ค. ๊ธฐ์กด์์๋ 10๋ถ์ ๋์ ๋ค์ดํ์์ด ๋ฐ์ํ์ต๋๋ค.
๋ค๋ง, ํด๋ฌ์คํฐ๊ฐ ๋ด๋ ค๊ฐ๋๊ฒ ์๋ ์ค๋์ ๋ ธ๋๋ค์ด ๋ณ๊ฒฝ๋๊ฑฐ๋ ์ฌ๋ฐฐ์น๋๋ ๊ฒ์ ๋ค์ดํ์์ด ์์ ์์์ต๋๋ค.
ํน์ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ด ์์ผ๋ฉด ๊ณต์ ํด์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค :)
์ต์
์ ์ถ๊ฐํ๊ณ ๋ฐฐํฌ๋ฅผ ๋ช ๋ฒ ํด๋ณด๋, ๋ฐฐํฌ ์ค ๋ค์ ์๋ฌ๋ก๊ทธ์ ํจ๊ป ์ ํ๋ฆฌ์ผ์ด์
์๋ฒ๊ฐ ๋ด๋ ค๊ฐ์ง ์๋ ํ์์ด ๋ฐ์ํฉ๋๋ค. ํด๋น ๋ฒ์ ์ lettuce 5.1.1
์์ ๋ฐ์ํ์ต๋๋ค.
ERROR: Failed to submit a listener notification task. Event loop shut down?
java.util.concurrent.RejectedExecutionException: event executor terminated
at io.netty.util.concurrent.SingleThreadEventExecutor.reject(SingleThreadEventExecutor.java:845)
at io.netty.util.concurrent.SingleThreadEventExecutor.offerTask(SingleThreadEventExecutor.java:328)
at io.netty.util.concurrent.SingleThreadEventExecutor.addTask(SingleThreadEventExecutor.java:321)
at io.netty.util.concurrent.SingleThreadEventExecutor.execute(SingleThreadEventExecutor.java:756)
at io.netty.util.concurrent.DefaultPromise.safeExecute(DefaultPromise.java:768)
at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:432)
at io.netty.util.concurrent.DefaultPromise.addListener(DefaultPromise.java:162)
at io.netty.channel.DefaultChannelPromise.addListener(DefaultChannelPromise.java:95)
at io.netty.channel.DefaultChannelPromise.addListener(DefaultChannelPromise.java:30)
...
jstack
์ ํ์ธํด๋ณด๋, ํด๋น ์ ํ๋ฆฌ์ผ์ด์
์๋ฒ์ thread ์ค WAITING
์ด ์กด์ฌํ๋ ๊ฒ์ ์ ์ ์์์ต๋๋ค. ํด๋น stack์ shutdown์์ ์ฐ๋ ๋ ๊ฒฝํฉ์ด ๋ฐ์ํ๋ฉด์ ์๊ธด ๋ฌธ์ ๋ก ๋ณด์๋๋ฐ์. (์์ฝ๊ฒ๋... ๋ก๊ทธ๊ฐ ์ ์ค๋์ด ์ฒจ๋ถํ์ง ๋ชป ํ์ต๋๋ค.) ์ด๋ lettuce ์ ์ฅ์ issue#989๋ฅผ ํตํด ๋ฐ๋ก ํด๊ฒฐํ ์ ์์์ต๋๋ค.
ํด๋น ์ด์์ ์ปค๋ฐ ๋ก๊ทธ๋ฅผ ์ ๊น ์ดํด๋ณด์๋ฉด, eventloop๊ฐ ํ์ฑํ๋์ด ์๋์ง ์ฌ๋ถ๋ฅผ ํ๋จํ๋ ๋ฐฉ์ด์ฝ๋๊ฐ ์ถ๊ฐ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
private boolean isEventLoopActive() {
EventExecutorGroup eventExecutors = clientResources.eventExecutorGroup();
return !eventExecutors.isShuttingDown();
}
์ ํฌ๋ ์ด๊ฒ์ 5.2.0
์ ํด๊ฒฐ๋ ๊ฒ์ผ๋ก ๋ณด์์ผ๋, ๊ทธ๋ฅ ๋ง์ด๋ ์ต์ ๋ฒ์ (5.3.7
)๊น์ง ์ฌ๋ ค์ ํ
์คํธ ํด๋ณด๊ธฐ๋ก ํ์ต๋๋ค. ๋คํํ ๋ฐฐํฌ์์ ์ ํ์์ด ํด๊ฒฐ๋์ด ์์ ์ ์ธ ์ค๋ฌด์คํ๊ฒ(?) ๋ฐฐํฌํ ์ ์์์ต๋๋ค.