Skip to content

Latest commit

ย 

History

History
115 lines (75 loc) ยท 6.98 KB

2021-07-22-elasticache-maintenance.md

File metadata and controls

115 lines (75 loc) ยท 6.98 KB

์ตœ๊ทผ AWS์˜ Redis Service์ธ ElastiCache๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๊ฒช์—ˆ๋˜ ์œ ์ง€๊ด€๋ฆฌ ๊ธฐ๊ฐ„(Maintenance)์— ๋Œ€ํ•œ ์ด์Šˆ ํ•ด๊ฒฐ๊ณผ์ •์„ ์ ์–ด๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

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 ๋Œ€์‘ํ•˜๊ธฐ

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();
}

enablePeriodicRefresh(...)

์ฃผ๊ธฐ์ ์œผ๋กœ connection์„ ๊ฐฑ์‹ ํ•ด์ฃผ๋Š” ์˜ต์…˜ ํ™œ์„ฑํ™”์™€ ๊ธฐ๊ฐ„์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๊ฐ„์€ ๊ธฐ๋ณธ 60์ดˆ์ž…๋‹ˆ๋‹ค.

enableAllAdaptiveRefreshTriggers()

๋ฌธ์ œ๊ฐ€ ๋ ๋งŒํ•œ 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)๊นŒ์ง€ ์˜ฌ๋ ค์„œ ํ…Œ์ŠคํŠธ ํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹คํ–‰ํžˆ ๋ฐฐํฌ์‹œ์— ์œ„ ํ˜„์ƒ์ด ํ•ด๊ฒฐ๋˜์–ด ์•ˆ์ •์ ์ธ ์Šค๋ฌด์Šคํ•˜๊ฒŒ(?) ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