Clustering

クラスタ構成

OK, you’ve made it this far. I’m assuming you more or less understand what CouchDB is and how the application API works. Maybe you’ve deployed an application or two, and now you’re dealing with enough traffic that you need to think about scaling. “Scaling” is an imprecise word, but in this chapter we’ll be dealing with the aspect of putting together a partitioned or sharded cluster that will have to grow at an increasing rate over time from day one.

ここまでで、あなたはCouchDBが何かは大体分かっていて、アプリケーションのAPIがどう動くかも分かっていると思います。多分、ひとつやふたつのアプリケーションはとうに作ってしまっていて、スケーリングを考慮しなければならないほどの大きなトラフィックを裁いてきたはずです。「スケーリング」は不正確な言葉なので、この章ではパーティション型や共有型のクラスタの立てて、それを初日からどうやって成長させ続けることとして、話を進めます。

We’ll look at request and response dispatch in a CouchDB cluster with stable nodes. Then we’ll cover how to add redundant hot-failover twin nodes, so you don’t have to worry about losing machines. In a large cluster, you should plan for 5–10% of your machines to experience some sort of failure or reduced performance, so cluster design must prevent node failures from affecting reliability. Finally, we’ll look at adjusting cluster layout dynamically by splitting or merging nodes using replication.

この章ではリクエストとレスポンスが静的な構成のCouchDBクラスタの中でどのようにディスパッチされるかを概観します。次にホットスタンバイ型の冗長構成をどのように組むかについて説明します。つまり、あなたはマシンが壊れることを心配しなくてもよいのです。大きなクラスタでは、5-10%のマシンは何らかの故障であったり性能低下を必ず起こしているので、ノードの故障がクラスタの信頼性に影響しないように設計しなければなりません。最後に、レプリケーションを使ってノードの統合や分割をすることによってクラスタのレイアウトを動的に変更して調整していく方法を説明していきます。

Introducing CouchDB Lounge

CouchDB-Loungeの導入

CouchDB Lounge is a proxy-based partitioning and clustering application, originally developed for Meebo, a web-based instant messaging service. Lounge comes with two major components: one that handles simple GET and PUT requests for documents, and another that distributes view requests.

CouchDB Lounge とは、プロキシによるパーティショニング・クラスタリングのアプリケーションです。もともと、Webベースのメッセージサービス Meebo のために開発されたものでした。Loungeは主に二つのコンポーネントからなり、ドキュメントに対する単純なGETとPUTリクエストを処理し、ビューのリクエストは分散するというものです。

The dumbproxy handles simple requests for anything that isn’t a CouchDB view. This comes as a module for nginx, a high-performance reverse HTTP proxy. Because of the way reverse HTTP proxies work, this automatically allows configurable security, encryption, load distribution, compression, and, of course, aggressive caching of your database resources.

プロキシ(のようなもの: dumbproxy) はCouchDBのビュー以外の単純なリクエストを全て処理する。これは高性能なリバースHTTPプロキシ nginxのために作られたものでした。リバースHTTPプロキシの動作の仕組みによって、セキュリティ、暗号化、負荷分散、圧縮、もちろんあなたのデータベースの積極的キャッシュを自動的にできるようになります。

The smartproxy handles only CouchDB view requests, and dispatches them to all the other nodes in the cluster so as to distribute the work, making view performance a function of the cluster’s cumulative processing power. This comes as a daemon for Twisted, a popular and high-performance event-driven network programming framework for Python.

スマートプロキシ はCouchDBのビューリクエストを処理するだけではなく、クラスタ内の他のノードにディスパッチして、クラスタ内の処理能力をかき集めてビューのパフォーマンスを上げます。これは高速で人気のあるイベントドリブンなPythonのネットワークプログラミングフレームワークの、Twistedデーモンです。

Consistent Hashing

コンシステント・ハッシュ法

