2014년 12월 21일

Redis partitioning (레디스 파티셔닝)

본 문서는 http://redis.io/topics/partitioning의 번역입니다.





http://redis.io/topics/partitioning


Partitioning: how to split data among multiple Redis instances.

Partitioning is the process of splitting your data into multiple Redis instances, so that every instance will only contain a subset of your keys. The first part of this document will introduce you to the concept of partitioning, the second part will show you the alternatives for Redis partitioning.

Why partitioning is useful

Partitioning in Redis serves two main goals:
  • It allows for much larger databases, using the sum of the memory of many computers. Without partitioning you are limited to the amount of memory a single computer can support.
  • It allows scaling the computational power to multiple cores and multiple computers, and the network bandwidth to multiple computers and network adapters.

파티셔닝: 데이터를 여러 Redis 서버로 분리하는 방법

파티셔닝은 사용자 데이터를 여러 개의 Redis 인스턴스로 분리하는 과정입니다. 그래서 각 인스턴스는 전체 키(keys)의 일부(subset)만을 포함합니다. 이 문서의 첫번째 부분에서는 파티셔닝의 개념에 대해서 소개합니다. 두번째 부분에서는 Redis 파티셔닝을 위한 대체수단을 알려드릴 것입니다.

왜 파티셔닝은 유용한가.

파티셔닝은 두 개의 주요 목적이 있습니다:
  • 파티셔닝은 더 큰 데이터베이스를 가능하게 해줍니다. 즉, 여러 서버들의 메모리들의 모두 합쳐서 사용할 수 있습니다. 서버 한대가 지원하는 메모리에는 한계가 있기때문에 파티셔닝이 없다면 이 한계를 넘지 못할 것입니다.
  • 파티셔닝은 멀티 코어와 여러 서버를 이용하여 컴퓨팅 파워를 증가시켜 줍니다. 그리고, 각 서버가 가진 네트워크 대역폭을 합쳐서 사용할 수 있게 해 줍니다.

Partitioning basics

There are different partitioning criteria. Imagine we have four Redis instances R0R1R2R3, and many keys representing users like user:1user:2, ... and so forth, we can find different ways to select in which instance we store a given key. In other words there are different systems to map a given key to a given Redis server.
One of the simplest ways to perform partitioning is with range partitioning, and is accomplished by mapping ranges of objects into specific Redis instances. For example, I could say users from ID 0 to ID 10000 will go into instance R0, while users form ID 10001 to ID 20000 will go into instance R1 and so forth.
This system works and is actually used in practice, however, it has the disadvantage of requiring a table that maps ranges to instances. This table needs to be managed and a table is needed for every kind of object, so therefore range partitioning in Redis is often undesirable because it is much more inefficient than other alternative partitioning approaches.
An alternative to range partitioning is hash partitioning. This scheme works with any key, without requiring a key in the form object_name:, and is as simple as:
  • Take the key name and use a hash function (e.g., the crc32 hash function) to turn it into a number. For example, if the key is foobarcrc32(foobar) will output something like 93024922.
  • Use a modulo operation with this number in order to turn it into a number between 0 and 3, so that this number can be mapped to one of my four Redis instances. 93024922 modulo 4 equals 2, so I know my key foobar should be stored into the R2 instance. Note: the modulo operation returns the remainder from a division operation, and is implemented with the % operator in many programming languages.
There are many other ways to perform partitioning, but with these two examples you should get the idea. One advanced form of hash partitioning is called consistent hashing and is implemented by a few Redis clients and proxies.
파티셔닝의 기초.
조금씩 다른 파티셔닝 기준이 있습니다. 먼저, 4개의 Redis 인스턴가 있다고 가정합니다. R0, R1, R2, R3 입니다. 그리고, 여기에 사용되는 많은 키(keys)들이 user:1, user:2와 같은 형식으로 사용자를 표현하고 하고 있습니다. 우리는 이러한 키들이 어느 인스턴스에 속해있는지 알기 위한 여러 방법이 가능하다는 것을 알 수 있습니다. 다시 말하면, 특정 키가 특정 Redis 서버에 맵핑되는 방식입니다.
파티셔닝을 수행하는 가장 간단한 방법 중에 하나는 이러한 range partitioning 입니다. 이 방식은 특정 구간의 오브젝트들을 특정 Redis 서버에 맵핑 시키는 것입니다. 예를 들어, 사용자들의 아이디 ID 0에서 ID 10000까지는 R0 인스턴스에 할당하고, ID 10001에서 20000까지는 R1 인스턴스에 할당하는 방식입니다.
이러한 시스템은 잘 동작하고, 실제로 사용되기도 합니다. 그러나, 이 방식의 단점은 특정 구간이 특정 인스턴스에 맵핑 되어있다는 정보를 가진 맵핑 테이블이 필요하다는 것입니다. 이 테이블은 지속적으로 관리되어야 하고, 모든 오브젝트가 이 테이블을 필요로 합니다. 그래서, range partitioning은 매력적이지 않습니다. 다른 효과적인 파티셔닝 방법이 있습니다.
Range partitioning의 대체수단으로 hash partitioning이 있습니다. 이 방식은 어떤 키에 대해서도 동작에 문제가 없고, 키의 형태가 object_name: 같은 모습이 가지도록 할 필요도 없습니다. 이 방식 또한 매우 간단합니다:
  • 키 이름 가지고 이를 숫자로 만들기 위해 해쉬 함수를 이용합니다(예를 들면, crc32 해쉬함수). 예를 들어, 키 이름이 foobar이고 이를 해쉬함수에 넣으면(crc32(foobar)) 93024922 같은 출력을 얻게 됩니다.
  • 이 숫자를 0에서 3사이에 숫자로 변환하기 위해서 이 숫자에 모듈로(modulo)를 수행합니다. 그러면 이 숫자는 Redis 인스턴스 4개 중에 하나로 맵핑됩니다. 93024922를 4로 모듈로를 수행하면 2가 됩니다. 따라서, foobar라는 키는 R2 인스턴스에 저장됩니다. Note: 모듈로는 나누기를 수행한 후에 나머지를 구하는 계산입니다. 일반적으로, 여러 언어가 ‘%’  기호를 통해서 구현해 놓았습니다.

파티셔닝을 수행하는 다른 방법도 많습니다만, 이 두 가지 예를 통해서 기본 아이디를 이해할 수 있습니다.
hash partitioning의 진보된 형태로 consistent hashing이라고 불리는 방식이 있습니다. 이 방식은 일부 Redis 클라이언트와 프락시에 구현되어 있는 상태입니다.

Different implementations of partitioning

Partitioning can be the responsibility of different parts of a software stack.
  • Client side partitioning means that the clients directly select the right node where to write or read a given key. Many Redis clients implement client side partitioning.
  • Proxy assisted partitioning means that our clients send requests to a proxy that is able to speak the Redis protocol, instead of sending requests directly to the right Redis instance. The proxy will make sure to forward our request to the right Redis instance accordingly to the configured partitioning schema, and will send the replies back to the client. The Redis and Memcached proxy Twemproxy implements proxy assisted partitioning.
  • Query routing means that you can send your query to a random instance, and the instance will make sure to forward your query to the right node. Redis Cluster implements an hybrid form of query routing, with the help of the client (the request is not directly forwarded from a Redis instance to another, but the client gets redirectedto the right node).

파티셔닝의 다른 구현 방식들

