Reids 를 사용하는 프로젝트라면 로컬 프로파일에서 embedded-redis 를 많이 사용하는데
새로 구입한 ARM Mac 에서 아래처럼 구동이 안되는 문제가 있었다.
Caused by: java.lang.RuntimeException: Can't start redis server. Check logs for details.
로그를 확인 하라는데 어디서 확인할 수 있는지 알 수가 없다.
그래서 라이브러리 코드를 디버깅 해 찾아보니 아래 부분에서 에러가 발생한다.
private void awaitRedisServerReady() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(redisProcess.getInputStream()));
try {
String outputLine;
do {
outputLine = reader.readLine();
if (outputLine == null) {
//Something goes wrong. Stream is ended before server was activated.
throw new RuntimeException("Can't start redis server. Check logs for details.");
}
} while (!outputLine.matches(redisReadyPattern()));
} finally {
IOUtils.closeQuietly(reader);
}
}
레디스 프로세스를 띄우고 stdout 을 받아서 실행되었는지 확인하는 듯 하다.
디버거로 reader 의 값을 받아보면
=== REDIS BUG REPORT START: Cut & paste starting from here ===
[8366] 14 Jan 18:14:28.233 # Redis 2.8.19 crashed by signal: 10
...
os:Darwin 20.2.0 x86_64
...
임베디드 redis 라이브러리에서 mac_arm64 용 바이너리가 준비되지 않은 것이 원인인 것을 알 수 있다.
https://github.com/kstyrc/embedded-redis/blob/master/src/main/java/redis/embedded/RedisExecProvider.java
private void initExecutables() {
executables.put(OsArchitecture.WINDOWS_x86, "redis-server-2.8.19.exe");
executables.put(OsArchitecture.WINDOWS_x86_64, "redis-server-2.8.19.exe");
executables.put(OsArchitecture.UNIX_x86, "redis-server-2.8.19-32");
executables.put(OsArchitecture.UNIX_x86_64, "redis-server-2.8.19");
executables.put(OsArchitecture.MAC_OS_X_x86, "redis-server-2.8.19.app");
executables.put(OsArchitecture.MAC_OS_X_x86_64, "redis-server-2.8.19.app");
}
라이브러리의 소스코드에도 MAC_OS_X_arm64 가 없는 것을 알 수 있다.
라이브러리를 수정해 사용할 수도 있겠지만, 문서에서는 사용자가 바이너리를 지정해 사용하는 방법을 제시하고 있다.
하지만 1번같은 경우는 RedisServer(String, int) 가 deprecate 되었는지 동작하지 않았고
2번은 Architecture enum 에 arm64 가 없어 사용할 수 없었다.
1번 방법 대신 RedisServer(File executable, int port) 생성자가 제공되는듯 해 이걸 사용해 문제를 해결하기로 했다.
우선 Redis 의 소스코드를 받아 컴파일한다.
$ wget https://download.redis.io/releases/redis-6.0.10.tar.gz
--2021-01-14 18:26:30-- https://download.redis.io/releases/redis-6.0.10.tar.gz
Resolving download.redis.io (download.redis.io)... 45.60.125.1
Connecting to download.redis.io (download.redis.io)|45.60.125.1|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2271970 (2.2M) [application/octet-stream]
Saving to: ‘redis-6.0.10.tar.gz’
redis-6.0.10.tar.gz 100%[===================>] 2.17M --.-KB/s in 0.09s
2021-01-14 18:26:30 (23.3 MB/s) - ‘redis-6.0.10.tar.gz’ saved [2271970/2271970]
$ tar -xzf redis-6.0.10.tar.gz
$ cd redis-6.0.10
$ make
...
$ src/redis-server
9566:C 14 Jan 2021 18:28:34.049 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
9566:C 14 Jan 2021 18:28:34.049 # Redis version=6.0.10, bits=64, commit=00000000, modified=0, pid=9566, just started
9566:C 14 Jan 2021 18:28:34.049 # Warning: no config file specified, using the default config. In order to specify a config file use src/redis-server /path/to/redis.conf
9566:M 14 Jan 2021 18:28:34.051 * Increased maximum number of open files to 10032 (it was originally set to 256).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 6.0.10 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 9566
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
9566:M 14 Jan 2021 18:28:34.053 # Server initialized
9566:M 14 Jan 2021 18:28:34.053 * Ready to accept connections
src/redis-server 에 생성된 바이너리의 이름을 바꿔 프로젝트에 추가한다.
그리고 EmbeddedRedisConfig 에 아키텍쳐를 확인해 분기하는 코드를 추가한다.
override fun afterPropertiesSet() {
// for support MAC_ARM64 Arch
redisServer = if (isArmMac()) {
RedisServer(getRedisFileForArmMac(), redisPort!!)
} else {
RedisServer(redisPort!!)
}
redisServer!!.start()
}
private fun isArmMac(): Boolean {
return System.getProperty("os.arch") == "aarch64" &&
System.getProperty("os.name") == "Mac OS X"
}
private fun getRedisFileForArmMac(): File {
return ClassPathResource("binary/redis/redis-server-6.0.10-mac-arm64").file
}
이렇게 하면 잘 실행된다.
안녕하세요.
src/redis-server 에 생성된 바이너리가 어떤걸까요? src/redis-server 파일인가요 ? 그 파일을 변경해서 실행하니 Permission denied가 뜨더라고요. ㅠ.ㅠ.