CouchDB’s storage model uses unique IDs to save and retrieve documents. Sitting at the core of Lounge is a simple method of hashing your document IDs. Lounge then uses the first few characters of this hash to determine which shard to dispatch the request to. You can configure this behavior by writing a shard map for Lounge, which is just a simple text configuration file.

CouchDBのストレージモデルではユニークなIDを使ってドキュメントを保存・管理します。Loungeの中ではドキュメントIDのハッシュ値を求めます。( TODO: Siting? )。Loungeはこのハッシュ値の最初の数バイトから、どのshardにリクエストをティスパッチすべきかを決めます。この挙動は、Loungeのshardマップ(簡単なテキストファイルです)を設定することによって変更できます。

Because Lounge allocates a portion of the hash (known as a keyspace) to each node, you can add as many nodes as you like. Because the hash function produces hexidecimal strings that bare no apparent relation to your DocIDs, and because we dispatch requests based on the first few characters, we ensure that all nodes see roughly equal load. And because the hash function is consistent, Lounge will take any arbitrary DocID from an HTTP request URI and point it to the same node each time.

Loungeはそれぞれのノードにハッシュ空間の一部(キー空間とも言います)を確保するため、好きなだけノードを追加することができます。ハッシュ関数はdocidとは無関係な16進数の文字列を生成し、最初の数バイトに基づいてリクエストをディスパッチするので、全てのノードに負荷が均等に分散することが保証されます。さらに、ハッシュ関数は常に同じで全ノードが共有するため、LoungeはHTTPリクエストのURIから得られる、任意のdocidから、必ず毎回同じノードにリクエストが渡されます。

This idea of splitting a collection of shards based on a keyspace is commonly illustrated as a ring, with the hash wrapped around the outside. Each tic mark designates the boundaries in the keyspace between two partitions. The hash function maps from document IDs to positions on the ring. The ring is continuous so that you can always add more nodes by splitting a single partition into pieces. With four physical servers, you allocate the keyspace into 16 independent partitions by distributing them across the servers like so:

キー空間に基づいていくつかのshardに分割するという考え方は、ハッシュ値が演習に乗っている輪っかにすると分かりやすくなります。それぞれの目盛がキー空間の二つのパーティションの境界になります。ハッシュ関数はドキュメントIDを輪っかの上の位置に変換します。輪っかは連続的なので、パーティションを分割することによっていつでもノードを追加することができます。4台の物理サーバがあれば、キー空間を16個に分割して、それぞれをサーバに次のように配置できます:

A0,1,2,3
B4,5,6,7
C8,9,a,b
Dc,d,e,f

If the hash of your DocID starts with 0, it would be dispatched to shard A. Similarly for 1, 2, or 3. Whereas, if the hash started with c, d, e, or f, it would be dispatched to shard D. As a full example, the hash 71db329b58378c8fa8876f0ec04c72e5 is mapped to the node B, database 7 in the table just shown. This could map to http://B.couches.local/db-7/ on your backend cluster. In this way, the hash table is just a mapping from hashes to backend database URIs. Don’t worry if this all sounds very complex; all you have to do is provide a mapping of shards to nodes and Lounge will build the hash ring appropriately—so no need to get your hands dirty if you don’t want to.

もし、あなたのdocidのハッシュ値が "0" から始まっていれば、shard Aにディスパッチされるでしょう。同様に "1", "2", "3" もAにディスパッチされるでしょう。一方、ハッシュ値が "c", "d", "e", "f" からであれば、shard Dにディスパッチされるでしょう。例えば、ハッシュ値 "71db329b58378c8fa8876f0ec04c72e5" はノードBのデータベース 7 へディスパッチされるでしょう。これは、あなたのバックエンドクラスタでは http://B.couches.local/db-7/ を意味します。このようにして、ハッシュテーブルはハッシュ値からバックエンドのデータベースへのURIとなります。これはとても複雑に見えますが、shardのノードへのマッピングを決めるだけでLoungeはハッシュリング(ハッシュ値の輪っか)を構築してくれます。あなた自身が手を汚すことはありません。