파티셔닝은 소프트웨어 스택에서 다른 부분이라고 할 수 있습니다.

  • Client side partitioning : 주어진 키에 따라 읽기, 쓰기를 수행할 노드를 클라이언트가 직접 선택하는 방식입니다. 많은 Redis 클라이언트가 이 방식을 구현하고 있습니다.
  • Proxy assisted partitioning : 클라이언트가 직접 맞는 Redis 인스턴스에 요청을 보내는 대신에, 요청을 프락시 서버로 보냅니다. 이때의 프락시 서버는 Redis 프로토콜을 처리할 수 있는 서버입니다.  프락시는 그 요청을 파티셔닝의 스킴에 따라 맞는 Redis 인스턴스에 전달하고 그 응답을 클라이언트에 전달합니다. Redis와 Memcached 프락시 역할을 구현한 Twemproxy가 파티셔닝을 지원하고 있습니다.
  • Query routing : 클라이언트는 요청을 임의의 인스턴스에 보냅니다. 그러면, 그 인스턴스는 그 요청을 맞는 인스턴스로 전달합니다. Redis 클러스터는 query routing 방식을 클라이언트를 도와주는, 하이브리드 형식으로 구현하고 있습니다(그 요청이 Redis 인스턴스에서 다른 인스턴스로 직접 전달되지 않고, 클라이언트가 맞는 노드로 재전달하도록 합니다)(역자주: 클라이언트는 임의의 인스턴스에 요청을 보내는 그 노드 서버는 맞는 노드를 응답하고, 다시 클라이언트가 그 노드에 다시 요청을 보내는 방식인 것으로 보입니다). 

Disadvantages of partitioning

Some features of Redis don't play very well with partitioning:
  • Operations involving multiple keys are usually not supported. For instance you can't perform the intersection between two sets if they are stored in keys that are mapped to different Redis instances (actually there are ways to do this, but not directly).
  • Redis transactions involving multiple keys can not be used.
  • The partitioning granuliary is the key, so it is not possible to shard a dataset with a single huge key like a very big sorted set.
  • When partitioning is used, data handling is more complex, for instance you have to handle multiple RDB / AOF files, and to make a backup of your data you need to aggregate the persistence files from multiple instances and hosts.
  • Adding and removing capacity can be complex. For instance Redis Cluster supports mostly transparent rebalancing of data with the ability to add and remove nodes at runtime, but other systems like client side partitioning and proxies don't support this feature. However a technique called Presharding helps in this regard.

파티셔닝의 단점

Redis의 일부 기능은 파티셔닝에서는 동작하지 않습니다.
  • 파티셔닝 환경에서는 일반적으로, 멀티 키와 관련 있는 동작들이 지원되지 않습니다. 예를 들어, 서로 다른 Redis 인스턴스에 맵핑 되어 있는 두 개의 SET 사이의 상호처리를 수행하는 것은 불가능합니다(실제로는 이 기능을 가능하게 하는 방법이 있지만, 직접적으로 가능한 방법은 아닙니다.)
  • 멀티 키와 관련되어 있는 트랙젝션은 사용될 수 없습니다.
  • 파티셔닝이 사용될 때에는 데이터 핸들링이 더 복잡합니다. 예를 들면, 여러 개의 RDF/AOF 파일들을 다루어야 하고 여러 인스턴스와 호스트로부터 영속성 유지에 필요한 파일들을 모으고 이를 백업해야합니다.
  • 용량을 더하거나 빼는 것이 복잡해질 수 있습니다. 예를 들어, Redis 클러스터는 런타임 중에도 노드를 추가하거나 제거할 수 있는데, 이때의 데이터들은 투명하게 밸런싱이 재조정됩니다. 그러나, Client side 파티셔닝과 프락시 같은 시스템에서는 이 기능을 지원하지 않습니다. 하지만, Presharding 이라고 불리는 기술을 이용하면 이러한 고려 상황에 도움이 될 수 있습니다.


Data store or cache?

Although partitioning in Redis is conceptually the same whether using Redis as a data store or as a cache, there is a significant limitation when using it as a data store. When Redis is used as a data store, a given key must always map to the same Redis instance. When Redis is used as a cache, if a given node is unavailable it is not a big problem if a different node is used, altering the key-instance map as we wish to improve the availability of the system (that is, the ability of the system to reply to our queries).
Consistent hashing implementations are often able to switch to other nodes if the preferred node for a given key is not available. Similarly if you add a new node, part of the new keys will start to be stored on the new node.
The main concept here is the following:
  • If Redis is used as a cache scaling up and down using consistent hashing is easy.
  • If Redis is used as a store, a fixed keys-to-nodes map is used, so the number of nodes must be fixed and cannot vary. Otherwise, a system is needed that is able to rebalance keys between nodes when nodes are added or removed, and currently only Redis Cluster is able to do this, but Redis Cluster is currently in beta, and not yet considered production-ready.

데이터 저장 또는 캐쉬?

Redis를 데이터 저장용이든 캐쉬용이든 이를 사용할 때, Redis 파티셔닝은 개념적으로 동일합니다. 그러나, 데이터 저장용도일 때 중요한 한계점이 있습니다. Redis를 저장용으로 사용하게 되면, 특정 키는 항상 같은 Redis 인스턴스에 맵핑되어야 합니다. Redis가 캐쉬로 사용된다면, 특정 노드가 이용될 수 없는 상태이더라도 큰 문제가 되진 않습니다. 왜냐하면, 보통은 다른 노드가 사용가능하기 때문입니다. 시스템의 사용성이라는 측면(즉, 요청에 대한 시스템이 응답할 수 있는 능력)에서 이를 개선하기 위해서 키-인스턴스 맵핑을 변경하고자 하는 바램이 있습니다.

consistent 해싱의 구현은 특정 키에 대해서 그 노드가 응답할 수 없을 때, 다른 노드로 변경할 수 있도록 해줍니다. 유사하게, 새로운 노드를 추가하기를 원한다면 새로운 키들이 새로운 노드에 저장되도록 해야할 것입니다.

다음은 이러한 기능을 위한 주요 개념을 설명합니다.:
  • Redis를 캐쉬 기능으로 사용하고 있다면, consistent 해싱을 이용하여 그 확장성을 높이고 줄이는 것(Scaling up and down)이 쉽습니다.
  • Redis를 저장용도로 사용하고 있다면, 고정된 키-노드 맵핑이 필요하게 됩니다. 그래서, 노드의 수가 고정되어야만 하고, 변경될 수 없습니다. 또 다른 상황으로, 노드가 추가 또는 제거되어 노드 사이에 키들의 밸런싱을 다시 조정해야하는 시스템이 필요할 수 있습니다. 현재는 Redis 클러스터만이 이 문제를 해결할 수 있는 유일한 방법입니다. 그러나, Redis 클러스터는 현재 베타이고, 아직 실제 서비스(production-ready)에 사용하도록 고려되어 있지 않은 상태입니다.

Presharding

We learned that a problem with partitioning is that, unless we are using Redis as a cache, to add and remove nodes can be tricky, and it is much simpler to use a fixed keys-instances map.
However the data storage needs may vary over the time. Today I can live with 10 Redis nodes (instances), but tomorrow I may need 50 nodes.
Since Redis is extremely small footprint and lightweight (a spare instance uses 1 MB of memory), a simple approach to this problem is to start with a lot of instances since the start. Even if you start with just one server, you can decide to live in a distributed world since your first day, and run multiple Redis instances in your single server, using partitioning.
And you can select this number of instances to be quite big since the start. For example, 32 or 64 instances could do the trick for most users, and will provide enough room for growth.
In this way as your data storage needs increase and you need more Redis servers, what to do is to simply move instances from one server to another. Once you add the first additional server, you will need to move half of the Redis instances from the first server to the second, and so forth.
Using Redis replication you will likely be able to do the move with minimal or no downtime for your users:
  • Start empty instances in your new server.
  • Move data configuring these new instances as slaves for your source instances.
  • Stop your clients.
  • Update the configuration of the moved instances with the new server IP address.
  • Send the SLAVEOF NO ONE command to the slaves in the new server.
  • Restart your clients with the new updated configuration.
  • Finally shut down the no longer used instances in the old server.

Presharding

우리는 파티셔닝이 가지는 문제점에 대해서 배웠습니다. Redis를 캐쉬 용도로 사용하고 있지 않다면, 노드를 추가하고 제거하는 것이 매우 까다로울 수 있습니다. 정해진 키-인스턴스 형태의 맵핑 정보를 사용하는 것이 더 간단합니다.

