Spark Streaming과 Redis 연동

2017. 10. 11. 10:38서버 프로그래밍

Jedis

Jedis is a blazingly small and sane Redis java client.

https://github.com/xetorthio/jedis


* Scala에서도 Java 라이브러리를 사용할 수 있으므로, Spark Streaming에서 Redis는 연동은 Jedis를 이용하는 것이 좋은 것 같다. Spark-Redis는 Get/Set 메소드에 대한 래핑 클래스만 제공하기 때문에, redis의 모든 기능을 직접 연동할 수 없고 결국 Jedis를 사용해야 하는 상황이 발생하기 때문이다.


Spark-Redis

A library for reading and writing data from and to Redis with Apache Spark

https://github.com/RedisLabs/spark-redis


Connecting to Redis Database

https://docs.databricks.com/spark/latest/data-sources/redis.html


https://spark-packages.org/package/RedisLabs/spark-redis



주요 Redis 명령어

dbsize : 저장된 Key 개수 조회

keys * : 저장된 Key 목록 조회

flushall : 전체 삭제


-------------------------------

Node.js에서 redis 저장하다가 오류 발생


/home/ec2-user/userhabit-engine/userhabit_api/node_modules/redis-parser/lib/parser.js:193

    return new ReplyError(string)

           ^

ReplyError: MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error.

    at parseError (/home/ec2-user/userhabit-engine/userhabit_api/node_modules/redis-parser/lib/parser.js:193:12)

    at parseType (/home/ec2-user/userhabit-engine/userhabit_api/node_modules/redis-parser/lib/parser.js:303:14)


https://charsyam.wordpress.com/2013/01/28/%EC%9E%85-%EA%B0%9C%EB%B0%9C-redis-%EC%84%9C%EB%B2%84%EA%B0%80-misconf-redis-is-configured-to-save-rdb-snapshots-%EC%97%90%EB%9F%AC%EB%A5%BC-%EB%82%B4%EB%A9%B0-%EB%8F%99%EC%9E%91%ED%95%98%EC%A7%80/


가끔식 Redis를 사용하는 분들에게 다음과 같은 질문을 받을 때가 있습니다. “갑자기 Redis 가 동작을 하지 않고 죽은거 같아요? ” 그럴 때, 실제로 Redis가 장애가 났을 때도, 나지 않았을 때도 있지만, 주로 다음과 같은 에러를 낼 때가 많습니다. “-

MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.

Redis 가 언제나 에러가 없고 stable 하면 좋을 텐데, 성능을 떨어뜨리는 몇가지 요소가 있습니다. 그 중에서 가장 큰 원인 중의 하나가 persistent 를 위해서 BGSAVE로 rdb를 만들어내는 것입니다. 그런데 기본적으로 이 BGSAVE가 실패하게 되면 Redis는 설정에 따라서 Write 커맨드를 전부 거부 해버리게 됩니다.

redis.c 를 보시면 processCommand에 다음과 같은 코드가 있습니다.

1
2
3
4
5
6
7
8
9
if (server.stop_writes_on_bgsave_err &&
server.saveparamslen > 0
&& server.lastbgsave_status == REDIS_ERR &&
c->cmd->flags & REDIS_CMD_WRITE)
 {
flagTransaction(c);
addReply(c, shared.bgsaveerr);
return REDIS_OK;
 }

여기서 보면 stop_writes_on_bgsave_err 이 true 이면 RDB 생성에 실패했을 때 Write는 전부 거부하는 것을 볼 수 있습니다. 그렇다면, 이 것을 어떻게 해결해야 할까요? 이부분은 Redis를 어떤 용도로 쓰고 있는가에 달려있습니다. 캐시용도로만 쓰시는 곳은, 그냥 RDB를 끄거나 config set stop-writes-on-bgsave-error no 를 통해서 해당 설정을 꺼두면 됩니다. 

RDB 저장에 실패하는 이유는 다양해서 뭐라고 말씀드리긴 힘들지만, 간혹 vm_overcommit_memory 정책이 문제일 수도 있고,  디스크 이슈일 수도 있습니다. 그렇지만, RDB가 꼭 필요하지 않지만 이런 이유로 고생하시는 분들에게는 도움이 되면 좋겠습니다.