To frame the same concept with web architecture, because CouchDB uses HTTP, the proxy can partition documents according to the request URL, without inspecting the body. This is a core principle behind REST and is one of the many benefits using HTTP affords us. In practice, this is accomplished by running the hash function against the request URI and comparing the result to find the portion of the keyspace allocated. Lounge then looks up the associated shard for the hash in a configuration table, forwarding the HTTP request to the backend CouchDB server.

Webアーキテクチャと同じ概念の枠組みで、CouchDBはHTTPを使うので、プロキシはリクエストURLだけで(中身を見ることなく)振り分けることができます。これはRESTの背後にある中核の原則で、HTTPにより享受できる最大の利益のひとつです。実際には、リクエストURIをハッシュ関数にかけて、その結果からキー空間の部分を見つけることによって、それを実現しています。Loungeは設定テーブルから関連するshardを探して、HTTPリクエストをバックエンドのCouchDBサーバに転送します。

Consistent hashing is a simple way to ensure that you can always find the documents you saved, while balancing storage load evenly across partitions. Because the hash function is simple (it is based on CRC32), you are free to implement your own HTTP intermediaries or clients that can similarly resolve requests to the correct physical location of your data.

コンシステント・ハッシュ法は、あなたが保存したドキュメントを見つけられることを保証しながらトレージの負荷をパーティション同士で分散するための、シンプルな方法です。ハッシュ関数がシンプルなため(CRC32に基づいています)、アプリケーション毎に独自のHTTP中間層やクライアントを使って、同様にリクエストを正しい物理ロケーションへ場所解決していくことができます。

Redundant Storage

冗長構成のストレージ

Consistent hashing solves the problem of how to break up a single logical database evenly across a set of partitions, which can then be distributed across multiple servers. It does not address the problem of how to ensure that data you’ve stored is safe from loss due to hardware or software failure. If you are serious about your data, you can’t consider it saved until you have at least two copies of it, preferably in different geographical locations.

コンシステント・ハッシュ法はひとつの論理データベースを分割して複数のパーティション(複数のサーバ)にするときの問題を解決します。しかし、ソフトウェアやハードウェアの故障からあなたのデータをどうやって守るかの問題の解決にはなっていません。もしも、データを絶対に失いたくないのであれば、少なくとも二つの複製を(できれば地理的に分散させて)保持しておくのがよいでしょう。

CouchDB replication makes maintaining hot-failover redundant slaves or load-balanced multi-master databases relatively painless. The specifics of how to manage replication are covered in Chapter 16, Replication. What is important in this context is to understand that maintaining redundant copies is orthogonal to the harder task of ensuring that the cluster consistently chooses the same partition for a particular document ID.

CouchDBのレプリケーションはホット・スタンバイの冗長スレーブの管理や、負荷分散用のマルチアクトデータベースをいくらか楽にしてくれます。レプリケーション管理の方法や特色は レプリケーションの章に書かれています。ここで重要なのは、複数のコピーを冗長化して保持するのは、クラスタはひとつのドキュメントIDに対して一貫して同じ(コンシステントな)パーティションを選ぶという困難な問題とは直交しているということです。

For data safety, you’ll want to have at least two or three copies of everything. However, if you encapsulate redundancy, the higher layers of the cluster can treat each partition as a single unit and let the logical partitions themselves manage redundancy and failover.

データを守るために、全てのデータに対して少なくとも2、3のコピーを持ちたいと思うかもしれませんが、冗長性を維持するためには、クラスタの上位レイヤでそれぞれのパーティション単位で維持し、論理的なパーティションを自動的に冗長化し、フェイルオーバーできるようにしなければなりません。

Redundant Proxies

冗長構成のプロキシ