그러나, 데이터 스토리지는 시간에 지남에 따라 변경의 여지가 큽니다. 오늘 내가 10개의 Redis 노드를 운영하다가 내일은 50개의 노드가 필요하게 될 수도 있습니다.

Redis는 매우 작은 메모리 공간(footprint)를 차지하고 매우 가볍습니다(인스턴스 약 1MB 메모리 사용). 이 문제를 해결하기 위한 간단한 해결방법으로 처음부터 많은 인스턴스를 가지고 시작하는 것입니다. 그냥 한대의 서버만 있다고 할지라도 처음부터 온세상에 배포한다는 결정을 하는 것이지요. 파티셔닝을 이용하고, 한대의 서버에 여러 개의 Redis 인스턴스를 실행합니다.

처음부터 매우 큰 수가 될거 같은 인스턴스의 수를 결정할 수 있는데요. 예를 들면, 모든 사용자들에게 32 또는 64개의 인스턴스가 있다고 속이는 것입니다. 그리고, 나중에 커질 것에 대비한 충분한 공간을 공급할 것입니다.

당신의 데이터가 점점 증가하면 더 많은 Redis 서버들이 필요하게 됩니다. 이 경우에 해야할 일은 간단하게 인스턴스를 이 서버에서 다른 서버로 옮기는 것입니다. 첫번째 서버를 추가한 후에 Redis 인스턴스의 반정도를 첫번째 서버에서 두번째 서버로 옮깁니다.

Redis 복제를 이용하면 최소시간 또는 다운시간 없이 이 작업을 수행할 수 있을 것입니다.
  • 새로운 서버에 비어 있는 인스턴스로 서버를 시작합니다.
  • 원본 인스턴스를 위해서 새로운 인스턴스들을 슬레이브로 만들어서 데이터를 옮깁니다.
  • 요청을 받지 않기 위해서 클라이언트들을 중지합니다.
  • 새로운 서버에서 옮겨진 인스턴스들의 설정을 갱신합니다.
  • 새로운 서버에 있는 슬레이브들에게 SLAVEOF NO ONE 커맨드를 전송합니다.
  • 새롭게 갱신된 설정을 가지고 클라이언트를 재시작합니다.
  • 마지막으로, 예전 서버에 더 이상 사용하지 않는 인스턴스들을 종료합니다.

Implementations of Redis partitioning

So far we covered Redis partitioning in theory, but what about practice? What system should you use?
Redis 파티셔닝의 구현

우리는 지금까지 Redis 파티셔닝에 대해서 이론적으로 알아보았습니다. 그러나, 실제는 어떠합니까? 어떤 시스템을 사용해야할까요?

Redis Cluster

Redis Cluster is the preferred way to get automatic sharding and high availability. It is currently not production ready, but finally entered beta stage, so we recommend you to start experimenting with it. You can get more information about Redis Cluster in the Cluster tutorial.
Once Redis Cluster will be available, and if a Redis Cluster complaint client is available for your language, Redis Cluster will be the de facto standard for Redis partitioning.
Redis Cluster is a mix between query routing and client side partitioning.

Redis 클러스터

Redis 클러스터는 자동 샤딩과 HA(High Availability, 역자주: 고가용성)를 얻기 위해서 선호하는 방식입니다. 이 방식은 마침내 베타 버전이고, 현재는 상용환경에서 사용하기에는 미흡한 상태입니다. 그래도, 베타 버전이므로 우선 적용해서 시험해보시기를 권장합니다. Redis 클러스터에 대한 상세한 정보는 Cluster tutorial 문서를 참고하십시오.
Redis 클러스트가 사용가능한 상태가 되고, 클러스터를 지원하는 클라이언트가 사용가능하게 된다면 Redis 클러스터는 Redis 파티셔닝에서 실질적인 표준이 될 것입니다.
Redis 클러스터는 query routing과 client side partitioning를 혼합해 놓은 형태입니다.

Twemproxy

Twemproxy is a proxy developed at Twitter for the Memcached ASCII and the Redis protocol. It is single threaded, it is written in C, and is extremely fast. It is open source software released under the terms of the Apache 2.0 license.
Twemproxy supports automatic partitioning among multiple Redis instances, with optional node ejection if a node is not available (this will change the keys-instances map, so you should use this feature only if you are using Redis as a cache).
It is not a single point of failure since you can start multiple proxies and instruct your clients to connect to the first that accepts the connection.
Basically Twemproxy is an intermediate layer between clients and Redis instances, that will reliably handle partitioning for us with minimal additional complexities. Currently it is the suggested way to handle partitioning with Redis.
You can read more about Twemproxy in this antirez blog post.

Twemproxy

Twemproxy는 트위터에서 개발된 프락시입니다. 이 프락시는 Memcached 아스키와 Redis 프로토콜을 지원합니다. 이것은 싱글쓰레드로 구현되었고 C 언어로 만들어졌으며 매우 빠릅니다. Apache 2.0 라이센스 기반으로 오픈소스로 릴리즈 되었습니다.
Twemproxy는 여러 Redis 인스턴스 사이에 자동적인 파티셔닝을 지원합니다. 어떤 노드가 사용가능한 상태가 아니라면, 노드 제거도 지원합니다(이 구현은 키-인스턴스 맵 정보를 바꿀 것입니다. 그래서 Redis를 캐쉬 용도로 사용하고 있다면 이 기능을 사용하는 것이 가능합니다).
Twemproxy는 여러 개를 동시에 시작할 수 있고, 클라이언트가 여러 개의 Twemproxy를 순환하면서 연결이 되는 서버를 찾을 수 있기때문에, SPF(single point failure)로 취급되지 않습니다. 
기본적으로, Twemproxy는 클라이언트와 서버 사이에 중간 레이어에 해당합니다. 이것은 우리에게 복잡성이 크지 않으면서도 믿음직스럽게 파티셔닝을 다룰 수 있게 해 줍니다. 현재로써는, 파티셔닝을 다룰 때 가장 괜찮은 방법입니다.
좀 더 자세한 내용은 antirez blog에 있는 글을 참고하십시오.

Clients supporting consistent hashing

An alternative to Twemproxy is to use a client that implements client side partitioning via consistent hashing or other similar algorithms. There are multiple Redis clients with support for consistent hashing, notably Redis-rb andPredis.
Please check the full list of Redis clients to check if there is a mature client with consistent hashing implementation for your language.

클라이언트는 consistent 해상을 지원하고 있습니다.

Twemproxy의 대안으로 가능한 것은, consistent 해싱 또는 다른 유사한 알고리즘을 통해서 client side partitioning 이용하는 것입니다. Consistent 해싱을 지원하는 여러 Redis 클라이언트들이 있습니다. 특히, Redis-rb와 Predis가 있습니다.
redis 웹사이트에서 Redis 클라이언트에 해당하는 전체 리스트를 참고하십시오. 여기에 있는 클라이언트 중에서 오랫 시간 동안 성숙한 클라이언트로의 이름을 유지하면서 consistent 해싱을 지원하는 클라이언트를 확인하실 수 있습니다.





Redis Replication (레디스 복제)

본 문서는 http://redis.io/topics/replication 의 번역입니다.

Replication

Redis replication is a very simple to use and configure master-slave replication that allows slave Redis servers to be exact copies of master servers. The following are some very important facts about Redis replication:
Redis 복제는 매우 간단합니다. 사용하기 쉽고 마스터-슬레이브 관계의 복제 구성도 간단합니다. 이 복제구성은 슬레이브 Redis 서버가 마스터 서버의 완전한 복사본이 되게 해줍니다. Redis 복제에 대해서 매우 중요한 사실이 몇 가지가 있습니다.

  • Redis uses asynchronous replication. Starting with Redis 2.8, however, slaves will periodically acknowledge the amount of data processed from the replication stream.
    Redis는 비동기 복제입니다. 그러나, Redis 버전 2.8 이후부터는 슬레이브들이 복제 스트림으로부터 복제한 데이터의 총량을 주기적으로 알려줄 것입니다.

  • A master can have multiple slaves.
    하나의 마스터는 여러 개의 슬레이브를 가질 수 있습니다.

  • Slaves are able to accept connections from other slaves. Aside from connecting a number of slaves to the same master, slaves can also be connected to other slaves in a graph-like structure.
    슬레이브들은 다른 슬레이브들로부터의 연결을 받아들일 수 있습니다. 슬레이브는 같은 마스터에 연결하고 있는 것과는 별도로, 그래프 구조와 유사하게 다른 슬레이브에 연결될 수 있습니다.

  • Redis replication is non-blocking on the master side. This means that the master will continue to handle queries when one or more slaves perform the initial synchronization.
    Redis 복제는 마스터 입장에서는 비블록입니다. 즉, 마스터는 하나 또는 그 이상의 슬레이브가 동기화 작업을 시작하더라도, 클라이언트의 요청을 처리할 수 있을 것입니다. 

  • Replication is also non-blocking on the slave side. While the slave is performing the initial synchronization, it can handle queries using the old version of the dataset, assuming you configured Redis to do so in redis.conf. Otherwise, you can configure Redis slaves to return an error to clients if the replication stream is down. However, after the initial sync, the old dataset must be deleted and the new one must be loaded. The slave will block incoming connections during this brief window.
    복제는 슬레이브 입장에서도 비블록입니다. 슬레이브는 설정파일 redis.conf에 그렇게 동작하도록 설정했다는 가정하에, 동기화 작업을 시작하는 동안에도 과거의 데이터셋을 이용해서 클라이언트의 요청을 처리할 수 있습니다. 이렇게 설정하지 않고, 복제가 진행되는 동안에 클라이언트로 에러를 전달하도록 할 수도 있습니다. 그러나, 초기 싱크가 시작된 이후에는 과거의 데이터셋은 지워져야만 하고 새로운 데이터셋이 로드 되어야 합니다. 슬레이브는 잠시동안 클라이언트의 새로운 연결을 블록하게 됩니다.

  • Replication can be used both for scalability, in order to have multiple slaves for read-only queries (for example, heavy SORT operations can be offloaded to slaves), or simply for data redundancy.
    복제는 확장성(scalability)이라는 관점에서, 읽기 전용을 위한 다중 슬레이브를 구성할 수 있고(예를 들면, 무거운 정렬 작업을 슬레이브에 맡길 수 있음), 간단하게는 잉여 데이터로도 활용될 수 있습니다. 

  • It is possible to use replication to avoid the cost of having the master write the full dataset to disk: just configure your master redis.conf to avoid saving (just comment all the "save" directives), then connect a slave configured to save from time to time. However in this setup make sure masters don't restart automatically (please read the next section for more information).
    복제 서버는 마스터가 전체 데이터셋을 디스크에 저장하는 할 때 소요될 수 있는 비용이 들지 않도록 하는데 이용될 수 있습니다. 마스터 서버의 redis.conf 설정에서 저장 옵션을 제거하는 것으로 가능한 일입니다(즉, save로 시작하는 지시어를 주석처리 하는 것). 슬레이브로 설정된 서버가 가끔씩 연결하여 데이터를 가져갑니다. 그러나, 이러한 설정을 포함하고 있다면, 마스터는 자동으로 재시작하지 않도로 해야한다는 것을 명심하십시오(좀 더 자세한 사항은 다음 세션을 읽어 보십시오).


Safety of replication when master has persistence turned off

마스터 서버의 데이터 영속성(persitence) 설정이 오프일 때, 복제의 안정성



In setups where Redis replication is used, it is strongly advised to have persistence turned on in the master, or when this is not possible, for example because of latency concerns, instances should be configured to avoid restarting automatically.
To better understand why masters with persistence turned off configured to auto restart are dangerous, check the following failure mode where data is wiped from the master and all its slaves:
Redis 복제를 이용하는 설정에서, 마스터에 데이터 영속성(persistence, 역자주: redis 메모리에 있는 dataset를 RDB 또는 AOF 형식으로 디스크에 남기는 모드) 설정은 켜는 것이 좋습니다. 그런데, 처리 지연 등의 이유로, 이 설정을 On 시킬 수 없다면 redis 서버를 자동으로 재시작하지 않도록 설정해야 합니다.
좀 더 쉬운 이해를 위해서 데이터 영속성이 off 상태이고, 자동 재시작 하도록 설정되었을 때, 이 상태가 왜 위험한지 다음의 시나리오를 통해서 설명하도록 하겠습니다. 이 상황은 마스터로 인해 슬레이브들의 데이터가 모두 사라지는 상황에 대한 것입니다.

  1. We have a setup with node A acting as master, with persistence turned down, and nodes B and C replicating from node A.
  2. A crashes, however it has some auto-restart system, that restarts the process. However since persistence is turned off, the node restarts with an empty data set.
  3. Nodes B and C will replicate from A, which is empty, so they'll effectively destroy their copy of the data.

  1. 마스터로 동작하는 노드A 서버가 있습니다. 이 서버는 데이터 영속성이 켜져있지 않습니다. 이제 노드 B,C 라고 불리는 노드가 있고, 이것들은 노드A의 복제입니다.
  2. 크래쉬 발생. 마스터에 크래쉬가 발생했지만, 자동 재시작되어서 마스터가 재시작됩니다. 그러나, 데이터 영속이 켜져있지 않았으므로 이 노드A는 비어있는 데이터셋으로 시작합니다.
  3. 노드B,C는 노드A로부터 복제를 시작합니다. 그런데, 데이터셋이 비어있는 상태이고 슬레이브 노드B,C 데이터가 모두 사라지게 됩니다.

When Redis Sentinel is used for high availability, also turning off persistency on the master, together with auto restart of the process, is dangerous. For example the master can restart fast enough for Sentinel to don't detect a failure, so that the failure mode described above happens.
Every time data safety is important, and replication is used with master configured without persistence, auto restart of instances should be disabled.
HA(High Availability)를 위해서 센티널을 사용중이고, 마스터에 데이터 영속성을 off인 경우에, 자동재시작하도록 설정하였다면, 이 경우에도 마찬가지로 위험합니다. 예를 들면, 마스터 서버는 센티널이 마스터 서버의 장애상황을 인지하는 것보다 더 짧은 시간내에 재시작할 수 있습니다. 
데이터 안전한 보관은 항상 중요한 사항입니다. 그래서, 데이터 영속성 없는 마스터를 복제하도록 사용하는 경우에는, 마스터의 자동재시작은 받드시 off로 되어야 합니다.

How Redis replication works

Redis 복제는 어떻게 동작하는가.

If you set up a slave, upon connection it sends a SYNC command. It doesn't matter if it's the first time it has connected or if it's a reconnection.
The master then starts background saving, and starts to buffer all new commands received that will modify the dataset. When the background saving is complete, the master transfers the database file to the slave, which saves it on disk, and then loads it into memory. The master will then send to the slave all buffered commands. This is done as a stream of commands and is in the same format of the Redis protocol itself.
You can try it yourself via telnet. Connect to the Redis port while the server is doing some work and issue the SYNC command. You'll see a bulk transfer and then every command received by the master will be re-issued in the telnet session.
Slaves are able to automatically reconnect when the master <-> slave link goes down for some reason. If the master receives multiple concurrent slave synchronization requests, it performs a single background save in order to serve all of them.
When a master and a slave reconnects after the link went down, a full resync is always performed. However, starting with Redis 2.8, a partial resynchronization is also possible.