Just as we can’t accept the possibility of hardware failure leading to data loss, we’ll need to run multiple instances of the proxy nodes to avoid the chance that a proxy node crash could leave portions of the cluster unavailable. By running redundant proxy instances, and load balancing across them, we can increase cluster throughput as well as reliability.

ハードウェア故障によってデータがなくなる可能性はどうしても受け入れられないので、複数のプロキシノードを立てることによって、クラスタのパーティションにアクセスできなくなることを防ぐ必要があります。プロキシを冗長構成で運用することによって、プロキシ同士での負荷分散とクラスタのスループットと信頼性が向上します。

View Merging

ビューのマージ

Consistent hashing leaves documents on the proper node, but documents can still emit() any key. The point of incremental MapReduce is to bring the function to the data, so we shoudn’t redistribute the emitted keys; instead, we send the queries to the CouchDB nodes via HTTP proxy, and merge the results using the Twisted Python Smartproxy.

コンシステント・ハッシュ法はドキュメントを正しいノードに置きますが、ドキュメントはどんなキーでも emit() することができます。インクリメンタルな map reduce は関数をデータのあるところまで運ぶため、emitされたキーを再配布する必要はありません。代わりに、HTTPプロキシを通じてクエリをCouchDBノードに送り、Twisted Python Smartproxy を使って結果をマージします。

Smartproxy sends each view request to every node, so it needs to merge the responses before returning them to the client. Thankfully, this operation is not resource-intensive, as merging can be done in constant memory space no matter how many rows are returned. The Smartproxy receives the first row from each cluster node and compares them. We sort the nodes according to their row key using CouchDB’s collation rules. Smartproxy pops the top row from the first sorted node and returns it to the client.

Smartproxy はそれぞれのビューのリクエストを全てのノードに送り、結果をクライアントに返す前にマージします。幸運なことにこのオペレーションは、マージ自体は、データがいくら得られようとも、一定のメモリで完了できるため、リソースがネックになることはありません。Smartproxyは各ノードからそれぞれの最初のデータを受け取り、CouchDBの照合ルールに基づいて比較します。Smartproxyはソートされたリストの中から最初のデータを取り出し、クライアントに返します。

This process can be repeated as long as the clients continue to send rows, but if a limit is imposed by the client, Smartproxy must end the response early, discarding any extra rows sent by the nodes.

この過程はクライアントがデータを送り続ける限り繰り返されますが、クライアントが上限を設けていた場合、Smartproxyはレスポンスを早めに止めて以降、各ノードからこれ以上のデータが送られても無視します。

This layout is simple and loosely coupled. It has the advantage that it’s simple, which helps in understanding topology and diagnosing failures. There is work underway to move the behavior to Erlang, which ought to make managing dynamic clusters possible as well as let us integrate cluster control into the CouchDB runtime.

このレイアウトはシンプルで粗結合です。このため、考えやすいでしし、トポロジーや故障解析の助けになります。動的なクラスタ管理によって、クラスタ管理をCouchDBランタイムに組み込むために、Erlangの挙動を変えるという取り組みもあります。

Growing the Cluster

クラスタの拡大

Using CouchDB at web scale likely requires CouchDB clusters that can be scaled dynamically. Growing sites must continuously add more storage capacity, so we need a strategy to increase the size of our cluster without taking it down. Some workloads can result in temporary growth in data size, in which case we’ll also need a process for shrinking the cluster without an interruption in service.

Web規模でCouchDBを使う場合、動的にスケールさせることができるCouchDBクラスタが必要になるでしょう。システムを拡大するために、ストレージを追加しなければならないので、クラスタを落とすことなく拡張していくための戦略が必要になります。サイトのタイプによっては、データが増えるのが一時的なものがあります。そういうものについては、サービスを止めずにクラスタを小さくしていくプロセスも必要です。

In this section, we’ll see how we can use CouchDB’s replication filters to split one database into several partitions, and how to use that technique to grow the cluster without downtime. There are simple steps you can take to avoid partitioning databases while growing the cluster.