슬레이브를 시작하고 마스터와의 연결도 이루어지면 SYNC 명령어를 보냅니다. 이 상황이 최초 연결이 이루어진 경우에 발생하거나 재연결이 이루어진 경우에 발생한다면 문제가 되지는 않습니다.
마스터는 백그라운드 저장을 시작합니다. 그리고, 이후에 인입되는 명령어 중에서 데이터셋을 변경하는 것이 있다면 buffer에 저장하기 시작합니다. 백그라운드 저장이 완료되면, 마스터는 데이터 파일을 슬레이브에 전송합니다. 슬레이브는 이 데이터를 디스크에 적은 후에 메모리에 적재합니다. 마스터는 buffer에 저장되어 있는 커맨드들을 슬레이브에 전송할 것입니다. 이 데이터는 Redis 프로토콜로 구성된 연속된 커맨드입니다.
이 상황을 telnet를 이용하여 확인할 수 있습니다. Redis 서버 포트에 telnet으로 연결합니다. 그리고 SYNC 커맨드를 전송합니다(물론, Redis 프로토콜에 맞게 전송해야함). 그러면, 일련의 데이터 전송이 출력되는 것을 볼 수 있고, 마스터로 인입되는 모든 명령어가 telnet 연결 세션으로 그대로 전달되어 화면에 보여집니다.
슬레이브는 마스터와의 연결이 끊어졌을 때, 자동으로 재연결수행하게 할 수 있습니다. 만약 마스터 서버가 여러 슬레이브들로부터 동시에 동기(sync)를 원하는 요청을 받게 된다면, 마스터는 이 요청을 모두 처리하기 위한 하나의 백그라운드 저장을 수행합니다.
마스터, 슬레이브 사이의 연결이 끊어졌을 때, 항상 전체 동기화(sync)가 이루어집니다. 그러나, Redis 2.8 버전부터 부분 동기화(partial sync)가 가능하게 되었습니다.

Partial resynchronization

부분 재동기화

Starting with Redis 2.8, master and slave are usually able to continue the replication process without requiring a full resynchronization after the replication link went down.
This works by creating an in-memory backlog of the replication stream on the master side. The master and all the slaves agree on a replication offsetand a master run id, so when the link goes down, the slave will reconnect and ask the master to continue the replication. Assuming the master run id is still the same, and that the offset specified is available in the replication backlog, replication will resume from the point where it left off. If either of these conditions are unmet, a full resynchronization is performed (which is the normal pre-2.8 behavior).
The new partial resynchronization feature uses the PSYNC command internally, while the old implementation uses the SYNC command. Note that a Redis 2.8 slave is able to detect if the server it is talking with does not support PSYNC, and will use SYNC instead.
Redis 2.8 부터는 마스터와 슬레이브의 연결이 끊어지더라도 전체 데이터를 다시 동기화하지 않고 복제을 계속할 수 있게 되었습니다.
이 기능은 마스터상에서 복제 스트림을 위한 메모리 백로그(in-memory backlog)를 만드는 작업 덕분에 동작할 수 있습니다. 마스터와 모든 슬레이브들은 복제 오프셋과 마스터 run id 라는 값으로 동일한 복제상태를 표시합니다. 그래서, 마스터, 슬레이브 연결이 끊어지면 슬레이브는 마스터에 다시 연결한 후에 복제를 계속할 것을 요청합니다. 마스터 run id가 여전히 동일하다는 가정과 복제 백로그에서 특정 오프셋이 가능한 상태이면, 복제는 그 지점부터 복구할 것입니다. 이 조건들 중에서 하나라도 일치하지 않는다면 전체 재동기화가 이루어지게 됩니다(이는 2.8 버전에서 일어나는 동작임).
새로운 부분 재동기화 기능은 내부적으로 PSYNC 명령어를 사용합니다. 구 버전의 구현에서는 SYNC 명령어를 사용했었습니다. Redis 2.8 버전의 슬레이브는 마스터 서버가 PSYNC 명령어를 지원하는지 여부를 판단하는 기능을 가지고 있습니다. 판단 결과에 따라 SYNC 명령어를 사용할 수도 있습니다.

Diskless replication

디스크에 저장없이 복제하기
Normally a full resynchronization requires to create an RDB file on disk, then reload the same RDB from disk in order to feed the slaves with the data.
With slow disks this can be a very stressing operation for the master. Redis version 2.8.18 will be the first version to have experimental support for diskless replication. In this setup the child process directly sends the RDB over the wire to slaves, without using the disk as intermediate storage.
The feature is currently considered experimental.
일반적으로, 전체 재동기화를 하기 위해서는 디스크에 RDB 파일을 생성해야합니다. 이 파일을 적재(reload)하여 같은 데이터를 필요로 하는 슬레이블들에게 전달하게 됩니다.
느린 디스크의 경우에 이러한 작업은 마스터 서버 입장에서는 간단한 수행이 아닙니다. Redis 2.8.18에는 실험적으로 디스크없는 복제 기능이 처음 포함되었습니다. 이러한 설정에는 자식 프로세스가  직접 RDB 파일을 슬레이브에 보냅니다. 이 과정에서 중간에 디스크 스토리지를 이용하지 않습니다.
현재 이 기능은 시험 단계에 있습니다.

Configuration

설정하기

To configure replication is trivial: just add the following line to the slave configuration file:
slaveof 192.168.1.1 6379
Of course you need to replace 192.168.1.1 6379 with your master IP address (or hostname) and port. Alternatively, you can call the SLAVEOFcommand and the master host will start a sync with the slave.
There are also a few parameters for tuning the replication backlog taken in memory by the master to perform the partial resynchronization. See the example redis.conf shipped with the Redis distribution for more information.
Diskless replication can be enabled using the repl-diskless-syncconfiguration parameter. The delay to start the transfer in order to wait more slaves to arrive after the first one, is controlled by the repl-diskless-sync-delay parameter. Please refer to the example redis.conf file in the Redis distribution for more details.

복제를 설정하는 것은 매우 간단합니다: 다음의 내용을 설정 파일에 추가하하면 됩니다.
slaveof 192.168.1.1 6379
위의 예에서 192.168.1.1 6379의 내용은 여러분이 사용하는 Redis 마스터 IP 주소(또는 호스트이름)와 포트는 대체하시고요. 다른 방법으로, SLAVEOF 라는 명령어를 이용할 수 있습니다. 마스터로 동작하고 있는 서버에 이 명령어를 내리면 슬레이브로 동작하게 되엇 동기화를 시작하게 될 것입니다.
마스터에서는 부분 재동기화(partial resynchronization)를 위해 존재하는, 메모리 상의 복제 백로그가 있고, 이를 튜닝하기 위한 몇 가지 파라미터가 있습니다. 더 자세한 사항은 Redis 배포 파일에서 redis.conf를 참고하시면 됩니다.
디스크 없이 복제하는 기능은 repl-diskless-syncconfiguration 라는 파라미터를 이용하면 됩니다. 첫 번째 복제 요청 이후에 더 많은 슬레이브들의 복제 요청을 기다리기 위해서 복제를 시작하기까지의 지연 시간을 설정할 수 있는데, 이 설정은 위한 파라미터는  repl-diskless-sync-delay 입니다. 더 자세한 부분은 redis.conf 파일의 내용 참고하십시오.

Read-only slave

읽기 전용 슬레이브