このセクションでは、CouchDBのレプリケーションフィルタを使ってデータベースをいくつかのパーティションに自動的に分割する方法や、サービスを停止せずにクラスタを拡大する方法を説明します。クラスタを拡大している間にパーティション分割が発生するのを防ぐためにいくつかのステップがあります。

Oversharding is a technique where you partition the cluster so that there are multiple shards on each physical machine. Moving a partition from one machine to another is simpler than splitting it into smaller partitions, as the configuration map of the cluster used by the proxy only needs to change to point to shards at their new homes, rather than adding new logical shards. It’s also less resource-intensive to move a partition than to split it into many.

多めにshardに分割するのは、複数のshardが個々の物理マシンに乗っているようにクラスタを分割するテクニックです。パーティションをマシン間で移動させるのは、パーティションをより小さく分割するよりもシンプルで、それに合わせてプロキシが持っているクラスタの設定マップを変更する必要があります。とはいえ、新しくshardを追加するよりは楽ですし、パーティションを分割するよりも移動する方が、システムに対する負荷も軽いです。

One question we need to answer is, “How much should we overshard?” The answer depends on your application and deployment, but there are some forces that push us in one direction over another. If we get the number of shards right, we’ll end up with a cluster that can grow optimally.

さて気になるのは「どの程度shardを多めにしておけばよいの?」ということですが、答えはアプリケーションやデプロイによりますが、判断材料はあります。正しくshardの数を設定できれば、最適にシステムを拡張することができるでしょう。

In the section called “View Merging”, we discussed how merges can be accomplished in constant space, no matter the number of rows returned. The memory space and network resources required to merge views, as well as to map from document IDs to partitions, does, however, grow linearly with the number of partitions under a given proxy. For this reason, we’ll want to limit the number of partitions for each proxy. However, we can’t accept an upper limit on cluster size. The solution is to use a tree of proxies, where the root proxy partitions to some number of intermediate proxies, which then proxy to database nodes.

「ビューのマージ」のセクションの冒頭でマージはデータ量によらず一定のリソース量で処理できることを書きました。メモリ空間とネットワークのリソースがビューをマージするために必要ですが、ドキュメントIDからパーティション毎にマップを行うのと同程度で、プロキシ数が一定なら線形に増加します。この理由から、プロキシ毎に担当するパーティションの数を制限した方がよいのです。しかし、クラスタの規模に上限をつけたくありませんから、プロキシをツリー状に配置します。ルートプロキシはいくつかの中間プロキシを配下にして、中間プロキシはデータベースノードを配下にします。

The factors that come into play when deciding how many partitions each proxy should manage are: the storage available to each individual server node, the projected growth rate of the data, the network and memory resources available to proxies, and the acceptable latency for requests against the cluster.

プロキシ毎にいくつパーティションをつけるかを決めるための判断材料は:個々のサーバが持っているストレージ、データの増加率、プロキシが利用可能なネットワークとメモリ量、そして、リクエストに対して許容されるレイテンシです。

Assuming a conservative 64 shards per proxy, and 1 TB of data storage per node (including room for compaction, these nodes will need roughly 2 TB of drive space), we can see that with a single proxy in front of CouchDB data nodes, we’ll be able to store at maximum 64 TB of data (on 128 or perhaps 192 server nodes, depending on the level of redundancy required by the system) before we have to increase the number of partitions.

保守的に、プロキシ当たり64のshardと、ノード当たり1TBのストレージ容量(コンパクションを考えると結局2TBは必要でしょう)があれば、CouchDBのデータノードに対してひとつのプロキシで十分で、パーティションの数を増やさずに最大で64TB程度のデータ(要求される冗長性によっては128ノードだったり192ノード必要だったりします)まで格納できるでしょう。

By replacing database nodes with another proxy, and repartitioning each of the 64 partitions into another 64 partitions, we end up with 4,096 partitions and a tree depth of 2. Just as the initial system can hold 64 partitions on just a few nodes, we can transition to the 2-layer tree without needing thousands of machines. If we assume each proxy must be run on its own node, and that at first database nodes can hold 16 partitions, we’ll see that we need 65 proxies and 256 database machines (not including redundancy factors, which should typically multiply the cluster size by two or three times). To get started with a cluster that can grow smoothly from 64 TB to 4 PB, we can begin with roughly 600 to 1,000 server nodes, adding new ones as data size grows and we move partitions to other machines.

データベースノードをプロキシで置換して64個のパーティションそれぞれを64個のパーティションに分割することによって、ツリーの深さを2にして4096パーティションまで保持することができます。初期のシステムが64個のパーティションをわずか2〜3のノードに持たせることができるのと同様に、2層のツリーにするために数千台のノードを実際に持つ必要はありません。個々のプロキシが自らのノード上で動作しているなら、最初はデータベースノードは16個のパーティションを持てますし、65個のプロキシと256個のデータベースマシンが必要になります(冗長性を今は考慮していませんが、ふつうは2倍から3倍の物理ノードが必要です)。64TBから4PBまでスムーズに拡張できるクラスタ構成で始めるためには、600から1000のサーバで初めて、データ量が増えてきたらパーティションを移していけばよいのです。

We’ve seen that even a cluster with a depth of 2 can hold a vast amount of data. Basic arithmetic shows us that by applying the same process to create a cluster with three layers of proxies, we can manage 262 petabytes on thousands of machines. Conservative estimates for the latency introduced by each layer is about 100 ms, so even without performance tuning we should see overall response times of 300 ms even with a tree depth of 3, and we should be able to manage queries over exabyte datasets in less than a second.

深さ2のクラスタですら、大量のデータを持っておけることが分かりました。簡単な算数で、同様のことを3レイヤのプロキシで組めば、262PBのデータを数千台のマシンで管理できます。保守的な推定してもそれぞれのレイヤでのレイテンシは 100ms 程度で、パフォーマンスチューニングすらしないで、最終的なレスポンスタイムが300msであることが分かりますし、エクサバイト規模であっても一秒以内にクエリを処理できるでしょう。

By using oversharding and iteratively replacing full shards (database nodes that host only one partition) with proxy nodes that point to another set of oversharded partitions, we can grow the cluster to very large sizes while incurring a minimum of latency.

多めにshard分割しておくことで、満杯になったshardを順番に交換していって(データベースノードはひとつのパーティションしか持たない)、プロキシノードで他のパーティションを指すようにしておけば、最低限のレイテンシでクラスタを大きなサイズに拡張していくことができます。 TODO: shard, partition, database, 包含関係が不明。絵がほしい…

Now we need to look at the mechanics of the two processes that allow the cluster to grow: moving a partition from an overcrowded node to an empty node, and splitting a large partition into many subpartitions. Moving partitions is simpler, which is why it makes sense to use it when possible, running the more resource-intensive repartition process only when partitions get large enough that only one or two can fit on each database server.

クラスタを拡張するためのふたつの方法を知っておく必要があります:満杯になってきたノードから空のノードへのパーティション移動と、巨大なパーティションの複数のサブパーティションへの分割です。パーティション移動は比較的簡単で、可能なときはこちらを使った方がよいですし、ひとつのパーティションがひとつのデータベースサーバを独占するくらい大きくなったときに限ってより負荷の大きい再分割を使うべきです。

Moving Partitions

パーティションの移動

As we mentioned earlier, each partition is made up of N redundant CouchDB databases, each stored on different physical servers. To keep things easy to conceptualize, any operations should be applied to all redundant copies automatically. For the sake of discussion, we’ll just talk about the abstract partition, but be aware that the redundant nodes will all be the same size and so should require the same operations during cluster growth.