Since Redis 2.6, slaves support a read-only mode that is enabled by default. This behavior is controlled by the slave-read-only option in the redis.conf file, and can be enabled and disabled at runtime using CONFIG SET.
Read-only slaves will reject all write commands, so that it is not possible to write to a slave because of a mistake. This does not mean that the feature is intended to expose a slave instance to the internet or more generally to a network where untrusted clients exist, because administrative commands like DEBUG or CONFIG are still enabled. However, security of read-only instances can be improved by disabling commands in redis.conf using the rename-command directive.
You may wonder why it is possible to revert the read-only setting and have slave instances that can be target of write operations. While those writes will be discarded if the slave and the master resynchronize or if the slave is restarted, there are a few legitimate use case for storing ephemeral data in writable slaves. However in the future it is possible that this feature will be dropped.
Redis 2.6 버전 이후부터, 슬레이브는 기본 설정으로 읽기전용 모드를 지원합니다. 이 동작은 redis.conf 설정 파일의 slave-read-only 라는 옵션으로 설정합니다. 그리고, 실행중이더라도 CONFIG SET 명령어를 통해서 동작여부를 변경할 수 있습니다.
읽기전용 슬레이브는 모든 쓰기 명령을 거부합니다. 그래서, 실수로라도 슬레이브에 쓰기 작업이 되는 경우는 없습니다. 이 기능은 슬레이브 서버가 외부 인터넷 또는 신뢰할 수 없는 클라이언트가 있는 네트웍에 노출되었을 때를 의도하여 있는 기능은 아닙니다. 왜냐하면, 관리자가 DEBUG, CONFIG 같은 명령어는 사용가능한 상태이기 때문입니다. 그러나, 보안 측면에서볼 때, rename-command 지시어로 redis.conf에 이 명령어를 사용할 수 없게 설정하는 것보다 읽기 전용으로 사용하는 것이 더욱 안전합니다.
여러분은 슬레이브가 읽기전용으로 설정 가능하거나, 쓰기가 가능한 서버로 변경이 가능한 것에 대해서 의문점을 가질 수도 있을 것입니다. 슬레이브가 마스터와 재동기화 중이거나, 슬레이브가 재시작되어서 이러한 쓰기 작업이 무시되는 동안에, 쓰기 가능한 슬레이브에 임시 데이터를 저장하기 위한 정상적인 사용 케이스가 있습니다. 그러나, 이 기능은 향후에 없어질 가능성도 있습니다.

Setting a slave to authenticate to a master

슬레이브가 마스터에 인증하도록 설정하기
If your master has a password via requirepass, it's trivial to configure the slave to use that password in all sync operations.
To do it on a running instance, use redis-cli and type:
config set masterauth 
To set it permanently, add this to your config file:
masterauth 
마스터 서버가 requirepass 설정을 가지고 있어서 패스워드를 요구한다면, 이를 위한 슬레이브의 설정도 매우 간단합니다.
실행 중인 상태에서 redis-cli 등을 사용해서 다음의 명령어를 입력하면 됩니다.
config set masterauth 
설정파일을 통해서도 다음과 같이 설정할 수 있습니다.
masterauth 

Allow writes only with N attached replicas

N개의 복제를 가진 쓰기 전용 마스터
Starting with Redis 2.8, it is possible to configure a Redis master to accept write queries only if at least N slaves are currently connected to the master.
However, because Redis uses asynchronous replication it is not possible to ensure the slave actually received a given write, so there is always a window for data loss.
This is how the feature works:
  • Redis slaves ping the master every second, acknowledging the amount of replication stream processed.
  • Redis masters will remember the last time it received a ping from every slave.
  • The user can configure a minimum number of slaves that have a lag not greater than a maximum number of seconds.
If there are at least N slaves, with a lag less than M seconds, then the write will be accepted.
You may think at it as a relaxed version of the "C" in the CAP theorem, where consistency is not ensured for a given write, but at least the time window for data loss is restricted to a given number of seconds.
If the conditions are not met, the master will instead reply with an error and the write will not be accepted.
There are two configuration parameters for this feature:
  • min-slaves-to-write 
  • min-slaves-max-lag 
For more information, please check the example redis.conf file shipped with the Redis source distribution.
Redis 2.8 버전부터, 적어도 N개의 슬레이브가 연결되어 있는 마스터의 경우에, 이 마스터를 쓰기 전용 요청만 처리하도록 설정하는 것이 가능하게 되었습니다.

그러나, Redis는 비동기 복제를 사용하기 때문에, 슬레이브에 이 쓰기 작업이 실제로 이루어졌다고 확신할 수 없는 상태입니다. 그래서, 데이터 손실을 고려한 일종의 윈도우가 존재합니다.

이 기능은 다음과 같이 동작합니다:

  • 슬레이브는 매초마다 마스터에게 Ping을 보냅니다. 이것은 슬레이브가 복제를 어느 시간까지 수행했는지를 표시하기 위함입니다.
  • 마스터는 모든 슬레이블로부터 이러한 ping을 받은 최종 시간을 기록합니다.
  • 사용자는 지연을 허용하는 최대 시간(초)과 최소 슬레이브 수를 설정할 수 있습니다.

최소 N개의 슬레이브가 있고, M초보다 적은 지연이 있을 때, 그 쓰기 작업은 성공하게 됩니다.

여러분은 CAP 이론(역자주: RDBMS 또는 NoSQL에서 일관성(Consistency), 가용성(Availability), 생존성(Partition tolerance)를 의미함.)의 유연한 ‘C’를 떠올릴 수도 있다고 생각합니다. 여기에서의 일관성(consistency)는 모든 쓰기 작업을 보장하지 않는다는 것입니다. 그러나, 데이터 손실을 고려한 최소 시간 윈도우를 지정하고 이 시간을 제약사항으로 인정하는 것이라 할 수 있습니다.

이러한 조건들을 만족하지 못하는 상황이라면, 마스터는 쓰기 요청에 대해서 에러를 응답하게 됩니다.

다음과 같은 2개의 설정 파라미터가 있습니다.
  • min-slaves-to-write 
  • min-slaves-max-lag 

더 자세한 사항은 Redis와 함께 배포되는 redis.conf 파일의 내용을 참고하시기 바랍니다.




2014년 10월 27일

센티널을 지원하는 레디스 클라이언트 구현의 가이드라인 (Guidelines for Redis clients with support for Redis Sentinel 번역)


본 내용은 http://redis.io/topics/sentinel-clients 문서를 번역한 것입니다.





WARNING: This document is a draft and the guidelines that it contains may change in the future as the Sentinel project evolves.


주의: 이 문서는 드래프트 버전이고, sentinel 프로젝트가 발전해감에 따라 미래에 변경될 수도 있는 정보를 포함하고 있습니다.






Redis Sentinel is a monitoring solution for Redis instances that handles automatic failover of Redis masters and service discovery (who is the current master for a given group of instances?). Since Sentinel is both responsible to reconfigure instances during failovers, and to provide configurations to clients connecting to Redis masters or slaves, clients require to have explicit support for Redis Sentinel.


This document is targeted at Redis clients developers that want to support Sentinel in their clients implementation with the following goals:

Automatic configuration of clients via Sentinel.
Improved safety of Redis Sentinel automatic failover.
For details about how Redis Sentinel works, please check the Redis Documentation, as this document only contains informations needed for Redis client developers, and it is expected that readers are familiar with the way Redis Sentinel works.

Redis Sentinel(이하 Sentinel)은 모니터링 솔루션이다. 이것은 redis 프로그램의 자동 failover와 그 이후의 서비스 사용가능에 대해서 다룬다(다른 redis instance들 중에서 어느 것이 현재의 마스터인가?). Sentinel은 두 가지 기능을 책임지고 있는데, 하나는 failover가 발생하는 동안에 redis 인스턴스(역자주: 여러 redis 서버를 의미함)들을 재설정하는 것이고, 다른 하나는 redis 마스터과 슬레이브에 연결하고 있는 클라이언트들에게 설정 사항을 제공합니다. 그러므로, 클라이언트들은 sentinel를 지원을 명확히 해줄 것을 요구합니다.

이 문서는 다음의 목적을 가지고 있는, Sentinel를 지원하는 redis 클라이언트 개발자들을 위한 것입니다.

-. Sentinel를 통해서 클라이언트들이 자동적으로 설정되기를 원함.

-. 더 안전한 자동 failover.

Sentinel를 어떻게 동작하는지에 대한 자세한 사항들은 Redis Documentation 문서를 참고하십시오. 이 문서는 단지 redis 클라이언트 개발자를 위한 정보만을 포함하고 있습니다. 또한, 개발자들이 Sentinel이 동작하는 방식에 대해서 잘 알고 있다고 가정합니다.







Redis service discovery via Sentinel


Redis Sentinel identify every master with a name like "stats" or "cache". Every name actually identifies a group of intances, composed of a master and a variable number of slaves.


The address of the Redis master that is used for a specific purpose inside a network may change after events like an automatic failover, a manually triggered failover (for instance in order to upgrade a Redis instance), and other reasons.