上記の通り、それぞれのパーティションは N個のCouchDBデータベースに冗長化されており、それぞれ異なる物理サーバに保持されています。考えやすいように全てのオペレーションは自動的に複製に反映されることとします。また簡便のため抽象化されたパーティションのことだけについて話しますが、冗長化されたノードは全て同じサイズで、クラスタを拡張する際には全て同じオペレーションを必要とします。

The simplest way to move a partition from one node to another is to create an empty database on the target node and use CouchDB replication to fill the new node with data from the old node. When the new copy of the partition is up-to-date with the original, the proxy node can be reconfigured to point to the new machine. Once the proxy points to the new partition location, one final round of replication will bring it up-to-date, and the old partition can be retired, freeing space on the original machine.

あるノードからパーティションを移す最も簡単な方法は、空のデータベースをターゲットとして作って、CouchDBのレプリケーション機能を使って古いノードから新しいノードへデータを移す方法です。パーティションの新しいコピーがオリジナルに追いついた時点で、プロキシノードの設定を変更して新しいノードを指すようにします。一旦プロキシが新しいパーティションを指すようになれば、レプリケーションの最終段階で追いつきが完了すると同時に古いパーティションを削除し、マシンの空間を空けてやります。

Another method for moving partition databases is to rsync the files on disk from the old node to the new one. Depending on how recently the partition was compacted, this should result in efficient, low-CPU initialization of a new node. Replication can then be used to bring the rsynced file up-to-date. See more about rsync and replication in Chapter 16, Replication.

パーティションを移すもうひとつの方法は、ディスク上のファイルを、古いノードから新しいノードへファイルをrsyncすることです。パーティションがいつコンパクションしたかによりますが、新しいノードへのCPU負荷が低く効率的なものになるでしょう。レプリケーションは、rsyncが完了してからでも使えます。rsyncとレプリケーションのことについては レプリケーションの章 にあります。

Splitting Partitions

パーティションの分割

The last major thing we need to run a CouchDB cluster is the capability to split an oversized partition into smaller pieces. In Chapter 16, Replication, we discussed how to do continuous replication using the _changes API. The _changes API can use filters (see Chapter 20, Change Notifications), and replication can be configured to use a filter function to replicate only a subset of a total database. Splitting partitions is accomplished by creating the target partitions and configuring them with the range of hash keys they are interested in. They then apply filtered replication to the source partition database, requesting only documents that meet their hash criteria. The result is multiple partial copies of the source database, so that each new partition has an equal share of the data. In total, they have a complete copy of the original data. Once the replication is complete and the new partitions have also brought their redundant backups up-to-date, a proxy for the new set of partitions is brought online and the top-level proxy is pointed at it instead of the old partition. Just like with moving a partition, we should do one final round of replication after the old partition is no longer reachable by the cluster, so that any last second updates are not lost. Once that is done, we can retire the old partition so that its hardware can be reused elsewhere in the cluster.

最後の重要なことは、大きくなりすぎたパーティションを小さなものに分割できるようにCouchDBクラスタを構築することです。レプリケーションの章 では、フィルタつきレプリケーションについて述べました。パーティション分割はターゲットになるパーティションを作って、担当しているハッシュキーの範囲を設定すればできます。そのとき、ソースパーティションに対して、フィルタつきレプリケーションをかけることによって、ハッシュ値の範囲が一致しているドキュメントだけをリクエストできます。これによっって、ソースとなるデータベースの一部をコピーした者が複数できることになり、それぞれのパーティションが均等にデータを持っている状態となります。トータルとしては、オリジナルの完全なコピーが保持されていることになります。一度レプリケーションが完了して新しいパーティションが冗長化のためのバックアップも完了したら、新しいパーティションのためのプロキシを起動し、トップレベルプロキシは新しいプロキシを指すようになります。パーティションを移動させるのと同様に、最後の瞬間のデータ更新も失われないように、古いパーティションの更新が停止してから最後のレプリケーションを行う必要があります。これが完了すれば、古いパーティションを削除してハードウェアをクラスタの他の部分で再利用できます。