Normally Redis clients have some kind of hard-coded configuraiton that specifies the address of a Redis master instance within a network as IP address and port number. However if the master address changes, manual intervention in every client is needed.


A Redis client supporting Sentinel can automatically discover the address of a Redis master from the master name using Redis Sentinel. So instead of an hard coded IP address and port, a client supporting Sentinel should optionally be able to take as input:

A list of ip:port pairs pointing to known Sentinel instances.
The name of the service, like "cache" or "timelines".
This is the procedure a client should follow in order to obtain the master address starting from the list of Sentinels and the service name.



sentinel를 통한 redis 서비스 발견하기


Sentinel은 “통계(stats)” 또는 “캐쉬(cache)”와 같은 하나의 이름을 가지고 모든 마스터를 구분합니다. 실제로 이러한 이름은 인스턴스의 그룹을 구분하는 것인데, 인스턴스들은 하나의 마스터와 바뀔 수 있는 몇몇의 슬레이브들로 구성된 것입니다.


내부 네트워크에서 특정 목적을 가지는 redis 마스터의 주소는 자동 failover, 수동으로 failover를 동작시키는 것(예를 들면, redis 인스턴스를 업그레이드 하는 경우)을 포함하여 몇 가지 다른 이유로 인해서 redis 마스터의 주소는 바뀔 수 있습니다.

보통 redis 클라이언트는 redis 마스터의 IP 주소와 포트로 하드 코딩되어 있는 경우가 있습니다. 그래서, 이 마스터의 주소가 바뀌면 매번 수작업을 변경해 주어야 합니다.

Sentinel를 지원하는 redis 클라이언트는 Sentinel를 이용하는 마스터의 이름(역자주: 예를 들면, mymaster)으로부터 마스터의 주소를 자동으로 알게 됩니다. 그러므로, Sentinel를 지원하는 redis 클라이언트는 redis IP 주소와 포트를 하드코딩 하는 대신에 부가적으로 다음의 입력으로부터 그 redis 마스터의 IP 주소와 포트를 받을 수 있습니다:

-. Sentinel 인스턴스로 알려진 IP:Port 리스트

-. “Cache” 또는 “timelines” 같은 서비스의 이름

다음은 Sentinel의 리스트와 서비스 이름으로 시작하는 마스터 주소를 얻기 위해서 클라이어트가 따라야하는 과정을 보여줍니다.






Step 1: connecting to the first Sentinel


The client should iterate the list of Sentinel addresses. For every address it should try to connect to the Sentinel, using a short timeout (in the order of a few hundreds of milliseconds). On errors or timeouts the next Sentinel address should be tried.


If all the Sentinel addresses were tried without success, an error should be returned to the client.


The first Sentinel replying to the client request should be put at the start of the list, so that at the next reconnection, we'll try first the Sentinel that was reachable in the previous connection attempt, minimizing latency.


과정 1: 첫번째 sentinel에 연결하기
클라이언트는 Sentinel 주소 리스트는 순환해야합니다. 클라이언트가 연결해야하는 모든 sentinel 주소에 대해서 짧은 간격의 시간 주기(수백 밀리 세컨드 주기)로 연결을 시도해야합니다. 에러 또는 타임아웃이 발생하면 다음 sentinel 주소로 연결해야합니다.


모든 sentinel 서버로의 연결이 성공없이 끝나게 되면, 그 에러가 클라이언트에게 리턴되어야 합니다.


클라이언트 요청에 응답하는 첫번째 sentinel은 그 리스트의 시작에 있어야합니다. 그러므로 다음의 재연결에서도, 우리는 지금 연결에 성공한 sentinel 서버에 맨처음 연결을 시도할 것입니다. 이는 전체적인 지연을 최소화하기 위함입니다.







Step 2: ask for master address


Once a connection with a Sentinel is established, the client should retry to execute the following command on the Sentinel:


SENTINEL get-master-addr-by-name master-name


Where master-name should be replaced with the actual service name specified by the user.


The result from this call can be one of the following two replies:

An ip:port pair.
A null reply. This means Sentinel does not know this master.
If an ip:port pair is received, this address should be used to connect to the Redis master. Otherwise if a null reply is received, the client should try the next Sentinel in the list.

과정 2: 마스터 주소 물어보기
sentinel로 연결에 성공하면 클라이언트는 다음의 명령을 시도해야합니다.

SENTINEL get-master-addr-by-name master-name

master-name 자리에는 서비스에서 지정한 이름으로 대체되어야 합니다.

이 명령으로 인한 결과는 다음 두 개의 응답 중에 하나입니다:
-. ip:port 쌍으로 된 정보
-. null 응답: 이 응답의 의미는 sentinel이 마스터의 주소를 모른다는 것입니다.

ip:port 정보를 수신하면, 이 주소는 redis 마스터 주소로 이용하면 됩니다. 만약, null 응답을 받았다면 클라이언트는 다음 sentinel 주소로 연결을 시도해야합니다.







Step 3: call the ROLE command in the target instance


Once the client discovered the address of the master instance, it should attempt a connection with the master, and call the ROLE command in order to verify the role of the instance is actually a master.


If the ROLE commands is not available (it was introduced in Redis 2.8.12), a client may resort to the INFO replication command parsing therole: field of the output.


If the instance is not a master as expected, the client should wait a short amount of time (a few hundreds of milliseconds) and should try again starting from Step 1.


과정 3: 타켓 인스턴스에 ROLE 명령어 호출하기
클라이언트가 마스터 인스턴스의 주소를 알게되면, 그 서버에 연결하여 “ROLE” 이라는 명령을 호출해야합니다. 이는 그 인스턴스가 실제로 마스터 역할을 하고 있는지 확인하기 위한 것입니다. 
ROLE 명령어를 이용할 없다면(이 명령어는 redis 2.8.12부터 가능함), INFO 명령의 결과에서 “replication” 항목으로 확인할 수 있습니다. 출력 데이터에서 “role”이라는 항목을 보면 됩니다.
(역자주: INFO 명령의 출력에서 다음 항목입니다.
# Replication
role:master
connected_slaves:0)







Handling reconnections


Once the service name is resolved into the master address and a connection is established with the Redis master instance, every time a reconnection is needed, the client should resolve again the address using Sentinels restarting from Step 1. For instance Sentinel should contacted again the following cases:

If the client reconnects after a timeout or socket error.
If the client reconnects because it was explicitly closed or reconnected by the user.
In the above cases and any other case where the client lost the connection with the Redis server, the client should resolve the master address again.

재연결 다루기(역자주: 클라이언트가 서버로 재연결 시도)
마스터 주소에 해당하는 서비스 이름을 알게되면 그 서버에 연결을 합니다. 매번 재연결 해야합니다. 과정 1로부터 sentinel의 재시작을 알게 될 수도 있습니다. 같은 sentinel 주소를 다시 접속해야한다면 매번 재연결을 시도해야한다는 의미입니다. sentinel의 다음의 상황에 놓여있다면 클라이언트는 sentinel에 다시 연결해야합니다.
-. sentinel로부터 타임아웃 또는 소켓에러를 받은 경우
-. sentinel이 명시적으로 소켓 종요를 수행했거나, 사용자에 의해서 재연결이 이루어진 경우







Sentinel failover disconnection


Starting with Redis 2.8.12, when Redis Sentinel changes the configuration of an instance, for example promoting a slave to a master, demoting a master to replicate to the new master after a failover, or simply changing the master address of a stale slave instance, it sends a CLIENT KILL type normal command to the instance in order to make sure all the clients are disconnected from the reconfigured instance. This will force clients to resolve the master address again.


If the client will contact a Sentinel with yet not updated information, the verification of the Redis instance role via the ROLE command will fail, allowing the client to detect that the contacted Sentinel provided stale information, and will try again.


Note: it is possible that a stale master returns online at the same time a client contacts a stale Sentinel instance, so the client may connect with a stale master, and yet the ROLE output will match. However when the master is back again Sentinel will try to demote it to slave, triggering a new disconnection. The same reasoning applies to connecting to stale slaves that will get reconfigured to replicate with a differnt master.


sentinel failover 끊어짐
redis 2.8.12부터는 sentinel이 인스턴스의 설정을 변경하게 되는 경우, 예를 들면 슬레이브가 새로운 마스터가 된 경우이거나 failover 이후에 예전 마스터가 새로운 마스터로부터 복제를 수행하는 경우, 그리고,  간단하게는 마스터가 슬레이브로 변경되는 경우에 대해서, sentinel은 “CLIENT KILL” 명령을 그 인스턴에서 보냅니다. 이것은 모든 클라이언트들의 연결을 끊게 만들기 위해서 입니다. 이렇게 되면 클라이언트들은 새로운 마스터 주소를 찾기 위한 과정을 시도하도록 하기 위함입니다.

클라이언트가 갱신되지 않은 정보로 연결을 시도하게 되면, ROLE 명령에 의해서 redis 인스턴스의 증명(역자주: role 명령에 의해서 master가 아님을 알게됨)은 실패할 것입니다. 클라이언트는 접근했던(역자주: 예전에 접근하여 얻은 redis master 정보) sentinel은 최신 정보를 주는 것이 아니라는 것을 알게 되면 sentinel에 새롭게 시도를 할 것입니다.

참고: 클라이언트가 오래된 sentinel에 접근한 시각과 동시에 예전 마스터가 다시 살아나는 것도 가능합니다. 그렇게되면 클라이언트는 오래된 마스터에 연결을 할 것이고, ROLE 명령에 대한 응답도 master로 일치하게 됩니다. 그러나, 그 마스터가 다시 살아났을 때에는 sentinel이 그 마스터를 슬레이브로 만들게 됩니다. 그러면 클라이언트는 현재 마스터로 알고 있는 인스턴스로부터 연결 종료를 받게 됩니다. 같은 방식의 추론으로 오래된 슬레이브는 다른 마스터를 통하여 복제되도록 설정이 이루어지게 됩니다.







Connecting to slaves


Sometimes clients are interested to connect to slaves, for example in order to scale read requests. This protocol supports connecting to slaves by modifying step 2 slightly. Instead of calling the following command:


SENTINEL get-master-addr-by-name master-name


The clients should call instead:


SENTINEL slaves master-name


In order to retrieve a list of slave instances.


Symmetrically the client should verify with the ROLE command that the instance is actually a slave, in order to avoid scaling read queries with the master.


슬레이브에 연결하기
가끔 클라이언트는 슬레이브에 연결하기도 합니다. 예를 들면, 대량의 읽기만 발생시키는 요청의 경우입니다. 이러한 방식은 과정 2를 조금 수정하여 슬레이브에 연결하는 것을 지원할 수 있습니다. 즉, 다음의 명령을 사용하는 대신에:

SENTINEL get-master-addr-by-name master-name

클라이언트는 다음 명령을 사용합니다:

SENTINEL slaves master-name

그 결과로 슬레이브들의 리스트를 받을 수 있습니다.

클라이언트는 ROLE 명령을 사용해서 그 인스턴스가 실제로 슬레이브인지 확인하게 됩니다. 이것은 대량의 읽기 요청을 마스터에 보내는 것을 피하기 위함입니다.








Connection pools


For clients implementing connection pools, on reconnection of a single connection, the Sentinel should be contacted again, and in case of a master address change all the existing connections should be closed and connected to the new address.


커넥셜 풀(connection pools)
클라이언트의 커넥션풀 구현과 하나의 커넥선을 재연결하기 위한 구현을 위해서, 클라이언트는 sentinel에 재연결을 시도해야합니다. 클라이언트는 현재 갖고 있는 모든 연결을 가진 마스터의 주소가 바뀐 경우라면 모든 연결을 종료하고 새로운 마스터로 연결을 시로해야합니다.








Error reporting


The client should correctly return the information to the user in case of errors. Specifically:

If no Sentinel can be contacted (so that the client was never able to get the reply to SENTINEL get-master-addr-by-name), an error that clearly states that Redis Sentinel is unreachable should be returned.
If all the Sentinels in the pool replied with a null reply, the user should be informed with an error that Sentinels don't know this master name.

에러 보고
클라이언트는 사용자에게 에러 상황이 발생한 경우에 그 정보를 올바르게 보고해야합니다. 특히 다음의 경우는 더 그러합니다:
-. 접근할 수 있는 sentinel이 없는 경우(그래서, 클라이언트는 SENTINEL get-master-addr-by-name 라는 명령의 응답을 받을 수 없는 경우)에는 sentinel에 도달하지 못했다(Sentinel is unreachable)라는 에러를 리턴해야합니다.
-. 모든 sentinel이 null 응답을 보낼 경우에는 sentinel은 마스터 이름을 모른다(Sentinels don't know this master name.)라는 에러를 사용자에게 통보해야합니다.







Sentinels list automatic refresh


Optionally once a successful reply to get-master-addr-by-name is received, a client may update its internal list of Sentinel nodes following this procedure:

Obtain a list of other Sentinels for this master using the command SENTINEL sentinels .
Add every ip:port pair not already existing in our list at the end of the list.
It is not needed for a client to be able to make the list persistent updating its own configuration. The ability to upgrade the in-memory representation of the list of Sentinels can be already useful to improve reliability.

sentinel 서버 목록의 자동 갱신
부가적으로, 마스터 정보를 알 수 있는 명령에 대한 성공 응답을 받았을 때, 클라이언트는 다음의 과정을 통해서 내부의 sentinel 서버 리스트를 갱신할 수도 있습니다.
-. SENTINEL sentinels 명령을 이용하여 다른 sentinel 서버 리스트를 획득할 수 있습니다.
-. 지금 가진 sentinel 서버 리스트(ip:port 쌍으로 된)의 끝에 새로운 ip:port 정보를 추가할 수 있습니다.

클라이언트가 자신이 갖고 있는 설정를 지속적으로 업데이트하여 그 리스트를 계속유지하는 것은 필요하지 않습니다. 메모리상에 존재하는 sentinel 서버 리스트 이용하여 업그레이드하는 것은 신뢰성을 높이는데 유용하게 사용될 수 있습니다.








Subscribe to Sentinel events to improve responsiveness


The Sentinel documentation shows how clients can connect to Sentinel instances using Pub/Sub in order to subscribe to changes in the Redis instances configurations.


This mechanism can be used in order to speedup the reconfiguration of clients, that is, clients may listent to Pub/Sub in order to know when a configuration change happened in order to run the three steps protocol explained in this document in order to resolve the new Redis master (or slave) address.


However update messages received via Pub/Sub should not substitute the above procedure, since there is no guarantee that a client is able to receive all the update messages.


sentinel 이벤트에 더 잘 대응하기 위한 구독자 되기

Sentinel documentation 이라는 문서는 클라이언트가 pub/sub를 이용하여 sentinel 인스턴스에 어떻게 연결해야하는지를 설명하고 있습니다. 이것은 클라이언트가 redis 인스턴스의 설정상의 변경을 알기 위한 구독자 역할로 동작하기 위함입니다. 

이 매커니즘은 클라이언트의 재설정 속도를 높이기 위해서 사용될 수 있습니다. 즉, 클라이언트는 redis 마스터 또는 슬레이브 정보의 변경을 알기 위해서, 위에서 설명한 과정 1,2,3 실행해야만 하는데요, pub/sub은 설정 변경이 발생했을 때, 이 변경을 항상 listen 할 수 있도록 해줍니다.

그러나, pub/sub를 통하여 수신한 매시지는 위 과정의 대체과정이 되어서는 안됩니다. 왜냐하면, 클라이언트가 항상 갱신 매시지를 받을 수 있다는 보장이 없기때문입니다.








Additional information


For additional information or to discuss specific aspects of this guidelines, please drop a message to the Redis Google Group.


추가 정보
이 가이드라인의 관점에서 특별한 상황을 논의하고자 한다면  Redis Google Group에 매시지를 남겨주세요.